merge from trunk
authorTony Mack <tmack@cs.princeton.edu>
Tue, 13 Nov 2007 23:05:08 +0000 (23:05 +0000)
committerTony Mack <tmack@cs.princeton.edu>
Tue, 13 Nov 2007 23:05:08 +0000 (23:05 +0000)
31 files changed:
PLC/Methods/AddNodeNetworkSetting.py
PLC/Methods/AddNodeNetworkSettingType.py
PLC/Methods/AddPCUProtocolType.py [new file with mode: 0644]
PLC/Methods/AddPCUType.py [new file with mode: 0644]
PLC/Methods/DeleteNodeNetworkSetting.py
PLC/Methods/DeleteNodeNetworkSettingType.py
PLC/Methods/DeletePCUProtocolType.py [new file with mode: 0644]
PLC/Methods/DeletePCUType.py [new file with mode: 0644]
PLC/Methods/GetNodeNetworkSettingTypes.py
PLC/Methods/GetNodeNetworkSettings.py
PLC/Methods/GetPCUProtocolTypes.py [new file with mode: 0644]
PLC/Methods/GetPCUTypes.py [new file with mode: 0644]
PLC/Methods/GetPCUs.py
PLC/Methods/GetPeerData.py
PLC/Methods/GetPeers.py
PLC/Methods/GetPersons.py
PLC/Methods/GetSliceAttributes.py
PLC/Methods/GetSlices.py
PLC/Methods/RefreshPeer.py
PLC/Methods/ResetPassword.py
PLC/Methods/UpdateNode.py
PLC/Methods/UpdateNodeGroup.py
PLC/Methods/UpdateNodeNetworkSetting.py
PLC/Methods/UpdateNodeNetworkSettingType.py
PLC/Methods/UpdatePCUProtocolType.py [new file with mode: 0644]
PLC/Methods/UpdatePCUType.py [new file with mode: 0644]
PLC/Methods/UpdatePerson.py
PLC/Methods/UpdateSite.py
PLC/Methods/UpdateSlice.py
PLC/Methods/VerifyPerson.py
PLC/Methods/__init__.py

index 9ca4d3a..f02670d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 from PLC.Faults import *
 from PLC.Method import Method
index 65d6d42..1c3cc2c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 
 
diff --git a/PLC/Methods/AddPCUProtocolType.py b/PLC/Methods/AddPCUProtocolType.py
new file mode 100644 (file)
index 0000000..76dad3b
--- /dev/null
@@ -0,0 +1,55 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUProtocolTypes import PCUProtocolType, PCUProtocolTypes
+from PLC.PCUTypes import PCUType, PCUTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+            ['pcu_type_id', 'port', 'protocol', 'supported']   
+
+class AddPCUProtocolType(Method):
+    """
+    Adds a new pcu protocol type.
+
+    Returns the new pcu_protocol_type_id (> 0) if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    protocol_type_fields = dict(filter(can_update, PCUProtocolType.fields.items()))
+
+    accepts = [
+        Auth(),
+       Mixed(PCUType.fields['pcu_type_id'],
+              PCUType.fields['model']),
+        protocol_type_fields
+       ]
+
+    returns = Parameter(int, 'New pcu_protocol_type_id (> 0) if successful')
+
+    def call(self, auth, pcu_type_id_or_model, protocol_type_fields):
+
+       # Check if pcu type exists
+       pcu_types = PCUTypes(self.api, [pcu_type_id_or_model])
+       if not pcu_types:
+           raise PLCInvalidArgument, "No such pcu type"
+       pcu_type = pcu_types[0]
+
+       
+       # Check if this port is already used
+       if 'port' not in protocol_type_fields:
+           raise PLCInvalidArgument, "Must specify a port"
+       else:
+           protocol_types = PCUProtocolTypes(self.api, {'pcu_type_id': pcu_type['pcu_type_id']})
+           for protocol_type in protocol_types:
+               if protocol_type['port'] == protocol_type_fields['port']:
+                   raise PLCInvalidArgument, "Port alreay in use" 
+
+       protocol_type_fields = dict(filter(can_update, protocol_type_fields.items()))
+        protocol_type = PCUProtocolType(self.api, protocol_type_fields)
+       protocol_type['pcu_type_id'] = pcu_type['pcu_type_id']
+       protocol_type.sync()
+       self.event_object = {'PCUProtocolType': [protocol_type['pcu_protocol_type_id']]}        
+
+        return protocol_type['pcu_protocol_type_id']
diff --git a/PLC/Methods/AddPCUType.py b/PLC/Methods/AddPCUType.py
new file mode 100644 (file)
index 0000000..106791a
--- /dev/null
@@ -0,0 +1,35 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUTypes import PCUType, PCUTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+            ['model', 'name']  
+
+class AddPCUType(Method):
+    """
+    Adds a new pcu type.
+
+    Returns the new pcu_type_id (> 0) if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    pcu_type_fields = dict(filter(can_update, PCUType.fields.items()))
+
+    accepts = [
+        Auth(),
+        pcu_type_fields
+       ]
+
+    returns = Parameter(int, 'New pcu_type_id (> 0) if successful')
+
+    
+    def call(self, auth, pcu_type_fields):
+       pcu_type_fields = dict(filter(can_update, pcu_type_fields.items()))
+        pcu_type = PCUType(self.api, pcu_type_fields)
+       pcu_type.sync()
+       self.event_object = {'PCUType': [pcu_type['pcu_type_id']]}      
+
+        return pcu_type['pcu_type_id']
index 0ce6561..e092f37 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 
 from PLC.Faults import *
index faa246e..d79a862 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 from PLC.Faults import *
 from PLC.Method import Method
diff --git a/PLC/Methods/DeletePCUProtocolType.py b/PLC/Methods/DeletePCUProtocolType.py
new file mode 100644 (file)
index 0000000..ab66520
--- /dev/null
@@ -0,0 +1,33 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUProtocolTypes import PCUProtocolType, PCUProtocolTypes
+from PLC.Auth import Auth
+
+class DeletePCUProtocolType(Method):
+    """
+    Deletes a PCU protocol type.
+
+    Returns 1 if successful, faults otherwise. 
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        Auth(),
+        PCUProtocolType.fields['pcu_protocol_type_id']
+        ]
+
+    returns = Parameter(int, '1 if successful')
+    
+
+    def call(self, auth, protocol_type_id):
+        protocol_types = PCUProtocolTypes(self.api, [protocol_type_id])
+        if not protocol_types:
+            raise PLCInvalidArgument, "No such pcu protocol type"
+
+        protocol_type = protocol_types[0]
+        protocol_type.delete()
+       self.event_objects = {'PCUProtocolType': [protocol_type['pcu_protocol_type_id']]}
+
+        return 1
diff --git a/PLC/Methods/DeletePCUType.py b/PLC/Methods/DeletePCUType.py
new file mode 100644 (file)
index 0000000..d73c204
--- /dev/null
@@ -0,0 +1,33 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUTypes import PCUType, PCUTypes
+from PLC.Auth import Auth
+
+class DeletePCUType(Method):
+    """
+    Deletes a PCU type.
+
+    Returns 1 if successful, faults otherwise. 
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        Auth(),
+        PCUType.fields['pcu_type_id']
+        ]
+
+    returns = Parameter(int, '1 if successful')
+    
+
+    def call(self, auth, pcu_type_id):
+        pcu_types = PCUTypes(self.api, [pcu_type_id])
+        if not pcu_types:
+            raise PLCInvalidArgument, "No such pcu type"
+
+        pcu_type = pcu_types[0]
+        pcu_type.delete()
+       self.event_objects = {'PCUType': [pcu_type['pcu_type_id']]}
+
+        return 1
index ac6f497..462cfbc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
index 207ad17..0003be9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 from PLC.Faults import *
 from PLC.Method import Method
diff --git a/PLC/Methods/GetPCUProtocolTypes.py b/PLC/Methods/GetPCUProtocolTypes.py
new file mode 100644 (file)
index 0000000..44f9380
--- /dev/null
@@ -0,0 +1,40 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUProtocolTypes import PCUProtocolType, PCUProtocolTypes
+from PLC.Auth import Auth
+from PLC.Filter import Filter
+
+class GetPCUProtocolTypes(Method):
+    """
+    Returns an array of PCU Types.
+    """
+
+    roles = ['admin', 'pi', 'user', 'tech', 'node']
+
+    accepts = [
+        Auth(),
+       Mixed([PCUProtocolType.fields['pcu_type_id']],
+               Filter(PCUProtocolType.fields)),
+        Parameter([str], "List of fields to return", nullok = True)
+        ]
+
+    returns = [PCUProtocolType.fields]
+    
+
+    def call(self, auth, protocol_type_filter = None, return_fields = None):
+
+       #Must query at least pcu_type_id
+       if return_fields is not None and 'pcu_protocol_type_id' not in return_fields:
+           return_fields.append('pcu_protocol_type_id')
+           added_fields = ['pcu_protocol_type_id']
+       else:
+           added_fields = []
+
+       protocol_types = PCUProtocolTypes(self.api, protocol_type_filter, return_fields)
+
+       for added_field in added_fields:
+           for protocol_type in protocol_types:
+               del protocol_type[added_field]
+               
+        return protocol_types 
diff --git a/PLC/Methods/GetPCUTypes.py b/PLC/Methods/GetPCUTypes.py
new file mode 100644 (file)
index 0000000..cf0d689
--- /dev/null
@@ -0,0 +1,48 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUTypes import PCUType, PCUTypes
+from PLC.Auth import Auth
+from PLC.Filter import Filter
+
+class GetPCUTypes(Method):
+    """
+    Returns an array of PCU Types.
+    """
+
+    roles = ['admin', 'pi', 'user', 'tech', 'node']
+
+    accepts = [
+        Auth(),
+       Mixed([PCUType.fields['pcu_type_id'],
+               PCUType.fields['model']],
+               Filter(PCUType.fields)),
+        Parameter([str], "List of fields to return", nullok = True)
+        ]
+
+    returns = [PCUType.fields]
+    
+
+    def call(self, auth, pcu_type_filter = None, return_fields = None):
+
+       #Must query at least pcu_type_id
+       if return_fields is not None:
+           added_fields = []
+           if 'pcu_type_id' not in return_fields:
+               return_fields.append('pcu_type_id')
+               added_fields.append('pcu_type_id')
+           if 'pcu_protocol_types' in return_fields and \
+              'pcu_protocol_type_ids' not in return_fields:
+               return_fields.append('pcu_protocol_type_ids')
+               added_fields.append('pcu_protocol_type_ids') 
+       else:
+           added_fields = []
+
+       pcu_types = PCUTypes(self.api, pcu_type_filter, return_fields)
+
+       # remove added fields and protocol_types
+       for added_field in added_fields:
+           for pcu_type in pcu_types:
+               del pcu_type[added_field]
+               
+        return pcu_types 
index 3280070..ee9ab4d 100644 (file)
@@ -67,6 +67,7 @@ class GetPCUs(Method):
         # Remove pcu_id if not specified
         if added_fields:
             for pcu in pcus:
-                del pcu['pcu_id']
+               if 'pcu_id' in pcu:
+                   del pcu['pcu_id']
 
         return pcus
index 42aad06..e68cf55 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 # 
-# $Id: GetPeerData.py,v 1.13 2007/03/28 14:00:27 thierry Exp $
+# $Id: GetPeerData.py 5574 2007-10-25 20:33:17Z thierry $
 
 import time
 
@@ -49,6 +49,10 @@ class GetPeerData(Method):
         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']] 
+        
 
         person_fields = filter(lambda field: field not in \
                                ['password', 'verification_key', 'verification_expires'],
@@ -70,7 +74,7 @@ class GetPeerData(Method):
         result = {
             'Sites': Sites(self.api, {'peer_id': None}),
             'Keys': Keys(self.api, {'peer_id': None}),
-            'Nodes': Nodes(self.api, {'peer_id': None}, node_fields),
+            'Nodes': nodes,
             'Persons': persons,
             'Slices': slices,
             }
index 235c27c..e93fe36 100644 (file)
@@ -8,6 +8,7 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Filter import Filter
 from PLC.Auth import Auth
 
+from PLC.Persons import Person
 from PLC.Peers import Peer, Peers
 
 class GetPeers (Method):
@@ -19,7 +20,7 @@ class GetPeers (Method):
     specified details will be returned.
     """
 
-    roles = ['admin', 'node']
+    roles = ['admin', 'node','pi','user']
 
     accepts = [
         Auth(),
@@ -32,4 +33,15 @@ class GetPeers (Method):
     returns = [Peer.fields]
 
     def call (self, auth, peer_filter = None, return_fields = None):
-       return Peers(self.api, peer_filter, return_fields)
+        
+        peers = Peers(self.api, peer_filter, return_fields)
+
+        # Remove admin only fields
+        if not isinstance(self.caller, Person) or \
+                'admin' not in self.caller['roles']:
+            for peer in peers:    
+               for field in ['key', 'cacert']:
+                    if field in peer:
+                        del peer[field]
+
+        return peers
index a483dd4..5228933 100644 (file)
@@ -81,6 +81,7 @@ class GetPersons(Method):
         if added_fields:
             for person in persons:
                 for field in added_fields:
-                    del person[field]
+                   if field in person:
+                       del person[field]
 
         return persons
index 80fc344..b8a0a11 100644 (file)
@@ -82,6 +82,7 @@ class GetSliceAttributes(Method):
         # Remove slice_attribute_id if not specified
         if added_fields:
             for slice_attribute in slice_attributes:
-                del slice_attribute['slice_attribute_id']
+               if 'slice_attribute_id' in slice_attribute:
+                   del slice_attribute['slice_attribute_id']
 
         return slice_attributes
index c300ce0..63dc0b4 100644 (file)
@@ -26,7 +26,7 @@ class GetSlices(Method):
         Auth(),
         Mixed([Mixed(Slice.fields['slice_id'],
                      Slice.fields['name'])],
-             Parameter(str,"name"),
+              Parameter(str,"name"),
               Parameter(int,"slice_id"),
               Filter(Slice.fields)),
         Parameter([str], "List of fields to return", nullok = True)
@@ -69,6 +69,7 @@ class GetSlices(Method):
         # Remove slice_id if not specified
         if added_fields:
             for slice in slices:
-                del slice['slice_id']
+               if 'slice_id' in slice:
+                   del slice['slice_id']
 
         return slices
index bf820da..a45f8bd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 # 
-# $Id: RefreshPeer.py,v 1.24 2007/06/14 16:26:23 tmack Exp $
+# $Id: RefreshPeer.py 5574 2007-10-25 20:33:17Z thierry $
 
 import time
 
index 367b7c8..0e2d2a9 100644 (file)
@@ -3,6 +3,8 @@ import base64
 import time
 import urllib
 
+from types import StringTypes
+
 from PLC.Debug import log
 from PLC.Faults import *
 from PLC.Method import Method
@@ -41,7 +43,13 @@ class ResetPassword(Method):
 
     def call(self, auth, person_id_or_email, verification_key = None, verification_expires = None):
        # Get account information
-        persons = Persons(self.api, [person_id_or_email])
+        # we need to search in local objects only
+        if isinstance (person_id_or_email,StringTypes):
+            filter={'email':person_id_or_email}
+        else:
+            filter={'person_id':person_id_or_email}
+        filter['peer_id']=None
+        persons = Persons(self.api, filter)
         if not persons:
             raise PLCInvalidArgument, "No such account"
         person = persons[0]
index d8128e0..d5cdb0d 100644 (file)
@@ -4,9 +4,11 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Nodes import Node, Nodes
 from PLC.Auth import Auth
 
+related_fields = Node.related_fields.keys()
 can_update = lambda (field, value): field in \
              ['hostname', 'boot_state', 'model', 'version',
-              'key', 'session', 'boot_nonce']
+              'key', 'session', 'boot_nonce'] + \
+            related_fields
 
 class UpdateNode(Method):
     """
@@ -21,7 +23,7 @@ class UpdateNode(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    node_fields = dict(filter(can_update, Node.fields.items()))
+    node_fields = dict(filter(can_update, Node.fields.items() + Node.related_fields.items()))
 
     accepts = [
         Auth(),
@@ -59,7 +61,13 @@ class UpdateNode(Method):
             if node['site_id'] not in self.caller['site_ids']:
                 raise PLCPermissionDenied, "Not allowed to delete nodes from specified site"
 
-        node.update(node_fields)
+        # Make requested associations
+        for field in related_fields:
+            if field in node_fields:
+                node.associate(auth, field, node_fields[field])
+                node_fields.pop(field)
+
+       node.update(node_fields)
        node.update_last_updated(False)
         node.sync()
        
index 78042be..c84c7f1 100644 (file)
@@ -4,8 +4,10 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.NodeGroups import NodeGroup, NodeGroups
 from PLC.Auth import Auth
 
+related_fields = NodeGroup.related_fields.keys()
 can_update = lambda (field, value): field in \
-             ['name', 'description']
+             ['name', 'description'] + \
+            related_fields
 
 class UpdateNodeGroup(Method):
     """
@@ -16,7 +18,7 @@ class UpdateNodeGroup(Method):
 
     roles = ['admin']
 
-    nodegroup_fields = dict(filter(can_update, NodeGroup.fields.items()))
+    nodegroup_fields = dict(filter(can_update, NodeGroup.fields.items() + NodeGroup.related_fields.items()))
 
     accepts = [
         Auth(),
@@ -35,6 +37,12 @@ class UpdateNodeGroup(Method):
        if not nodegroups:
             raise PLCInvalidArgument, "No such nodegroup"
        nodegroup = nodegroups[0]
+
+       # Make requested associations
+        for field in related_fields:
+            if field in nodegroup_fields:
+                nodegroup.associate(auth, field, nodegroup_fields[field])
+                nodegroup_fields.pop(field)
        
        nodegroup.update(nodegroup_fields)
         nodegroup.sync()
index f039717..e8f7497 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 
 from PLC.Faults import *
index 8b20ea7..b18079b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Thierry Parmentelat - INRIA
 #
-# $Revision: 1.1 $
+# $Revision: 5574 $
 #
 from PLC.Faults import *
 from PLC.Method import Method
diff --git a/PLC/Methods/UpdatePCUProtocolType.py b/PLC/Methods/UpdatePCUProtocolType.py
new file mode 100644 (file)
index 0000000..b1a30bc
--- /dev/null
@@ -0,0 +1,41 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUProtocolTypes import PCUProtocolType, PCUProtocolTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+             ['pcu_type_id', 'port', 'protocol', 'supported']
+
+class UpdatePCUProtocolType(Method):
+    """
+    Updates a pcu protocol type. Only the fields specified in
+    port_typee_fields are updated, all other fields are left untouched.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    protocol_type_fields = dict(filter(can_update, PCUProtocolType.fields.items()))
+
+    accepts = [
+        Auth(),
+        PCUProtocolType.fields['pcu_protocol_type_id'],
+        protocol_type_fields
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, protocol_type_id, protocol_type_fields):
+        protocol_type_fields = dict(filter(can_update, protocol_type_fields.items()))
+
+        protocol_types = PCUProtocolTypes(self.api, [protocol_type_id])
+        if not protocol_types:
+            raise PLCInvalidArgument, "No such pcu protocol type"
+
+        protocol_type = protocol_types[0]
+        protocol_type.update(protocol_type_fields)
+        protocol_type.sync()
+       self.event_objects = {'PCUProtocolType': [protocol_type['pcu_protocol_type_id']]}       
+        return 1
diff --git a/PLC/Methods/UpdatePCUType.py b/PLC/Methods/UpdatePCUType.py
new file mode 100644 (file)
index 0000000..fc4e886
--- /dev/null
@@ -0,0 +1,42 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.PCUTypes import PCUType, PCUTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+             ['model', 'name']
+
+class UpdatePCUType(Method):
+    """
+    Updates a PCU type. Only the fields specified in
+    pcu_typee_fields are updated, all other fields are left untouched.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    pcu_type_fields = dict(filter(can_update, PCUType.fields.items()))
+
+    accepts = [
+        Auth(),
+        PCUType.fields['pcu_type_id'],
+        pcu_type_fields
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, pcu_type_id, pcu_type_fields):
+        pcu_type_fields = dict(filter(can_update, pcu_type_fields.items()))
+
+        pcu_types = PCUTypes(self.api, [pcu_type_id])
+        if not pcu_types:
+            raise PLCInvalidArgument, "No such pcu type"
+
+        pcu_type = pcu_types[0]
+        pcu_type.update(pcu_type_fields)
+        pcu_type.sync()
+       self.event_objects = {'PCUType': [pcu_type['pcu_type_id']]}     
+
+        return 1
index 790307e..8f74fc0 100644 (file)
@@ -4,10 +4,11 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Persons import Person, Persons
 from PLC.Auth import Auth
 
+related_fields = Person.related_fields.keys()
 can_update = lambda (field, value): field in \
              ['first_name', 'last_name', 'title', 'email',
               'password', 'phone', 'url', 'bio', 'accepted_aup',
-              'enabled']
+              'enabled'] + related_fields
 
 class UpdatePerson(Method):
     """
@@ -22,7 +23,7 @@ class UpdatePerson(Method):
 
     roles = ['admin', 'pi', 'user', 'tech']
 
-    person_fields = dict(filter(can_update, Person.fields.items()))
+    person_fields = dict(filter(can_update, Person.fields.items() + Person.related_fields.items()))
 
     accepts = [
         Auth(),
@@ -51,6 +52,12 @@ class UpdatePerson(Method):
         # Check if we can update this account
         if not self.caller.can_update(person):
             raise PLCPermissionDenied, "Not allowed to update specified account"
+       
+       # Make requested associations
+        for field in related_fields:
+            if field in person_fields:
+                person.associate(auth, field, person_fields[field])
+                person_fields.pop(field)
 
         person.update(person_fields)
        person.update_last_updated(False)
index 03b1e13..6a33c5e 100644 (file)
@@ -4,10 +4,12 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Sites import Site, Sites
 from PLC.Auth import Auth
 
+related_fields = Site.related_fields.keys()
 can_update = lambda (field, value): field in \
              ['name', 'abbreviated_name', 'login_base',
               'is_public', 'latitude', 'longitude', 'url',
-              'max_slices', 'max_slivers', 'enabled', 'ext_consortium_id']
+              'max_slices', 'max_slivers', 'enabled', 'ext_consortium_id'] + \
+             related_fields    
 
 class UpdateSite(Method):
     """
@@ -22,7 +24,7 @@ class UpdateSite(Method):
 
     roles = ['admin', 'pi']
 
-    site_fields = dict(filter(can_update, Site.fields.items()))
+    site_fields = dict(filter(can_update, Site.fields.items() + Site.related_fields.items()))
 
     accepts = [
         Auth(),
@@ -59,6 +61,12 @@ class UpdateSite(Method):
                 if key in site_fields:
                     del site_fields[key]
 
+       # Make requested associations
+       for field in related_fields:
+           if field in site_fields:
+               site.associate(auth, field, site_fields[field])
+               site_fields.pop(field)  
+       
         site.update(site_fields)
        site.update_last_updated(False)
        site.sync()
index 2596c74..de4a023 100644 (file)
@@ -7,8 +7,11 @@ from PLC.Slices import Slice, Slices
 from PLC.Auth import Auth
 from PLC.Sites import Site, Sites
 
+related_fields = Slice.related_fields.keys() 
 can_update = lambda (field, value): field in \
-             ['instantiation', 'url', 'description', 'max_nodes', 'expires']
+             ['instantiation', 'url', 'description', 'max_nodes', 'expires'] + \
+            related_fields
+
 
 class UpdateSlice(Method):
     """
@@ -28,7 +31,7 @@ class UpdateSlice(Method):
 
     roles = ['admin', 'pi', 'user']
 
-    slice_fields = dict(filter(can_update, Slice.fields.items()))
+    slice_fields = dict(filter(can_update, Slice.fields.items() + Slice.related_fields.items()))
 
     accepts = [
         Auth(),
@@ -41,8 +44,8 @@ class UpdateSlice(Method):
 
     def call(self, auth, slice_id_or_name, slice_fields):
         slice_fields = dict(filter(can_update, slice_fields.items()))
-
-        slices = Slices(self.api, [slice_id_or_name])
+        
+       slices = Slices(self.api, [slice_id_or_name])
         if not slices:
             raise PLCInvalidArgument, "No such slice"
         slice = slices[0]
@@ -79,14 +82,20 @@ class UpdateSlice(Method):
                'pi' not in self.caller['roles']:
                 raise PLCInvalidArgument, "Only admins and PIs may update max_nodes"
 
-        slice.update(slice_fields)
-
         # XXX Make this a configurable policy
         if slice['description'] is None or not slice['description'].strip() or \
            slice['url'] is None or not slice['url'].strip():
             raise PLCInvalidArgument, "Cannot renew a slice with an empty description or URL"
 
+       # Make requested associations
+       for field in related_fields:
+           if field in slice_fields:
+               slice.associate(auth, field, slice_fields[field])
+               slice_fields.pop(field)
+
+       slice.update(slice_fields)
         slice.sync()
+
        self.event_objects = {'Slice': [slice['slice_id']]}
 
         return 1
index fd4adb7..9dd784b 100644 (file)
@@ -46,14 +46,14 @@ class VerifyPerson(Method):
        # Get account information
         persons = Persons(self.api, [person_id_or_email])
         if not persons:
-            raise PLCInvalidArgument, "No such account"
+            raise PLCInvalidArgument, "No such account %r"%person_id_or_email
         person = persons[0]
 
         if person['peer_id'] is not None:
-            raise PLCInvalidArgument, "Not a local account"
+            raise PLCInvalidArgument, "Not a local account %r"%person_id_or_email
 
         if person['enabled']:
-            raise PLCInvalidArgument, "Account must be new (disabled)"
+            raise PLCInvalidArgument, "Account %r must be new (disabled)"%person_id_or_email
 
         # Get the primary site name
         person_sites = Sites(self.api, person['site_ids'])
index 0527421..45c9228 100644 (file)
@@ -3,59 +3,62 @@ AddAddressType
 AddAddressTypeToAddress
 AddBootState
 AddConfFile
-AddConfFileToNode
 AddConfFileToNodeGroup
+AddConfFileToNode
 AddInitScript
 AddKeyType
 AddMessage
 AddNetworkMethod
 AddNetworkType
-AddNode
 AddNodeGroup
 AddNodeNetwork
 AddNodeNetworkSetting
 AddNodeNetworkSettingType
+AddNode
 AddNodeToNodeGroup
 AddNodeToPCU
+AddPCUProtocolType
 AddPCU
+AddPCUType
 AddPeer
-AddPerson
 AddPersonKey
+AddPerson
 AddPersonToSite
 AddPersonToSlice
 AddRole
 AddRoleToPerson
 AddSession
-AddSite
 AddSiteAddress
-AddSlice
+AddSite
 AddSliceAttribute
 AddSliceAttributeType
 AddSliceInstantiation
+AddSlice
 AddSliceToNodes
 AddSliceToNodesWhitelist
 AdmAddAddressType
-AdmAddNode
 AdmAddNodeGroup
 AdmAddNodeNetwork
+AdmAddNode
 AdmAddNodeToNodeGroup
-AdmAddPerson
 AdmAddPersonKey
+AdmAddPerson
 AdmAddPersonToSite
-AdmAddSite
 AdmAddSitePowerControlUnit
+AdmAddSite
 AdmAssociateNodeToPowerControlUnitPort
 AdmAuthCheck
 AdmDeleteAddressType
 AdmDeleteAllPersonKeys
-AdmDeleteNode
 AdmDeleteNodeGroup
 AdmDeleteNodeNetwork
-AdmDeletePerson
+AdmDeleteNode
 AdmDeletePersonKeys
-AdmDeleteSite
+AdmDeletePerson
 AdmDeleteSitePowerControlUnit
+AdmDeleteSite
 AdmDisassociatePowerControlUnitPort
+AdmGenerateNodeConfFile
 AdmGetAllAddressTypes
 AdmGetAllKeyTypes
 AdmGetAllNodeNetworks
@@ -70,11 +73,11 @@ AdmGetPersons
 AdmGetPowerControlUnitNodes
 AdmGetPowerControlUnits
 AdmGetSiteNodes
-AdmGetSitePIs
 AdmGetSitePersons
+AdmGetSitePIs
 AdmGetSitePowerControlUnits
-AdmGetSiteTechContacts
 AdmGetSites
+AdmGetSiteTechContacts
 AdmGrantRoleToPerson
 AdmIsPersonInRole
 AdmQueryConfFile
@@ -88,12 +91,12 @@ AdmRemovePersonFromSite
 AdmRevokeRoleFromPerson
 AdmSetPersonEnabled
 AdmSetPersonPrimarySite
-AdmUpdateNode
 AdmUpdateNodeGroup
 AdmUpdateNodeNetwork
+AdmUpdateNode
 AdmUpdatePerson
-AdmUpdateSite
 AdmUpdateSitePowerControlUnit
+AdmUpdateSite
 AnonAdmGetNodeGroups
 AuthCheck
 BlacklistKey
@@ -102,59 +105,64 @@ BootGetNodeDetails
 BootNotifyOwners
 BootUpdateNode
 DeleteAddress
-DeleteAddressType
 DeleteAddressTypeFromAddress
+DeleteAddressType
 DeleteBootState
-DeleteConfFile
-DeleteConfFileFromNode
 DeleteConfFileFromNodeGroup
+DeleteConfFileFromNode
+DeleteConfFile
 DeleteInitScript
 DeleteKey
 DeleteKeyType
 DeleteMessage
 DeleteNetworkMethod
 DeleteNetworkType
-DeleteNode
 DeleteNodeFromNodeGroup
 DeleteNodeFromPCU
 DeleteNodeGroup
 DeleteNodeNetwork
 DeleteNodeNetworkSetting
 DeleteNodeNetworkSettingType
+DeleteNode
+DeletePCUProtocolType
 DeletePCU
+DeletePCUType
 DeletePeer
-DeletePerson
 DeletePersonFromSite
 DeletePersonFromSlice
-DeleteRole
+DeletePerson
 DeleteRoleFromPerson
+DeleteRole
 DeleteSession
 DeleteSite
-DeleteSlice
 DeleteSliceAttribute
 DeleteSliceAttributeType
 DeleteSliceFromNodes
 DeleteSliceFromNodesWhitelist
 DeleteSliceInstantiation
-GetAddressTypes
+DeleteSlice
+GenerateNodeConfFile
 GetAddresses
+GetAddressTypes
 GetBootMedium
 GetBootStates
 GetConfFiles
 GetEventObjects
 GetEvents
 GetInitScripts
-GetKeyTypes
 GetKeys
+GetKeyTypes
 GetMessages
 GetNetworkMethods
 GetNetworkTypes
 GetNodeGroups
-GetNodeNetworkSettingTypes
 GetNodeNetworkSettings
+GetNodeNetworkSettingTypes
 GetNodeNetworks
 GetNodes
+GetPCUProtocolTypes
 GetPCUs
+GetPCUTypes
 GetPeerData
 GetPeerName
 GetPeers
@@ -164,13 +172,13 @@ GetRoles
 GetSession
 GetSessions
 GetSites
-GetSliceAttributeTypes
 GetSliceAttributes
+GetSliceAttributeTypes
 GetSliceInstantiations
 GetSliceKeys
-GetSliceTicket
-GetSlices
 GetSlicesMD5
+GetSlices
+GetSliceTicket
 GetSlivers
 GetWhitelist
 NotifyPersons
@@ -195,27 +203,29 @@ SliceUpdate
 SliceUserAdd
 SliceUserDel
 SliceUsersList
+system.listMethods
+system.methodHelp
+system.methodSignature
+system.multicall
 UpdateAddress
 UpdateAddressType
 UpdateConfFile
 UpdateInitScript
 UpdateKey
 UpdateMessage
-UpdateNode
 UpdateNodeGroup
 UpdateNodeNetwork
 UpdateNodeNetworkSetting
 UpdateNodeNetworkSettingType
+UpdateNode
+UpdatePCUProtocolType
 UpdatePCU
+UpdatePCUType
 UpdatePeer
 UpdatePerson
 UpdateSite
-UpdateSlice
 UpdateSliceAttribute
 UpdateSliceAttributeType
+UpdateSlice
 VerifyPerson
-system.listMethods
-system.methodHelp
-system.methodSignature
-system.multicall
 """.split()