Merge remote-tracking branch 'origin/pycurl' into planetlab-4_0-branch
[plcapi.git] / PLC / Methods / GetPeerData.py
index d651fa9..e68cf55 100644 (file)
@@ -1,6 +1,9 @@
 #
 # Thierry Parmentelat - INRIA
 # 
 #
 # Thierry Parmentelat - INRIA
 # 
+# $Id: GetPeerData.py 5574 2007-10-25 20:33:17Z thierry $
+
+import time
 
 from PLC.Faults import *
 from PLC.Method import Method
 
 from PLC.Faults import *
 from PLC.Method import Method
@@ -13,46 +16,72 @@ from PLC.Sites import Site, Sites
 from PLC.Keys import Key, Keys
 from PLC.Nodes import Node, Nodes
 from PLC.Persons import Person, Persons
 from PLC.Keys import Key, Keys
 from PLC.Nodes import Node, Nodes
 from PLC.Persons import Person, Persons
-from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes
 from PLC.Slices import Slice, Slices
 from PLC.Slices import Slice, Slices
-from PLC.SliceAttributes import SliceAttribute, SliceAttributes
+from PLC.SliceAttributes import SliceAttributes
 
 
-class GetPeerData (Method):
+class GetPeerData(Method):
     """
     """
-    Gather all data needed by RefreshPeer in a single xmlrpc request
-
-    Expects a peer id or peer name, that identifies the requesting peer
+    Returns lists of local objects that a peer should cache in its
+    database as foreign objects. Also returns the list of foreign
+    nodes in this database, for which the calling peer is
+    authoritative, to assist in synchronization of slivers.
     
     
-    Returns a dict containing, for the various types of cached entities,
-    the local objects as well as the ones attached to that peer
+    See the implementation of RefreshPeer for how this data is used.
     """
 
     """
 
-    roles = ['admin']
+    roles = ['admin', 'peer']
+
+    accepts = [Auth()]
 
 
-    accepts = [Auth(),
-               Parameter (int, "Peer id"),
-               ]
-    # for RefreshPeer 
-    returns = Parameter (dict,"Sites, Keys, Nodes, Persons, Slices")
+    returns = {
+        'Sites': Parameter([dict], "List of local sites"),
+        'Keys': Parameter([dict], "List of local keys"),
+        'Nodes': Parameter([dict], "List of local nodes"),
+        'Persons': Parameter([dict], "List of local users"),
+        'Slices': Parameter([dict], "List of local slices"),
+        'db_time': Parameter(float, "(Debug) Database fetch time"),
+        }
 
 
-    def call (self, auth, peer_id):
-        # xxx a peer cannot yet compute it's peer_id under another plc
-        # so we return all foreign objects by now
+    def call (self, auth):
+        start = time.time()
+
+        # Filter out various secrets
+        node_fields = filter(lambda field: field not in \
+                             ['boot_nonce', 'key', 'session', 'root_person_ids'],
+                             Node.fields)
+        nodes = Nodes(self.api, {'peer_id': None}, node_fields);
+        # filter out whitelisted nodes
+        nodes = [ n for n in nodes if not n['slice_ids_whitelist']] 
         
         
-        return {
-            'Sites-local' : Sites (self.api,{'peer_id':None}),
-            'Sites-peer' : Sites (self.api,{'~peer_id':None}),
-            'Keys-local' : Keys (self.api,{'peer_id':None}),
-            'Keys-peer' : Keys (self.api,{'~peer_id':None}),
-            'Nodes-local' : Nodes (self.api,{'peer_id':None}),
-            'Nodes-peer' : Nodes (self.api,{'~peer_id':None}),
-            'Persons-local' : Persons (self.api,{'peer_id':None}),
-            'Persons-peer' : Persons (self.api,{'~peer_id':None}),
-            'SliceAttibuteTypes-local' : SliceAttributeTypes (self.api,{'peer_id':None}),
-            'SliceAttibuteTypes-peer' : SliceAttributeTypes (self.api,{'~peer_id':None}),
-            'Slices-local' : Slices (self.api,{'peer_id':None}),
-            'Slices-peer' : Slices (self.api,{'~peer_id':None}),
-            'SliceAttributes-local': SliceAttributes (self.api,{'peer_id':None}),
-            'SliceAttributes-peer': SliceAttributes (self.api,{'~peer_id':None}),
+
+        person_fields = filter(lambda field: field not in \
+                               ['password', 'verification_key', 'verification_expires'],
+                               Person.fields)
+
+        # XXX Optimize to return only those Persons, Keys, and Slices
+        # necessary for slice creation on the calling peer's nodes.
+
+       # filter out special person
+       persons = Persons(self.api, {'~email':[self.api.config.PLC_API_MAINTENANCE_USER,
+                                              self.api.config.PLC_ROOT_USER],
+                                    'peer_id': None}, person_fields)
+
+       # filter out system slices
+        system_slice_ids = SliceAttributes(self.api, {'name': 'system', 'value': '1'}).dict('slice_id')
+       slices = Slices(self.api, {'peer_id': None,
+                                  '~slice_id':system_slice_ids.keys()})
+       
+        result = {
+            'Sites': Sites(self.api, {'peer_id': None}),
+            'Keys': Keys(self.api, {'peer_id': None}),
+            'Nodes': nodes,
+            'Persons': persons,
+            'Slices': slices,
             }
             }
-        
+
+        if isinstance(self.caller, Peer):
+            result['PeerNodes'] = Nodes(self.api, {'peer_id': self.caller['peer_id']})
+
+        result['db_time'] = time.time() - start
+
+        return result