from PLC.Faults import *
from PLC.Parameter import Parameter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
-class KeyType(Row):
+class KeyType(AlchemyObj):
"""
Representation of a row in the key_types table. To use,
instantiate with a dict of values.
"""
- table_name = 'key_types'
- primary_key = 'key_type'
- join_tables = ['keys']
+ tablename = 'key_types'
fields = {
- 'key_type': Parameter(str, "Key type", max = 20),
+ 'key_type': Parameter(str, "Key type", max = 20, primary_key=True),
}
def validate_key_type(self, name):
raise PLCInvalidArgument, "Key type must be specified"
# Make sure key type does not alredy exist
- conflicts = KeyTypes(self.api, [name])
+ conflicts = KeyType().select(filter={'key_type': name})
if conflicts:
raise PLCInvalidArgument, "Key type name already in use"
return name
-class KeyTypes(Table):
+ def sync(self, commit = True, validate=True):
+ AlchemyObj.sync(self, commit=commit, validate=validate)
+ AlchemyObj.insert(self, dict(self))
+
+ def delete(self, commit=True):
+ """
+ Delete existing key type
+ """
+ assert 'key_type' in self
+ AlchemyObj.delete(self, filter={'key_type': self['key_type']})
+
+class KeyTypes(list):
"""
Representation of the key_types table in the database.
"""
def __init__(self, api, key_types = None):
- Table.__init__(self, api, KeyType)
-
- sql = "SELECT %s FROM key_types" % \
- ", ".join(KeyType.fields)
-
- if key_types:
- sql += " WHERE key_type IN (%s)" % ", ".join( [ api.db.quote (t) for t in key_types ] )
-
- self.selectall(sql)
+ if key_types:
+ key_types = KeyType().select(filter={'key_type': key_types})
+ else:
+ key_types = KeyType().select()
+
+ for key_type in key_types:
+ key_type = KeyType(api, object=key_type)
+ self.append(key_type)
import re
+import random
+import string
+from types import StringTypes
from PLC.Faults import *
from PLC.Parameter import Parameter
'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
assert 'key_id' in self
assert 'key' in self
- pass
+ AlchemyObj.updatedb(self, filter={'key': self['key']}, values={'is_blacklisted': True})
+
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)