add pcu/node functions
authorMark Huang <mlhuang@cs.princeton.edu>
Wed, 11 Oct 2006 20:48:58 +0000 (20:48 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Wed, 11 Oct 2006 20:48:58 +0000 (20:48 +0000)
PLC/Methods/AddNodeToPCU.py [new file with mode: 0644]
PLC/Methods/DeleteNodeFromPCU.py [new file with mode: 0644]
PLC/Methods/__init__.py
PLC/Nodes.py
PLC/PCUs.py

diff --git a/PLC/Methods/AddNodeToPCU.py b/PLC/Methods/AddNodeToPCU.py
new file mode 100644 (file)
index 0000000..6a4cd75
--- /dev/null
@@ -0,0 +1,64 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Nodes import Node, Nodes
+from PLC.PCUs import PCU, PCUs
+from PLC.Auth import PasswordAuth
+
+class AddNodeToPCU(Method):
+    """
+    Adds a node to a port on a PCU. Faults if the node has already
+    been added to the PCU or if the port is already in use.
+
+    Non-admins may only update PCUs at their sites.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin', 'pi', 'tech']
+
+    accepts = [
+        PasswordAuth(),
+       Mixed(Node.fields['node_id'],
+              Node.fields['hostname']),
+        PCU.fields['pcu_id'],
+        Parameter(int, 'PCU port number')
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, node_id_or_hostname, pcu_id, port):
+        # Get node
+        nodes = Nodes(self.api, [node_id_or_hostname])
+        if not nodes:
+            raise PLCInvalidArgument, "No such node"
+
+        node = nodes.values()[0]
+
+        # Get PCU
+        pcus = PCUs(self.api, [pcu_id])
+        if not pcus:
+            raise PLCInvalidArgument, "No such PCU"
+
+        pcu = pcus.values()[0]
+
+        if 'admin' not in self.caller['roles']:
+            ok = False
+            sites = Sites(self.api, self.caller['site_ids']).values()
+            for site in sites:
+                if pcu['pcu_id'] in site['pcu_ids']:
+                    ok = True
+                    break
+            if not ok:
+                raise PLCPermissionDenied, "Not allowed to update that PCU"
+       
+       # Add node to PCU
+        if node['node_id'] in pcu['node_ids']:
+            raise PLCInvalidArgument, "Node already controlled by PCU"
+
+        if port in pcu['ports']:
+            raise PLCInvalidArgument, "PCU port already in use"
+
+        pcu.add_node(node, port)
+
+        return 1
diff --git a/PLC/Methods/DeleteNodeFromPCU.py b/PLC/Methods/DeleteNodeFromPCU.py
new file mode 100644 (file)
index 0000000..9e2afec
--- /dev/null
@@ -0,0 +1,57 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Nodes import Node, Nodes
+from PLC.PCUs import PCU, PCUs
+from PLC.Auth import PasswordAuth
+
+class DeleteNodeFromPCU(Method):
+    """
+    Deletes a node from a PCU.
+
+    Non-admins may only update PCUs at their sites.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin', 'pi', 'tech']
+
+    accepts = [
+        PasswordAuth(),
+       Mixed(Node.fields['node_id'],
+              Node.fields['hostname']),
+        PCU.fields['pcu_id']
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, node_id_or_hostname, pcu_id):
+        # Get node
+        nodes = Nodes(self.api, [node_id_or_hostname])
+        if not nodes:
+            raise PLCInvalidArgument, "No such node"
+
+        node = nodes.values()[0]
+
+        # Get PCU
+        pcus = PCUs(self.api, [pcu_id])
+        if not pcus:
+            raise PLCInvalidArgument, "No such PCU"
+
+        pcu = pcus.values()[0]
+
+        if 'admin' not in self.caller['roles']:
+            ok = False
+            sites = Sites(self.api, self.caller['site_ids']).values()
+            for site in sites:
+                if pcu['pcu_id'] in site['pcu_ids']:
+                    ok = True
+                    break
+            if not ok:
+                raise PLCPermissionDenied, "Not allowed to update that PCU"
+       
+       # Removed node from PCU
+        if node['node_id'] in pcu['node_ids']:
+            pcu.remove_node(node)
+
+        return 1
index 2aeb73f..3de5381 100644 (file)
@@ -1 +1 @@
-methods = 'AddAddress AddAddressType AddAddressTypeToAddress AddAttribute AddBootState AddKey AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddPCU AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSite AddSliceAttribute AddSlice AddSliceToNodes AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPerson AdmAddPersonToSite AdmAddSite AdmAuthCheck AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePerson AdmDeleteSite AdmGetAllNodeNetworkBandwidthLimits AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetSiteNodes AdmGetSitePersons AdmGetSites AdmGrantRoleToPerson AdmIsPersonInRole AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteAttribute DeleteBootState DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetAttributes GetBootStates GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSlices SetPersonPrimarySite UpdateAddress UpdateAddressType UpdateAttribute UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSlice  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
+methods = 'AddAddress AddAddressType AddAddressTypeToAddress AddAttribute AddBootState AddKey AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSite AddSliceAttribute AddSlice AddSliceToNodes AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPerson AdmAddPersonToSite AdmAddSite AdmAuthCheck AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePerson AdmDeleteSite AdmGetAllNodeNetworkBandwidthLimits AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetSiteNodes AdmGetSitePersons AdmGetSites AdmGrantRoleToPerson AdmIsPersonInRole AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteAttribute DeleteBootState DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetAttributes GetBootStates GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSlices SetPersonPrimarySite UpdateAddress UpdateAddressType UpdateAttribute UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSlice  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
index 7bf7b9c..86dc061 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Nodes.py,v 1.9 2006/10/03 19:25:43 mlhuang Exp $
+# $Id: Nodes.py,v 1.10 2006/10/11 19:51:18 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -55,7 +55,8 @@ class Node(Row):
         # 'conf_file_ids': Parameter([int], "List of configuration files specific to this node", ro = True),
         # 'root_person_ids': Parameter([int], "(Admin only) List of people who have root access to this node", ro = True),
         'slice_ids': Parameter([int], "List of slices on this node", ro = True),
-        # 'pcu_ids': Parameter([int], "List of PCUs that control this node", ro = True),
+        'pcu_ids': Parameter([int], "List of PCUs that control this node", ro = True),
+        'ports': Parameter([int], "List of PCU ports that this node is connected to", ro = True),
         }
 
     def __init__(self, api, fields):
index 155ac9a..820ac00 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: PCUs.py,v 1.1 2006/09/06 15:36:07 mlhuang Exp $
+# $Id: PCUs.py,v 1.2 2006/10/11 19:54:53 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -12,6 +12,7 @@ from PLC.Parameter import Parameter
 from PLC.Debug import profile
 from PLC.Table import Row, Table
 from PLC.NodeNetworks import valid_ip, NodeNetwork, NodeNetworks
+from PLC.Nodes import Node, Nodes
 
 class PCU(Row):
     """
@@ -44,6 +45,57 @@ class PCU(Row):
             raise PLCInvalidArgument, "Invalid IP address " + ip
         return ip
 
+    def add_node(self, node, port, commit = True):
+        """
+        Add node to existing PCU.
+        """
+
+        assert 'pcu_id' in self
+        assert isinstance(node, Node)
+        assert isinstance(port, (int, long))
+        assert 'node_id' in node
+
+        pcu_id = self['pcu_id']
+        node_id = node['node_id']
+
+        if node_id not in self['node_ids'] and port not in self['ports']:
+            self.api.db.do("INSERT INTO pcu_node (pcu_id, node_id, port)" \
+                           " VALUES(%(pcu_id)d, %(node_id)d, %(port)d)",
+                           locals())
+
+            if commit:
+                self.api.db.commit()
+
+            self['node_ids'].append(node_id)
+            self['ports'].append(port)
+
+    def remove_node(self, node, commit = True):
+        """
+        Remove node from existing PCU.
+        """
+
+        assert 'pcu_id' in self
+        assert isinstance(node, Node)
+        assert 'node_id' in node
+
+        pcu_id = self['pcu_id']
+        node_id = node['node_id']
+
+        if node_id in self['node_ids']:
+            i = self['node_ids'].index(node_id)
+            port = self['ports'][i]
+
+            self.api.db.do("DELETE FROM pcu_node" \
+                           " WHERE pcu_id = %(pcu_id)d" \
+                           " AND node_id = %(node_id)d",
+                           locals())
+
+            if commit:
+                self.api.db.commit()
+
+            self['node_ids'].remove(node_id)
+            self['ports'].remove(port)
+
     def delete(self, commit = True):
         """
         Delete existing PCU.
@@ -80,7 +132,7 @@ class PCUs(Table):
 
         for row in rows:
             self[row['pcu_id']] = pcu = PCU(api, row)
-            for aggregate in ['pcu_ids', 'ports']:
+            for aggregate in ['node_ids', 'ports']:
                 if not pcu.has_key(aggregate) or pcu[aggregate] is None:
                     pcu[aggregate] = []
                 else: