X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=PLC%2FKeys.py;fp=PLC%2FKeys.py;h=e633a431606dc3264605cc14c81c5f5ca8077bf3;hb=0e514ee3c14478bd852f71bf0211335c5ec848f0;hp=c17447032376c3e9d4cbc6222e7c096bc52b4ddf;hpb=e54df4b6f909062a91e96976668d5dd48974180e;p=plcapi.git diff --git a/PLC/Keys.py b/PLC/Keys.py index c174470..e633a43 100644 --- a/PLC/Keys.py +++ b/PLC/Keys.py @@ -1,4 +1,7 @@ import re +import random +import string +from types import StringTypes from PLC.Faults import * from PLC.Parameter import Parameter @@ -20,44 +23,71 @@ class Key(AlchemyObj): 'key_id': Parameter(str, "Key identifier", primary_key=True), 'key_type': Parameter(str, "Key type"), 'key': Parameter(str, "Key string", max = 4096), # backwards compatibility + 'person_id': Parameter(int, "User to which this key belongs", nullok = True), + 'is_blacklisted': Parameter(bool, "Is the key blacklisted", default=False), 'name': Parameter(str, "Key name"), - 'uuid': Parameter(str, "Key name", ro=True) + 'peer_id': Parameter(int, "Peer to which this key belongs", nullok = True), + 'peer_key_id': Parameter(int, "Foreign key identifier at peer", nullok = True), } def sync(self, commit = True, validate = True): + from PLC.Persons import Person # sync the nova record and the plc record assert 'key' in self - assert 'name' in self AlchemyObj.sync(self, commit=commit, validate=validate) - nova_key = { - 'public_key': self['key'], - 'name': self['name'] - } - self.object = self.api.client_shell.nova.keypairs.create(**nova_key) - self['uuid'] = self.object.uuid - AlchemyObj.insert(self, dict(self)) - + persons = Person().select(filter={'person_id': self['person_id']}) + if not persons: + raise PLCInvalidArgument, "Invalid person id" + person = persons[0] + if 'key_id' not in self: + rand = ''.join(random.choice(string.ascii_letters) for x in range(5)) + self['name'] = person.email.split('@')[0] + rand + nova_key = { + 'public_key': self['key'], + 'name': self['name'] + } + self.object = self.api.client_shell.nova.keypairs.create(**nova_key) + AlchemyObj.insert(self, dict(self)) + key = Key().select(filter={'name': self['name']})[0] + self['key_id'] = key.key_id + else: + # nova has no way to update existing keys. Just remove the old + # key and add a new one + nova_key = { + 'public_key': self['key'], + 'name': self['name'] + } + self.api.client_shell.nova.keypairs.delete(self['name']) + self.object = self.api.client_shell.nova.keypairs.create(**nova_key) + AlchemyObj.update(self, {'key_id': self['key_id']}, dict(self)) + def delete(self): assert 'key_id' in self assert 'name' in self - self.api.client_shell.nova.keypairs.delete(self.id) + self.api.client_shell.nova.keypairs.delete(self['name']) + AlchemyObj.delete(self, filter={'key_id': self['key_id']}) + - def validate_public_key(self, key): - # Key must not be blacklisted - pass - return key + def validate_key_type(self, key_type): + exists = KeyTypes(self.api, key_type) + if not exists: + raise PLCInvalidArgument, "Invalid key type" + return key_type - def validate_name(self, name): - keys = Keys(self.api, name) + def validate_key(self, key): + # Key must not be blacklisted + keys = Keys(self.api, {'key': key, 'is_blacklisted': True}) if keys: - raise PLCInvalidArgument, "Key name alredy in use" + raise PLCInvalidArgument, "Key is blacklisted and cannot be used" + + return key def validate(self): # Basic validation - NovaObject.validate(self) + AlchemyObj.validate(self) - assert 'public_key' in self - key = self['public_key'] + assert 'key' in self + key = self['key'] if self['key_type'] == 'ssh': # Accept only SSH version 2 keys without options. From @@ -85,7 +115,8 @@ class Key(AlchemyObj): assert 'key_id' in self assert 'key' in self - pass + AlchemyObj.updatedb(self, filter={'key': self['key']}, values={'is_blacklisted': True}) + class Keys(list): """ @@ -95,19 +126,24 @@ class Keys(list): def __init__(self, api, key_filter = None, columns = None): self.api = api - keysManager = self.api.client_shell.nova.keypairs - keyPairs = [] - - if key_filter is not None: - if isinstance(key_filter, (list, tuple, set, int, long)): - keyPairs = filter(lambda kp: kp.uuid in key_filter, - keysManager.findall()) - elif isinstance(key_filter, dict): - keyPairs = keysManager.findall(**key_filter) - elif isinstnace(key_filter, StringTypes): - keyPairs = keyManagers.findall(uuid = key_filter) - else: - raise PLCInvalidArgument, "Wrong key filter %r"%key_filter - - self.extend(keyPairs) + + if not key_filter: + keys = Key().select() + elif isinstance(key_filter, dict): + keys = Key().select(filter=key_filter) + elif isinstance(key_filter, StringTypes): + keys = Key().select(filter={'name': key_filter}) + elif isinstance(key_filter, int): + keys = Key().select(filter={'key_id': key_filter}) + elif isinstance(key_filter, (list, tuple, set)): + ints = filter(lambda x: isinstance(x, (int, long)), key_filter) + strs = filter(lambda x: isinstance(x, StringTypes), key_filter) + key_filter = {'key_id': ints, 'name': strs} + keys = Key().select(filter=key_filter) + else: + raise PLCInvalidArgument, "Wrong key filter %s" % key_filter + + for key in keys: + key = Key(api, object=key, columns=columns) + self.append(key)