From: Tony Mack Date: Thu, 4 Oct 2012 14:47:59 +0000 (-0400) Subject: fix bugs X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=6c1d0870a035807c15ef5b47db4b7678feb5fa76;p=plcapi.git fix bugs --- diff --git a/PLC/BootStates.py b/PLC/BootStates.py index 4ce45ca5..0485aa2b 100644 --- a/PLC/BootStates.py +++ b/PLC/BootStates.py @@ -51,7 +51,7 @@ class BootStates(list): elif isinstance(filter, StringTypes) or isinstance(filter, (list, tuple, set)): boot_states = BootState().select(filter={'boot_state': filter}) else: - raise PLCInvalidArgument, "Wrong boot state filter %r" filter + raise PLCInvalidArgument, "Wrong boot state filter %r" % filter for boot_state in boot_states: self.append(boot_state) diff --git a/PLC/Interfaces.py b/PLC/Interfaces.py index dcb395bf..38735870 100644 --- a/PLC/Interfaces.py +++ b/PLC/Interfaces.py @@ -234,7 +234,7 @@ class Interface(AlchemyObj): if 'ip' not in self or not self['ip']: raise PLCInvalidArgument, "For ipmi method, ip is required" - validate_last_updated = Row.validate_timestamp + validate_last_updated = AlchemyObj.validate_timestamp def update_timestamp(self, col_name, commit = True): """ @@ -256,7 +256,7 @@ class Interface(AlchemyObj): def delete(self,commit=True): ### need to cleanup ilinks assert 'interface_id' in self - AlchemyObj.delete(self, dict(self) + AlchemyObj.delete(self, dict(self)) class Interfaces(list): @@ -275,7 +275,7 @@ class Interfaces(list): strs = filter(lambda x: isinstance(x, StringTypes), interface_filter) interfaces = Interface().select(filter={'interface_id': ints, 'ip': strs}) elif isinstance(interface_filter, dict): - interfaces = Interface().select(filter=interface_filter}) + interfaces = Interface().select(filter=interface_filter) elif isinstance(interface_filter, int): interfaces = Interface().select(filter={'interface_id': interface_filter}) elif isinstance (interface_filter, StringTypes): diff --git a/PLC/Keys.py b/PLC/Keys.py index 07a05e4f..6f828384 100644 --- a/PLC/Keys.py +++ b/PLC/Keys.py @@ -41,7 +41,7 @@ class Key(NovaObject): pass return key - def validate_name(self, name) + def validate_name(self, name): keys = Keys(self.api, name) if keys: raise PLCInvalidArgument, "Key name alredy in use" diff --git a/PLC/Method.py b/PLC/Method.py index 1236f0cc..12a54530 100644 --- a/PLC/Method.py +++ b/PLC/Method.py @@ -325,7 +325,11 @@ w password=auth['AuthString'], tenant=auth['Tenant']) self.api.client_shell.authenticate() - self.caller = Person(self.api, object=self.api.client_shell.keystone.users.find(name=auth['Username'])) + persons = Persons(self.api, {'email': auth['Username']}) + if not persons: + raise PLCAuthenticationFailure, "Username not found" + self.caller = persons[0] + keystone_user = self.api.client_shell.keystone.users.find(id=self.caller['keystone_id']) self.caller_tenant = self.api.client_shell.keystone.tenants.find(name=auth['Tenant']) caller_roles = self.api.client_shell.keystone.roles.roles_for_user(self.caller, self.caller_tenant) role_names = [role.name for role in caller_roles] diff --git a/PLC/Methods/GetRoles.py b/PLC/Methods/GetRoles.py index 769922bc..8525ee36 100644 --- a/PLC/Methods/GetRoles.py +++ b/PLC/Methods/GetRoles.py @@ -2,7 +2,6 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Roles import Role, Roles -from PLC.NovaObject import NovaObject from PLC.Auth import Auth class GetRoles(Method): diff --git a/PLC/NodeTypes.py b/PLC/NodeTypes.py index fd5e022f..cfffdcc4 100644 --- a/PLC/NodeTypes.py +++ b/PLC/NodeTypes.py @@ -33,7 +33,7 @@ class NodeType(AlchemyObj): def sync(self, commit=True, validate=True): AlchemyObj.sync(self, commit=commit, validate=validate) - AlchemyObj.insert(self, dict(self) + AlchemyObj.insert(self, dict(self)) def delete(self, commit=True): assert 'node_type' in self diff --git a/PLC/Nodes.py b/PLC/Nodes.py index 182ef4e6..ba939067 100644 --- a/PLC/Nodes.py +++ b/PLC/Nodes.py @@ -12,7 +12,7 @@ from PLC.Faults import * from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter from PLC.Debug import profile -from PLC.Storage.AlchemyObj import AlchemyObj +from PLC.Storage.AlchemyObject import AlchemyObj from PLC.NodeTypes import NodeTypes from PLC.BootStates import BootStates from PLC.Interfaces import Interface, Interfaces @@ -278,7 +278,7 @@ class Node(AlchemyObj): assert 'node_id' in self assert 'interface_ids' in self Interface().delete(filter={'interface_id': self['interface_ids']}) - AlchemyObj.delete(self, dict(self) + AlchemyObj.delete(self, dict(self)) class Nodes(list): """ diff --git a/PLC/Parameter.py b/PLC/Parameter.py index c5b79f9e..14a8b189 100644 --- a/PLC/Parameter.py +++ b/PLC/Parameter.py @@ -48,6 +48,12 @@ class Parameter: self.primary_key = primary_key + # Whether the DB field is indexed + self.indexed = indexed + + # Whether the DB field lives in another table + self.joined = joined + def type(self): return self.type diff --git a/PLC/Persons.py b/PLC/Persons.py index 76487304..f6d44078 100644 --- a/PLC/Persons.py +++ b/PLC/Persons.py @@ -92,7 +92,7 @@ class Person(AlchemyObj): return True if 'pi' in self['roles']: - if set(self['tenants']).intersection(person['tenants']): + if set(self['site_ids']).intersection(person['site_ids']): # non-admin users cannot update a person who is neither a PI or ADMIN return (not set(['pi','admin']).intersection(person['roles'])) @@ -126,14 +126,13 @@ class Person(AlchemyObj): #add_key = Row.add_object(Key, 'person_key') #remove_key = Row.remove_object(Key, 'person_key') - def sync(self, insert=False, validate=True): - NovaObject.sync(self, insert, validate) + def sync(self, commit=True, validate=True): + AlchemyObj.sync(self, commit=commit, validate=validate) nova_fields = ['enabled', 'email', 'password'] - nova_can_update = lambda (field, value): field in nova_fields nova_person = dict(filter(nova_can_update, self.items())) nova_person['name'] = "%s %s" % (self.get('first_name', ''), self.get('last_name', '')) - if insert == True or 'person_id' not in self: + if 'person_id' not in self: self.object = self.api.client_shell.keystone.users.create(**self) self['keystone_id'] = self.object.id AlchemyObj.insert(self, dict(self)) @@ -144,12 +143,16 @@ class Person(AlchemyObj): def delete(self): assert 'person_id' in self + assert 'keystone_id' in self + + # delete keystone record + nova_user = self.api.client_shell.keystone.users.find(id=self['keystone_id']) + self.api.client_shell.keystone.users.delete(nova_user) + # delete relationships SlicePerson().delete.filter({'person_id': self['person_id']}) - # delete nova object - user = self.api.client_shell.keystone.users.find(**self) - self.api.client_shell.keystone.users.delete(user) + # delete person AlchemyObj.delete(self, dict(self)) @@ -195,11 +198,10 @@ class Persons(list): raise PLCInvalidArgument, "Wrong person filter %r"%person_filter for person in persons: - person = Person(self.api, object = person) - person.tenant=None - if person.tenantId: - person.tenant = self.api.client_shell.keystone.tenants.find(id=person.tenantId) + keystone_user = self.api.client_shell.keystone.persons.find(id=person['keystone_id']) + tenant = self.api.client_shell.keystone.tenants.find(id=keystone_user.tenantId) if not columns or 'roles' in columns: + roles = self.api.client_shell.keystone.roles.roles_for_user(keystone_user, tenant) person['roles'] = person.get_roles() if not columns or 'tenant_ids' in columns: person['tenant_ids'] = person.get_tenants_ids() diff --git a/PLC/Sites.py b/PLC/Sites.py index 79f5bb17..777fe6a1 100644 --- a/PLC/Sites.py +++ b/PLC/Sites.py @@ -23,9 +23,9 @@ class Site(AlchemyObj): tablename = 'sites' fields = { - 'enabled': Parameter(bool, "Has been enabled"), - 'site_id': Parameter(str, "Site identifier"), + 'site_id': Parameter(int, "Site identifier", primary_key=True), 'tenant_id': Parameter(str, "Tenant identifier"), + 'enabled': Parameter(bool, "Has been enabled"), 'abbreviated_name': Parameter(str, "Abbreviated site name", max = 50), 'login_base': Parameter(str, "Site slice prefix", max = 20), 'is_public': Parameter(bool, "Publicly viewable site"), @@ -49,13 +49,16 @@ class Site(AlchemyObj): 'ext_consortium_id': Parameter(int, "external consortium id", nullok = True) } - def sync(self, insert=False, validate=True): - + def sync(self, commit=True, validate=True): + """ + Add or update the site. + """ + # sync the nova record and the plc record + AlchemyObj.sync(self, commit=commit, validate=validate) nova_fields = ['enabled', 'name', 'description'] nova_can_update = lambda (field, value): field in nova_fields nova_site = dict(filter(nova_can_update, self.items())) - AlchemyObj.sync(self, insert, validate) - if insert == True or 'site_id' not in self: + if 'site_id' not in self: self.object = self.api.client_shell.keystone.tenants.create(**nova_site) self['tenant_id'] = self.object.id AlchemyObj.insert(self, dict(self)) @@ -64,6 +67,9 @@ class Site(AlchemyObj): AlchemyObj.update(self, {'site_id': self['site_id']}, dict(self)) def delete(self, commit=True): + assert 'site_id' in self + assert 'tenant_id' in self + # delete nova object tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id']) self.api.client_shell.keystone.tenants.delete(tenant) diff --git a/PLC/Slices.py b/PLC/Slices.py index b594909c..a79f86fd 100644 --- a/PLC/Slices.py +++ b/PLC/Slices.py @@ -27,6 +27,7 @@ class Slice(AlchemyObj): fields = { 'slice_id': Parameter(int, "Slice identifier", primary_key=True), 'site_id': Parameter(int, "Identifier of the site to which this slice belongs"), + 'tenant_id': Parameter(int, "Keystone tenant identifier"), 'name': Parameter(str, "Slice name", max = 32), 'instantiation': Parameter(str, "Slice instantiation state", nullok=True), 'url': Parameter(str, "URL further describing this slice", max = 254, nullok = True), @@ -83,14 +84,22 @@ class Slice(AlchemyObj): """ Add or update a slice. """ - AlchemyObj.sync(self, commit, validate) + # sync the nova record and the plc record + AlchemyObj.sync(self, commit=commit, validate=validate) + # create the nova record + nova_fields = ['enabled', 'name', 'description'] + nova_can_update = lambda (field, value): field in nova_fields + nova_slice = dict(filter(nova_can_update, self.items())) if 'slice_id' not in self: # Before a new slice is added, delete expired slices #expired = Slices(self.api, expires = -int(time.time())) #for slice in expired: # slice.delete(commit) + self.object = self.api.client_shell.keystone.tenants.create(**nova_slice) + self['tenant_id'] = self.object.id AlchemyObj.insert(self, dict(self)) else: + self.object = self.api.client_shell.keystone.tenants.update(self['tenant_id'], **nova_slice) AlchemyObj.update(self, {'slice_id': self['slice_id']}, dict(self)) def delete(self, commit = True): @@ -98,10 +107,18 @@ class Slice(AlchemyObj): Delete existing slice. """ assert 'slice_id' in self + assert 'tenant_id' in self + + # delete the nova object + tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id']) + self.api.client_shell.keystone.tenants.delete(tenant) + # delete relationships SlicePerson().delete(self, filter={'slice_id': self['slice_id']}) SliceNode().delete(self, filter={'slice_id': self['slice_id']}) - SliceTag().delete(self, filter={'slice_id': self['slice_id']}) + SliceTag().delete(self, filter={'slice_id': self['slice_id']}) + + # delete slice AlchemyObj.delete(self, dict(self)) diff --git a/PLC/Storage/AlchemyObject.py b/PLC/Storage/AlchemyObject.py index 33ec0be8..ddf0adb8 100644 --- a/PLC/Storage/AlchemyObject.py +++ b/PLC/Storage/AlchemyObject.py @@ -44,7 +44,7 @@ class AlchemyObj(Record): type = DateTime column = Column(field, type, nullable = param.nullok, - indexed = param.indexed, + index = param.indexed, primary_key=param.primary_key) table.append_column(column) if not table.exists():