From 805c1cec609b39ee5a0ba1517bf2f1d41e0c4fa9 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Thu, 18 Aug 2011 15:05:35 -0700 Subject: allow specification of key pair/security group info via metadata extract metadata about keypair / security group configuration from server metadata sent on create. This allows users to use these extensions with their existing api implementations. Also remove the code that choose the first key pair in the tenant - since it seems to have been used during the development of os api --- nova/api/openstack/create_instance_helper.py | 21 ++++++++------------- nova/api/openstack/servers.py | 1 - 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index b4a08dac0..031b06921 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -73,20 +73,15 @@ class CreateInstanceHelper(object): if not 'server' in body: raise exc.HTTPUnprocessableEntity() - server_dict = body['server'] context = req.environ['nova.context'] + server_dict = body['server'] + metadata = server_dict.get('metadata', {}) password = self.controller._get_server_admin_password(server_dict) - key_name = None - key_data = None - # TODO(vish): Key pair access should move into a common library - # instead of being accessed directly from the db. - key_pairs = db.key_pair_get_all_by_user(context.elevated(), - context.user_id) - if key_pairs: - key_pair = key_pairs[0] - key_name = key_pair['name'] - key_data = key_pair['public_key'] + # NOTE(ja): extract key_name and security_group from metadata + # to use in os extensions for firewall & keypairs + key_name = metadata.get('key_name') + security_group = metadata.get('security_group') image_href = self.controller._image_ref_from_req_data(body) # If the image href was generated by nova api, strip image_href @@ -155,8 +150,8 @@ class CreateInstanceHelper(object): display_name=name, display_description=name, key_name=key_name, - key_data=key_data, - metadata=server_dict.get('metadata', {}), + security_group=security_group, + metadata=metadata, injected_files=injected_files, admin_password=password, zone_blob=zone_blob, diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 335ecad86..2cf4e3eda 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -146,7 +146,6 @@ class Controller(object): def create(self, req, body): """ Creates a new server for a given user """ extra_values = None - result = None extra_values, instances = self.helper.create_instance( req, body, self.compute_api.create) -- cgit From bbe414cba5d389b553fb3122a3a7dbc9c6d898f2 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Thu, 18 Aug 2011 16:26:32 -0700 Subject: follow same pattern as userdata (not metadata apporach) --- nova/api/openstack/create_instance_helper.py | 27 +++++++++++++-------------- nova/api/openstack/views/servers.py | 3 +++ 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index e64a076c8..c2e9e76ac 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -75,13 +75,15 @@ class CreateInstanceHelper(object): context = req.environ['nova.context'] server_dict = body['server'] - metadata = server_dict.get('metadata', {}) password = self.controller._get_server_admin_password(server_dict) - # NOTE(ja): extract key_name and security_group from metadata - # to use in os extensions for firewall & keypairs - key_name = metadata.get('key_name') - security_group = metadata.get('security_group') + if not 'name' in server_dict: + msg = _("Server name is not defined") + raise exc.HTTPBadRequest(explanation=msg) + + name = server_dict['name'] + self._validate_server_name(name) + name = name.strip() image_href = self.controller._image_ref_from_req_data(body) # If the image href was generated by nova api, strip image_href @@ -112,16 +114,13 @@ class CreateInstanceHelper(object): msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) - if not 'name' in server_dict: - msg = _("Server name is not defined") - raise exc.HTTPBadRequest(explanation=msg) - zone_blob = server_dict.get('blob') - user_data = server_dict.get('user_data') availability_zone = server_dict.get('availability_zone') - name = server_dict['name'] - self._validate_server_name(name) - name = name.strip() + + # optional openstack extensions: + key_name = server_dict.get('key_name') + security_group = server_dict.get('security_group') + user_data = server_dict.get('user_data') reservation_id = server_dict.get('reservation_id') min_count = server_dict.get('min_count') @@ -152,7 +151,7 @@ class CreateInstanceHelper(object): display_description=name, key_name=key_name, security_group=security_group, - metadata=metadata, + metadata=server_dict.get('metadata', {}), injected_files=injected_files, admin_password=password, zone_blob=zone_blob, diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index edc328129..ac2de0c57 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -78,6 +78,9 @@ class ViewBuilder(object): metadata[item['key']] = str(item['value']) inst_dict['metadata'] = metadata + inst_dict['key_name'] = inst.get('key_name') + inst_dict['security_group'] = inst.get('security_group') + inst_dict['hostId'] = '' if inst.get('host'): inst_dict['hostId'] = hashlib.sha224(inst['host']).hexdigest() -- cgit From f4f0ce95946962be73cfc509b24fd000fc931198 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Thu, 18 Aug 2011 16:46:16 -0700 Subject: tests pass --- nova/api/openstack/views/servers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index ac2de0c57..285228b30 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -78,8 +78,8 @@ class ViewBuilder(object): metadata[item['key']] = str(item['value']) inst_dict['metadata'] = metadata - inst_dict['key_name'] = inst.get('key_name') - inst_dict['security_group'] = inst.get('security_group') + inst_dict['key_name'] = inst.get('key_name', '') + inst_dict['security_group'] = inst.get('security_group', '') inst_dict['hostId'] = '' if inst.get('host'): -- cgit From 203309693fc2dd648b9d4b211686228557728c89 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 18 Aug 2011 19:05:40 -0700 Subject: remove security groups, improve exception handling, add tests --- nova/api/openstack/create_instance_helper.py | 5 +++-- nova/api/openstack/views/servers.py | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index c2e9e76ac..84d8c0c39 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -119,7 +119,6 @@ class CreateInstanceHelper(object): # optional openstack extensions: key_name = server_dict.get('key_name') - security_group = server_dict.get('security_group') user_data = server_dict.get('user_data') reservation_id = server_dict.get('reservation_id') @@ -150,7 +149,6 @@ class CreateInstanceHelper(object): display_name=name, display_description=name, key_name=key_name, - security_group=security_group, metadata=server_dict.get('metadata', {}), injected_files=injected_files, admin_password=password, @@ -168,6 +166,9 @@ class CreateInstanceHelper(object): except exception.FlavorNotFound as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) + except exception.KeypairNotFound as error: + msg = _("Invalid key_name provided.") + raise exc.HTTPBadRequest(explanation=msg) # Let the caller deal with unhandled exceptions. def _handle_quota_error(self, error): diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 285228b30..c0df5abe6 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -79,7 +79,6 @@ class ViewBuilder(object): inst_dict['metadata'] = metadata inst_dict['key_name'] = inst.get('key_name', '') - inst_dict['security_group'] = inst.get('security_group', '') inst_dict['hostId'] = '' if inst.get('host'): -- cgit From 19cb3672f2849fe659173631f7f81ed489f1ea7e Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Fri, 26 Aug 2011 17:46:47 -0700 Subject: v1.0 of server create injects first users keypair --- nova/api/openstack/create_instance_helper.py | 1 - nova/api/openstack/servers.py | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index e7428bf41..d82cb534f 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -19,7 +19,6 @@ import base64 from webob import exc from xml.dom import minidom -from nova import db from nova import exception from nova import flags from nova import log as logging diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index ad563b771..f288f2228 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -22,6 +22,7 @@ from xml.dom import minidom import webob from nova import compute +from nova import db from nova import exception from nova import flags from nova import log as logging @@ -563,6 +564,18 @@ class ControllerV10(Controller): raise exc.HTTPNotFound() return webob.Response(status_int=202) + def create(self, req, body): + """ Creates a new server for a given user """ + # note(ja): v1.0 injects the first keypair for the project for testing + if 'server' in body and not 'key_name' in body['server']: + context = req.environ["nova.context"] + keypairs = db.key_pair_get_all_by_user(context.elevated(), + context.user_id) + if keypairs: + body['server']['key_name'] = keypairs[0]['name'] + + return super(ControllerV10, self).create(req, body) + def _image_ref_from_req_data(self, data): return data['server']['imageId'] -- cgit From abd6b240b5247a2981e86c1d3161306fb2b4c4c5 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 31 Aug 2011 12:02:14 -0700 Subject: moved key_name per review --- nova/api/openstack/views/servers.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 35821f9a7..cd01c9373 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -79,8 +79,6 @@ class ViewBuilder(object): metadata[item['key']] = str(item['value']) inst_dict['metadata'] = metadata - inst_dict['key_name'] = inst.get('key_name', '') - inst_dict['hostId'] = '' if inst.get('host'): inst_dict['hostId'] = hashlib.sha224(inst['host']).hexdigest() @@ -190,6 +188,7 @@ class ViewBuilderV11(ViewBuilder): def _build_extra(self, response, inst): self._build_links(response, inst) response['uuid'] = inst['uuid'] + response['key_name'] = inst.get('key_name', '') self._build_config_drive(response, inst) def _build_links(self, response, inst): -- cgit From c9758dd4832c167562baefad5dcc88f2a1a19b73 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 31 Aug 2011 12:51:16 -0700 Subject: fix keypairs stubs --- nova/api/openstack/create_instance_helper.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index d82cb534f..744353f31 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -189,6 +189,7 @@ class CreateInstanceHelper(object): raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound as error: msg = _("Invalid key_name provided.") + raise exc.HTTPBadRequest(explanation=msg) except exception.SecurityGroupNotFound as error: raise exc.HTTPBadRequest(explanation=unicode(error)) except RemoteError as err: -- cgit From 9de8a589b4ee0e007267efe2394b504382e4cdc1 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 31 Aug 2011 14:58:55 -0700 Subject: change to use _get_key_name to retrieve the key --- nova/api/openstack/servers.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index f288f2228..53684fa52 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -144,8 +144,15 @@ class Controller(object): except exception.NotFound: raise exc.HTTPNotFound() + def _get_key_name(self, req, body): + """ Get default keypair if not set """ + raise NotImplementedError() + def create(self, req, body): """ Creates a new server for a given user """ + if 'server' in body: + body['server']['key_name'] = self._get_key_name(req, body) + extra_values = None extra_values, instances = self.helper.create_instance( req, body, self.compute_api.create) @@ -564,17 +571,12 @@ class ControllerV10(Controller): raise exc.HTTPNotFound() return webob.Response(status_int=202) - def create(self, req, body): - """ Creates a new server for a given user """ - # note(ja): v1.0 injects the first keypair for the project for testing - if 'server' in body and not 'key_name' in body['server']: - context = req.environ["nova.context"] - keypairs = db.key_pair_get_all_by_user(context.elevated(), - context.user_id) - if keypairs: - body['server']['key_name'] = keypairs[0]['name'] - - return super(ControllerV10, self).create(req, body) + def _get_key_name(self, req, body): + context = req.environ["nova.context"] + keypairs = db.key_pair_get_all_by_user(context, + context.user_id) + if keypairs: + return keypairs[0]['name'] def _image_ref_from_req_data(self, data): return data['server']['imageId'] @@ -647,6 +649,10 @@ class ControllerV11(Controller): except exception.NotFound: raise exc.HTTPNotFound() + def _get_key_name(self, req, body): + if 'server' in body: + return body['server'].get('key_name') + def _image_ref_from_req_data(self, data): try: return data['server']['imageRef'] -- cgit