Keypair unit tests
Change-Id: I217a9c6abd52fd423e775459334e590a8e1549e7
This commit is contained in:
parent
8053ca77bb
commit
92e11cc9d8
|
@ -1242,7 +1242,7 @@ class CloudController(object):
|
|||
return key_pair.delete_key_pair(context, key_name)
|
||||
|
||||
def import_key_pair(self, context, key_name, public_key_material):
|
||||
return key_pair.create_key_pair(context, key_name,
|
||||
return key_pair.import_key_pair(context, key_name,
|
||||
public_key_material)
|
||||
|
||||
def describe_availability_zones(self, context, zone_name=None,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import base64
|
||||
|
||||
from novaclient import exceptions as nova_exception
|
||||
from oslo.config import cfg
|
||||
|
||||
from ec2api.api import clients
|
||||
|
@ -61,25 +62,38 @@ def describe_key_pairs(context, key_name=None, filter=None):
|
|||
return {'keySet': formatted_key_pairs}
|
||||
|
||||
|
||||
def _validate_name(name):
|
||||
if len(name) > 255:
|
||||
raise exception.InvalidParameterValue(
|
||||
value=name,
|
||||
parameter='KeyName',
|
||||
reason='lenght is exceeds maximum of 255')
|
||||
|
||||
|
||||
def create_key_pair(context, key_name):
|
||||
_validate_name(key_name)
|
||||
nova = clients.nova(context)
|
||||
try:
|
||||
key_pair = nova.keypairs.create(key_name)
|
||||
except clients.novaclient.exceptions.Conflict as ex:
|
||||
raise exception.KeyPairExists(key_name=key_name)
|
||||
except nova_exception.OverLimit:
|
||||
raise exception.ResourceLimitExceeded(resource='keypairs')
|
||||
except nova_exception.Conflict:
|
||||
raise exception.InvalidKeyPairDuplicate(key_name=key_name)
|
||||
formatted_key_pair = _format_key_pair(key_pair)
|
||||
formatted_key_pair['keyMaterial'] = key_pair.private_key
|
||||
return formatted_key_pair
|
||||
|
||||
|
||||
def import_key_pair(context, key_name, public_key_material):
|
||||
_validate_name(key_name)
|
||||
nova = clients.nova(context)
|
||||
public_key = base64.b64decode(public_key_material)
|
||||
try:
|
||||
key_pair = nova.keypairs.create(key_name, public_key)
|
||||
except clients.novaclient.exceptions.Conflict as ex:
|
||||
raise exception.KeyPairExists(key_name=key_name)
|
||||
|
||||
except nova_exception.OverLimit:
|
||||
raise exception.ResourceLimitExceeded(resource='keypairs')
|
||||
except nova_exception.Conflict:
|
||||
raise exception.InvalidKeyPairDuplicate(key_name=key_name)
|
||||
return _format_key_pair(key_pair)
|
||||
|
||||
|
||||
|
@ -87,7 +101,7 @@ def delete_key_pair(context, key_name):
|
|||
nova = clients.nova(context)
|
||||
try:
|
||||
nova.keypairs.delete(key_name)
|
||||
except exception.NotFound:
|
||||
except nova_exception.NotFound:
|
||||
# aws returns true even if the key doesn't exist
|
||||
pass
|
||||
return True
|
||||
|
|
|
@ -353,6 +353,10 @@ class ResourceLimitExceeded(Overlimit):
|
|||
msg_fmt = _('You have reached the limit of %(resource)s')
|
||||
|
||||
|
||||
class SecurityGroupLimitExceeded(Overlimit):
|
||||
msg_fmt = _('You have reached the limit of security groups')
|
||||
|
||||
|
||||
class ImageNotActive(Invalid):
|
||||
ec2_code = 'InvalidAMIID.Unavailable'
|
||||
# TODO(ft): Change the message with the real AWS message
|
||||
|
@ -375,7 +379,7 @@ class InvalidAvailabilityZoneNotFound(NotFound):
|
|||
msg_fmt = _("Availability zone %(id)s not found")
|
||||
|
||||
|
||||
class KeyPairExists(Invalid):
|
||||
class InvalidKeyPairDuplicate(Invalid):
|
||||
ec2_code = 'InvalidKeyPair.Duplicate'
|
||||
msg_fmt = _("Key pair '%(key_name)s' already exists.")
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class ApiTestCase(test_base.BaseTestCase):
|
|||
self.nova_servers = nova_mock.return_value.servers
|
||||
self.nova_flavors = nova_mock.return_value.flavors
|
||||
self.nova_floating_ips = nova_mock.return_value.floating_ips
|
||||
self.nova_key_pairs = nova_mock.return_value.keypairs
|
||||
self.nova_security_groups = nova_mock.return_value.security_groups
|
||||
self.nova_security_group_rules = (
|
||||
nova_mock.return_value.security_group_rules)
|
||||
|
|
|
@ -924,6 +924,63 @@ EC2_ROUTE_TABLE_2 = {
|
|||
}
|
||||
|
||||
|
||||
# keypair objects
|
||||
|
||||
class NovaKeyPair(object):
|
||||
|
||||
def __init__(self, nova_keypair_dict):
|
||||
self.name = nova_keypair_dict['name']
|
||||
self.fingerprint = nova_keypair_dict['fingerprint']
|
||||
self.private_key = nova_keypair_dict['private_key']
|
||||
self.public_key = nova_keypair_dict['public_key']
|
||||
|
||||
PRIVATE_KEY = (
|
||||
'-----BEGIN RSA PRIVATE KEY-----\n'
|
||||
'MIIEowIBAAKCAQEAgXvm1sZ9MDiAXvGraRFja0/WqyJ1gE6j/QPjreNryd34zBFcv2pQXLyvb'
|
||||
'gQG\nFxN4rMGNScgKgLSgHjE/TNywkT8N7aYOiRmGkzQciP5t+zf8ZdCyl+hqgoQig1uY8sV/'
|
||||
'fSxUWCB9\n8sF7Tpl0iGkWM6Wo0H/PvcwiS2+UPSzArj+b+Erb/JbBF4O8GgSmtLMeq60RuDM'
|
||||
'dJi5JYCP66HUw\njtYb/f9y1Q9nEGVcxY2v0RI1n0yOaZDKPInLKHeR/ole2QVwPZB69mBj11'
|
||||
'LErqb+jzCaSivnhy6g\nPzaSHdZaRmy1f+6ltFI1iKt+4y/iINOY0skYC1hc7IevE7j7dGQTD'
|
||||
'wIDAQABAoIBAEbD2Vfd6MM2\nzemVuHFWoHggjRjAX2k9EWCRBJifJuSPXI7imka+qqbUNCgz'
|
||||
'KMTpzlTT/wyouBy5Gp0Fmyu9nP30\ncP9FdsI04hiHLWUtcBwQ7+8RDNn6mmM0JcyWfdOIXnG'
|
||||
'hjYMQVuUaGvLM6SQ4EnsteUJh57451zBV\nDbYVRES2Fbq+j8tPQj1KuD0HhZBboNPOxo6E5n'
|
||||
'TxvMXnvuI+cb9D99lqATcb8c0zsLMl/5SKEBDc\nj72X4GPfE3Dc5/MO6L/89ms3TqF3lx8lh'
|
||||
'wFSMfFfA3Nf5xrX3gnorGe81odXBXFveqMCemvfJYxg\nS9KPkM8CMnwn6yPS3ftW5xH3nMkC'
|
||||
'gYEAvN4lQuOTy9RONCtfgZ6lhR00xfDiibOsE2jFXqXlXrZS\nunBx2WRwNuhAcYGbC4T71iC'
|
||||
'BR+LJHECpFjEFX9cKjd8xZPdIzJmwMBylPnli8IxK9UMroxF/MDNy\nnJfdPIWagIrk9VRsQH'
|
||||
'UOQW8Ab5dYJuP6c03L5xwmnFfeFnlz10MCgYEAr4Iu182bC2ppwr5AYD8T\n/QKVPZTmizbtG'
|
||||
'H/7a2+WnfNCz2u0MOo2h1rF7/SOYR8nalTTsN1z4D8cRX7YQ0P4yBtNRNiN7WH3\n+smTWztI'
|
||||
'VYvJA2RsOeP0zfGLJiFSMWLOjlqpJ7KbkEuPcxshGd+/w8upxgJeV8Dwz0ZWbY302kUC\ngYE'
|
||||
'AhneTB+CHpaNuWm5W/S46ol9850DtySSG6vq5Kv3qJFii5eKQ7Do6Op145FdmT/lKY9WYtdmd'
|
||||
'\nXeQbfpVAQlAUT5YM0NnOlv0FF/wNGkHKU4FPDPfZ5avbZjH688qb1S86JTK+eHy25d1xXNz'
|
||||
'u7oRO\nWsIN2nIVLmI4iy90C4RFGYkCgYBXpKPtwk/VkItF46nUJku+Agcy3GOQS5p0rJyJ1w'
|
||||
'yYzbykRf2S\nm7MlPpAvtqlPGLafI8MexEe0SO++SIyIcq4Oh4u7gITHcS/bfcPnQCBsD8UOu'
|
||||
'5xMAGjkWuWI4gTg\ngp3xepaUK14B3anB6l9KQ3DIvrCGH/Kq0b+vUkmgpc4LHQKBgBtul9bN'
|
||||
'KLF+LJf4JHYNFSurE8Y/\nn8FZ3dZo3T0Q3Sap9bP3ZHemoQ6QXbmpu3H4Mf+2kcNg6YKFW3p'
|
||||
'hxW3cuAcZOMHPCrpr3mCdyhF0\nKM74ANEwg8MekBJTcWZUNFv9HZDvTuhp6HSrbMnNEQogkd'
|
||||
'5PoubiusvAKpeb6NBGnLMq\n'
|
||||
'-----END RSA PRIVATE KEY-----'
|
||||
)
|
||||
|
||||
PUBLIC_KEY = ('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIkYwwXm8UeQXx1c2eFrDIB6b'
|
||||
'6ApI0KTKs1wezDfFdSIs93vAt4Jx1MyaR/PwqwLk2CDyFoGJBWBI9YcodLAjoRg'
|
||||
'Ovr6JigEv5V3yp+eEkeAJO0cPA21vN/KQ8Vxml68ZvvqbdqKZXc/rpFZ1OgCmHt'
|
||||
'udo96uQiRB0FM3mdE8YOTswcfkJxTvCe3axX50pYXXfIb0dn9CzC1hyQWYPXvlv'
|
||||
'qFNvr/Li7sSBycTBAh4Ar/uEigs/uOjhvzd7GpzY7qDqBVJFAmP7HiiOxoXPkKu'
|
||||
'W62Ftd')
|
||||
|
||||
KEY_FINGERPRINT = '2a:72:dd:aa:0d:a6:45:4d:27:4f:75:28:73:0d:a6:10:35:88:e1:ce'
|
||||
|
||||
OS_KEY_PAIR = {'name': 'keyname',
|
||||
'private_key': PRIVATE_KEY,
|
||||
'public_key': PUBLIC_KEY,
|
||||
'fingerprint': KEY_FINGERPRINT}
|
||||
|
||||
EC2_KEY_PAIR = {'keyName': 'keyname',
|
||||
'keyFingerprint': KEY_FINGERPRINT,
|
||||
'keyMaterial': PRIVATE_KEY}
|
||||
|
||||
|
||||
# Object generator functions section
|
||||
|
||||
# internet gateway generator functions
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
# Copyright 2014
|
||||
# The Cloudscaling Group, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import base64
|
||||
|
||||
from novaclient import exceptions as nova_exception
|
||||
|
||||
from ec2api.tests import base
|
||||
from ec2api.tests import fakes
|
||||
from ec2api.tests import matchers
|
||||
from ec2api.tests import tools
|
||||
|
||||
|
||||
class KeyPairCase(base.ApiTestCase):
|
||||
|
||||
def test_create_key_pair(self):
|
||||
self.nova_key_pairs.create.return_value = (
|
||||
fakes.NovaKeyPair(fakes.OS_KEY_PAIR))
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': 'keyname'})
|
||||
self.assertEqual(200, resp['status'])
|
||||
self.assertThat(fakes.EC2_KEY_PAIR, matchers.DictMatches(
|
||||
tools.purge_dict(resp, {'status'})))
|
||||
self.nova_key_pairs.create.assert_called_once_with('keyname')
|
||||
|
||||
def test_create_key_pair_invalid(self):
|
||||
self.nova_key_pairs.create.side_effect = (
|
||||
nova_exception.Conflict(409))
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': 'keyname'})
|
||||
self.assertEqual(400, resp['status'])
|
||||
self.assertEqual('InvalidKeyPair.Duplicate', resp['Error']['Code'])
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': 'k' * 256})
|
||||
self.assertEqual(400, resp['status'])
|
||||
self.assertEqual('InvalidParameterValue', resp['Error']['Code'])
|
||||
self.nova_key_pairs.create.side_effect = (
|
||||
nova_exception.OverLimit(413))
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': 'keyname'})
|
||||
self.assertEqual(400, resp['status'])
|
||||
self.assertEqual('ResourceLimitExceeded', resp['Error']['Code'])
|
||||
|
||||
def test_import_key_pair(self):
|
||||
self.nova_key_pairs.create.return_value = (
|
||||
fakes.NovaKeyPair(fakes.OS_KEY_PAIR))
|
||||
resp = self.execute('ImportKeyPair',
|
||||
{'KeyName': 'keyname',
|
||||
'PublicKeyMaterial': base64.b64encode(
|
||||
fakes.PUBLIC_KEY)})
|
||||
self.assertEqual(200, resp['status'])
|
||||
self.assertThat(tools.purge_dict(fakes.EC2_KEY_PAIR, {'keyMaterial'}),
|
||||
matchers.DictMatches(tools.purge_dict(resp, {'status'})))
|
||||
self.nova_key_pairs.create.assert_called_once_with('keyname',
|
||||
fakes.PUBLIC_KEY)
|
||||
|
||||
def test_import_key_pair_invalid(self):
|
||||
self.nova_key_pairs.create.side_effect = (
|
||||
nova_exception.OverLimit(413))
|
||||
resp = self.execute('ImportKeyPair',
|
||||
{'KeyName': 'keyname',
|
||||
'PublicKeyMaterial': base64.b64encode(
|
||||
fakes.PUBLIC_KEY)})
|
||||
self.assertEqual(400, resp['status'])
|
||||
self.assertEqual('ResourceLimitExceeded', resp['Error']['Code'])
|
||||
|
||||
def test_delete_key_pair(self):
|
||||
self.nova_key_pairs.delete.return_value = True
|
||||
resp = self.execute('DeleteKeyPair', {'KeyName': 'keyname'})
|
||||
self.assertEqual(200, resp['status'])
|
||||
self.nova_key_pairs.delete.assert_called_once_with('keyname')
|
||||
self.nova_key_pairs.delete.side_effect = nova_exception.NotFound(404)
|
||||
resp = self.execute('DeleteKeyPair', {'KeyName': 'keyname1'})
|
||||
self.assertEqual(200, resp['status'])
|
||||
self.nova_key_pairs.delete.assert_any_call('keyname1')
|
||||
|
||||
def test_describe_key_pair(self):
|
||||
self.nova_key_pairs.list.return_value = [fakes.NovaKeyPair(
|
||||
fakes.OS_KEY_PAIR)]
|
||||
resp = self.execute('DescribeKeyPairs', {})
|
||||
self.assertEqual(200, resp['status'])
|
||||
self.assertThat(resp['keySet'],
|
||||
matchers.ListMatches([
|
||||
tools.purge_dict(fakes.EC2_KEY_PAIR,
|
||||
{'keyMaterial'})]))
|
||||
self.nova_key_pairs.list.assert_called_once()
|
||||
|
||||
def test_describe_key_pair_invalid(self):
|
||||
self.nova_key_pairs.list.return_value = [fakes.NovaKeyPair(
|
||||
fakes.OS_KEY_PAIR)]
|
||||
resp = self.execute('DescribeKeyPairs', {'KeyName': 'badname'})
|
||||
self.assertEqual(404, resp['status'])
|
||||
self.assertEqual('InvalidKeyPair.NotFound', resp['Error']['Code'])
|
||||
self.nova_key_pairs.list.assert_called_once()
|
Loading…
Reference in New Issue