3 from PLC.Faults import *
4 from PLC.Auth import Auth
5 from PLC.Method import Method
6 from PLC.Parameter import Parameter, Mixed
7 from PLC.Table import Row
8 from PLC.Namespace import hostname_to_hrn
9 from PLC.Peers import Peers
10 from PLC.Sites import Site, Sites
11 from PLC.Nodes import Node, Nodes
12 from PLC.TagTypes import TagTypes
13 from PLC.NodeTags import NodeTags
14 from PLC.Methods.AddNodeTag import AddNodeTag
15 from PLC.Methods.UpdateNodeTag import UpdateNodeTag
17 can_update = ['hostname', 'node_type', 'boot_state', 'model', 'version']
19 class AddNode(Method):
21 Adds a new node. Any values specified in node_fields are used,
22 otherwise defaults are used.
24 PIs and techs may only add nodes to their own sites. Admins may
25 add nodes to any site.
27 Returns the new node_id (> 0) if successful, faults otherwise.
30 roles = ['admin', 'pi', 'tech']
32 accepted_fields = Row.accepted_fields(can_update,Node.fields)
33 accepted_fields.update(Node.tags)
37 Mixed(Site.fields['site_id'],
38 Site.fields['login_base']),
42 returns = Parameter(int, 'New node_id (> 0) if successful')
44 def call(self, auth, site_id_or_login_base, node_fields):
46 [native,tags,rejected]=Row.split_fields(node_fields,[Node.fields,Node.tags])
49 native = Row.check_fields(native, self.accepted_fields)
51 raise PLCInvalidArgument, "Cannot add Node with column(s) %r"%rejected
53 # Get site information
54 sites = Sites(self.api, [site_id_or_login_base])
56 raise PLCInvalidArgument, "No such site"
60 # Authenticated function
61 assert self.caller is not None
63 # If we are not an admin, make sure that the caller is a
65 if 'admin' not in self.caller['roles']:
66 if site['site_id'] not in self.caller['site_ids']:
67 assert self.caller['person_id'] not in site['person_ids']
68 raise PLCPermissionDenied, "Not allowed to add nodes to specified site"
70 assert self.caller['person_id'] in site['person_ids']
72 node = Node(self.api, native)
73 node['site_id'] = site['site_id']
76 # since hostname was specified lets add the 'hrn' node tag
77 root_auth = self.api.config.PLC_HRN_ROOT
78 login_base = site['login_base']
79 tags['hrn'] = hostname_to_hrn(root_auth, login_base, node['hostname'])
81 for (tagname,value) in tags.iteritems():
82 # the tagtype instance is assumed to exist, just check that
83 if not TagTypes(self.api,{'tagname':tagname}):
84 raise PLCInvalidArgument,"No such TagType %s"%tagname
85 node_tags=NodeTags(self.api,{'tagname':tagname,'node_id':node['node_id']})
87 AddNodeTag(self.api).__call__(auth,node['node_id'],tagname,value)
89 UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],value)
91 self.event_objects = {'Site': [site['site_id']],
92 'Node': [node['node_id']]}
93 self.message = "Node %d=%s created" % (node['node_id'],node['hostname'])
95 return node['node_id']