bring over newinterface branch from Verivue
[plcapi.git] / PLC / Methods / AddIpAddress.py
diff --git a/PLC/Methods/AddIpAddress.py b/PLC/Methods/AddIpAddress.py
new file mode 100644 (file)
index 0000000..9847c3c
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# Thierry Parmentelat - INRIA
+#
+from PLC.Faults import *
+from PLC.Auth import Auth
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Table import Row
+
+from PLC.Nodes import Node, Nodes
+from PLC.Interfaces import Interface, Interfaces
+from PLC.IpAddresses import IpAddresses, IpAddress
+from PLC.TagTypes import TagTypes
+
+cannot_update = ['ip_address_id', 'interface_id']
+
+class AddIpAddress(Method):
+    """
+
+    Adds a new address for an interface. Any values specified in
+    ip_address_fields are used, otherwise defaults are
+    used.
+
+    PIs and techs may only add interfaces to their own nodes. Admins may
+    add interfaces to any node.
+
+    Returns the new ip_address_id (> 0) if successful, faults otherwise.
+    """
+
+    roles = ['admin', 'pi', 'tech']
+
+    accepted_fields = Row.accepted_fields(cannot_update, IpAddress.fields, exclude=True)
+    accepted_fields.update(IpAddress.tags)
+
+    accepts = [
+        Auth(),
+        Mixed(Interface.fields['interface_id']),
+        accepted_fields
+        ]
+
+    returns = Parameter(int, 'New ip_address_id (> 0) if successful')
+
+
+    def call(self, auth, interface_id, ip_address_fields):
+
+        [native,tags,rejected]=Row.split_fields(ip_address_fields,[IpAddress.fields,IpAddress.tags])
+
+        # type checking
+        native = Row.check_fields (native, self.accepted_fields)
+        if rejected:
+            raise PLCInvalidArgument, "Cannot add IpAddress with column(s) %r"%rejected
+
+        # Get interface information
+        interfaces = Interfaces(self.api, [interface_id])
+        if not interfaces:
+            raise PLCInvalidArgument, "No such interfaces %r"%interface_id
+        interface = interfaces[0]
+
+        # Check if node exists
+        nodes = Nodes(self.api, [interface['node_id']])
+        if not nodes:
+            raise PLCInvalidArgument, "No such node %r"%node_id_or_hostname
+        node = nodes[0]
+
+        # Authenticated function
+        assert self.caller is not None
+
+        # If we are not an admin, make sure that the caller is a
+        # member of the site where the node exists.
+        if 'admin' not in self.caller['roles']:
+            if node['site_id'] not in self.caller['site_ids']:
+                raise PLCPermissionDenied, "Not allowed to add an interface to the specified node"
+
+        # Add interface
+        ip_address = IpAddress(self.api, native)
+        ip_address['interface_id'] = interface['interface_id']
+        ip_address.sync()
+
+        # Logging variables
+        self.event_objects = { 'Interace': [interface['interface_id']],
+                               'IpAddress' : [ip_address['ip_address_id']] }
+        self.message = "Address %d added" % ip_address['ip_address_id']
+
+        return ip_address['ip_address_id']