for federation : Peers and ForeignNodes
[plcapi.git] / PLC / Methods / UpdatePeer.py
1 import xmlrpclib
2
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Auth import Auth
7
8 from PLC.Peers import Peer, Peers
9 from PLC.Persons import Person, Persons
10 from PLC.ForeignNodes import ForeignNode, ForeignNodes
11
12
13 class UpdatePeer(Method):
14     """
15     Query a peer PLC for its list of nodes, and refreshes
16     the local database accordingly
17     
18     Returns None
19     """
20     
21     roles = ['admin']
22     
23     accepts = [ Auth(),
24                 Parameter (int, "Peer id") ]
25     
26     returns = None
27
28     def call (self, auth, peer_id):
29         
30         ### retrieve peer info
31         peers = Peers (self.api)
32         peer = peers[peer_id]
33         
34         ### retrieve account info
35         person_id = peer['person_id']
36         persons = Persons (self.api,[person_id])
37         person = persons[person_id]
38         
39         ### build up foreign auth
40         auth={ 'Username': person['email'],
41                'AuthMethod' : 'password',
42                'AuthString' : person['password'],
43                'Role' : 'admin' }
44
45         ## connect to the peer's API
46         apiserver = xmlrpclib.Server (peer['peer_url']+"/PLCAPI/")
47         print 'auth',auth
48         current_peer_nodes = apiserver.GetNodes(auth,[])
49         
50         ## manual feed for tests
51 #       n1 = {'hostname': 'n1.plc', 'boot_state': 'inst'}
52 #       n2 = {'hostname': 'n2.plc', 'boot_state': 'inst'}
53 #       n3 = {'hostname': 'n3.plc', 'boot_state': 'inst'}
54 #       current_peer_nodes = [n2,n3]
55
56         ### now to the db
57         # we get the whole table just in case 
58         # a host would have switched from one plc to the other
59         foreign_nodes = ForeignNodes (self.api)
60         
61         ### mark entries for this peer outofdate
62         for foreign_node in foreign_nodes.values():
63             if foreign_node['peer_id'] == peer_id:
64                 foreign_node.uptodate=False
65
66         ### scan the new entries, and mark them uptodate
67         for node in current_peer_nodes:
68             hostname = node['hostname']
69             foreign_node = foreign_nodes.get(hostname)
70             if foreign_node:
71                 ### update it anyway
72                 foreign_node['peer_id'] = peer_id
73                 foreign_node['boot_state'] = node['boot_state']
74                 foreign_node.uptodate = True
75             else:
76                 foreign_nodes[hostname] = ForeignNode(self.api,
77                                                       {'hostname':hostname,
78                                                        'boot_state':node['boot_state'],
79                                                        'peer_id':peer_id})
80             foreign_nodes[hostname].sync()
81
82         ### delete entries that are not uptodate
83         [ x.delete() for x in foreign_nodes.values() if not x.uptodate ]
84