873ebe6d661a493679f10d596b6f0c3fcb5728f6
[plcapi.git] / PLC / Sites.py
1 from types import StringTypes
2 import string
3
4 from PLC.Faults import *
5 from PLC.Logger import logger
6 from PLC.Parameter import Parameter, Mixed
7 from PLC.NovaTable import NovaObject, NovaTable
8 from PLC.Storage.AlchemyObj import AlchemyObj
9 from PLC.Slices import Slice, Slices
10 from PLC.SitePersons import SitePerson, SitePersons
11 from PLC.Addresses import Address, Addresses
12 from PLC.PCUs import PCU, PCUs
13 from PLC.Nodes import Node, Nodes
14 from PLC.SiteTags import SiteTag, SiteTags
15
16 class Site(AlchemyObj):
17     """
18     Representation of a row in the sites table. To use, optionally
19     instantiate with a dict of values. Update as you would a
20     dict. Commit to the database with sync().
21     """
22
23     tablename = 'sites'
24
25     fields = {
26         'enabled': Parameter(bool, "Has been enabled"),
27         'site_id': Parameter(str, "Site identifier"),
28         'tenant_id': Parameter(str, "Tenant identifier"),
29         'abbreviated_name': Parameter(str, "Abbreviated site name", max = 50),
30         'login_base': Parameter(str, "Site slice prefix", max = 20),
31         'is_public': Parameter(bool, "Publicly viewable site"),
32         'name': Parameter(str, "Full site name", max = 254),
33         'description': Parameter(str, "Description", max = 254),
34         'latitude': Parameter(float, "Decimal latitude of the site", min = -90.0, max = 90.0, nullok = True),
35         'longitude': Parameter(float, "Decimal longitude of the site", min = -180.0, max = 180.0, nullok = True),
36         'url': Parameter(str, "URL of a page that describes the site", max = 254, nullok = True),
37         'date_created': Parameter(int, "Date and time when site entry was created, in seconds since UNIX epoch", ro = True),
38         'last_updated': Parameter(int, "Date and time when site entry was last updated, in seconds since UNIX epoch", ro = True),
39         'max_slices': Parameter(int, "Maximum number of slices that the site is able to create"),
40         'max_slivers': Parameter(int, "Maximum number of slivers that the site is able to create"),
41         'person_ids': Parameter([int], "List of account identifiers", joined=True),
42         'slice_ids': Parameter([int], "List of slice identifiers", joined=True),
43         'address_ids': Parameter([int], "List of address identifiers", joined=True),
44         'pcu_ids': Parameter([int], "List of PCU identifiers", joined=True),
45         'node_ids': Parameter([int], "List of site node identifiers", joined=True),
46         'site_tag_ids' : Parameter ([int], "List of tags attached to this site", joined=True),
47         'peer_id': Parameter(int, "Peer to which this site belongs", nullok = True),
48         'peer_site_id': Parameter(int, "Foreign site identifier at peer", nullok = True),
49         'ext_consortium_id': Parameter(int, "external consortium id", nullok = True) 
50         }
51
52     def sync(self, insert=False, validate=True):
53
54         nova_fields = ['enabled', 'name', 'description']
55         nova_can_update = lambda (field, value): field in nova_fields
56         nova_site = dict(filter(nova_can_update, self.items()))
57         AlchemyObj.sync(self, insert, validate)     
58         if insert == True or 'site_id' not in self:
59             self.object = self.api.client_shell.keystone.tenants.create(**nova_site)
60             self['tenant_id'] = self.object.id
61             AlchemyObj.insert(self, dict(self)) 
62         else:
63             self.object = self.api.client_shell.keystone.tenants.update(self['tenant_id'], **nova_site)
64             AlchemyObj.update(self, dict(self))
65
66     def delete(self, commit=True):
67         # delete nova object
68         tenant = self.api.client_shell.keystone.tenants.find(id=self['tenant_id'])
69         self.api.client_shell.keystone.tenants.delete(tenant)
70         
71         # delete relationships
72         SitePerson().delete(filter={'site_id': self['site_id']}) 
73         Slice().delete(filter={'site_id': self['site_id']}) 
74         PCU().delete(filter={'site_id': self['site_id']}) 
75         Node().delete(filter={'site_id': self['site_id']}) 
76         Address().delete(filter={'site_id': self['site_id']}) 
77         SiteTag().delete(filter={'site_id': self['site_id']}) 
78         
79         # delete site
80         AlchemyObj.delete(self, dict(self))        
81         
82                
83
84 class Sites(list):
85     """
86     Representation of row(s) from the sites table in the
87     database.
88     """
89
90     def __init__(self, api, site_filter = None, columns = None):
91         self.api = api 
92         if not site_filter:
93             sites = Site().select() 
94         elif isinstance(site_filter, int):
95             sites = Site().select(filter={'site_id': site_filter})
96         elif isinstance(site_filter, StringTypes):
97             sites = Site().select(filter={'login_base': site_filter})
98         elif isinstance(site_filter, dict):
99             sites = Site().select(filter=site_filter)
100         elif isinstance(site_filter, (list, tuple, set)):
101             sites = Site().select() 
102             sites = [site for site in sites if site.id in site_filter]
103         else:
104             raise PLCInvalidArgument, "Wrong site filter %s" % site_filter         
105
106         for site in sites:
107             site = Site(self.api, object = site)
108             if not columns or 'person_ids' in columns:
109                 site_persons = SitePerson().select(filter={'site_id': site.id})
110                 site['person_ids'] = [rec.person_id for rec in site_persons]
111
112             if not columns or 'slice_ids' in columns:
113                 site_slices = Slice().select(filter={'site_id': site.id})
114                 site['slice_ids'] = [rec.person_id for rec in site_slices]
115
116             if not columns or 'puc_ids' in columns:
117                 site_pcus = PCU().select(filter={'site_id': site.id})
118                 site['pcu_ids'] = [rec.id for rec in site_pcus]
119
120             if not columns or 'node_ids' in columns:
121                 site_nodes = Node().select(filter={'site_id': site.id})
122                 site['node_ids'] = [rec.id for rec in site_nodes]
123
124             if not columns or 'address_ids' in columns:
125                 site_addresses = Address().select(filter={'site_id': site.id})
126                 site['address_ids'] = [rec.id for rec in site_addresses]
127
128             if not columns or 'site_tag_ids' in columns:
129                 site_tags = SiteTag().select(filter={'site_id': site.id})
130                 site['site_tag_ids'] = [rec.id for rec in site_tags]
131
132             self.append(site)