Initial checkin of new API implementation
[plcapi.git] / PLC / Methods / AdmGetSiteNodes.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.Sites import Site, Sites
7 from PLC.Nodes import Node, Nodes
8 from PLC.Auth import PasswordAuth
9
10 class AdmGetSiteNodes(Method):
11     """
12     Return a dictionary containing a list of node_ids for the  sites specified.
13
14     Admins may retrieve details about all nodes on a site by not specifying
15     site_id_or_name 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     """
20
21     roles = ['admin', 'pi', 'user', 'tech']
22
23     accepts = [
24         PasswordAuth(),
25         [Mixed(Site.fields['site_id'],
26                Site.fields['name'])],
27         Parameter([str], 'List of fields to return')
28         ]
29
30     # Filter out hidden fields
31     #can_return = lambda (field, value): field not in ['deleted']
32     #return_fields = dict(filter(can_return, Site.all_fields.items()))
33     return_fields=['site_id', 'node_ids']
34     returns = [return_fields]
35
36     def __init__(self, *args, **kwds):
37         Method.__init__(self, *args, **kwds)
38         # Update documentation with list of default fields returned
39         self.__doc__ += os.linesep.join(Site.default_fields.keys())
40
41     def call(self, auth, site_id_or_name_list = None):
42         # Authenticated function
43         assert self.caller is not None
44         #copy list of fields to return
45         return_fields=self.return_fields
46
47         #convert site_id_or_name_list to 'None' if is [] (empty list)
48         if site_id_or_name_list is not None and site_id_or_name_list == []:
49                 site_id_or_name_list = None
50
51         # Get site information
52         sites = Sites(self.api, site_id_or_name_list, return_fields).values()   
53
54         # make sure sites are found
55         if not sites:
56                 raise PLCInvalidArgument, "No such site"
57         elif site_id_or_name_list is None:
58                 pass
59         elif not len(sites) == len(site_id_or_name_list):
60                 raise PLCInvalidArgument, "at least one site_id is invalid"
61
62         # Filter out undesired or None fields (XML-RPC cannot marshal
63         # None) and turn each node into a real dict.
64         valid_return_fields_only = lambda (key, value): \
65                                    key in return_fields and value is not None
66         sites = [dict(filter(valid_return_fields_only, site.items())) \
67                  for site in sites]
68         
69         #Convert list of sites dictionaries into a dictionary of sites -> sites:[node_ids]
70         site_nodes = {}
71         for site in sites:
72                 # Filter out deleted Nodes.  Nodes(...) will not reuturn deleted nodes
73                 # XXX This shouldn't be necssary once the join tables are cleaned up
74                 nodes = Nodes(self.api, site['node_ids'])
75                 #creat valid node list dictionary
76                 site_nodes[str(site['site_id'])] = nodes.keys()
77                 
78         return site_nodes