From 28e937cd2bc19a4278c73ef7da0f71dfb3358fb8 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 14 Aug 2013 11:30:30 -0700 Subject: Make compute_api use KeyPair objects This makes compute_api's KeypairAPI use KeyPair objects to do its work. Most of the change here is to tests to account for the change. Related to blueprint compute-api-objects Change-Id: If516a88eac107670d9ae37fcfaf56f2add9dd0c5 --- nova/api/ec2/cloud.py | 7 ++-- nova/api/openstack/compute/contrib/keypairs.py | 23 +++++++---- nova/api/openstack/compute/plugins/v3/keypairs.py | 25 ++++++++---- nova/cloudpipe/pipelib.py | 7 ++-- nova/compute/api.py | 46 ++++++++++------------ nova/tests/api/ec2/test_cloud.py | 3 +- .../api/openstack/compute/contrib/test_keypairs.py | 22 +++++++---- .../openstack/compute/plugins/v3/test_keypairs.py | 22 +++++++---- nova/tests/api/openstack/compute/test_servers.py | 8 ++-- nova/tests/api/openstack/fakes.py | 7 +++- nova/tests/compute/test_keypairs.py | 22 ++++++----- 11 files changed, 113 insertions(+), 79 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 834ea2dece..7bf37928b1 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -444,15 +444,14 @@ class CloudController(object): LOG.audit(_("Create key pair %s"), key_name, context=context) try: - keypair = self.keypair_api.create_key_pair(context, - context.user_id, - key_name) + keypair, private_key = self.keypair_api.create_key_pair( + context, context.user_id, key_name) except exception.KeypairLimitExceeded: msg = _("Quota exceeded, too many key pairs.") raise exception.EC2APIError(msg, code='ResourceLimitExceeded') return {'keyName': key_name, 'keyFingerprint': keypair['fingerprint'], - 'keyMaterial': keypair['private_key']} + 'keyMaterial': private_key} # TODO(vish): when context is no longer an object, pass it here def import_key_pair(self, context, key_name, public_key_material, diff --git a/nova/api/openstack/compute/contrib/keypairs.py b/nova/api/openstack/compute/contrib/keypairs.py index 2a7c44b06c..3dc7941ed0 100644 --- a/nova/api/openstack/compute/contrib/keypairs.py +++ b/nova/api/openstack/compute/contrib/keypairs.py @@ -54,6 +54,16 @@ class KeypairController(object): def __init__(self): self.api = compute_api.KeypairAPI() + def _filter_keypair(self, keypair, **attrs): + clean = { + 'name': keypair.name, + 'public_key': keypair.public_key, + 'fingerprint': keypair.fingerprint, + } + for attr in attrs: + clean[attr] = keypair[attr] + return clean + @wsgi.serializers(xml=KeypairTemplate) def create(self, req, body): """ @@ -84,9 +94,12 @@ class KeypairController(object): keypair = self.api.import_key_pair(context, context.user_id, name, params['public_key']) + keypair = self._filter_keypair(keypair, user_id=True) else: - keypair = self.api.create_key_pair(context, context.user_id, - name) + keypair, private_key = self.api.create_key_pair( + context, context.user_id, name) + keypair = self._filter_keypair(keypair, user_id=True) + keypair['private_key'] = private_key return {'keypair': keypair} @@ -134,11 +147,7 @@ class KeypairController(object): key_pairs = self.api.get_key_pairs(context, context.user_id) rval = [] for key_pair in key_pairs: - rval.append({'keypair': { - 'name': key_pair['name'], - 'public_key': key_pair['public_key'], - 'fingerprint': key_pair['fingerprint'], - }}) + rval.append({'keypair': self._filter_keypair(key_pair)}) return {'keypairs': rval} diff --git a/nova/api/openstack/compute/plugins/v3/keypairs.py b/nova/api/openstack/compute/plugins/v3/keypairs.py index adbd06c1b1..bb204082f4 100644 --- a/nova/api/openstack/compute/plugins/v3/keypairs.py +++ b/nova/api/openstack/compute/plugins/v3/keypairs.py @@ -55,6 +55,16 @@ class KeypairController(object): def __init__(self): self.api = compute_api.KeypairAPI() + def _filter_keypair(self, keypair, **attrs): + clean = { + 'name': keypair.name, + 'public_key': keypair.public_key, + 'fingerprint': keypair.fingerprint, + } + for attr in attrs: + clean[attr] = keypair[attr] + return clean + @wsgi.serializers(xml=KeypairTemplate) @extensions.expected_errors((400, 409, 413)) def create(self, req, body): @@ -86,9 +96,12 @@ class KeypairController(object): keypair = self.api.import_key_pair(context, context.user_id, name, params['public_key']) + keypair = self._filter_keypair(keypair, user_id=True) else: - keypair = self.api.create_key_pair(context, context.user_id, - name) + keypair, private_key = self.api.create_key_pair( + context, context.user_id, name) + keypair = self._filter_keypair(keypair, user_id=True) + keypair['private_key'] = private_key return {'keypair': keypair} @@ -126,7 +139,7 @@ class KeypairController(object): keypair = self.api.get_key_pair(context, context.user_id, id) except exception.KeypairNotFound: raise webob.exc.HTTPNotFound() - return {'keypair': keypair} + return {'keypair': self._filter_keypair(keypair)} @extensions.expected_errors(()) @wsgi.serializers(xml=KeypairsTemplate) @@ -139,11 +152,7 @@ class KeypairController(object): key_pairs = self.api.get_key_pairs(context, context.user_id) rval = [] for key_pair in key_pairs: - rval.append({'keypair': { - 'name': key_pair['name'], - 'public_key': key_pair['public_key'], - 'fingerprint': key_pair['fingerprint'], - }}) + rval.append({'keypair': self._filter_keypair(key_pair)}) return {'keypairs': rval} diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py index e44cd9c460..643406280f 100644 --- a/nova/cloudpipe/pipelib.py +++ b/nova/cloudpipe/pipelib.py @@ -171,10 +171,9 @@ class CloudPipe(object): key_name = '%s%s' % (context.project_id, CONF.vpn_key_suffix) try: keypair_api = compute.api.KeypairAPI() - result = keypair_api.create_key_pair(context, - context.user_id, - key_name) - private_key = result['private_key'] + result, private_key = keypair_api.create_key_pair(context, + context.user_id, + key_name) key_dir = os.path.join(CONF.keys_path, context.user_id) fileutils.ensure_tree(key_dir) key_path = os.path.join(key_dir, '%s.pem' % key_name) diff --git a/nova/compute/api.py b/nova/compute/api.py index 776f92d7b1..7656847361 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -55,6 +55,7 @@ from nova.objects import base as obj_base from nova.objects import instance as instance_obj from nova.objects import instance_action from nova.objects import instance_info_cache +from nova.objects import keypair as keypair_obj from nova.objects import security_group from nova.openstack.common import excutils from nova.openstack.common.gettextutils import _ @@ -669,9 +670,10 @@ class API(base.Base): config_drive = self._check_config_drive(config_drive) if key_data is None and key_name: - key_pair = self.db.key_pair_get(context, context.user_id, - key_name) - key_data = key_pair['public_key'] + key_pair = keypair_obj.KeyPair.get_by_name(context, + context.user_id, + key_name) + key_data = key_pair.public_key root_device_name = block_device.properties_root_device_name( boot_meta.get('properties', {})) @@ -3188,12 +3190,13 @@ class KeypairAPI(base.Base): fingerprint = crypto.generate_fingerprint(public_key) - keypair = {'user_id': user_id, - 'name': key_name, - 'fingerprint': fingerprint, - 'public_key': public_key} + keypair = keypair_obj.KeyPair() + keypair.user_id = user_id + keypair.name = key_name + keypair.fingerprint = fingerprint + keypair.public_key = public_key + keypair.create(context) - self.db.key_pair_create(context, keypair) return keypair def create_key_pair(self, context, user_id, key_name): @@ -3202,33 +3205,26 @@ class KeypairAPI(base.Base): private_key, public_key, fingerprint = crypto.generate_key_pair() - keypair = {'user_id': user_id, - 'name': key_name, - 'fingerprint': fingerprint, - 'public_key': public_key, - 'private_key': private_key} + keypair = keypair_obj.KeyPair() + keypair.user_id = user_id + keypair.name = key_name + keypair.fingerprint = fingerprint + keypair.public_key = public_key + keypair.create(context) - self.db.key_pair_create(context, keypair) - return keypair + return keypair, private_key def delete_key_pair(self, context, user_id, key_name): """Delete a keypair by name.""" - self.db.key_pair_destroy(context, user_id, key_name) - - def _get_key_pair(self, key_pair): - return {'name': key_pair['name'], - 'public_key': key_pair['public_key'], - 'fingerprint': key_pair['fingerprint']} + keypair_obj.KeyPair.destroy_by_name(context, user_id, key_name) def get_key_pairs(self, context, user_id): """List key pairs.""" - key_pairs = self.db.key_pair_get_all_by_user(context, user_id) - return [self._get_key_pair(k) for k in key_pairs] + return keypair_obj.KeyPairList.get_by_user(context, user_id) def get_key_pair(self, context, user_id, key_name): """Get a keypair by name.""" - key_pair = self.db.key_pair_get(context, user_id, key_name) - return self._get_key_pair(key_pair) + return keypair_obj.KeyPair.get_by_name(context, user_id, key_name) class SecurityGroupAPI(base.Base, security_group_base.SecurityGroupBase): diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py index 1c462a458c..17a449631a 100644 --- a/nova/tests/api/ec2/test_cloud.py +++ b/nova/tests/api/ec2/test_cloud.py @@ -1678,8 +1678,7 @@ class CloudTestCase(test.TestCase): rv = self.cloud.terminate_instances(self.context, [instance_id]) def test_key_generation(self): - result = self._create_key('test') - private_key = result['private_key'] + result, private_key = self._create_key('test') expected = db.key_pair_get(self.context, self.context.user_id, diff --git a/nova/tests/api/openstack/compute/contrib/test_keypairs.py b/nova/tests/api/openstack/compute/contrib/test_keypairs.py index 2cd7cd3dcf..358c91aae9 100644 --- a/nova/tests/api/openstack/compute/contrib/test_keypairs.py +++ b/nova/tests/api/openstack/compute/contrib/test_keypairs.py @@ -25,15 +25,21 @@ from nova.openstack.common import policy from nova import quota from nova import test from nova.tests.api.openstack import fakes +from nova.tests.objects import test_keypair QUOTAS = quota.QUOTAS +keypair_data = { + 'public_key': 'FAKE_KEY', + 'fingerprint': 'FAKE_FINGERPRINT', +} + + def fake_keypair(name): - return {'public_key': 'FAKE_KEY', - 'fingerprint': 'FAKE_FINGERPRINT', - 'name': name} + return dict(test_keypair.fake_keypair, + name=name, **keypair_data) def db_key_pair_get_all_by_user(self, user_id): @@ -41,7 +47,7 @@ def db_key_pair_get_all_by_user(self, user_id): def db_key_pair_create(self, keypair): - return keypair + return fake_keypair(name=keypair['name']) def db_key_pair_destroy(context, user_id, name): @@ -78,7 +84,7 @@ class KeypairsTest(test.TestCase): res = req.get_response(self.app) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) - response = {'keypairs': [{'keypair': fake_keypair('FAKE')}]} + response = {'keypairs': [{'keypair': dict(keypair_data, name='FAKE')}]} self.assertEqual(res_dict, response) def test_keypair_create(self): @@ -284,7 +290,8 @@ class KeypairsTest(test.TestCase): def test_keypair_show(self): def _db_key_pair_get(context, user_id, name): - return {'name': 'foo', 'public_key': 'XXX', 'fingerprint': 'YYY'} + return dict(test_keypair.fake_keypair, + name='foo', public_key='XXX', fingerprint='YYY') self.stubs.Set(db, "key_pair_get", _db_key_pair_get) @@ -356,7 +363,8 @@ class KeypairPolicyTest(test.TestCase): self.KeyPairController = keypairs.KeypairController() def _db_key_pair_get(context, user_id, name): - return {'name': 'foo', 'public_key': 'XXX', 'fingerprint': 'YYY'} + return dict(test_keypair.fake_keypair, + name='foo', public_key='XXX', fingerprint='YYY') self.stubs.Set(db, "key_pair_get", _db_key_pair_get) diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_keypairs.py b/nova/tests/api/openstack/compute/plugins/v3/test_keypairs.py index f16bdde1fe..6e5681a032 100644 --- a/nova/tests/api/openstack/compute/plugins/v3/test_keypairs.py +++ b/nova/tests/api/openstack/compute/plugins/v3/test_keypairs.py @@ -27,15 +27,21 @@ from nova.openstack.common import policy from nova import quota from nova import test from nova.tests.api.openstack import fakes +from nova.tests.objects import test_keypair QUOTAS = quota.QUOTAS +keypair_data = { + 'public_key': 'FAKE_KEY', + 'fingerprint': 'FAKE_FINGERPRINT', +} + + def fake_keypair(name): - return {'public_key': 'FAKE_KEY', - 'fingerprint': 'FAKE_FINGERPRINT', - 'name': name} + return dict(test_keypair.fake_keypair, + name=name, **keypair_data) def db_key_pair_get_all_by_user(self, user_id): @@ -43,7 +49,7 @@ def db_key_pair_get_all_by_user(self, user_id): def db_key_pair_create(self, keypair): - return keypair + return fake_keypair(name=keypair['name']) def db_key_pair_destroy(context, user_id, name): @@ -80,7 +86,7 @@ class KeypairsTest(test.TestCase): res = req.get_response(self.app) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) - response = {'keypairs': [{'keypair': fake_keypair('FAKE')}]} + response = {'keypairs': [{'keypair': dict(keypair_data, name='FAKE')}]} self.assertEqual(res_dict, response) def test_keypair_create(self): @@ -285,7 +291,8 @@ class KeypairsTest(test.TestCase): def test_keypair_show(self): def _db_key_pair_get(context, user_id, name): - return {'name': 'foo', 'public_key': 'XXX', 'fingerprint': 'YYY'} + return dict(test_keypair.fake_keypair, + name='foo', public_key='XXX', fingerprint='YYY') self.stubs.Set(db, "key_pair_get", _db_key_pair_get) @@ -358,7 +365,8 @@ class KeypairPolicyTest(test.TestCase): self.KeyPairController = keypairs.KeypairController() def _db_key_pair_get(context, user_id, name): - return {'name': 'foo', 'public_key': 'XXX', 'fingerprint': 'YYY'} + return dict(test_keypair.fake_keypair, + name='foo', public_key='XXX', fingerprint='YYY') self.stubs.Set(db, "key_pair_get", _db_key_pair_get) diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index 0f91cf3513..0c716441f2 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -58,6 +58,7 @@ from nova.tests import fake_instance from nova.tests import fake_network from nova.tests.image import fake from nova.tests import matchers +from nova.tests.objects import test_keypair from nova.tests import utils from nova import utils as nova_utils @@ -2838,9 +2839,10 @@ class ServersControllerCreateTest(test.TestCase): # NOTE(sdague): key pair goes back to the database, # so we need to stub it out for tests def key_pair_get(context, user_id, name): - return {'public_key': 'FAKE_KEY', - 'fingerprint': 'FAKE_FINGERPRINT', - 'name': name} + return dict(test_keypair.fake_keypair, + public_key='FAKE_KEY', + fingerprint='FAKE_FINGERPRINT', + name=name) def create(*args, **kwargs): self.assertEqual(kwargs['key_name'], key_name) diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index b69a233042..7a713e5056 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -45,6 +45,7 @@ from nova.openstack.common import timeutils from nova import quota from nova.tests import fake_network from nova.tests.glance import stubs as glance_stubs +from nova.tests.objects import test_keypair from nova import utils from nova import wsgi @@ -126,11 +127,13 @@ def wsgi_app_v3(inner_app_v3=None, fake_auth_context=None, def stub_out_key_pair_funcs(stubs, have_key_pair=True): def key_pair(context, user_id): - return [dict(name='key', public_key='public_key')] + return [dict(test_keypair.fake_keypair, + name='key', public_key='public_key')] def one_key_pair(context, user_id, name): if name == 'key': - return dict(name='key', public_key='public_key') + return dict(test_keypair.fake_keypair, + name='key', public_key='public_key') else: raise exc.KeypairNotFound(user_id=user_id, name=name) diff --git a/nova/tests/compute/test_keypairs.py b/nova/tests/compute/test_keypairs.py index 147f636703..36ce74b522 100644 --- a/nova/tests/compute/test_keypairs.py +++ b/nova/tests/compute/test_keypairs.py @@ -25,7 +25,7 @@ from nova import exception from nova.openstack.common.gettextutils import _ from nova import quota from nova.tests.compute import test_compute - +from nova.tests.objects import test_keypair CONF = cfg.CONF QUOTAS = quota.QUOTAS @@ -51,21 +51,23 @@ class KeypairAPITestCase(test_compute.BaseTestCase): def _keypair_db_call_stubs(self): def db_key_pair_get_all_by_user(context, user_id): - return [{'name': self.existing_key_name, - 'public_key': self.pub_key, - 'fingerprint': self.fingerprint}] + return [dict(test_keypair.fake_keypair, + name=self.existing_key_name, + public_key=self.pub_key, + fingerprint=self.fingerprint)] def db_key_pair_create(context, keypair): - pass + return dict(test_keypair.fake_keypair, **keypair) def db_key_pair_destroy(context, user_id, name): pass def db_key_pair_get(context, user_id, name): if name == self.existing_key_name: - return {'name': self.existing_key_name, - 'public_key': self.pub_key, - 'fingerprint': self.fingerprint} + return dict(test_keypair.fake_keypair, + name=self.existing_key_name, + public_key=self.pub_key, + fingerprint=self.fingerprint) else: raise exception.KeypairNotFound(user_id=user_id, name=name) @@ -135,8 +137,8 @@ class CreateKeypairTestCase(KeypairAPITestCase, CreateImportSharedTestMixIn): func_name = 'create_key_pair' def test_success(self): - keypair = self.keypair_api.create_key_pair(self.ctxt, - self.ctxt.user_id, 'foo') + keypair, private_key = self.keypair_api.create_key_pair( + self.ctxt, self.ctxt.user_id, 'foo') self.assertEqual('foo', keypair['name']) -- cgit v1.2.1