(*) Peer has new fields person_ids and site_ids
[plcapi.git] / PLC / Peers.py
1 #
2 # Thierry Parmentelat - INRIA
3
4
5 import re
6 from types import StringTypes
7
8 from PLC.Faults import *
9 from PLC.Parameter import Parameter
10 from PLC.Filter import Filter
11 from PLC.Table import Row, Table
12
13 from PLC.Nodes import Nodes,Node
14 from PLC.Slices import Slices,Slice
15
16 class Peer (Row):
17     """
18     Stores the list of peering PLCs in the peers table. 
19     See the Row class for more details
20     """
21
22     table_name = 'peers'
23     primary_key = 'peer_id'
24     fields = {
25         'peer_id' : Parameter (int, "Peer identifier"),
26         'peername' : Parameter (str, "Peer name"),
27         'peer_url' : Parameter (str, "Peer API url"),
28         ### xxx this trick is temporary, for peer authentication
29         'auth_person_id' : Parameter (int, "Person_id of the account storing credentials - temporary"),
30         ### cross refs
31         'site_ids' : Parameter ([int], "This peer's sites ids"),
32         'person_ids' : Parameter ([int], "This peer's persons ids"),
33         'node_ids' : Parameter ([int], "This peer's nodes ids"),
34         'slice_ids' : Parameter ([int], "This peer's slices ids"),
35         }
36
37     def validate_peer_url (self, url):
38         """
39         Validate URL, checks it looks like https 
40         """
41         invalid_url = PLCInvalidArgument("Invalid URL")
42         if not re.compile ("^https://.*$").match(url) : 
43             raise invalid_url
44         return url
45
46     ### for use by RefreshPeer, *not* a method of the API
47     def update_name (self,peername):
48         if self['peername'] != peername:
49             self['peername']=peername
50             self.sync()
51
52     def delete (self, commit=True):
53         """
54         Delete peer
55         """
56         
57         assert 'peer_id' in self
58
59         # remove nodes depending on this peer
60         for foreign_node in Nodes (self.api, self['node_ids']):
61             foreign_node.delete(commit)
62
63         # remove the peer
64         self['deleted'] = True
65         self.sync(commit)
66
67 class Peers (Table):
68     """ 
69     Maps to the peers table in the database
70     """
71     
72     def __init__ (self, api, peer_filter = None, columns = None):
73         Table.__init__(self, api, Peer, columns)
74
75         sql = "SELECT %s FROM view_peers WHERE deleted IS False" % \
76               ", ".join(self.columns)
77
78         if peer_filter is not None:
79             if isinstance(peer_filter, (list, tuple, set)):
80                 # Separate the list into integers and strings
81                 ints = filter(lambda x: isinstance(x, (int, long)), peer_filter)
82                 strs = filter(lambda x: isinstance(x, StringTypes), peer_filter)
83                 peer_filter = Filter(Peer.fields, {'peer_id': ints, 'peername': strs})
84                 sql += " AND (%s)" % peer_filter.sql(api, "OR")
85             elif isinstance(peer_filter, dict):
86                 peer_filter = Filter(Peer.fields, peer_filter)
87                 sql += " AND (%s)" % peer_filter.sql(api, "AND")
88
89         self.selectall(sql)