fix bugs
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 4 Oct 2012 14:47:59 +0000 (10:47 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 4 Oct 2012 14:47:59 +0000 (10:47 -0400)
12 files changed:
PLC/BootStates.py
PLC/Interfaces.py
PLC/Keys.py
PLC/Method.py
PLC/Methods/GetRoles.py
PLC/NodeTypes.py
PLC/Nodes.py
PLC/Parameter.py
PLC/Persons.py
PLC/Sites.py
PLC/Slices.py
PLC/Storage/AlchemyObject.py

index 4ce45ca..0485aa2 100644 (file)
@@ -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)
index dcb395b..3873587 100644 (file)
@@ -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):
index 07a05e4..6f82838 100644 (file)
@@ -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"
index 1236f0c..12a5453 100644 (file)
@@ -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] 
index 769922b..8525ee3 100644 (file)
@@ -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):
index fd5e022..cfffdcc 100644 (file)
@@ -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
index 182ef4e..ba93906 100644 (file)
@@ -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):
     """
index c5b79f9..14a8b18 100644 (file)
@@ -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
 
index 7648730..f6d4407 100644 (file)
@@ -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() 
index 79f5bb1..777fe6a 100644 (file)
@@ -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)
index b594909..a79f86f 100644 (file)
@@ -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))
 
 
index 33ec0be..ddf0adb 100644 (file)
@@ -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():