selection on foreign nodes : either on id or hostname, undoes selection on peername
[plcapi.git] / PLC / Methods / UpdatePeer.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 UpdatePeer(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 #       current_peer_nodes = [n2,n3]
59
60         ### now to the db
61         # we get the whole table just in case 
62         # a host would have switched from one plc to the other
63         foreign_nodes = ForeignNodes (self.api)
64         
65         ### mark entries for this peer outofdate
66         for foreign_node in foreign_nodes.values():
67             if foreign_node['peer_id'] == peer_id:
68                 foreign_node.uptodate=False
69
70         ### scan the new entries, and mark them uptodate
71         for node in current_peer_nodes:
72             hostname = node['hostname']
73             foreign_node = foreign_nodes.get(hostname)
74             if foreign_node:
75                 ### update it anyway
76                 foreign_node['peer_id'] = peer_id
77                 foreign_node['boot_state'] = node['boot_state']
78                 foreign_node.uptodate = True
79             else:
80                 foreign_nodes[hostname] = ForeignNode(self.api,
81                                                       {'hostname':hostname,
82                                                        'boot_state':node['boot_state'],
83                                                        'peer_id':peer_id})
84             foreign_nodes[hostname].sync()
85
86         ### delete entries that are not uptodate
87         [ x.delete() for x in foreign_nodes.values() if not x.uptodate ]
88