From: Thierry Parmentelat Date: Fri, 5 Dec 2008 19:53:39 +0000 (+0000) Subject: boot manager assumes the tagname is identical to the initscript conventions X-Git-Tag: PLCAPI-4.3-3~34 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=45c0478d3a722ae04ee9e6b1b1b0f2b31e9ef6f4;p=plcapi.git boot manager assumes the tagname is identical to the initscript conventions --- diff --git a/PLC/Accessors/Accessors_wireless.py b/PLC/Accessors/Accessors_wireless.py index 1b8a7ce..986ebe6 100644 --- a/PLC/Accessors/Accessors_wireless.py +++ b/PLC/Accessors/Accessors_wireless.py @@ -13,7 +13,7 @@ current_module = sys.modules[__name__] #### Wireless -define_accessors(current_module, Interface, "WifiMode", "wifi_mode", "interface/wifi", "Wifi operation mode - see iwconfig", +define_accessors(current_module, Interface, "WifiMode", "mode", "interface/wifi", "Wifi operation mode - see iwconfig", get_roles=all_roles, set_roles=tech_roles) define_accessors(current_module, Interface, "Essid", "essid", "interface/wifi", "Wireless essid - see iwconfig", get_roles=all_roles, set_roles=tech_roles) diff --git a/PLC/Methods/AddNode.py b/PLC/Methods/AddNode.py index 5ddb467..a7f7406 100644 --- a/PLC/Methods/AddNode.py +++ b/PLC/Methods/AddNode.py @@ -2,13 +2,13 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed +from PLC.Table import Row from PLC.Nodes import Node, Nodes from PLC.NodeGroups import NodeGroup, NodeGroups from PLC.Sites import Site, Sites from PLC.Auth import Auth -can_update = lambda (field, value): field in \ - ['hostname', 'node_type', 'boot_state', 'model', 'version'] +can_update = ['hostname', 'node_type', 'boot_state', 'model', 'version'] class AddNode(Method): """ @@ -23,19 +23,23 @@ class AddNode(Method): roles = ['admin', 'pi', 'tech'] - node_fields = dict(filter(can_update, Node.fields.items())) + accepted_fields = Row.accepted_fields(can_update, [Node.fields,Node.tags]) accepts = [ Auth(), Mixed(Site.fields['site_id'], Site.fields['login_base']), - node_fields + accepted_fields ] returns = Parameter(int, 'New node_id (> 0) if successful') def call(self, auth, site_id_or_login_base, node_fields): - node_fields = dict(filter(can_update, node_fields.items())) + + [native,tags,rejected]=Row.split_fields(node_fields,[Node.fields,Node.tags]) + + if rejected: + raise PLCInvalidArgument, "Cannot add Node with column(s) %r"%rejected # Get site information sites = Sites(self.api, [site_id_or_login_base]) @@ -56,10 +60,15 @@ class AddNode(Method): else: assert self.caller['person_id'] in site['person_ids'] - node = Node(self.api, node_fields) + node = Node(self.api, native) node['site_id'] = site['site_id'] node.sync() + if tags: + print 'AddNode: warning, tags not handled yet' + for (k,v) in tags.iteritems(): + print 'tag',k,v + self.event_objects = {'Site': [site['site_id']], 'Node': [node['node_id']]} self.message = "Node %s created" % node['node_id'] diff --git a/PLC/Methods/UpdateNode.py b/PLC/Methods/UpdateNode.py index d6c9e45..9163fa1 100644 --- a/PLC/Methods/UpdateNode.py +++ b/PLC/Methods/UpdateNode.py @@ -2,14 +2,12 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed +from PLC.Table import Row from PLC.Nodes import Node, Nodes from PLC.Auth import Auth -related_fields = Node.related_fields.keys() -can_update = lambda (field, value): field in \ - ['hostname', 'boot_state', 'model', 'version', - 'key', 'session', 'boot_nonce', 'site_id'] + \ - related_fields +can_update = ['hostname', 'boot_state', 'model', 'version','key', 'session', 'boot_nonce', 'site_id'] + \ + Node.related_fields.keys() class UpdateNode(Method): """ @@ -24,7 +22,7 @@ class UpdateNode(Method): roles = ['admin', 'pi', 'tech'] - node_fields = dict(filter(can_update, Node.fields.items() + Node.related_fields.items())) + node_fields = Row.accepted_fields(can_update,[Node.fields,Node.related_fields,Node.tags]) accepts = [ Auth(), @@ -37,22 +35,26 @@ class UpdateNode(Method): def call(self, auth, node_id_or_hostname, node_fields): - node_fields = dict(filter(can_update, node_fields.items())) + # split provided fields + [native,related,tags,rejected] = Row.split_fields(node_fields,[Node.fields,Node.related_fields,Node.tags]) + + if rejected: + raise PLCInvalidArgument, "Cannot update column(s) %r"%rejected # Remove admin only fields if 'admin' not in self.caller['roles']: for key in 'key', 'session', 'boot_nonce', 'site_id': - if node_fields.has_key(key): - del node_fields[key] + if native.has_key(key): + del native[key] # Get account information nodes = Nodes(self.api, [node_id_or_hostname]) if not nodes: - raise PLCInvalidArgument, "No such node" + raise PLCInvalidArgument, "No such node %r"%node_id_or_hostname node = nodes[0] if node['peer_id'] is not None: - raise PLCInvalidArgument, "Not a local node" + raise PLCInvalidArgument, "Not a local node %r"%node_id_or_hostname # Authenticated function assert self.caller is not None @@ -64,14 +66,17 @@ class UpdateNode(Method): raise PLCPermissionDenied, "Not allowed to delete nodes from specified site" # Make requested associations - for field in related_fields: - if field in node_fields: - node.associate(auth, field, node_fields[field]) - node_fields.pop(field) - - node.update(node_fields) - node.update_last_updated(False) - node.sync() + for (k,v) in related.iteritems(): + node.associate(auth, k,v) + + if tags: + print 'UpdateNode: warning, tags not handled yet' + for (k,v) in tags.iteritems(): + print 'tag',k,v + + node.update(native) + node.update_last_updated(commit=False) + node.sync(commit=True) # Logging variables self.event_objects = {'Node': [node['node_id']]} diff --git a/PLC/Nodes.py b/PLC/Nodes.py index a1cea70..db62aae 100644 --- a/PLC/Nodes.py +++ b/PLC/Nodes.py @@ -72,8 +72,6 @@ class Node(Row): related_fields = { 'interfaces': [Mixed(Parameter(int, "Interface identifier"), Filter(Interface.fields))], - 'nodegroups': [Mixed(Parameter(int, "NodeGroup identifier"), - Parameter(str, "NodeGroup name"))], 'conf_files': [Parameter(int, "ConfFile identifier")], 'slices': [Mixed(Parameter(int, "Slice identifier"), Parameter(str, "Slice name"))], @@ -82,6 +80,7 @@ class Node(Row): } view_tags_name = "view_node_tags" + # tags declared here should also be defined as Accessors to ensure that the TagType is created tags = { # regular 'arch': Parameter(str, "node/config", ro=True), diff --git a/PLC/Table.py b/PLC/Table.py index 2ce8bb7..a86e21e 100644 --- a/PLC/Table.py +++ b/PLC/Table.py @@ -223,17 +223,48 @@ class Row(dict): return dict ( [ (key,value) for (key,value) in obj.iteritems() if key in self.tags and Row.is_writable(key,value,self.tags) ] ) - # takes in input a list of columns, returns three lists + # takes in input a list of columns, returns 2 dicts and one list # fields, tags, rejected @classmethod def parse_columns (cls, columns): - (fields,tags,rejected)=({},{},{}) + (fields,tags,rejected)=({},{},[]) for column in columns: if column in cls.fields: fields[column]=cls.fields[column] elif column in cls.tags: tags[column]=cls.tags[column] else: rejected.append(column) return (fields,tags,rejected) + # given a dict (typically passed to an Update method), we check and sort + # them against a list of dicts, e.g. [Node.fields, Node.related_fields] + # return is a list that contains n+1 dicts, last one has the rejected fields + @staticmethod + def split_fields (fields, dicts): + result=[] + for x in dicts: result.append({}) + rejected={} + for (field,value) in fields.iteritems(): + found=False + for i in range(len(dicts)): + candidate_dict=dicts[i] + if field in candidate_dict.keys(): + result[i][field]=value + found=True + break + if not found: rejected[field]=value + result.append(rejected) + return result + + # compute the accepts part of an update method from a list of column names, and a (list of) field dict + @staticmethod + def accepted_fields (can_update_columns, fields): + result={} + if not isinstance(fields,list): fields = [fields] + for dict in fields: + for (k,v) in dict.iteritems(): + if k in can_update_columns: + result[k]=v + return result + @classmethod def tagvalue_view_name (cls, tagname): return "tagvalue_view_%s_%s"%(cls.primary_key,tagname)