- fix accidental modification of class variable
[plcapi.git] / PLC / Methods / AdmGetNodes.py
1 import os
2
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Nodes import Node, Nodes
7 from PLC.Auth import PasswordAuth
8
9 class AdmGetNodes(Method):
10     """
11     Return an array of dictionaries containing details about the
12     specified accounts.
13
14     Admins may retrieve details about all accounts by not specifying
15     node_id_or_email_list or by specifying an empty list. Users and
16     techs may only retrieve details about themselves. PIs may retrieve
17     details about themselves and others at their sites.
18
19     If return_fields is specified, only the specified fields will be
20     returned, if set. Otherwise, the default set of fields returned is:
21
22     """
23
24     roles = ['admin', 'pi', 'user', 'tech']
25
26     accepts = [
27         PasswordAuth(),
28         [Mixed(Node.fields['node_id'],
29                Node.fields['hostname'])],
30         Parameter([str], 'List of fields to return')
31         ]
32
33     # Filter out hidden fields
34     can_return = lambda (field, value): field not in ['deleted']
35     return_fields = dict(filter(can_return, Node.all_fields.items()))
36     returns = [return_fields]
37
38     def __init__(self, *args, **kwds):
39         Method.__init__(self, *args, **kwds)
40         # Update documentation with list of default fields returned
41         self.__doc__ += os.linesep.join(Node.default_fields.keys())
42
43     def call(self, auth, node_id_or_hostname_list = None, return_fields = None):
44         # Authenticated function
45         assert self.caller is not None
46
47         valid_fields = dict(self.return_fields)
48
49         # Remove admin only fields
50         if 'admin' not in self.caller['roles']:
51             for key in ['boot_nonce', 'key', 'session', 'root_person_ids']:
52                 del valid_fields[key]
53
54         # Make sure that only valid fields are specified
55         if return_fields is None:
56             return_fields = valid_fields
57         elif filter(lambda field: field not in valid_fields, return_fields):
58             raise PLCInvalidArgument, "Invalid return field specified"
59
60         # Get node information
61         nodes = Nodes(self.api, node_id_or_hostname_list, return_fields).values()
62
63         # Filter out undesired or None fields (XML-RPC cannot marshal
64         # None) and turn each node into a real dict.
65         valid_return_fields_only = lambda (key, value): \
66                                    key in return_fields and value is not None
67         nodes = [dict(filter(valid_return_fields_only, node.items())) \
68                  for node in nodes]
69                     
70         return nodes