Merge lp:~vishvananda/nova/move-keypairs into lp:~hudson-openstack/nova/trunk

Proposed by Vish Ishaya
Status: Merged
Approved by: Jesse Andrews
Approved revision: 380
Merged at revision: 288
Proposed branch: lp:~vishvananda/nova/move-keypairs
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 700 lines (+200/-225)
11 files modified
nova/auth/ldapdriver.py (+0/-60)
nova/auth/manager.py (+6/-101)
nova/cloudpipe/pipelib.py (+2/-2)
nova/crypto.py (+1/-1)
nova/db/api.py (+28/-0)
nova/db/sqlalchemy/api.py (+40/-0)
nova/db/sqlalchemy/models.py (+36/-0)
nova/endpoint/cloud.py (+38/-19)
nova/tests/api_unittest.py (+4/-3)
nova/tests/auth_unittest.py (+0/-31)
nova/tests/cloud_unittest.py (+45/-8)
To merge this branch: bzr merge lp:~vishvananda/nova/move-keypairs
Reviewer Review Type Date Requested Status
Jesse Andrews (community) Approve
Jay Pipes (community) Approve
Review via email: mp+35615@code.launchpad.net

Commit message

Moves keypairs out of ldap and into the common datastore.

Description of the change

Moves keypairs out of ldap and into the common datastore.

To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote :

Rock on. One less thing in LDAP makes Jay a happy boy.

review: Approve
lp:~vishvananda/nova/move-keypairs updated
380. By Vish Ishaya

merged trunk

Revision history for this message
Jesse Andrews (anotherjesse) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/auth/ldapdriver.py'
--- nova/auth/ldapdriver.py 2010-09-10 11:52:48 +0000
+++ nova/auth/ldapdriver.py 2010-09-21 04:21:00 +0000
@@ -99,13 +99,6 @@
99 dn = FLAGS.ldap_user_subtree99 dn = FLAGS.ldap_user_subtree
100 return self.__to_user(self.__find_object(dn, query))100 return self.__to_user(self.__find_object(dn, query))
101101
102 def get_key_pair(self, uid, key_name):
103 """Retrieve key pair by uid and key name"""
104 dn = 'cn=%s,%s' % (key_name,
105 self.__uid_to_dn(uid))
106 attr = self.__find_object(dn, '(objectclass=novaKeyPair)')
107 return self.__to_key_pair(uid, attr)
108
109 def get_project(self, pid):102 def get_project(self, pid):
110 """Retrieve project by id"""103 """Retrieve project by id"""
111 dn = 'cn=%s,%s' % (pid,104 dn = 'cn=%s,%s' % (pid,
@@ -119,12 +112,6 @@
119 '(objectclass=novaUser)')112 '(objectclass=novaUser)')
120 return [self.__to_user(attr) for attr in attrs]113 return [self.__to_user(attr) for attr in attrs]
121114
122 def get_key_pairs(self, uid):
123 """Retrieve list of key pairs"""
124 attrs = self.__find_objects(self.__uid_to_dn(uid),
125 '(objectclass=novaKeyPair)')
126 return [self.__to_key_pair(uid, attr) for attr in attrs]
127
128 def get_projects(self, uid=None):115 def get_projects(self, uid=None):
129 """Retrieve list of projects"""116 """Retrieve list of projects"""
130 pattern = '(objectclass=novaProject)'117 pattern = '(objectclass=novaProject)'
@@ -154,21 +141,6 @@
154 self.conn.add_s(self.__uid_to_dn(name), attr)141 self.conn.add_s(self.__uid_to_dn(name), attr)
155 return self.__to_user(dict(attr))142 return self.__to_user(dict(attr))
156143
157 def create_key_pair(self, uid, key_name, public_key, fingerprint):
158 """Create a key pair"""
159 # TODO(vish): possibly refactor this to store keys in their own ou
160 # and put dn reference in the user object
161 attr = [
162 ('objectclass', ['novaKeyPair']),
163 ('cn', [key_name]),
164 ('sshPublicKey', [public_key]),
165 ('keyFingerprint', [fingerprint]),
166 ]
167 self.conn.add_s('cn=%s,%s' % (key_name,
168 self.__uid_to_dn(uid)),
169 attr)
170 return self.__to_key_pair(uid, dict(attr))
171
172 def create_project(self, name, manager_uid,144 def create_project(self, name, manager_uid,
173 description=None, member_uids=None):145 description=None, member_uids=None):
174 """Create a project"""146 """Create a project"""
@@ -283,19 +255,10 @@
283 """Delete a user"""255 """Delete a user"""
284 if not self.__user_exists(uid):256 if not self.__user_exists(uid):
285 raise exception.NotFound("User %s doesn't exist" % uid)257 raise exception.NotFound("User %s doesn't exist" % uid)
286 self.__delete_key_pairs(uid)
287 self.__remove_from_all(uid)258 self.__remove_from_all(uid)
288 self.conn.delete_s('uid=%s,%s' % (uid,259 self.conn.delete_s('uid=%s,%s' % (uid,
289 FLAGS.ldap_user_subtree))260 FLAGS.ldap_user_subtree))
290261
291 def delete_key_pair(self, uid, key_name):
292 """Delete a key pair"""
293 if not self.__key_pair_exists(uid, key_name):
294 raise exception.NotFound("Key Pair %s doesn't exist for user %s" %
295 (key_name, uid))
296 self.conn.delete_s('cn=%s,uid=%s,%s' % (key_name, uid,
297 FLAGS.ldap_user_subtree))
298
299 def delete_project(self, project_id):262 def delete_project(self, project_id):
300 """Delete a project"""263 """Delete a project"""
301 project_dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)264 project_dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
@@ -306,10 +269,6 @@
306 """Check if user exists"""269 """Check if user exists"""
307 return self.get_user(uid) != None270 return self.get_user(uid) != None
308271
309 def __key_pair_exists(self, uid, key_name):
310 """Check if key pair exists"""
311 return self.get_key_pair(uid, key_name) != None
312
313 def __project_exists(self, project_id):272 def __project_exists(self, project_id):
314 """Check if project exists"""273 """Check if project exists"""
315 return self.get_project(project_id) != None274 return self.get_project(project_id) != None
@@ -359,13 +318,6 @@
359 """Check if group exists"""318 """Check if group exists"""
360 return self.__find_object(dn, '(objectclass=groupOfNames)') != None319 return self.__find_object(dn, '(objectclass=groupOfNames)') != None
361320
362 def __delete_key_pairs(self, uid):
363 """Delete all key pairs for user"""
364 keys = self.get_key_pairs(uid)
365 if keys != None:
366 for key in keys:
367 self.delete_key_pair(uid, key['name'])
368
369 @staticmethod321 @staticmethod
370 def __role_to_dn(role, project_id=None):322 def __role_to_dn(role, project_id=None):
371 """Convert role to corresponding dn"""323 """Convert role to corresponding dn"""
@@ -490,18 +442,6 @@
490 'secret': attr['secretKey'][0],442 'secret': attr['secretKey'][0],
491 'admin': (attr['isAdmin'][0] == 'TRUE')}443 'admin': (attr['isAdmin'][0] == 'TRUE')}
492444
493 @staticmethod
494 def __to_key_pair(owner, attr):
495 """Convert ldap attributes to KeyPair object"""
496 if attr == None:
497 return None
498 return {
499 'id': attr['cn'][0],
500 'name': attr['cn'][0],
501 'owner_id': owner,
502 'public_key': attr['sshPublicKey'][0],
503 'fingerprint': attr['keyFingerprint'][0]}
504
505 def __to_project(self, attr):445 def __to_project(self, attr):
506 """Convert ldap attributes to Project object"""446 """Convert ldap attributes to Project object"""
507 if attr == None:447 if attr == None:
508448
=== modified file 'nova/auth/manager.py'
--- nova/auth/manager.py 2010-09-21 03:53:46 +0000
+++ nova/auth/manager.py 2010-09-21 04:21:00 +0000
@@ -128,24 +128,6 @@
128 def is_project_manager(self, project):128 def is_project_manager(self, project):
129 return AuthManager().is_project_manager(self, project)129 return AuthManager().is_project_manager(self, project)
130130
131 def generate_key_pair(self, name):
132 return AuthManager().generate_key_pair(self.id, name)
133
134 def create_key_pair(self, name, public_key, fingerprint):
135 return AuthManager().create_key_pair(self.id,
136 name,
137 public_key,
138 fingerprint)
139
140 def get_key_pair(self, name):
141 return AuthManager().get_key_pair(self.id, name)
142
143 def delete_key_pair(self, name):
144 return AuthManager().delete_key_pair(self.id, name)
145
146 def get_key_pairs(self):
147 return AuthManager().get_key_pairs(self.id)
148
149 def __repr__(self):131 def __repr__(self):
150 return "User('%s', '%s', '%s', '%s', %s)" % (self.id,132 return "User('%s', '%s', '%s', '%s', %s)" % (self.id,
151 self.name,133 self.name,
@@ -154,29 +136,6 @@
154 self.admin)136 self.admin)
155137
156138
157class KeyPair(AuthBase):
158 """Represents an ssh key returned from the datastore
159
160 Even though this object is named KeyPair, only the public key and
161 fingerprint is stored. The user's private key is not saved.
162 """
163
164 def __init__(self, id, name, owner_id, public_key, fingerprint):
165 AuthBase.__init__(self)
166 self.id = id
167 self.name = name
168 self.owner_id = owner_id
169 self.public_key = public_key
170 self.fingerprint = fingerprint
171
172 def __repr__(self):
173 return "KeyPair('%s', '%s', '%s', '%s', '%s')" % (self.id,
174 self.name,
175 self.owner_id,
176 self.public_key,
177 self.fingerprint)
178
179
180class Project(AuthBase):139class Project(AuthBase):
181 """Represents a Project returned from the datastore"""140 """Represents a Project returned from the datastore"""
182141
@@ -663,67 +622,13 @@
663 return User(**user_dict)622 return User(**user_dict)
664623
665 def delete_user(self, user):624 def delete_user(self, user):
666 """Deletes a user"""625 """Deletes a user
667 with self.driver() as drv:626
668 drv.delete_user(User.safe_id(user))627 Additionally deletes all users key_pairs"""
669
670 def generate_key_pair(self, user, key_name):
671 """Generates a key pair for a user
672
673 Generates a public and private key, stores the public key using the
674 key_name, and returns the private key and fingerprint.
675
676 @type user: User or uid
677 @param user: User for which to create key pair.
678
679 @type key_name: str
680 @param key_name: Name to use for the generated KeyPair.
681
682 @rtype: tuple (private_key, fingerprint)
683 @return: A tuple containing the private_key and fingerprint.
684 """
685 # NOTE(vish): generating key pair is slow so check for legal
686 # creation before creating keypair
687 uid = User.safe_id(user)628 uid = User.safe_id(user)
688 with self.driver() as drv:629 db.key_pair_destroy_all_by_user(None, uid)
689 if not drv.get_user(uid):630 with self.driver() as drv:
690 raise exception.NotFound("User %s doesn't exist" % user)631 drv.delete_user(uid)
691 if drv.get_key_pair(uid, key_name):
692 raise exception.Duplicate("The keypair %s already exists"
693 % key_name)
694 private_key, public_key, fingerprint = crypto.generate_key_pair()
695 self.create_key_pair(uid, key_name, public_key, fingerprint)
696 return private_key, fingerprint
697
698 def create_key_pair(self, user, key_name, public_key, fingerprint):
699 """Creates a key pair for user"""
700 with self.driver() as drv:
701 kp_dict = drv.create_key_pair(User.safe_id(user),
702 key_name,
703 public_key,
704 fingerprint)
705 if kp_dict:
706 return KeyPair(**kp_dict)
707
708 def get_key_pair(self, user, key_name):
709 """Retrieves a key pair for user"""
710 with self.driver() as drv:
711 kp_dict = drv.get_key_pair(User.safe_id(user), key_name)
712 if kp_dict:
713 return KeyPair(**kp_dict)
714
715 def get_key_pairs(self, user):
716 """Retrieves all key pairs for user"""
717 with self.driver() as drv:
718 kp_list = drv.get_key_pairs(User.safe_id(user))
719 if not kp_list:
720 return []
721 return [KeyPair(**kp_dict) for kp_dict in kp_list]
722
723 def delete_key_pair(self, user, key_name):
724 """Deletes a key pair for user"""
725 with self.driver() as drv:
726 drv.delete_key_pair(User.safe_id(user), key_name)
727632
728 def get_credentials(self, user, project=None):633 def get_credentials(self, user, project=None):
729 """Get credential zip for user in project"""634 """Get credential zip for user in project"""
730635
=== modified file 'nova/cloudpipe/pipelib.py'
--- nova/cloudpipe/pipelib.py 2010-08-16 12:16:21 +0000
+++ nova/cloudpipe/pipelib.py 2010-09-21 04:21:00 +0000
@@ -58,7 +58,7 @@
58 z.write(FLAGS.boot_script_template,'autorun.sh')58 z.write(FLAGS.boot_script_template,'autorun.sh')
59 z.close()59 z.close()
6060
61 key_name = self.setup_keypair(project.project_manager_id, project_id)61 key_name = self.setup_key_pair(project.project_manager_id, project_id)
62 zippy = open(zippath, "r")62 zippy = open(zippath, "r")
63 context = api.APIRequestContext(handler=None, user=project.project_manager, project=project)63 context = api.APIRequestContext(handler=None, user=project.project_manager, project=project)
6464
@@ -74,7 +74,7 @@
74 security_groups=["vpn-secgroup"])74 security_groups=["vpn-secgroup"])
75 zippy.close()75 zippy.close()
7676
77 def setup_keypair(self, user_id, project_id):77 def setup_key_pair(self, user_id, project_id):
78 key_name = '%s%s' % (project_id, FLAGS.vpn_key_suffix)78 key_name = '%s%s' % (project_id, FLAGS.vpn_key_suffix)
79 try:79 try:
80 private_key, fingerprint = self.manager.generate_key_pair(user_id, key_name)80 private_key, fingerprint = self.manager.generate_key_pair(user_id, key_name)
8181
=== modified file 'nova/crypto.py'
--- nova/crypto.py 2010-08-16 12:16:21 +0000
+++ nova/crypto.py 2010-09-21 04:21:00 +0000
@@ -18,7 +18,7 @@
1818
19"""19"""
20Wrappers around standard crypto, including root and intermediate CAs,20Wrappers around standard crypto, including root and intermediate CAs,
21SSH keypairs and x509 certificates.21SSH key_pairs and x509 certificates.
22"""22"""
2323
24import base6424import base64
2525
=== modified file 'nova/db/api.py'
--- nova/db/api.py 2010-09-12 01:45:35 +0000
+++ nova/db/api.py 2010-09-21 04:21:00 +0000
@@ -296,6 +296,34 @@
296 return IMPL.instance_update(context, instance_id, values)296 return IMPL.instance_update(context, instance_id, values)
297297
298298
299###################
300
301
302def key_pair_create(context, values):
303 """Create a key_pair from the values dictionary."""
304 return IMPL.key_pair_create(context, values)
305
306
307def key_pair_destroy(context, user_id, name):
308 """Destroy the key_pair or raise if it does not exist."""
309 return IMPL.key_pair_destroy(context, user_id, name)
310
311
312def key_pair_destroy_all_by_user(context, user_id):
313 """Destroy all key_pairs by user."""
314 return IMPL.key_pair_destroy_all_by_user(context, user_id)
315
316
317def key_pair_get(context, user_id, name):
318 """Get a key_pair or raise if it does not exist."""
319 return IMPL.key_pair_get(context, user_id, name)
320
321
322def key_pair_get_all_by_user(context, user_id):
323 """Get all key_pairs by user."""
324 return IMPL.key_pair_get_all_by_user(context, user_id)
325
326
299####################327####################
300328
301329
302330
=== modified file 'nova/db/sqlalchemy/api.py'
--- nova/db/sqlalchemy/api.py 2010-09-12 02:40:38 +0000
+++ nova/db/sqlalchemy/api.py 2010-09-21 04:21:00 +0000
@@ -462,6 +462,46 @@
462###################462###################
463463
464464
465def key_pair_create(_context, values):
466 key_pair_ref = models.KeyPair()
467 for (key, value) in values.iteritems():
468 key_pair_ref[key] = value
469 key_pair_ref.save()
470 return key_pair_ref
471
472
473def key_pair_destroy(_context, user_id, name):
474 session = get_session()
475 with session.begin():
476 key_pair_ref = models.KeyPair.find_by_args(user_id,
477 name,
478 session=session)
479 key_pair_ref.delete(session=session)
480
481
482def key_pair_destroy_all_by_user(_context, user_id):
483 session = get_session()
484 with session.begin():
485 # TODO(vish): do we have to use sql here?
486 session.execute('update key_pairs set deleted=1 where user_id=:id',
487 {'id': user_id})
488
489
490def key_pair_get(_context, user_id, name):
491 return models.KeyPair.find_by_args(user_id, name)
492
493
494def key_pair_get_all_by_user(_context, user_id):
495 session = get_session()
496 return session.query(models.KeyPair
497 ).filter_by(user_id=user_id
498 ).filter_by(deleted=False
499 ).all()
500
501
502###################
503
504
465def network_count(_context):505def network_count(_context):
466 return models.Network.count()506 return models.Network.count()
467507
468508
=== modified file 'nova/db/sqlalchemy/models.py'
--- nova/db/sqlalchemy/models.py 2010-09-12 03:00:56 +0000
+++ nova/db/sqlalchemy/models.py 2010-09-21 04:21:00 +0000
@@ -323,6 +323,42 @@
323 uselist=False))323 uselist=False))
324324
325325
326class KeyPair(BASE, NovaBase):
327 """Represents a public key pair for ssh"""
328 __tablename__ = 'key_pairs'
329 id = Column(Integer, primary_key=True)
330 name = Column(String(255))
331
332 user_id = Column(String(255))
333
334 fingerprint = Column(String(255))
335 public_key = Column(Text)
336
337 @property
338 def str_id(self):
339 return '%s.%s' % (self.user_id, self.name)
340
341 @classmethod
342 def find_by_str(cls, str_id, session=None, deleted=False):
343 user_id, _sep, name = str_id.partition('.')
344 return cls.find_by_str(user_id, name, session, deleted)
345
346 @classmethod
347 def find_by_args(cls, user_id, name, session=None, deleted=False):
348 if not session:
349 session = get_session()
350 try:
351 return session.query(cls
352 ).filter_by(user_id=user_id
353 ).filter_by(name=name
354 ).filter_by(deleted=deleted
355 ).one()
356 except exc.NoResultFound:
357 new_exc = exception.NotFound("No model for user %s, name %s" %
358 (user_id, name))
359 raise new_exc.__class__, new_exc, sys.exc_info()[2]
360
361
326class Network(BASE, NovaBase):362class Network(BASE, NovaBase):
327 """Represents a network"""363 """Represents a network"""
328 __tablename__ = 'networks'364 __tablename__ = 'networks'
329365
=== modified file 'nova/endpoint/cloud.py'
--- nova/endpoint/cloud.py 2010-09-21 04:08:25 +0000
+++ nova/endpoint/cloud.py 2010-09-21 04:21:00 +0000
@@ -30,6 +30,7 @@
3030
31from twisted.internet import defer31from twisted.internet import defer
3232
33from nova import crypto
33from nova import db34from nova import db
34from nova import exception35from nova import exception
35from nova import flags36from nova import flags
@@ -37,7 +38,6 @@
37from nova import rpc38from nova import rpc
38from nova import utils39from nova import utils
39from nova.auth import rbac40from nova.auth import rbac
40from nova.auth import manager
41from nova.compute.instance_types import INSTANCE_TYPES41from nova.compute.instance_types import INSTANCE_TYPES
42from nova.endpoint import images42from nova.endpoint import images
4343
@@ -51,14 +51,30 @@
51 pass51 pass
5252
5353
54def _gen_key(user_id, key_name):54def _gen_key(context, user_id, key_name):
55 """ Tuck this into AuthManager """55 """Generate a key
56
57 This is a module level method because it is slow and we need to defer
58 it into a process pool."""
56 try:59 try:
57 mgr = manager.AuthManager()60 # NOTE(vish): generating key pair is slow so check for legal
58 private_key, fingerprint = mgr.generate_key_pair(user_id, key_name)61 # creation before creating key_pair
62 try:
63 db.key_pair_get(context, user_id, key_name)
64 raise exception.Duplicate("The key_pair %s already exists"
65 % key_name)
66 except exception.NotFound:
67 pass
68 private_key, public_key, fingerprint = crypto.generate_key_pair()
69 key = {}
70 key['user_id'] = user_id
71 key['name'] = key_name
72 key['public_key'] = public_key
73 key['fingerprint'] = fingerprint
74 db.key_pair_create(context, key)
75 return {'private_key': private_key, 'fingerprint': fingerprint}
59 except Exception as ex:76 except Exception as ex:
60 return {'exception': ex}77 return {'exception': ex}
61 return {'private_key': private_key, 'fingerprint': fingerprint}
6278
6379
64class CloudController(object):80class CloudController(object):
@@ -193,18 +209,18 @@
193209
194 @rbac.allow('all')210 @rbac.allow('all')
195 def describe_key_pairs(self, context, key_name=None, **kwargs):211 def describe_key_pairs(self, context, key_name=None, **kwargs):
196 key_pairs = context.user.get_key_pairs()212 key_pairs = db.key_pair_get_all_by_user(context, context.user.id)
197 if not key_name is None:213 if not key_name is None:
198 key_pairs = [x for x in key_pairs if x.name in key_name]214 key_pairs = [x for x in key_pairs if x['name'] in key_name]
199215
200 result = []216 result = []
201 for key_pair in key_pairs:217 for key_pair in key_pairs:
202 # filter out the vpn keys218 # filter out the vpn keys
203 suffix = FLAGS.vpn_key_suffix219 suffix = FLAGS.vpn_key_suffix
204 if context.user.is_admin() or not key_pair.name.endswith(suffix):220 if context.user.is_admin() or not key_pair['name'].endswith(suffix):
205 result.append({221 result.append({
206 'keyName': key_pair.name,222 'keyName': key_pair['name'],
207 'keyFingerprint': key_pair.fingerprint,223 'keyFingerprint': key_pair['fingerprint'],
208 })224 })
209225
210 return {'keypairsSet': result}226 return {'keypairsSet': result}
@@ -220,14 +236,18 @@
220 dcall.callback({'keyName': key_name,236 dcall.callback({'keyName': key_name,
221 'keyFingerprint': kwargs['fingerprint'],237 'keyFingerprint': kwargs['fingerprint'],
222 'keyMaterial': kwargs['private_key']})238 'keyMaterial': kwargs['private_key']})
223 pool.apply_async(_gen_key, [context.user.id, key_name],239 # TODO(vish): when context is no longer an object, pass it here
240 pool.apply_async(_gen_key, [None, context.user.id, key_name],
224 callback=_complete)241 callback=_complete)
225 return dcall242 return dcall
226243
227 @rbac.allow('all')244 @rbac.allow('all')
228 def delete_key_pair(self, context, key_name, **kwargs):245 def delete_key_pair(self, context, key_name, **kwargs):
229 context.user.delete_key_pair(key_name)246 try:
230 # aws returns true even if the key doens't exist247 db.key_pair_destroy(context, context.user.id, key_name)
248 except exception.NotFound:
249 # aws returns true even if the key doesn't exist
250 pass
231 return True251 return True
232252
233 @rbac.allow('all')253 @rbac.allow('all')
@@ -575,11 +595,10 @@
575 launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())595 launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
576 key_data = None596 key_data = None
577 if kwargs.has_key('key_name'):597 if kwargs.has_key('key_name'):
578 key_pair = context.user.get_key_pair(kwargs['key_name'])598 key_pair_ref = db.key_pair_get(context,
579 if not key_pair:599 context.user.id,
580 raise exception.ApiError('Key Pair %s not found' %600 kwargs['key_name'])
581 kwargs['key_name'])601 key_data = key_pair_ref['public_key']
582 key_data = key_pair.public_key
583602
584 # TODO: Get the real security group of launch in here603 # TODO: Get the real security group of launch in here
585 security_group = "default"604 security_group = "default"
586605
=== modified file 'nova/tests/api_unittest.py'
--- nova/tests/api_unittest.py 2010-08-10 13:55:00 +0000
+++ nova/tests/api_unittest.py 2010-09-21 04:21:00 +0000
@@ -41,8 +41,8 @@
41# it's pretty damn circuitous so apologies if you have to fix41# it's pretty damn circuitous so apologies if you have to fix
42# a bug in it42# a bug in it
43# NOTE(jaypipes) The pylint disables here are for R0913 (too many args) which43# NOTE(jaypipes) The pylint disables here are for R0913 (too many args) which
44# isn't controllable since boto's HTTPRequest needs that many 44# isn't controllable since boto's HTTPRequest needs that many
45# args, and for the version-differentiated import of tornado's 45# args, and for the version-differentiated import of tornado's
46# httputil.46# httputil.
47# NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint is47# NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint is
48# unable to introspect the deferred's return value properly48# unable to introspect the deferred's return value properly
@@ -224,7 +224,8 @@
224 for x in range(random.randint(4, 8)))224 for x in range(random.randint(4, 8)))
225 user = self.manager.create_user('fake', 'fake', 'fake')225 user = self.manager.create_user('fake', 'fake', 'fake')
226 project = self.manager.create_project('fake', 'fake', 'fake')226 project = self.manager.create_project('fake', 'fake', 'fake')
227 self.manager.generate_key_pair(user.id, keyname)227 # NOTE(vish): create depends on pool, so call helper directly
228 cloud._gen_key(None, user.id, keyname)
228229
229 rv = self.ec2.get_all_key_pairs()230 rv = self.ec2.get_all_key_pairs()
230 results = [k for k in rv if k.name == keyname]231 results = [k for k in rv if k.name == keyname]
231232
=== modified file 'nova/tests/auth_unittest.py'
--- nova/tests/auth_unittest.py 2010-09-21 03:53:46 +0000
+++ nova/tests/auth_unittest.py 2010-09-21 04:21:00 +0000
@@ -17,8 +17,6 @@
17# under the License.17# under the License.
1818
19import logging19import logging
20from M2Crypto import BIO
21from M2Crypto import RSA
22from M2Crypto import X50920from M2Crypto import X509
23import unittest21import unittest
2422
@@ -65,35 +63,6 @@
65 'export S3_URL="http://127.0.0.1:3333/"\n' +63 'export S3_URL="http://127.0.0.1:3333/"\n' +
66 'export EC2_USER_ID="test1"\n')64 'export EC2_USER_ID="test1"\n')
6765
68 def test_006_test_key_storage(self):
69 user = self.manager.get_user('test1')
70 user.create_key_pair('public', 'key', 'fingerprint')
71 key = user.get_key_pair('public')
72 self.assertEqual('key', key.public_key)
73 self.assertEqual('fingerprint', key.fingerprint)
74
75 def test_007_test_key_generation(self):
76 user = self.manager.get_user('test1')
77 private_key, fingerprint = user.generate_key_pair('public2')
78 key = RSA.load_key_string(private_key, callback=lambda: None)
79 bio = BIO.MemoryBuffer()
80 public_key = user.get_key_pair('public2').public_key
81 key.save_pub_key_bio(bio)
82 converted = crypto.ssl_pub_to_ssh_pub(bio.read())
83 # assert key fields are equal
84 self.assertEqual(public_key.split(" ")[1].strip(),
85 converted.split(" ")[1].strip())
86
87 def test_008_can_list_key_pairs(self):
88 keys = self.manager.get_user('test1').get_key_pairs()
89 self.assertTrue(filter(lambda k: k.name == 'public', keys))
90 self.assertTrue(filter(lambda k: k.name == 'public2', keys))
91
92 def test_009_can_delete_key_pair(self):
93 self.manager.get_user('test1').delete_key_pair('public')
94 keys = self.manager.get_user('test1').get_key_pairs()
95 self.assertFalse(filter(lambda k: k.name == 'public', keys))
96
97 def test_010_can_list_users(self):66 def test_010_can_list_users(self):
98 users = self.manager.get_users()67 users = self.manager.get_users()
99 logging.warn(users)68 logging.warn(users)
10069
=== modified file 'nova/tests/cloud_unittest.py'
--- nova/tests/cloud_unittest.py 2010-09-11 07:21:58 +0000
+++ nova/tests/cloud_unittest.py 2010-09-21 04:21:00 +0000
@@ -17,13 +17,18 @@
17# under the License.17# under the License.
1818
19import logging19import logging
20from M2Crypto import BIO
21from M2Crypto import RSA
20import StringIO22import StringIO
21import time23import time
24
22from tornado import ioloop25from tornado import ioloop
23from twisted.internet import defer26from twisted.internet import defer
24import unittest27import unittest
25from xml.etree import ElementTree28from xml.etree import ElementTree
2629
30from nova import crypto
31from nova import db
27from nova import flags32from nova import flags
28from nova import rpc33from nova import rpc
29from nova import test34from nova import test
@@ -55,16 +60,21 @@
55 proxy=self.compute)60 proxy=self.compute)
56 self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop))61 self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop))
5762
58 try:63 self.manager = manager.AuthManager()
59 manager.AuthManager().create_user('admin', 'admin', 'admin')64 self.user = self.manager.create_user('admin', 'admin', 'admin', True)
60 except: pass65 self.project = self.manager.create_project('proj', 'admin', 'proj')
61 admin = manager.AuthManager().get_user('admin')66 self.context = api.APIRequestContext(handler=None,
62 project = manager.AuthManager().create_project('proj', 'admin', 'proj')67 user=self.user,
63 self.context = api.APIRequestContext(handler=None,project=project,user=admin)68 project=self.project)
6469
65 def tearDown(self):70 def tearDown(self):
66 manager.AuthManager().delete_project('proj')71 self.manager.delete_project(self.project)
67 manager.AuthManager().delete_user('admin')72 self.manager.delete_user(self.user)
73 super(CloudTestCase, self).setUp()
74
75 def _create_key(self, name):
76 # NOTE(vish): create depends on pool, so just call helper directly
77 return cloud._gen_key(self.context, self.context.user.id, name)
6878
69 def test_console_output(self):79 def test_console_output(self):
70 if FLAGS.connection_type == 'fake':80 if FLAGS.connection_type == 'fake':
@@ -77,6 +87,33 @@
77 self.assert_(output)87 self.assert_(output)
78 rv = yield self.compute.terminate_instance(instance_id)88 rv = yield self.compute.terminate_instance(instance_id)
7989
90
91 def test_key_generation(self):
92 result = self._create_key('test')
93 private_key = result['private_key']
94 key = RSA.load_key_string(private_key, callback=lambda: None)
95 bio = BIO.MemoryBuffer()
96 public_key = db.key_pair_get(self.context,
97 self.context.user.id,
98 'test')['public_key']
99 key.save_pub_key_bio(bio)
100 converted = crypto.ssl_pub_to_ssh_pub(bio.read())
101 # assert key fields are equal
102 self.assertEqual(public_key.split(" ")[1].strip(),
103 converted.split(" ")[1].strip())
104
105 def test_describe_key_pairs(self):
106 self._create_key('test1')
107 self._create_key('test2')
108 result = self.cloud.describe_key_pairs(self.context)
109 keys = result["keypairsSet"]
110 self.assertTrue(filter(lambda k: k['keyName'] == 'test1', keys))
111 self.assertTrue(filter(lambda k: k['keyName'] == 'test2', keys))
112
113 def test_delete_key_pair(self):
114 self._create_key('test')
115 self.cloud.delete_key_pair(self.context, 'test')
116
80 def test_run_instances(self):117 def test_run_instances(self):
81 if FLAGS.connection_type == 'fake':118 if FLAGS.connection_type == 'fake':
82 logging.debug("Can't test instances without a real virtual env.")119 logging.debug("Can't test instances without a real virtual env.")