federation in progress - associate a local slice to a foreign node
[plcapi.git] / PLC / Methods / RefreshPeer.py
1 #
2 # Thierry Parmentelat - INRIA
3
4
5 import xmlrpclib
6
7 from PLC.Faults import *
8 from PLC.Method import Method
9 from PLC.Parameter import Parameter, Mixed
10 from PLC.Auth import Auth
11
12 from PLC.Peers import Peer, Peers
13 from PLC.Persons import Person, Persons
14 from PLC.ForeignNodes import ForeignNode, ForeignNodes
15
16
17 class RefreshPeer(Method):
18     """
19     Query a peer PLC for its list of nodes, and refreshes
20     the local database accordingly
21     
22     Returns None
23     """
24     
25     roles = ['admin']
26     
27     accepts = [ Auth(),
28                 Parameter (int, "Peer id") ]
29     
30     returns = None
31
32     def call (self, auth, peer_id):
33         
34         ### retrieve peer info
35         peers = Peers (self.api)
36         peer = peers[peer_id]
37         
38         ### retrieve account info
39         person_id = peer['person_id']
40         persons = Persons (self.api,[person_id])
41         person = persons[person_id]
42         
43         ### build up foreign auth
44         auth={ 'Username': person['email'],
45                'AuthMethod' : 'password',
46                'AuthString' : person['password'],
47                'Role' : 'admin' }
48
49         ## connect to the peer's API
50         apiserver = xmlrpclib.Server (peer['peer_url']+"/PLCAPI/")
51         print 'auth',auth
52         current_peer_nodes = apiserver.GetNodes(auth,[])
53         
54         ## manual feed for tests
55 #       n1 = {'hostname': 'n1.plc', 'boot_state': 'inst'}
56 #       n2 = {'hostname': 'n2.plc', 'boot_state': 'inst'}
57 #       n3 = {'hostname': 'n3.plc', 'boot_state': 'inst'}
58         n11={'session': None, 'slice_ids': [], 'nodegroup_ids': [], 'last_updated': 1162884349, 'version': None, 'nodenetwork_ids': [], 'boot_state': 'inst', 'hostname': 'n11.plc1.org', 'site_id': 1, 'ports': None, 'pcu_ids': [], 'boot_nonce': None, 'node_id': 1, 'root_person_ids': [], 'key': None, 'date_created': 1162884349, 'model': None, 'conf_file_ids': [], 'ssh_rsa_key': None}
59         n12={'session': None, 'slice_ids': [], 'nodegroup_ids': [], 'last_updated': 1162884349, 'version': None, 'nodenetwork_ids': [], 'boot_state': 'inst', 'hostname': 'n12.plc1.org', 'site_id': 1, 'ports': None, 'pcu_ids': [], 'boot_nonce': None, 'node_id': 1, 'root_person_ids': [], 'key': None, 'date_created': 1162884349, 'model': None, 'conf_file_ids': [], 'ssh_rsa_key': None}
60         n21={'session': None, 'slice_ids': [], 'nodegroup_ids': [], 'last_updated': 1162884349, 'version': None, 'nodenetwork_ids': [], 'boot_state': 'boot', 'hostname': 'n21.plc2.org', 'site_id': 1, 'ports': None, 'pcu_ids': [], 'boot_nonce': None, 'node_id': 1, 'root_person_ids': [], 'key': None, 'date_created': 1162884349, 'model': None, 'conf_file_ids': [], 'ssh_rsa_key': None}
61         n22={'session': None, 'slice_ids': [], 'nodegroup_ids': [], 'last_updated': 1162884349, 'version': None, 'nodenetwork_ids': [], 'boot_state': 'boot', 'hostname': 'n22.plc2.org', 'site_id': 1, 'ports': None, 'pcu_ids': [], 'boot_nonce': None, 'node_id': 1, 'root_person_ids': [], 'key': None, 'date_created': 1162884349, 'model': None, 'conf_file_ids': [], 'ssh_rsa_key': None}
62
63 #        current_peer_nodes = [n21,n22]
64
65         ### now to the db
66         # we get the whole table just in case 
67         # a host would have switched from one plc to the other
68         foreign_nodes = ForeignNodes (self.api)
69         
70         ### mark entries for this peer outofdate
71         for foreign_node in foreign_nodes.values():
72             if foreign_node['peer_id'] == peer_id:
73                 foreign_node.uptodate=False
74
75         ### these fields get copied through
76         remote_fields = ['boot_state','model','version','date_created','date_updated']
77         
78         ### scan the new entries, and mark them uptodate
79         for node in current_peer_nodes:
80             hostname = node['hostname']
81             foreign_node = foreign_nodes.get(hostname)
82             if foreign_node:
83                 ### update it anyway
84                 foreign_node['cached'] = True
85                 foreign_node['peer_id'] = peer_id
86                 # copy other relevant fields
87                 for field in remote_fields:
88                     foreign_node[field]=node[field]
89                 # this row is valid
90                 foreign_node.uptodate = True
91             else:
92                 foreign_nodes[hostname] = ForeignNode(self.api,
93                                                       {'hostname':hostname,
94                                                        'cached':True,
95                                                        'peer_id':peer_id,})
96                 for field in remote_fields:
97                     foreign_nodes[hostname][field]=node[field]
98                     
99             foreign_nodes[hostname].sync()
100
101         ### delete entries that are not uptodate
102         [ x.delete() for x in foreign_nodes.values() if not x.uptodate ]
103