summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-05-15 09:02:36 +0000
committerGerrit Code Review <review@openstack.org>2012-05-15 09:02:36 +0000
commit8823f7bef2142a807b3c92e512f602b6b415a3e2 (patch)
tree83aef3cd63cde931108a8316e372fe870053e7a0 /nova/api
parentfbae8d09fdb9ad370fa827aab0f9bfe0c0c7041f (diff)
parentec0a65d81fd11d26be77b45827a4dd7c77711675 (diff)
Merge "Create an internal key pair API."
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/ec2/cloud.py94
-rw-r--r--nova/api/openstack/compute/contrib/keypairs.py82
2 files changed, 58 insertions, 118 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 70933d2bc..797cf35bf 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -34,7 +34,6 @@ from nova import block_device
from nova import compute
from nova.compute import instance_types
from nova.compute import vm_states
-from nova import crypto
from nova import db
from nova import exception
from nova import flags
@@ -61,33 +60,6 @@ def validate_ec2_id(val):
raise exception.InvalidInstanceIDMalformed(val)
-def _gen_key(context, user_id, key_name):
- """Generate a key
-
- This is a module level method because it is slow and we need to defer
- it into a process pool."""
- # NOTE(vish): generating key pair is slow so check for legal
- # creation before creating key_pair
- try:
- db.key_pair_get(context, user_id, key_name)
- raise exception.KeyPairExists(key_name=key_name)
- except exception.NotFound:
- pass
-
- if quota.allowed_key_pairs(context, 1) < 1:
- msg = _("Quota exceeded, too many key pairs.")
- raise exception.EC2APIError(msg)
-
- private_key, public_key, fingerprint = crypto.generate_key_pair()
- key = {}
- key['user_id'] = user_id
- key['name'] = key_name
- key['public_key'] = public_key
- key['fingerprint'] = fingerprint
- db.key_pair_create(context, key)
- return {'private_key': private_key, 'fingerprint': fingerprint}
-
-
# EC2 API can return the following values as documented in the EC2 API
# http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/
# ApiReference-ItemType-InstanceStateType.html
@@ -217,6 +189,7 @@ class CloudController(object):
self.volume_api = volume.API()
self.compute_api = compute.API(network_api=self.network_api,
volume_api=self.volume_api)
+ self.keypair_api = compute.api.KeypairAPI()
self.sgh = importutils.import_object(FLAGS.security_group_handler)
def __str__(self):
@@ -357,7 +330,7 @@ class CloudController(object):
return True
def describe_key_pairs(self, context, key_name=None, **kwargs):
- key_pairs = db.key_pair_get_all_by_user(context, context.user_id)
+ key_pairs = self.keypair_api.get_key_pairs(context, context.user_id)
if not key_name is None:
key_pairs = [x for x in key_pairs if x['name'] in key_name]
@@ -374,52 +347,55 @@ class CloudController(object):
return {'keySet': result}
def create_key_pair(self, context, key_name, **kwargs):
- if not re.match('^[a-zA-Z0-9_\- ]+$', str(key_name)):
- err = _("Value (%s) for KeyName is invalid."
- " Content limited to Alphanumeric character, "
- "spaces, dashes, and underscore.") % key_name
- raise exception.EC2APIError(err)
-
- if len(str(key_name)) > 255:
- err = _("Value (%s) for Keyname is invalid."
- " Length exceeds maximum of 255.") % key_name
- raise exception.EC2APIError(err)
-
LOG.audit(_("Create key pair %s"), key_name, context=context)
- data = _gen_key(context, context.user_id, key_name)
+
+ try:
+ keypair = 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)
+ except exception.InvalidKeypair:
+ msg = _("Keypair data is invalid")
+ raise exception.EC2APIError(msg)
+ except exception.KeyPairExists:
+ msg = _("Key pair '%s' already exists.") % key_name
+ raise exception.KeyPairExists(msg)
return {'keyName': key_name,
- 'keyFingerprint': data['fingerprint'],
- 'keyMaterial': data['private_key']}
+ 'keyFingerprint': keypair['fingerprint'],
+ 'keyMaterial': keypair['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,
**kwargs):
LOG.audit(_("Import key %s"), key_name, context=context)
- try:
- db.key_pair_get(context, context.user_id, key_name)
- raise exception.KeyPairExists(key_name=key_name)
- except exception.NotFound:
- pass
- if quota.allowed_key_pairs(context, 1) < 1:
+ public_key = base64.b64decode(public_key_material)
+
+ try:
+ keypair = self.keypair_api.import_key_pair(context,
+ context.user_id,
+ key_name,
+ public_key)
+ except exception.KeypairLimitExceeded:
msg = _("Quota exceeded, too many key pairs.")
raise exception.EC2APIError(msg)
+ except exception.InvalidKeypair:
+ msg = _("Keypair data is invalid")
+ raise exception.EC2APIError(msg)
+ except exception.KeyPairExists:
+ msg = _("Key pair '%s' already exists.") % key_name
+ raise exception.EC2APIError(msg)
- public_key = base64.b64decode(public_key_material)
- fingerprint = crypto.generate_fingerprint(public_key)
- key = {}
- key['user_id'] = context.user_id
- key['name'] = key_name
- key['public_key'] = public_key
- key['fingerprint'] = fingerprint
- db.key_pair_create(context, key)
return {'keyName': key_name,
- 'keyFingerprint': fingerprint}
+ 'keyFingerprint': keypair['fingerprint']}
def delete_key_pair(self, context, key_name, **kwargs):
LOG.audit(_("Delete key pair %s"), key_name, context=context)
try:
- db.key_pair_destroy(context, context.user_id, key_name)
+ self.keypair_api.delete_key_pair(context, context.user_id,
+ key_name)
except exception.NotFound:
# aws returns true even if the key doesn't exist
pass
diff --git a/nova/api/openstack/compute/contrib/keypairs.py b/nova/api/openstack/compute/contrib/keypairs.py
index 5a764978c..186d836de 100644
--- a/nova/api/openstack/compute/contrib/keypairs.py
+++ b/nova/api/openstack/compute/contrib/keypairs.py
@@ -17,18 +17,14 @@
""" Keypair management extension"""
-import string
-
import webob
import webob.exc
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova.api.openstack import extensions
-from nova import crypto
-from nova import db
+from nova.compute import api as compute_api
from nova import exception
-from nova import quota
authorize = extensions.extension_authorizer('compute', 'keypairs')
@@ -50,26 +46,10 @@ class KeypairsTemplate(xmlutil.TemplateBuilder):
class KeypairController(object):
- """ Keypair API controller for the OpenStack 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
- """
- private_key, public_key, fingerprint = crypto.generate_key_pair()
- return {'private_key': private_key,
- 'public_key': public_key,
- 'fingerprint': fingerprint}
-
- def _validate_keypair_name(self, value):
- safechars = "_-" + string.digits + string.ascii_letters
- clean_value = "".join(x for x in value if x in safechars)
- if clean_value != value:
- msg = _("Keypair name contains unsafe characters")
- raise webob.exc.HTTPBadRequest(explanation=msg)
+ """ Keypair API controller for the OpenStack API """
+ def __init__(self):
+ self.api = compute_api.KeypairAPI()
@wsgi.serializers(xml=KeypairTemplate)
def create(self, req, body):
@@ -90,45 +70,29 @@ class KeypairController(object):
authorize(context)
params = body['keypair']
name = params['name']
- self._validate_keypair_name(name)
- if not 0 < len(name) < 256:
- msg = _('Keypair name must be between 1 and 255 characters long')
- raise webob.exc.HTTPBadRequest(explanation=msg)
- # NOTE(ja): generation is slow, so shortcut invalid name exception
try:
- db.key_pair_get(context, context.user_id, name)
- msg = _("Key pair '%s' already exists.") % name
- raise webob.exc.HTTPConflict(explanation=msg)
- except exception.NotFound:
- pass
+ if 'public_key' in params:
+ keypair = self.api.import_key_pair(context,
+ context.user_id, name,
+ params['public_key'])
+ else:
+ keypair = self.api.create_key_pair(context, context.user_id,
+ name)
- keypair = {'user_id': context.user_id,
- 'name': name}
+ return {'keypair': keypair}
- if quota.allowed_key_pairs(context, 1) < 1:
+ except exception.KeypairLimitExceeded:
msg = _("Quota exceeded, too many key pairs.")
raise webob.exc.HTTPRequestEntityTooLarge(
- explanation=msg,
- headers={'Retry-After': 0})
- # import if public_key is sent
- if 'public_key' in params:
- try:
- fingerprint = crypto.generate_fingerprint(params['public_key'])
- except exception.InvalidKeypair:
- msg = _("Keypair data is invalid")
- raise webob.exc.HTTPBadRequest(explanation=msg)
-
- keypair['public_key'] = params['public_key']
- keypair['fingerprint'] = fingerprint
- 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}
+ explanation=msg,
+ headers={'Retry-After': 0})
+ except exception.InvalidKeypair:
+ msg = _("Keypair data is invalid")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+ except exception.KeyPairExists:
+ msg = _("Key pair '%s' already exists.") % name
+ raise webob.exc.HTTPConflict(explanation=msg)
def delete(self, req, id):
"""
@@ -137,7 +101,7 @@ class KeypairController(object):
context = req.environ['nova.context']
authorize(context)
try:
- db.key_pair_destroy(context, context.user_id, id)
+ self.api.delete_key_pair(context, context.user_id, id)
except exception.KeypairNotFound:
raise webob.exc.HTTPNotFound()
return webob.Response(status_int=202)
@@ -149,7 +113,7 @@ class KeypairController(object):
"""
context = req.environ['nova.context']
authorize(context)
- key_pairs = db.key_pair_get_all_by_user(context, context.user_id)
+ key_pairs = self.api.get_key_pairs(context, context.user_id)
rval = []
for key_pair in key_pairs:
rval.append({'keypair': {