Merge lp:~vishvananda/nova/move-keypairs into lp:~hudson-openstack/nova/trunk
- move-keypairs
- Merge into 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 | ||||
Related bugs: |
|
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.
- 380. By Vish Ishaya
-
merged trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'nova/auth/ldapdriver.py' |
2 | --- nova/auth/ldapdriver.py 2010-09-10 11:52:48 +0000 |
3 | +++ nova/auth/ldapdriver.py 2010-09-21 04:21:00 +0000 |
4 | @@ -99,13 +99,6 @@ |
5 | dn = FLAGS.ldap_user_subtree |
6 | return self.__to_user(self.__find_object(dn, query)) |
7 | |
8 | - def get_key_pair(self, uid, key_name): |
9 | - """Retrieve key pair by uid and key name""" |
10 | - dn = 'cn=%s,%s' % (key_name, |
11 | - self.__uid_to_dn(uid)) |
12 | - attr = self.__find_object(dn, '(objectclass=novaKeyPair)') |
13 | - return self.__to_key_pair(uid, attr) |
14 | - |
15 | def get_project(self, pid): |
16 | """Retrieve project by id""" |
17 | dn = 'cn=%s,%s' % (pid, |
18 | @@ -119,12 +112,6 @@ |
19 | '(objectclass=novaUser)') |
20 | return [self.__to_user(attr) for attr in attrs] |
21 | |
22 | - def get_key_pairs(self, uid): |
23 | - """Retrieve list of key pairs""" |
24 | - attrs = self.__find_objects(self.__uid_to_dn(uid), |
25 | - '(objectclass=novaKeyPair)') |
26 | - return [self.__to_key_pair(uid, attr) for attr in attrs] |
27 | - |
28 | def get_projects(self, uid=None): |
29 | """Retrieve list of projects""" |
30 | pattern = '(objectclass=novaProject)' |
31 | @@ -154,21 +141,6 @@ |
32 | self.conn.add_s(self.__uid_to_dn(name), attr) |
33 | return self.__to_user(dict(attr)) |
34 | |
35 | - def create_key_pair(self, uid, key_name, public_key, fingerprint): |
36 | - """Create a key pair""" |
37 | - # TODO(vish): possibly refactor this to store keys in their own ou |
38 | - # and put dn reference in the user object |
39 | - attr = [ |
40 | - ('objectclass', ['novaKeyPair']), |
41 | - ('cn', [key_name]), |
42 | - ('sshPublicKey', [public_key]), |
43 | - ('keyFingerprint', [fingerprint]), |
44 | - ] |
45 | - self.conn.add_s('cn=%s,%s' % (key_name, |
46 | - self.__uid_to_dn(uid)), |
47 | - attr) |
48 | - return self.__to_key_pair(uid, dict(attr)) |
49 | - |
50 | def create_project(self, name, manager_uid, |
51 | description=None, member_uids=None): |
52 | """Create a project""" |
53 | @@ -283,19 +255,10 @@ |
54 | """Delete a user""" |
55 | if not self.__user_exists(uid): |
56 | raise exception.NotFound("User %s doesn't exist" % uid) |
57 | - self.__delete_key_pairs(uid) |
58 | self.__remove_from_all(uid) |
59 | self.conn.delete_s('uid=%s,%s' % (uid, |
60 | FLAGS.ldap_user_subtree)) |
61 | |
62 | - def delete_key_pair(self, uid, key_name): |
63 | - """Delete a key pair""" |
64 | - if not self.__key_pair_exists(uid, key_name): |
65 | - raise exception.NotFound("Key Pair %s doesn't exist for user %s" % |
66 | - (key_name, uid)) |
67 | - self.conn.delete_s('cn=%s,uid=%s,%s' % (key_name, uid, |
68 | - FLAGS.ldap_user_subtree)) |
69 | - |
70 | def delete_project(self, project_id): |
71 | """Delete a project""" |
72 | project_dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree) |
73 | @@ -306,10 +269,6 @@ |
74 | """Check if user exists""" |
75 | return self.get_user(uid) != None |
76 | |
77 | - def __key_pair_exists(self, uid, key_name): |
78 | - """Check if key pair exists""" |
79 | - return self.get_key_pair(uid, key_name) != None |
80 | - |
81 | def __project_exists(self, project_id): |
82 | """Check if project exists""" |
83 | return self.get_project(project_id) != None |
84 | @@ -359,13 +318,6 @@ |
85 | """Check if group exists""" |
86 | return self.__find_object(dn, '(objectclass=groupOfNames)') != None |
87 | |
88 | - def __delete_key_pairs(self, uid): |
89 | - """Delete all key pairs for user""" |
90 | - keys = self.get_key_pairs(uid) |
91 | - if keys != None: |
92 | - for key in keys: |
93 | - self.delete_key_pair(uid, key['name']) |
94 | - |
95 | @staticmethod |
96 | def __role_to_dn(role, project_id=None): |
97 | """Convert role to corresponding dn""" |
98 | @@ -490,18 +442,6 @@ |
99 | 'secret': attr['secretKey'][0], |
100 | 'admin': (attr['isAdmin'][0] == 'TRUE')} |
101 | |
102 | - @staticmethod |
103 | - def __to_key_pair(owner, attr): |
104 | - """Convert ldap attributes to KeyPair object""" |
105 | - if attr == None: |
106 | - return None |
107 | - return { |
108 | - 'id': attr['cn'][0], |
109 | - 'name': attr['cn'][0], |
110 | - 'owner_id': owner, |
111 | - 'public_key': attr['sshPublicKey'][0], |
112 | - 'fingerprint': attr['keyFingerprint'][0]} |
113 | - |
114 | def __to_project(self, attr): |
115 | """Convert ldap attributes to Project object""" |
116 | if attr == None: |
117 | |
118 | === modified file 'nova/auth/manager.py' |
119 | --- nova/auth/manager.py 2010-09-21 03:53:46 +0000 |
120 | +++ nova/auth/manager.py 2010-09-21 04:21:00 +0000 |
121 | @@ -128,24 +128,6 @@ |
122 | def is_project_manager(self, project): |
123 | return AuthManager().is_project_manager(self, project) |
124 | |
125 | - def generate_key_pair(self, name): |
126 | - return AuthManager().generate_key_pair(self.id, name) |
127 | - |
128 | - def create_key_pair(self, name, public_key, fingerprint): |
129 | - return AuthManager().create_key_pair(self.id, |
130 | - name, |
131 | - public_key, |
132 | - fingerprint) |
133 | - |
134 | - def get_key_pair(self, name): |
135 | - return AuthManager().get_key_pair(self.id, name) |
136 | - |
137 | - def delete_key_pair(self, name): |
138 | - return AuthManager().delete_key_pair(self.id, name) |
139 | - |
140 | - def get_key_pairs(self): |
141 | - return AuthManager().get_key_pairs(self.id) |
142 | - |
143 | def __repr__(self): |
144 | return "User('%s', '%s', '%s', '%s', %s)" % (self.id, |
145 | self.name, |
146 | @@ -154,29 +136,6 @@ |
147 | self.admin) |
148 | |
149 | |
150 | -class KeyPair(AuthBase): |
151 | - """Represents an ssh key returned from the datastore |
152 | - |
153 | - Even though this object is named KeyPair, only the public key and |
154 | - fingerprint is stored. The user's private key is not saved. |
155 | - """ |
156 | - |
157 | - def __init__(self, id, name, owner_id, public_key, fingerprint): |
158 | - AuthBase.__init__(self) |
159 | - self.id = id |
160 | - self.name = name |
161 | - self.owner_id = owner_id |
162 | - self.public_key = public_key |
163 | - self.fingerprint = fingerprint |
164 | - |
165 | - def __repr__(self): |
166 | - return "KeyPair('%s', '%s', '%s', '%s', '%s')" % (self.id, |
167 | - self.name, |
168 | - self.owner_id, |
169 | - self.public_key, |
170 | - self.fingerprint) |
171 | - |
172 | - |
173 | class Project(AuthBase): |
174 | """Represents a Project returned from the datastore""" |
175 | |
176 | @@ -663,67 +622,13 @@ |
177 | return User(**user_dict) |
178 | |
179 | def delete_user(self, user): |
180 | - """Deletes a user""" |
181 | - with self.driver() as drv: |
182 | - drv.delete_user(User.safe_id(user)) |
183 | - |
184 | - def generate_key_pair(self, user, key_name): |
185 | - """Generates a key pair for a user |
186 | - |
187 | - Generates a public and private key, stores the public key using the |
188 | - key_name, and returns the private key and fingerprint. |
189 | - |
190 | - @type user: User or uid |
191 | - @param user: User for which to create key pair. |
192 | - |
193 | - @type key_name: str |
194 | - @param key_name: Name to use for the generated KeyPair. |
195 | - |
196 | - @rtype: tuple (private_key, fingerprint) |
197 | - @return: A tuple containing the private_key and fingerprint. |
198 | - """ |
199 | - # NOTE(vish): generating key pair is slow so check for legal |
200 | - # creation before creating keypair |
201 | + """Deletes a user |
202 | + |
203 | + Additionally deletes all users key_pairs""" |
204 | uid = User.safe_id(user) |
205 | - with self.driver() as drv: |
206 | - if not drv.get_user(uid): |
207 | - raise exception.NotFound("User %s doesn't exist" % user) |
208 | - if drv.get_key_pair(uid, key_name): |
209 | - raise exception.Duplicate("The keypair %s already exists" |
210 | - % key_name) |
211 | - private_key, public_key, fingerprint = crypto.generate_key_pair() |
212 | - self.create_key_pair(uid, key_name, public_key, fingerprint) |
213 | - return private_key, fingerprint |
214 | - |
215 | - def create_key_pair(self, user, key_name, public_key, fingerprint): |
216 | - """Creates a key pair for user""" |
217 | - with self.driver() as drv: |
218 | - kp_dict = drv.create_key_pair(User.safe_id(user), |
219 | - key_name, |
220 | - public_key, |
221 | - fingerprint) |
222 | - if kp_dict: |
223 | - return KeyPair(**kp_dict) |
224 | - |
225 | - def get_key_pair(self, user, key_name): |
226 | - """Retrieves a key pair for user""" |
227 | - with self.driver() as drv: |
228 | - kp_dict = drv.get_key_pair(User.safe_id(user), key_name) |
229 | - if kp_dict: |
230 | - return KeyPair(**kp_dict) |
231 | - |
232 | - def get_key_pairs(self, user): |
233 | - """Retrieves all key pairs for user""" |
234 | - with self.driver() as drv: |
235 | - kp_list = drv.get_key_pairs(User.safe_id(user)) |
236 | - if not kp_list: |
237 | - return [] |
238 | - return [KeyPair(**kp_dict) for kp_dict in kp_list] |
239 | - |
240 | - def delete_key_pair(self, user, key_name): |
241 | - """Deletes a key pair for user""" |
242 | - with self.driver() as drv: |
243 | - drv.delete_key_pair(User.safe_id(user), key_name) |
244 | + db.key_pair_destroy_all_by_user(None, uid) |
245 | + with self.driver() as drv: |
246 | + drv.delete_user(uid) |
247 | |
248 | def get_credentials(self, user, project=None): |
249 | """Get credential zip for user in project""" |
250 | |
251 | === modified file 'nova/cloudpipe/pipelib.py' |
252 | --- nova/cloudpipe/pipelib.py 2010-08-16 12:16:21 +0000 |
253 | +++ nova/cloudpipe/pipelib.py 2010-09-21 04:21:00 +0000 |
254 | @@ -58,7 +58,7 @@ |
255 | z.write(FLAGS.boot_script_template,'autorun.sh') |
256 | z.close() |
257 | |
258 | - key_name = self.setup_keypair(project.project_manager_id, project_id) |
259 | + key_name = self.setup_key_pair(project.project_manager_id, project_id) |
260 | zippy = open(zippath, "r") |
261 | context = api.APIRequestContext(handler=None, user=project.project_manager, project=project) |
262 | |
263 | @@ -74,7 +74,7 @@ |
264 | security_groups=["vpn-secgroup"]) |
265 | zippy.close() |
266 | |
267 | - def setup_keypair(self, user_id, project_id): |
268 | + def setup_key_pair(self, user_id, project_id): |
269 | key_name = '%s%s' % (project_id, FLAGS.vpn_key_suffix) |
270 | try: |
271 | private_key, fingerprint = self.manager.generate_key_pair(user_id, key_name) |
272 | |
273 | === modified file 'nova/crypto.py' |
274 | --- nova/crypto.py 2010-08-16 12:16:21 +0000 |
275 | +++ nova/crypto.py 2010-09-21 04:21:00 +0000 |
276 | @@ -18,7 +18,7 @@ |
277 | |
278 | """ |
279 | Wrappers around standard crypto, including root and intermediate CAs, |
280 | -SSH keypairs and x509 certificates. |
281 | +SSH key_pairs and x509 certificates. |
282 | """ |
283 | |
284 | import base64 |
285 | |
286 | === modified file 'nova/db/api.py' |
287 | --- nova/db/api.py 2010-09-12 01:45:35 +0000 |
288 | +++ nova/db/api.py 2010-09-21 04:21:00 +0000 |
289 | @@ -296,6 +296,34 @@ |
290 | return IMPL.instance_update(context, instance_id, values) |
291 | |
292 | |
293 | +################### |
294 | + |
295 | + |
296 | +def key_pair_create(context, values): |
297 | + """Create a key_pair from the values dictionary.""" |
298 | + return IMPL.key_pair_create(context, values) |
299 | + |
300 | + |
301 | +def key_pair_destroy(context, user_id, name): |
302 | + """Destroy the key_pair or raise if it does not exist.""" |
303 | + return IMPL.key_pair_destroy(context, user_id, name) |
304 | + |
305 | + |
306 | +def key_pair_destroy_all_by_user(context, user_id): |
307 | + """Destroy all key_pairs by user.""" |
308 | + return IMPL.key_pair_destroy_all_by_user(context, user_id) |
309 | + |
310 | + |
311 | +def key_pair_get(context, user_id, name): |
312 | + """Get a key_pair or raise if it does not exist.""" |
313 | + return IMPL.key_pair_get(context, user_id, name) |
314 | + |
315 | + |
316 | +def key_pair_get_all_by_user(context, user_id): |
317 | + """Get all key_pairs by user.""" |
318 | + return IMPL.key_pair_get_all_by_user(context, user_id) |
319 | + |
320 | + |
321 | #################### |
322 | |
323 | |
324 | |
325 | === modified file 'nova/db/sqlalchemy/api.py' |
326 | --- nova/db/sqlalchemy/api.py 2010-09-12 02:40:38 +0000 |
327 | +++ nova/db/sqlalchemy/api.py 2010-09-21 04:21:00 +0000 |
328 | @@ -462,6 +462,46 @@ |
329 | ################### |
330 | |
331 | |
332 | +def key_pair_create(_context, values): |
333 | + key_pair_ref = models.KeyPair() |
334 | + for (key, value) in values.iteritems(): |
335 | + key_pair_ref[key] = value |
336 | + key_pair_ref.save() |
337 | + return key_pair_ref |
338 | + |
339 | + |
340 | +def key_pair_destroy(_context, user_id, name): |
341 | + session = get_session() |
342 | + with session.begin(): |
343 | + key_pair_ref = models.KeyPair.find_by_args(user_id, |
344 | + name, |
345 | + session=session) |
346 | + key_pair_ref.delete(session=session) |
347 | + |
348 | + |
349 | +def key_pair_destroy_all_by_user(_context, user_id): |
350 | + session = get_session() |
351 | + with session.begin(): |
352 | + # TODO(vish): do we have to use sql here? |
353 | + session.execute('update key_pairs set deleted=1 where user_id=:id', |
354 | + {'id': user_id}) |
355 | + |
356 | + |
357 | +def key_pair_get(_context, user_id, name): |
358 | + return models.KeyPair.find_by_args(user_id, name) |
359 | + |
360 | + |
361 | +def key_pair_get_all_by_user(_context, user_id): |
362 | + session = get_session() |
363 | + return session.query(models.KeyPair |
364 | + ).filter_by(user_id=user_id |
365 | + ).filter_by(deleted=False |
366 | + ).all() |
367 | + |
368 | + |
369 | +################### |
370 | + |
371 | + |
372 | def network_count(_context): |
373 | return models.Network.count() |
374 | |
375 | |
376 | === modified file 'nova/db/sqlalchemy/models.py' |
377 | --- nova/db/sqlalchemy/models.py 2010-09-12 03:00:56 +0000 |
378 | +++ nova/db/sqlalchemy/models.py 2010-09-21 04:21:00 +0000 |
379 | @@ -323,6 +323,42 @@ |
380 | uselist=False)) |
381 | |
382 | |
383 | +class KeyPair(BASE, NovaBase): |
384 | + """Represents a public key pair for ssh""" |
385 | + __tablename__ = 'key_pairs' |
386 | + id = Column(Integer, primary_key=True) |
387 | + name = Column(String(255)) |
388 | + |
389 | + user_id = Column(String(255)) |
390 | + |
391 | + fingerprint = Column(String(255)) |
392 | + public_key = Column(Text) |
393 | + |
394 | + @property |
395 | + def str_id(self): |
396 | + return '%s.%s' % (self.user_id, self.name) |
397 | + |
398 | + @classmethod |
399 | + def find_by_str(cls, str_id, session=None, deleted=False): |
400 | + user_id, _sep, name = str_id.partition('.') |
401 | + return cls.find_by_str(user_id, name, session, deleted) |
402 | + |
403 | + @classmethod |
404 | + def find_by_args(cls, user_id, name, session=None, deleted=False): |
405 | + if not session: |
406 | + session = get_session() |
407 | + try: |
408 | + return session.query(cls |
409 | + ).filter_by(user_id=user_id |
410 | + ).filter_by(name=name |
411 | + ).filter_by(deleted=deleted |
412 | + ).one() |
413 | + except exc.NoResultFound: |
414 | + new_exc = exception.NotFound("No model for user %s, name %s" % |
415 | + (user_id, name)) |
416 | + raise new_exc.__class__, new_exc, sys.exc_info()[2] |
417 | + |
418 | + |
419 | class Network(BASE, NovaBase): |
420 | """Represents a network""" |
421 | __tablename__ = 'networks' |
422 | |
423 | === modified file 'nova/endpoint/cloud.py' |
424 | --- nova/endpoint/cloud.py 2010-09-21 04:08:25 +0000 |
425 | +++ nova/endpoint/cloud.py 2010-09-21 04:21:00 +0000 |
426 | @@ -30,6 +30,7 @@ |
427 | |
428 | from twisted.internet import defer |
429 | |
430 | +from nova import crypto |
431 | from nova import db |
432 | from nova import exception |
433 | from nova import flags |
434 | @@ -37,7 +38,6 @@ |
435 | from nova import rpc |
436 | from nova import utils |
437 | from nova.auth import rbac |
438 | -from nova.auth import manager |
439 | from nova.compute.instance_types import INSTANCE_TYPES |
440 | from nova.endpoint import images |
441 | |
442 | @@ -51,14 +51,30 @@ |
443 | pass |
444 | |
445 | |
446 | -def _gen_key(user_id, key_name): |
447 | - """ Tuck this into AuthManager """ |
448 | +def _gen_key(context, user_id, key_name): |
449 | + """Generate a key |
450 | + |
451 | + This is a module level method because it is slow and we need to defer |
452 | + it into a process pool.""" |
453 | try: |
454 | - mgr = manager.AuthManager() |
455 | - private_key, fingerprint = mgr.generate_key_pair(user_id, key_name) |
456 | + # NOTE(vish): generating key pair is slow so check for legal |
457 | + # creation before creating key_pair |
458 | + try: |
459 | + db.key_pair_get(context, user_id, key_name) |
460 | + raise exception.Duplicate("The key_pair %s already exists" |
461 | + % key_name) |
462 | + except exception.NotFound: |
463 | + pass |
464 | + private_key, public_key, fingerprint = crypto.generate_key_pair() |
465 | + key = {} |
466 | + key['user_id'] = user_id |
467 | + key['name'] = key_name |
468 | + key['public_key'] = public_key |
469 | + key['fingerprint'] = fingerprint |
470 | + db.key_pair_create(context, key) |
471 | + return {'private_key': private_key, 'fingerprint': fingerprint} |
472 | except Exception as ex: |
473 | return {'exception': ex} |
474 | - return {'private_key': private_key, 'fingerprint': fingerprint} |
475 | |
476 | |
477 | class CloudController(object): |
478 | @@ -193,18 +209,18 @@ |
479 | |
480 | @rbac.allow('all') |
481 | def describe_key_pairs(self, context, key_name=None, **kwargs): |
482 | - key_pairs = context.user.get_key_pairs() |
483 | + key_pairs = db.key_pair_get_all_by_user(context, context.user.id) |
484 | if not key_name is None: |
485 | - key_pairs = [x for x in key_pairs if x.name in key_name] |
486 | + key_pairs = [x for x in key_pairs if x['name'] in key_name] |
487 | |
488 | result = [] |
489 | for key_pair in key_pairs: |
490 | # filter out the vpn keys |
491 | suffix = FLAGS.vpn_key_suffix |
492 | - if context.user.is_admin() or not key_pair.name.endswith(suffix): |
493 | + if context.user.is_admin() or not key_pair['name'].endswith(suffix): |
494 | result.append({ |
495 | - 'keyName': key_pair.name, |
496 | - 'keyFingerprint': key_pair.fingerprint, |
497 | + 'keyName': key_pair['name'], |
498 | + 'keyFingerprint': key_pair['fingerprint'], |
499 | }) |
500 | |
501 | return {'keypairsSet': result} |
502 | @@ -220,14 +236,18 @@ |
503 | dcall.callback({'keyName': key_name, |
504 | 'keyFingerprint': kwargs['fingerprint'], |
505 | 'keyMaterial': kwargs['private_key']}) |
506 | - pool.apply_async(_gen_key, [context.user.id, key_name], |
507 | + # TODO(vish): when context is no longer an object, pass it here |
508 | + pool.apply_async(_gen_key, [None, context.user.id, key_name], |
509 | callback=_complete) |
510 | return dcall |
511 | |
512 | @rbac.allow('all') |
513 | def delete_key_pair(self, context, key_name, **kwargs): |
514 | - context.user.delete_key_pair(key_name) |
515 | - # aws returns true even if the key doens't exist |
516 | + try: |
517 | + db.key_pair_destroy(context, context.user.id, key_name) |
518 | + except exception.NotFound: |
519 | + # aws returns true even if the key doesn't exist |
520 | + pass |
521 | return True |
522 | |
523 | @rbac.allow('all') |
524 | @@ -575,11 +595,10 @@ |
525 | launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) |
526 | key_data = None |
527 | if kwargs.has_key('key_name'): |
528 | - key_pair = context.user.get_key_pair(kwargs['key_name']) |
529 | - if not key_pair: |
530 | - raise exception.ApiError('Key Pair %s not found' % |
531 | - kwargs['key_name']) |
532 | - key_data = key_pair.public_key |
533 | + key_pair_ref = db.key_pair_get(context, |
534 | + context.user.id, |
535 | + kwargs['key_name']) |
536 | + key_data = key_pair_ref['public_key'] |
537 | |
538 | # TODO: Get the real security group of launch in here |
539 | security_group = "default" |
540 | |
541 | === modified file 'nova/tests/api_unittest.py' |
542 | --- nova/tests/api_unittest.py 2010-08-10 13:55:00 +0000 |
543 | +++ nova/tests/api_unittest.py 2010-09-21 04:21:00 +0000 |
544 | @@ -41,8 +41,8 @@ |
545 | # it's pretty damn circuitous so apologies if you have to fix |
546 | # a bug in it |
547 | # NOTE(jaypipes) The pylint disables here are for R0913 (too many args) which |
548 | -# isn't controllable since boto's HTTPRequest needs that many |
549 | -# args, and for the version-differentiated import of tornado's |
550 | +# isn't controllable since boto's HTTPRequest needs that many |
551 | +# args, and for the version-differentiated import of tornado's |
552 | # httputil. |
553 | # NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint is |
554 | # unable to introspect the deferred's return value properly |
555 | @@ -224,7 +224,8 @@ |
556 | for x in range(random.randint(4, 8))) |
557 | user = self.manager.create_user('fake', 'fake', 'fake') |
558 | project = self.manager.create_project('fake', 'fake', 'fake') |
559 | - self.manager.generate_key_pair(user.id, keyname) |
560 | + # NOTE(vish): create depends on pool, so call helper directly |
561 | + cloud._gen_key(None, user.id, keyname) |
562 | |
563 | rv = self.ec2.get_all_key_pairs() |
564 | results = [k for k in rv if k.name == keyname] |
565 | |
566 | === modified file 'nova/tests/auth_unittest.py' |
567 | --- nova/tests/auth_unittest.py 2010-09-21 03:53:46 +0000 |
568 | +++ nova/tests/auth_unittest.py 2010-09-21 04:21:00 +0000 |
569 | @@ -17,8 +17,6 @@ |
570 | # under the License. |
571 | |
572 | import logging |
573 | -from M2Crypto import BIO |
574 | -from M2Crypto import RSA |
575 | from M2Crypto import X509 |
576 | import unittest |
577 | |
578 | @@ -65,35 +63,6 @@ |
579 | 'export S3_URL="http://127.0.0.1:3333/"\n' + |
580 | 'export EC2_USER_ID="test1"\n') |
581 | |
582 | - def test_006_test_key_storage(self): |
583 | - user = self.manager.get_user('test1') |
584 | - user.create_key_pair('public', 'key', 'fingerprint') |
585 | - key = user.get_key_pair('public') |
586 | - self.assertEqual('key', key.public_key) |
587 | - self.assertEqual('fingerprint', key.fingerprint) |
588 | - |
589 | - def test_007_test_key_generation(self): |
590 | - user = self.manager.get_user('test1') |
591 | - private_key, fingerprint = user.generate_key_pair('public2') |
592 | - key = RSA.load_key_string(private_key, callback=lambda: None) |
593 | - bio = BIO.MemoryBuffer() |
594 | - public_key = user.get_key_pair('public2').public_key |
595 | - key.save_pub_key_bio(bio) |
596 | - converted = crypto.ssl_pub_to_ssh_pub(bio.read()) |
597 | - # assert key fields are equal |
598 | - self.assertEqual(public_key.split(" ")[1].strip(), |
599 | - converted.split(" ")[1].strip()) |
600 | - |
601 | - def test_008_can_list_key_pairs(self): |
602 | - keys = self.manager.get_user('test1').get_key_pairs() |
603 | - self.assertTrue(filter(lambda k: k.name == 'public', keys)) |
604 | - self.assertTrue(filter(lambda k: k.name == 'public2', keys)) |
605 | - |
606 | - def test_009_can_delete_key_pair(self): |
607 | - self.manager.get_user('test1').delete_key_pair('public') |
608 | - keys = self.manager.get_user('test1').get_key_pairs() |
609 | - self.assertFalse(filter(lambda k: k.name == 'public', keys)) |
610 | - |
611 | def test_010_can_list_users(self): |
612 | users = self.manager.get_users() |
613 | logging.warn(users) |
614 | |
615 | === modified file 'nova/tests/cloud_unittest.py' |
616 | --- nova/tests/cloud_unittest.py 2010-09-11 07:21:58 +0000 |
617 | +++ nova/tests/cloud_unittest.py 2010-09-21 04:21:00 +0000 |
618 | @@ -17,13 +17,18 @@ |
619 | # under the License. |
620 | |
621 | import logging |
622 | +from M2Crypto import BIO |
623 | +from M2Crypto import RSA |
624 | import StringIO |
625 | import time |
626 | + |
627 | from tornado import ioloop |
628 | from twisted.internet import defer |
629 | import unittest |
630 | from xml.etree import ElementTree |
631 | |
632 | +from nova import crypto |
633 | +from nova import db |
634 | from nova import flags |
635 | from nova import rpc |
636 | from nova import test |
637 | @@ -55,16 +60,21 @@ |
638 | proxy=self.compute) |
639 | self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop)) |
640 | |
641 | - try: |
642 | - manager.AuthManager().create_user('admin', 'admin', 'admin') |
643 | - except: pass |
644 | - admin = manager.AuthManager().get_user('admin') |
645 | - project = manager.AuthManager().create_project('proj', 'admin', 'proj') |
646 | - self.context = api.APIRequestContext(handler=None,project=project,user=admin) |
647 | + self.manager = manager.AuthManager() |
648 | + self.user = self.manager.create_user('admin', 'admin', 'admin', True) |
649 | + self.project = self.manager.create_project('proj', 'admin', 'proj') |
650 | + self.context = api.APIRequestContext(handler=None, |
651 | + user=self.user, |
652 | + project=self.project) |
653 | |
654 | def tearDown(self): |
655 | - manager.AuthManager().delete_project('proj') |
656 | - manager.AuthManager().delete_user('admin') |
657 | + self.manager.delete_project(self.project) |
658 | + self.manager.delete_user(self.user) |
659 | + super(CloudTestCase, self).setUp() |
660 | + |
661 | + def _create_key(self, name): |
662 | + # NOTE(vish): create depends on pool, so just call helper directly |
663 | + return cloud._gen_key(self.context, self.context.user.id, name) |
664 | |
665 | def test_console_output(self): |
666 | if FLAGS.connection_type == 'fake': |
667 | @@ -77,6 +87,33 @@ |
668 | self.assert_(output) |
669 | rv = yield self.compute.terminate_instance(instance_id) |
670 | |
671 | + |
672 | + def test_key_generation(self): |
673 | + result = self._create_key('test') |
674 | + private_key = result['private_key'] |
675 | + key = RSA.load_key_string(private_key, callback=lambda: None) |
676 | + bio = BIO.MemoryBuffer() |
677 | + public_key = db.key_pair_get(self.context, |
678 | + self.context.user.id, |
679 | + 'test')['public_key'] |
680 | + key.save_pub_key_bio(bio) |
681 | + converted = crypto.ssl_pub_to_ssh_pub(bio.read()) |
682 | + # assert key fields are equal |
683 | + self.assertEqual(public_key.split(" ")[1].strip(), |
684 | + converted.split(" ")[1].strip()) |
685 | + |
686 | + def test_describe_key_pairs(self): |
687 | + self._create_key('test1') |
688 | + self._create_key('test2') |
689 | + result = self.cloud.describe_key_pairs(self.context) |
690 | + keys = result["keypairsSet"] |
691 | + self.assertTrue(filter(lambda k: k['keyName'] == 'test1', keys)) |
692 | + self.assertTrue(filter(lambda k: k['keyName'] == 'test2', keys)) |
693 | + |
694 | + def test_delete_key_pair(self): |
695 | + self._create_key('test') |
696 | + self.cloud.delete_key_pair(self.context, 'test') |
697 | + |
698 | def test_run_instances(self): |
699 | if FLAGS.connection_type == 'fake': |
700 | logging.debug("Can't test instances without a real virtual env.") |
Rock on. One less thing in LDAP makes Jay a happy boy.