- make Add() calling convention consistent among all functions that
[plcapi.git] / PLC / Methods / UpdateNode.py
1 from PLC.Faults import *
2 from PLC.Method import Method
3 from PLC.Parameter import Parameter, Mixed
4 from PLC.Nodes import Node, Nodes
5 from PLC.Auth import PasswordAuth
6
7 can_update = lambda (field, value): field in \
8              ['hostname', 'boot_state', 'model', 'version',
9               'key', 'session']
10
11 class UpdateNode(Method):
12     """
13     Updates a node. Only the fields specified in node_fields are
14     updated, all other fields are left untouched.
15     
16     PIs and techs can update only the nodes at their sites. Only
17     admins can update the key and session fields.
18
19     Returns 1 if successful, faults otherwise.
20     """
21
22     roles = ['admin', 'pi', 'tech']
23
24     node_fields = dict(filter(can_update, Node.fields.items()))
25     for field in node_fields.values():
26         field.optional = True
27
28     accepts = [
29         PasswordAuth(),
30         Mixed(Node.fields['node_id'],
31               Node.fields['hostname']),
32         node_fields
33         ]
34
35     returns = Parameter(int, '1 if successful')
36
37     def call(self, auth, node_id_or_hostname, node_fields):
38         node_fields = dict(filter(can_update, node_fields.items()))
39
40         # Remove admin only fields
41         if 'admin' not in self.caller['roles']:
42             for key in 'key', 'session':
43                 del node_fields[key]
44
45         # Get account information
46         nodes = Nodes(self.api, [node_id_or_hostname])
47         if not nodes:
48             raise PLCInvalidArgument, "No such node"
49
50         node = nodes.values()[0]
51
52         # Authenticated function
53         assert self.caller is not None
54
55         # If we are not an admin, make sure that the caller is a
56         # member of the site at which the node is located.
57         if 'admin' not in self.caller['roles']:
58             if node['site_id'] not in self.caller['site_ids']:
59                 raise PLCPermissionDenied, "Not allowed to delete nodes from specified site"
60
61         node.update(node_fields)
62         node.sync()
63
64         return 1