f07f1ff9e7dd696611fb09d1c71379f4658f4d4c
[plcapi.git] / PLC / Methods / UpdateIpAddress.py
1 # $Id$
2 # $URL$
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Table import Row
7 from PLC.Auth import Auth
8
9 from PLC.Nodes import Node, Nodes
10 from PLC.TagTypes import TagTypes
11 from PLC.InterfaceTags import InterfaceTags
12 from PLC.Interfaces import Interface, Interfaces
13 from PLC.IpAddresses import IpAddress, IpAddresses
14
15 cannot_update = ['ip_address_id', 'interface_id']
16
17 class UpdateIpAddress(Method):
18     """
19     PIs and techs may only update interfaces associated with their own
20     nodes. Admins may update any interface network.
21
22     Returns 1 if successful, faults otherwise.
23     """
24
25     roles = ['admin', 'pi', 'tech']
26
27     accepted_fields = Row.accepted_fields(cannot_update, IpAddress.fields,exclude=True)
28     accepted_fields.update(IpAddress.tags)
29
30     accepts = [
31         Auth(),
32         IpAddress.fields['ip_address_id'],
33         accepted_fields
34         ]
35
36     returns = Parameter(int, '1 if successful')
37
38     def call(self, auth, ip_address_id, ip_address_fields):
39
40         [native,tags,rejected] = Row.split_fields(ip_address_fields,[IpAddress.fields,IpAddress.tags])
41
42         # type checking
43         native= Row.check_fields (native, self.accepted_fields)
44         if rejected:
45             raise PLCInvalidArgument, "Cannot update IpAddress column(s) %r"%rejected
46
47         # Get ip_address information
48         ip_addresses = IpAddresses(self.api, [ip_address_id])
49         if not ip_addresses:
50             raise PLCInvalidArgument, "No such ip address"
51
52         ip_address = ip_addresses[0]
53
54         # Authenticated function
55         assert self.caller is not None
56
57         # If we are not an admin, make sure that the caller is a
58         # member of the site where the node exists.
59         if 'admin' not in self.caller['roles']:
60             # Get interface information
61             interface_id = ip_address["interface_id"]
62             interfaces = Interfaces(self.api, [interface_id])
63             if not interfaces:
64                 raise PLCPermissionDenied, "Ip address is not associated with an interface"
65             interface = interfaces[0]
66
67             nodes = Nodes(self.api, [interface['node_id']])
68             if not nodes:
69                 raise PLCPermissionDenied, "Interface is not associated with a node"
70             node = nodes[0]
71             if node['site_id'] not in self.caller['site_ids']:
72                 raise PLCPermissionDenied, "Not allowed to update address"
73
74         ip_address.update(native)
75         ip_address.update_last_updated(commit=False)
76         ip_address.sync()
77
78         self.event_objects = {'IpAddress': [ip_address['ip_address_id']]}
79         self.message = "Address %s updated"%ip_address['ip_addr']
80         self.message += "[%s]." % ", ".join(ip_address_fields.keys())
81
82         return 1