Store sites in PLC db and sync with nova db
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Fri, 28 Sep 2012 00:29:01 +0000 (20:29 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Fri, 28 Sep 2012 00:29:01 +0000 (20:29 -0400)
PLC/Sites.py

index 22284b7..beec765 100644 (file)
@@ -5,33 +5,81 @@ from PLC.Faults import *
 from PLC.Logger import logger
 from PLC.Parameter import Parameter, Mixed
 from PLC.NovaTable import NovaObject, NovaTable
+from PLC.Storage.AlchemyObj 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.PCUs import PCU, PCUs
+from PLC.Nodes import Node, Nodes
+from PLC.SiteTags import SiteTag, SiteTags
 
-class Site(NovaObject):
+class Site(AlchemyObj):
     """
     Representation of a row in the sites table. To use, optionally
     instantiate with a dict of values. Update as you would a
     dict. Commit to the database with sync().
     """
 
+    tablename = 'sites'
+
     fields = {
         'enabled': Parameter(bool, "Has been enabled"),
         'id': Parameter(str, "Site identifier"),
+        'tenant_id': Parameter(str, "Tenant identifier"),
+        '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"),
         'name': Parameter(str, "Full site name", max = 254),
         'description': Parameter(str, "Description", max = 254),
-        #'max_slices': Parameter(int, "Maximum number of slices that the site is able to create"),
-        #'max_slivers': Parameter(int, "Maximum number of slivers that the site is able to create"),
-        'person_ids': Parameter([int], "List of account identifiers"),
-        'slice_ids': Parameter([int], "List of slice identifiers"),
-        'pcu_ids': Parameter([int], "List of PCU identifiers"),
-        'node_ids': Parameter([int], "List of site node identifiers"),
+        'latitude': Parameter(float, "Decimal latitude of the site", min = -90.0, max = 90.0, nullok = True),
+        'longitude': Parameter(float, "Decimal longitude of the site", min = -180.0, max = 180.0, nullok = True),
+        'url': Parameter(str, "URL of a page that describes the site", max = 254, nullok = True),
+        'date_created': Parameter(int, "Date and time when site entry was created, in seconds since UNIX epoch", ro = True),
+        'last_updated': Parameter(int, "Date and time when site entry was last updated, in seconds since UNIX epoch", ro = True),
+        'max_slices': Parameter(int, "Maximum number of slices that the site is able to create"),
+        'max_slivers': Parameter(int, "Maximum number of slivers that the site is able to create"),
+        'person_ids': Parameter([int], "List of account identifiers", ro=True),
+        'slice_ids': Parameter([int], "List of slice identifiers", ro=True),
+        'address_ids': Parameter([int], "List of address identifiers"),
+        'pcu_ids': Parameter([int], "List of PCU identifiers", ro=True),
+        'node_ids': Parameter([int], "List of site node identifiers", ro=True),
+        'site_tag_ids' : Parameter ([int], "List of tags attached to this site", ro=True),
+        'peer_id': Parameter(int, "Peer to which this site belongs", nullok = True),
+        'peer_site_id': Parameter(int, "Foreign site identifier at peer", nullok = True),
+        'ext_consortium_id': Parameter(int, "external consortium id", nullok = True) 
         }
 
     def sync(self, insert=False, validate=True):
-        NovaObject.sync(self, insert, validate)
-        if insert == True or id not in self:
-            self.object = self.api.client_shell.keystone.tenants.create(**self)
+
+        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 '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)) 
+        else:
+            self.object = self.api.client_shell.keystone.tenants.update(self['tenant_id'], **nova_site)
+            AlchemyObj.update(self, dict(self))
+
+    def delete(self):
+        # delete nova object
+        tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id'])
+        self.api.client_shell.keystone.tenants.delete(tenant)
+        
+        # delete relationships
+        SitePerson().delete(filter={'site_id': self['id']}) 
+        Slice().delete(filter={'site_id': self['id']}) 
+        PCU().delete(filter={'site_id': self['id']}) 
+        Node().delete(filter={'site_id': self['id']}) 
+        Address().delete(filter={'site_id': self['id']}) 
+        SiteTag().delete(filter={'site_id': self['id']}) 
+        
+        # delete site
+        AlchemyObj.delete(self, dict(self))        
+        
+               
 
 class Sites(NovaTable):
     """
@@ -42,17 +90,43 @@ class Sites(NovaTable):
     def __init__(self, api, site_filter = None, columns = None):
         self.api = api 
         if not site_filter:
-            sites = self.api.client_shell.keystone.tenants.findall()
+            sites = Site().select() 
+        elif isinstance(site_filter, int):
+            sites = Site().select(filter={'id': site_filter})
         elif isinstance(site_filter, StringTypes):
-            sites = [self.api.client_shell.keystone.tenants.find(id=site_filter)]
+            sites = Site().select(filter={'login_base': site_filter})
         elif isinstance(site_filter, dict):
-            sites = self.api.client_shell.keystone.tenants.findall(**site_filter)
+            sites = Site().select(filter=site_filter)
         elif isinstance(site_filter, (list, tuple, set)):
-            sites = self.api.client_shell.keystone.tenants.findall()
+            sites = Site().select() 
             sites = [site for site in sites if site.id in site_filter]
         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['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['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['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['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['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['site_tag_ids'] = [rec.id for rec in site_tags]
+
             self.append(site)