From 916e0ce0997bdf3135684865eff6fadcda95752b Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Wed, 3 Aug 2011 14:13:53 -0400 Subject: remove unused imports --- nova/api/openstack/create_instance_helper.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py index 53e814cd5..e4b897cd6 100644 --- a/nova/api/openstack/create_instance_helper.py +++ b/nova/api/openstack/create_instance_helper.py @@ -14,8 +14,6 @@ # under the License. import base64 -import re -import webob from webob import exc from xml.dom import minidom -- cgit From 91e16e057f083d1a0b8dffaa00b5979c12c23edc Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Wed, 3 Aug 2011 14:30:45 -0400 Subject: fix potential runtime exception The exception could occur if a client were to create an APIRouter object. The fix relies on more established OOP patterns. --- nova/api/openstack/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 868b98a31..8d7f7a405 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -81,7 +81,10 @@ class APIRouter(base_wsgi.Router): self._setup_routes(mapper) super(APIRouter, self).__init__(mapper) - def _setup_routes(self, mapper, version): + def _setup_routes(self, mapper): + raise NotImplementedError("you must implement _setup_routes") + + def _setup_base_routes(self, mapper, version): """Routes common to all versions.""" server_members = self.server_members @@ -147,7 +150,7 @@ class APIRouterV10(APIRouter): """Define routes specific to OpenStack API V1.0.""" def _setup_routes(self, mapper): - super(APIRouterV10, self)._setup_routes(mapper, '1.0') + self._setup_base_routes(mapper, '1.0') mapper.resource("shared_ip_group", "shared_ip_groups", collection={'detail': 'GET'}, @@ -163,7 +166,7 @@ class APIRouterV11(APIRouter): """Define routes specific to OpenStack API V1.1.""" def _setup_routes(self, mapper): - super(APIRouterV11, self)._setup_routes(mapper, '1.1') + self._setup_base_routes(mapper, '1.1') image_metadata_controller = image_metadata.create_resource() mapper.resource("image_meta", "metadata", controller=image_metadata_controller, -- cgit From a5add8b30c96ad1d83eebcd9756b0f358c9cb725 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Wed, 3 Aug 2011 15:16:38 -0400 Subject: follow convention when raising exceptions --- nova/api/openstack/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 8d7f7a405..0af39c2df 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -82,7 +82,7 @@ class APIRouter(base_wsgi.Router): super(APIRouter, self).__init__(mapper) def _setup_routes(self, mapper): - raise NotImplementedError("you must implement _setup_routes") + raise NotImplementedError(_("You must implement _setup_routes.")) def _setup_base_routes(self, mapper, version): """Routes common to all versions.""" -- cgit From 23f6ec84a93638e880f60bec00db8587b9e3e8d8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Wed, 3 Aug 2011 20:26:37 -0400 Subject: fix pylint W0102 errors. --- nova/api/openstack/extensions.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index cc889703e..b070dd61a 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -460,7 +460,11 @@ class ResourceExtension(object): """Add top level resources to the OpenStack API in nova.""" def __init__(self, collection, controller, parent=None, - collection_actions={}, member_actions={}): + collection_actions=None, member_actions=None): + if not collection_actions: + collection_actions = {} + if not member_actions: + member_actions = {} self.collection = collection self.controller = controller self.parent = parent -- cgit From d5bcc6764b418d7aa16b53b50173261385445ee8 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Tue, 9 Aug 2011 11:31:48 -0700 Subject: initial port --- nova/api/openstack/contrib/keypairs.py | 137 +++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 nova/api/openstack/contrib/keypairs.py (limited to 'nova/api') diff --git a/nova/api/openstack/contrib/keypairs.py b/nova/api/openstack/contrib/keypairs.py new file mode 100644 index 000000000..879bd9712 --- /dev/null +++ b/nova/api/openstack/contrib/keypairs.py @@ -0,0 +1,137 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" Keypair management extension""" + +from webob import exc + +from nova import db +from nova import crypto +from nova import exception +from nova.api.openstack import extensions + + +class KeypairController(object): + """ Keypair API controller for the Openstack API """ + + # TODO(ja): the keypair crud logic should be in nova.compute.API? + + def _gen_key(self): + """ + Generate a key + """ + # TODO(ja): crypto.generate_key_pair is currently a slow method + # and should probably be moved to a process pool? + private_key, public_key, fingerprint = crypto.generate_key_pair() + return {'private_key': private_key, + 'public_key': public_key, + 'fingerprint': fingerprint} + + def create(self, req, body): + """ + Create or import keypair. + + Sending key_name will generate a key and return private_key + and fingerprint. + + You can send a public_key to add an existing ssh key + + params: keypair object with: + key_name (required) - string + fingerprint (optional) - string + public_key (optional) - string + """ + + context = req.environ['nova.context'] + params = body['keypair'] + key_name = params['key_name'] + + # NOTE(ja): generation is slow, so shortcut invalid key_name exception + try: + db.key_pair_get(context, context.user_id, key_name) + raise exception.KeyPairExists(key_name=key_name) + except exception.NotFound: + pass + + keypair = {'user_id': context.user_id, + 'name': key_name} + + # import if public_key is sent + if 'public_key' in params: + keypair['public_key'] = params['public_key'] + keypair['fingerprint'] = params.get('fingerprint', None) + else: + generated_key = self._gen_key() + keypair['private_key'] = generated_key['private_key'] + keypair['public_key'] = generated_key['public_key'] + keypair['fingerprint'] = generated_key['fingerprint'] + + db.key_pair_create(context, keypair) + return {'keypair': keypair} + + def delete(self, req, name): + """ + Delete a keypair with a given name + """ + context = req.environ['nova.context'] + db.key_pair_destroy(context, context.user_id, name) + return exc.HTTPAccepted() + + def index(self, req): + """ + List of keypairs for a user + """ + context = req.environ['nova.context'] + key_pairs = db.key_pair_get_all_by_user(context, context.user_id) + rval = [] + for key_pair in key_pairs: + rval.append({ + 'name': key_pair['name'], + 'key_name': key_pair['name'], + 'fingerprint': key_pair['fingerprint'], + }) + + return {'keypairs': rval} + + +class Keypairs(extensions.ExtensionDescriptor): + + def get_name(self): + return "Keypairs" + + def get_alias(self): + return "os-keypairs" + + def get_description(self): + return "Keypair Support" + + def get_namespace(self): + return \ + "http://docs.openstack.org/ext/keypairs/api/v1.1" + + def get_updated(self): + return "2011-08-08T00:00:00+00:00" + + def get_resources(self): + resources = [] + + res = extensions.ResourceExtension( + 'os-keypairs', + KeypairController()) + + resources.append(res) + return resources -- cgit From 057b6ad650013a952f88f6e02f3e3db0164084d1 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Tue, 9 Aug 2011 13:00:13 -0700 Subject: added tests - list doesn't pass due to unicode issues --- nova/api/openstack/contrib/keypairs.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/contrib/keypairs.py b/nova/api/openstack/contrib/keypairs.py index 879bd9712..8435494e1 100644 --- a/nova/api/openstack/contrib/keypairs.py +++ b/nova/api/openstack/contrib/keypairs.py @@ -23,19 +23,20 @@ from nova import db from nova import crypto from nova import exception from nova.api.openstack import extensions - +import os +import shutil +import tempfile class KeypairController(object): """ Keypair API controller for the Openstack API """ - # TODO(ja): the keypair crud logic should be in nova.compute.API? + # TODO(ja): both this file and nova.api.ec2.cloud.py have similar logic. + # move the common keypair logic to nova.compute.API? def _gen_key(self): """ Generate a key """ - # TODO(ja): crypto.generate_key_pair is currently a slow method - # and should probably be moved to a process pool? private_key, public_key, fingerprint = crypto.generate_key_pair() return {'private_key': private_key, 'public_key': public_key, @@ -52,7 +53,6 @@ class KeypairController(object): params: keypair object with: key_name (required) - string - fingerprint (optional) - string public_key (optional) - string """ @@ -72,8 +72,14 @@ class KeypairController(object): # import if public_key is sent if 'public_key' in params: + tmpdir = tempfile.mkdtemp() + fn = os.path.join(tmpdir, 'import.pub') + with open(fn, 'w') as pub: + pub.write(params['public_key']) + fingerprint = crypto.generate_fingerprint(fn) + shutil.rmtree(tmpdir) keypair['public_key'] = params['public_key'] - keypair['fingerprint'] = params.get('fingerprint', None) + keypair['fingerprint'] = fingerprint else: generated_key = self._gen_key() keypair['private_key'] = generated_key['private_key'] @@ -83,12 +89,12 @@ class KeypairController(object): db.key_pair_create(context, keypair) return {'keypair': keypair} - def delete(self, req, name): + def delete(self, req, id): """ Delete a keypair with a given name """ context = req.environ['nova.context'] - db.key_pair_destroy(context, context.user_id, name) + db.key_pair_destroy(context, context.user_id, id) return exc.HTTPAccepted() def index(self, req): @@ -99,11 +105,11 @@ class KeypairController(object): key_pairs = db.key_pair_get_all_by_user(context, context.user_id) rval = [] for key_pair in key_pairs: - rval.append({ + rval.append({'keypair': { 'name': key_pair['name'], 'key_name': key_pair['name'], 'fingerprint': key_pair['fingerprint'], - }) + }}) return {'keypairs': rval} -- cgit From 131b2185e23567895e3f87cdfe9c2822d18910b2 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Tue, 9 Aug 2011 16:12:59 -0700 Subject: tests pass --- nova/api/openstack/contrib/keypairs.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/contrib/keypairs.py b/nova/api/openstack/contrib/keypairs.py index 8435494e1..d718846f1 100644 --- a/nova/api/openstack/contrib/keypairs.py +++ b/nova/api/openstack/contrib/keypairs.py @@ -46,29 +46,29 @@ class KeypairController(object): """ Create or import keypair. - Sending key_name will generate a key and return private_key + Sending name will generate a key and return private_key and fingerprint. You can send a public_key to add an existing ssh key params: keypair object with: - key_name (required) - string + name (required) - string public_key (optional) - string """ context = req.environ['nova.context'] params = body['keypair'] - key_name = params['key_name'] + name = params['name'] - # NOTE(ja): generation is slow, so shortcut invalid key_name exception + # NOTE(ja): generation is slow, so shortcut invalid name exception try: - db.key_pair_get(context, context.user_id, key_name) - raise exception.KeyPairExists(key_name=key_name) + db.key_pair_get(context, context.user_id, name) + raise exception.KeyPairExists(key_name=name) except exception.NotFound: pass keypair = {'user_id': context.user_id, - 'name': key_name} + 'name': name} # import if public_key is sent if 'public_key' in params: @@ -107,7 +107,7 @@ class KeypairController(object): for key_pair in key_pairs: rval.append({'keypair': { 'name': key_pair['name'], - 'key_name': key_pair['name'], + 'public_key': key_pair['public_key'], 'fingerprint': key_pair['fingerprint'], }}) -- cgit From 83ed9faa488b3ec0f1cb16e7147293c912e2fc2b Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 9 Aug 2011 19:35:40 -0400 Subject: pep8 fix --- nova/api/openstack/contrib/floating_ips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/contrib/floating_ips.py b/nova/api/openstack/contrib/floating_ips.py index 52c9c6cf9..2aba1068a 100644 --- a/nova/api/openstack/contrib/floating_ips.py +++ b/nova/api/openstack/contrib/floating_ips.py @@ -102,7 +102,7 @@ class FloatingIPController(object): def delete(self, req, id): context = req.environ['nova.context'] ip = self.network_api.get_floating_ip(context, id) - + if 'fixed_ip' in ip: try: self.disassociate(req, id, '') -- cgit From 0719b038ba1548f98668991507c001eb18c82981 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Tue, 9 Aug 2011 17:22:01 -0700 Subject: import formatting - thx --- nova/api/openstack/contrib/keypairs.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/contrib/keypairs.py b/nova/api/openstack/contrib/keypairs.py index d718846f1..201648ab5 100644 --- a/nova/api/openstack/contrib/keypairs.py +++ b/nova/api/openstack/contrib/keypairs.py @@ -17,15 +17,17 @@ """ Keypair management extension""" +import os +import shutil +import tempfile + from webob import exc -from nova import db from nova import crypto +from nova import db from nova import exception from nova.api.openstack import extensions -import os -import shutil -import tempfile + class KeypairController(object): """ Keypair API controller for the Openstack API """ -- cgit