3 from PLC.Faults import *
4 from PLC.Parameter import Parameter
5 from PLC.Filter import Filter
6 from PLC.Debug import profile
7 from PLC.Table import Row, Table
8 from PLC.KeyTypes import KeyType, KeyTypes
9 from PLC.Storage.AlchemyObject import AlchemyObj
11 class Key(AlchemyObj):
13 Representation of a row in the keys table. To use, instantiate with a
14 dict of values. Update as you would a dict. Commit to the database
20 'key_id': Parameter(str, "Key identifier", primary_key=True),
21 'key_type': Parameter(str, "Key type"),
22 'key': Parameter(str, "Key string", max = 4096), # backwards compatibility
23 'name': Parameter(str, "Key name"),
24 'uuid': Parameter(str, "Key name", ro=True)
27 def sync(self, commit = True, validate = True):
28 # sync the nova record and the plc record
31 AlchemyObj.sync(self, commit=commit, validate=validate)
33 'public_key': self['key'],
36 self.object = self.api.client_shell.nova.keypairs.create(**nova_key)
37 self['uuid'] = self.object.uuid
38 AlchemyObj.insert(self, dict(self))
41 assert 'key_id' in self
43 self.api.client_shell.nova.keypairs.delete(self.id)
45 def validate_public_key(self, key):
46 # Key must not be blacklisted
50 def validate_name(self, name):
51 keys = Keys(self.api, name)
53 raise PLCInvalidArgument, "Key name alredy in use"
57 NovaObject.validate(self)
59 assert 'public_key' in self
60 key = self['public_key']
62 if self['key_type'] == 'ssh':
63 # Accept only SSH version 2 keys without options. From
66 # Each protocol version 2 public key consists of: options,
67 # keytype, base64 encoded key, comment. The options field
68 # is optional...The comment field is not used for anything
69 # (but may be convenient for the user to identify the
70 # key). For protocol version 2 the keytype is ``ssh-dss''
73 good_ssh_key = r'^.*(?:ssh-dss|ssh-rsa)[ ]+[A-Za-z0-9+/=]+(?: .*)?$'
74 if not re.match(good_ssh_key, key, re.IGNORECASE):
75 raise PLCInvalidArgument, "Invalid SSH version 2 public key"
77 def blacklist(self, commit = True):
79 Permanently blacklist key (and all other identical keys),
80 preventing it from ever being added again. Because this could
81 affect multiple keys associated with multiple accounts, it
85 assert 'key_id' in self
92 Representation of row(s) from the keys table in the
96 def __init__(self, api, key_filter = None, columns = None):
98 keysManager = self.api.client_shell.nova.keypairs
101 if key_filter is not None:
102 if isinstance(key_filter, (list, tuple, set, int, long)):
103 keyPairs = filter(lambda kp: kp.uuid in key_filter,
104 keysManager.findall())
105 elif isinstance(key_filter, dict):
106 keyPairs = keysManager.findall(**key_filter)
107 elif isinstnace(key_filter, StringTypes):
108 keyPairs = keyManagers.findall(uuid = key_filter)
110 raise PLCInvalidArgument, "Wrong key filter %r"%key_filter
112 self.extend(keyPairs)