bug fixes
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Fri, 5 Oct 2012 15:15:35 +0000 (11:15 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Fri, 5 Oct 2012 15:15:35 +0000 (11:15 -0400)
PLC/Persons.py
PLC/Roles.py
PLC/SiteTags.py
PLC/Sites.py

index 958a23d..742afd9 100644 (file)
@@ -19,6 +19,8 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Messages import Message, Messages
 from PLC.Roles import Role, Roles
 from PLC.Keys import Key, Keys
+from PLC.SitePersons import SitePerson, SitePersons 
+from PLC.SlicePersons import SlicePerson, SlicePersons 
 from PLC.Storage.AlchemyObject import AlchemyObj
 
 class Person(AlchemyObj):
@@ -32,7 +34,7 @@ class Person(AlchemyObj):
 
     fields = {
         'person_id': Parameter(int, "User identifier", primary_key=True),
-        'keystone_id': Parameter(int, "Keystone User identifier"),
+        'keystone_id': Parameter(str, "Keystone User identifier"),
         'first_name': Parameter(str, "Given name", max = 128),
         'last_name': Parameter(str, "Surname", max = 128),
         'title': Parameter(str, "Title", max = 128, nullok = True),
@@ -139,7 +141,7 @@ class Person(AlchemyObj):
             for site in sites: 
                 # add role at the requested site
                 tenant = self.api.client_shell.keystone.tenants.find(id=site['tenant_id']) 
-                self.api.client_shell.keystone.roles.add_user_role(user, tenant, role)
+                self.api.client_shell.keystone.roles.add_user_role(user, tenant, role.object)
         else:
             # add role to at all of users sites
             if not self['site_ids']:
@@ -148,7 +150,7 @@ class Person(AlchemyObj):
                 sites = Sites(self.api, {'site_id': site_id})
                 site = sites[0]
                 tenant = self.api.client_shell.keystone.tenants.find(id=site['tenant_id'])
-                self.api.client_shell.keystone.roles.add_user_role(user, tenant, role)
+                self.api.client_shell.keystone.roles.add_user_role(user, tenant, role.object)
     
     def remove_role(self, role_name, login_base=None):
         assert 'keystone_id' in self
@@ -161,7 +163,7 @@ class Person(AlchemyObj):
         if login_base:
             # add role at the requested site
             tenant = self.api.client_shell.keystone.tenants.find(name=login_base)
-            self.api.client_shell.keystone.roles.add_user_role(user, role, tenant)
+            self.api.client_shell.keystone.roles.add_user_role(user, role.object, tenant)
         else:
             from PLC.Sites import Sites
             # add role to at all of users sites
@@ -171,19 +173,26 @@ class Person(AlchemyObj):
                 sites = Sites(self.api, {'site_id': site_id})
                 site = sites[0]
                 tenant = self.api.client_shell.keystone.tenants.find(id=site['tenant_id'])
-                self.api.client_shell.keystone.roles.remove_user_role(user, role, tenant)
+                self.api.client_shell.keystone.roles.remove_user_role(user, role.object, tenant)
 
     #add_key = Row.add_object(Key, 'person_key')
     #remove_key = Row.remove_object(Key, 'person_key')
 
     def sync(self, commit=True, validate=True):
+        assert 'email' in self
         AlchemyObj.sync(self, commit=commit, validate=validate)
+        # filter out fields that are not supported in keystone
         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', ''))  
+        nova_person['name'] = "%s %s" % (self.get('first_name', ''), self.get('last_name', '')) 
         if 'person_id' not in self:
-            self.object = self.api.client_shell.keystone.users.create(**self)
+            # check if keystone record exists
+            users = self.api.client_shell.keystone.users.findall(email=self['email'])
+            if not users:
+                self.object = self.api.client_shell.keystone.users.create(**nova_person)
+            else:
+                self.object = users[0]
             self['keystone_id'] = self.object.id
             AlchemyObj.insert(self, dict(self))
         else:
@@ -206,15 +215,6 @@ class Person(AlchemyObj):
         AlchemyObj.delete(self, dict(self))
 
  
-    def get_tenants_ids(self):
-        tenants = []
-        if self.tenantId:
-            tenants = [self.tenantId]
-        return tenants
-
-    def get_key_ids(self):
-        return []
-
 class Persons(list):
     """
     Representation of row(s) from the persons table in the
@@ -222,6 +222,7 @@ class Persons(list):
     """
 
     def __init__(self, api, person_filter = None, columns = None):
+        from PLC.Sites import Sites
         self.api = api
         if not person_filter:
             #persons = self.api.client_shell.keystone.users.findall()
@@ -240,16 +241,23 @@ class Persons(list):
             raise PLCInvalidArgument, "Wrong person filter %r"%person_filter
 
         for person in persons:
-            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)
+            person = Person(self.api, object=person) 
+            keystone_user = self.api.client_shell.keystone.users.find(id=person['keystone_id'])
+            if not columns or 'site_ids' in columns:
+                site_persons = SitePerson().select(filter={'person_id': person['person_id']})
+                person['site_ids'] = [rec.site_id for rec in site_persons]
             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() 
+                roles = set()
+                sites = Sites(self.api, person['site_ids'])
+                for site in sites:
+                    tenant = self.api.client_shell.keystone.tenants.find(id=site['tenant_id'])
+                    tenant_roles = self.api.client_shell.keystone.roles.roles_for_user(keystone_user, tenant)
+                    for tenant_role in tenant_roles:
+                        roles.add(tenant_role.name)  
+                person['roles'] = list(roles)
             if not columns or 'key_ids' in columns:
-                person['key_ids'] = person.get_keys_ids() 
+                person['key_ids'] = [] 
             if not columns or 'slice_ids' in columns:
-                person_slices = SlicePerson().select(filter={'person_id': person.person_id})
+                person_slices = SlicePerson().select(filter={'person_id': person['person_id']})
                 person['slice_ids'] = [rec.slice_id for rec in person_slices]
             self.append(person) 
index 65ab289..6e93f10 100644 (file)
@@ -26,7 +26,7 @@ class Roles(NovaTable):
         if not role_filter:
             roles = self.api.client_shell.keystone.roles.findall()
         elif isinstance(role_filter, StringTypes):
-            roles = [self.api.client_shell.keystone.roles.find(id=role_filter)] 
+            roles = [self.api.client_shell.keystone.roles.find(name=role_filter)] 
         elif isinstance(role_filter, (list, tuple, set)):
             roles = self.api.client_shell.keystone.roles.findall()
             roles = [role for role in roles if role.id in role_filter]
index a1f2b6f..a22d80d 100644 (file)
@@ -14,7 +14,7 @@ class SiteTag(AlchemyObj):
     To use, instantiate with a dict of values.
     """
 
-    table_name = 'site_tags'
+    tablename = 'site_tags'
     fields = {
         'site_tag_id': Parameter(int, "Site setting identifier", primary_key=True),
         'site_id': Parameter(int, "Site identifier"),
@@ -56,5 +56,6 @@ class SiteTags(list):
             raise PLCInvalidArgument, "Wrong site setting filter %r"%site_tag_filter
 
         for site_tag in site_tags:
+            site_tag = SiteTag(self.api, object=site_tag)
             self.append(site_tag)
     
index 6147cd0..c66d38f 100644 (file)
@@ -9,9 +9,10 @@ from PLC.Storage.AlchemyObject import AlchemyObj
 from PLC.Slices import Slice, Slices
 from PLC.Persons import Person, Persons
 from PLC.SitePersons import SitePerson, SitePersons
-from PLC.Addresses import Address, Addresses
+from PLC.SiteAddresses import SiteAddress, SiteAddress
 from PLC.PCUs import PCU, PCUs
 from PLC.Nodes import Node, Nodes
+from PLC.Roles import Role, Roles
 from PLC.SiteTags import SiteTag, SiteTags
 
 class Site(AlchemyObj):
@@ -55,17 +56,21 @@ class Site(AlchemyObj):
         last_updated = datetime.now()
         return last_updated
 
-    def add_person(self, person_filter, role=None):
+    def add_person(self, person_filter, role_name=None):
         assert 'site_id' in self
         assert 'tenant_id' in self
-        if not role:
-            role = 'user'
+        if not role_name:
+            role_name = 'user'
+        roles = Roles(self.api, role_name)
+        if not roles:
+            raise PLCInvalidArgument, "No such role %s" % role_name
+        role = roles[0]
         tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id']) 
         persons = Persons(self.api, person_filter)
         for person in persons:
             keystone_user = self.api.client_shell.keystone.users.find(id=person['keystone_id'])
-            tenant.add_user(keystone_user, role)  
-            site_person = SitePerson(self.api, {'site_id': self['id'], 
+            tenant.add_user(keystone_user, role.object)  
+            site_person = SitePerson(self.api, {'site_id': self['site_id'], 
                                                 'person_id': person['person_id']}) 
             site_person.sync()
 
@@ -75,11 +80,15 @@ class Site(AlchemyObj):
         assert 'tenant_id' in self
         if not role:
             role = 'user'
+        roles = Roles(self.api, role_name)
+        if not roles:
+            raise PLCInvalidArgument, "No such role %s" % role_name
+        role = roles[0]
         tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id'])
         persons = Persons(self.api, person_filter)
         for person in persons:
             keystone_user = self.api.client_shell.keystone.users.find(id=person['keystone_id'])
-            tenant.remove_user(keystone_user, role)
+            tenant.remove_user(keystone_user, role.object)
             site_persons = SitePersons(self.api, {'site_id': self['id'],
                                                 'person_id': person['person_id']})
             for site_person in site_persons:
@@ -91,19 +100,21 @@ class Site(AlchemyObj):
         Add or update the site.
         """
         assert 'login_base' in self
-        # sync the nova record and the plc record
         AlchemyObj.sync(self, commit=commit, validate=validate)     
+        # filter out fields that are not supported in keystone
         nova_fields = ['enabled', 'description']
         nova_can_update = lambda (field, value): field in nova_fields
         nova_site = dict(filter(nova_can_update, self.items()))
         nova_site['tenant_name'] = self['login_base']
         if 'site_id' not in self:
+            # check if keystone record exsits
             tenants = self.api.client_shell.keystone.tenants.findall(name=self['login_base'])
             if not tenants:
                 self.object = self.api.client_shell.keystone.tenants.create(**nova_site)
             else:
                 self.object = tenants[0]
             self['tenant_id'] = self.object.id
+            # sync the plc record
             AlchemyObj.insert(self, dict(self)) 
         else:
             self.object = self.api.client_shell.keystone.tenants.update(self['tenant_id'], **nova_site)
@@ -152,30 +163,29 @@ class Sites(list):
         else:
             raise PLCInvalidArgument, "Wrong site filter %s" % site_filter         
 
+
         for site in sites:
             site = Site(self.api, object = site)
             if not columns or 'person_ids' in columns:
-                site_persons = SitePerson().select(filter={'site_id': site.id})
+                site_persons = SitePerson().select(filter={'site_id': site['site_id']})
                 site['person_ids'] = [rec.person_id for rec in site_persons]
 
             if not columns or 'slice_ids' in columns:
-                site_slices = Slice().select(filter={'site_id': site.id})
+                site_slices = Slice().select(filter={'site_id': site['site_id']})
                 site['slice_ids'] = [rec.person_id for rec in site_slices]
 
             if not columns or 'puc_ids' in columns:
-                site_pcus = PCU().select(filter={'site_id': site.id})
+                site_pcus = PCU().select(filter={'site_id': site['site_id']})
                 site['pcu_ids'] = [rec.id for rec in site_pcus]
-
             if not columns or 'node_ids' in columns:
-                site_nodes = Node().select(filter={'site_id': site.id})
+                site_nodes = Node().select(filter={'site_id': site['site_id']})
                 site['node_ids'] = [rec.id for rec in site_nodes]
-
             if not columns or 'address_ids' in columns:
-                site_addresses = Address().select(filter={'site_id': site.id})
+                site_addresses = SiteAddress().select(filter={'site_id': site['site_id']})
                 site['address_ids'] = [rec.id for rec in site_addresses]
 
             if not columns or 'site_tag_ids' in columns:
-                site_tags = SiteTag().select(filter={'site_id': site.id})
+                site_tags = SiteTag().select(filter={'site_id': site['site_id']})
                 site['site_tag_ids'] = [rec.id for rec in site_tags]
 
             self.append(site)