From: Tony Mack Date: Thu, 11 Mar 2010 22:24:08 +0000 (+0000) Subject: Store node's hrn (SFA specific human readable name) using the 'hrn' tag. This tag... X-Git-Tag: PLCAPI-5.0-3^2~14 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=b4b902d85a7966403dc09cc1c3f0da8a07b7a1e9;p=plcapi.git Store node's hrn (SFA specific human readable name) using the 'hrn' tag. This tag is automatically added to the node when AddNode() is called and is updated when either UpdateNode(), Peer.add_node(), Peer.remove_node() is called --- diff --git a/PLC/Methods/AddNode.py b/PLC/Methods/AddNode.py index 8403162..90cf14f 100644 --- a/PLC/Methods/AddNode.py +++ b/PLC/Methods/AddNode.py @@ -5,7 +5,8 @@ from PLC.Auth import Auth from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Table import Row - +from PLC.Namespace import hostname_to_hrn +from PLC.Peers import Peers from PLC.Sites import Site, Sites from PLC.Nodes import Node, Nodes from PLC.TagTypes import TagTypes @@ -72,6 +73,14 @@ class AddNode(Method): node['site_id'] = site['site_id'] node.sync() + # since hostname was specified lets add the 'hrn' node tag + root_auth = self.api.config.PLC_HRN_ROOT + # sub auth is the login base of this node's site + sites = Sites(self.api, node['site_id'], ['login_base']) + site = sites[0] + login_base = site['login_base'] + tags['hrn'] = hostname_to_hrn(root_auth, login_base, node['hostname']) + for (tagname,value) in tags.iteritems(): # the tagtype instance is assumed to exist, just check that if not TagTypes(self.api,{'tagname':tagname}): diff --git a/PLC/Methods/UpdateNode.py b/PLC/Methods/UpdateNode.py index 04d1036..dbcc2b4 100644 --- a/PLC/Methods/UpdateNode.py +++ b/PLC/Methods/UpdateNode.py @@ -5,7 +5,9 @@ from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Table import Row from PLC.Auth import Auth - +from PLC.Namespace import hostname_to_hrn +from PLC.Peers import Peers +from PLC.Sites import Sites from PLC.Nodes import Node, Nodes from PLC.TagTypes import TagTypes from PLC.NodeTags import NodeTags @@ -55,8 +57,8 @@ class UpdateNode(Method): # Authenticated function assert self.caller is not None - # Remove admin only fields - if 'admin' not in self.caller['roles']: + # Remove admin only fields + if 'admin' not in self.caller['roles']: for key in admin_only: if native.has_key(key): del native[key] @@ -80,10 +82,27 @@ class UpdateNode(Method): for (k,v) in related.iteritems(): node.associate(auth, k,v) - node.update(native) - node.update_last_updated(commit=False) + node.update(native) + node.update_last_updated(commit=False) node.sync(commit=True) - + + # if hostname was modifed make sure to update the hrn + # tag + if 'hostname' in native: + # root authority should be PLC_HRN_ROOT for local + # objects or peer['hrn_root'] for peer objects + root_auth = self.api.config.PLC_HRN_ROOT + if node['peer_id']: + peers = Peers(self.api, node['peer_id'], ['hrn_root']) + if peers: + root_auth = peers[0]['hrn_root'] + + # sub auth is the login base of this node's site + sites = Sites(self.api, node['site_id'], ['login_base']) + site = sites[0] + login_base = site['login_base'] + tags['hrn'] = hostname_to_hrn(root_auth, login_base, node['hostname']) + for (tagname,value) in tags.iteritems(): # the tagtype instance is assumed to exist, just check that if not TagTypes(self.api,{'tagname':tagname}): @@ -94,14 +113,14 @@ class UpdateNode(Method): else: UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],value) - # Logging variables - self.event_objects = {'Node': [node['node_id']]} + # Logging variables + self.event_objects = {'Node': [node['node_id']]} if 'hostname' in node: self.message = 'Node %s updated'%node['hostname'] else: self.message = 'Node %d updated'%node['node_id'] self.message += " [%s]." % (", ".join(node_fields.keys()),) - if 'boot_state' in node_fields.keys(): - self.message += ' boot_state updated to %s' % node_fields['boot_state'] + if 'boot_state' in node_fields.keys(): + self.message += ' boot_state updated to %s' % node_fields['boot_state'] return 1 diff --git a/PLC/Namespace.py b/PLC/Namespace.py new file mode 100644 index 0000000..2d41fea --- /dev/null +++ b/PLC/Namespace.py @@ -0,0 +1,89 @@ +### $Id: Namespace.py +### $URL: + +URN_PREFIX = "urn:publicid:IDN" + +def get_leaf(hrn): + parts = hrn.split(".") + return ".".join(parts[-1:]) + +def get_authority(hrn): + parts = hrn.split(".") + return ".".join(parts[:-1]) + +def hrn_to_pl_slicename(hrn): + parts = hrn.split(".") + return parts[-2] + "_" + parts[-1] + +# assuming hrn is the hrn of an authority, return the plc authority name +def hrn_to_pl_authname(hrn): + parts = hrn.split(".") + return parts[-1] + +# assuming hrn is the hrn of an authority, return the plc login_base +def hrn_to_pl_login_base(hrn): + return hrn_to_pl_authname(hrn) + +def hostname_to_hrn(auth_hrn, login_base, hostname): + """ + Convert hrn to plantelab name. + """ + sfa_hostname = ".".join([auth_hrn, login_base, hostname.split(".")[0]]) + return sfa_hostname + +def slicename_to_hrn(auth_hrn, slicename): + """ + Convert hrn to planetlab name. + """ + parts = slicename.split("_") + slice_hrn = ".".join([auth_hrn, parts[0]]) + "." + "_".join(parts[1:]) + + return slice_hrn + +def email_to_hrn(auth_hrn, email): + parts = email.split("@") + username = parts[0] + username = username.replace(".", "_") + person_hrn = ".".join([auth_hrn, username]) + + return person_hrn + +def urn_to_hrn(urn): + """ + convert a urn to hrn + return a tuple (hrn, type) + """ + + # if this is already a hrn dont do anything + if not urn or not urn.startswith(URN_PREFIX): + return urn, None + + name = urn[len(URN_PREFIX):] + hrn_parts = name.split("+") + + # type is always the second to last element in the list + type = hrn_parts.pop(-2) + + # convert hrn_parts (list) into hrn (str) by doing the following + # remove blank elements + # replace ':' with '.' + # join list elements using '.' + hrn = '.'.join([part.replace(':', '.') for part in hrn_parts if part]) + + return str(hrn), str(type) + + +def hrn_to_urn(hrn, type=None): + """ + convert an hrn and type to a urn string + """ + # if this is already a urn dont do anything + if not hrn or hrn.startswith(URN_PREFIX): + return hrn + + authority = get_authority(hrn) + name = get_leaf(hrn) + urn = "+".join([unicode(part).replace('.', ':') \ + for part in ['',authority,type,name]]) + + return URN_PREFIX + urn diff --git a/PLC/Peers.py b/PLC/Peers.py index b2cb738..e78f568 100644 --- a/PLC/Peers.py +++ b/PLC/Peers.py @@ -13,7 +13,7 @@ from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter from PLC.Table import Row, Table import PLC.Auth - +from PLC.Shell import * from PLC.Sites import Site, Sites from PLC.Persons import Person, Persons from PLC.Keys import Key, Keys @@ -164,6 +164,13 @@ class Peer(Row): 'peer_node_id': peer_node_id}, commit = commit) + # calling UpdateNode with the node's hostname + # will force the 'hrn' tag to be updated with the + # correct root auth + shell = Shell() + UpdateNode = self.api.callable('UpdateNode') + UpdateNode(shell.auth, node['node_id'], {'hostname': node['hostname']}) + def remove_node(self, node, commit = True): """ Unassociate a node with this peer. @@ -171,6 +178,8 @@ class Peer(Row): remove = Row.remove_object(Node, 'peer_node') remove(self, node, commit) + UpdateNode = self.api.callable('UpdateNode') + UpdateNode(shell.auth, node['node_id'], {'hostname': node['hostname']}) def add_slice(self, slice, peer_slice_id, commit = True): """