Added Nova vendordata POST API.

This commit is contained in:
Pino de Candia 2017-10-30 20:06:57 +00:00
parent 79a56d259c
commit 95a183a301
3 changed files with 66 additions and 2 deletions

View File

@ -10,7 +10,8 @@ def create_app(sa):
api.add_route('/usercerts/{user_id}/{fingerprint}', models.UserCert())
api.add_route('/hostcerts', models.HostCerts())
api.add_route('/hostcerts/{host_id}/{fingerprint}', models.HostCert())
api.add_route('/hosttokens', models.Token())
api.add_route('/hosttokens', models.Tokens())
api.add_route('/novavendordata', models.NovaVendorData())
return api

View File

@ -99,7 +99,7 @@ class HostCert(object):
resp.body = json.dumps(body)
resp.status = falcon.HTTP_OK
class Token(object):
class Tokens(object):
def on_post(self, req, resp):
body = None
@ -113,3 +113,39 @@ class Token(object):
)
resp.status = falcon.HTTP_201
resp.location = '/hosttokens/' + token.token_id
class NovaVendorData(object):
def on_post(self, req, resp):
# An example of the data nova sends to vendordata services:
# {
# "hostname": "foo",
# "image-id": "75a74383-f276-4774-8074-8c4e3ff2ca64",
# "instance-id": "2ae914e9-f5ab-44ce-b2a2-dcf8373d899d",
# "metadata": {},
# "project-id": "039d104b7a5c4631b4ba6524d0b9e981",
# "user-data": null
# }
body = None
if req.content_length:
body = json.load(req.stream)
token = db.createToken(
self.session,
body['instance-id'],
body['project-id'],
body['hostname']
)
auth = db.getAuthority(self.session, body['project-id'])
if auth is None:
resp.status = falcon.HTTP_NOT_FOUND
return
key = RSA.importKey(auth.user_key)
pub_key = key.publickey().exportKey('OpenSSH')
vendordata = {
'token': token.token_id,
'auth_pub_key_user': pub_key,
'principals': 'admin'
}
resp.body = json.dumps(vendordata)
resp.location = '/hosttokens/' + token.token_id
resp.status = falcon.HTTP_201

View File

@ -32,6 +32,7 @@ user_pub_key = user_key.publickey().exportKey('OpenSSH')
user_fingerprint = sshpubkeys.SSHKey(user_pub_key).hash()
auth_id = str(uuid.uuid4())
auth_user_pub_key = None
@pytest.mark.dependency()
def test_post_authority(client, db):
@ -55,6 +56,8 @@ def test_get_authority(client):
body = json.loads(response.content)
assert 'auth_id' in body
assert 'user_key.pub' in body
global auth_user_pub_key
auth_user_pub_key = body['user_key.pub']
assert 'host_key.pub' in body
assert 'user_key' not in body
assert 'host_key' not in body
@ -147,6 +150,30 @@ def host_request(token, host=host_id, pub_key=host_pub_key):
'key.pub': pub_key
}
@pytest.mark.dependency(depends=['test_post_authority'])
def test_post_novavendordata(client, db):
host = str(uuid.uuid4())
req = {
'instance-id': host,
'project-id': auth_id,
'hostname': 'mytest.testing'
}
response = client.simulate_post(
'/novavendordata',
body=json.dumps(req)
)
assert response.status == falcon.HTTP_CREATED
assert 'location' in response.headers
location_path = response.headers['location'].split('/')
assert location_path[1] == 'hosttokens'
vendordata = json.loads(response.content)
assert 'token' in vendordata
assert vendordata['token'] == location_path[-1]
assert 'auth_pub_key_user' in vendordata
assert vendordata['auth_pub_key_user'] == auth_user_pub_key
assert 'principals' in vendordata
assert vendordata['principals'] == 'admin'
@pytest.mark.dependency(depends=['test_post_authority'])
def test_post_token_and_host(client, db):
token = token_request()