Store node's hrn (SFA specific human readable name) using the 'hrn' tag. This tag...
authorTony Mack <tmack@cs.princeton.edu>
Thu, 11 Mar 2010 22:24:08 +0000 (22:24 +0000)
committerTony Mack <tmack@cs.princeton.edu>
Thu, 11 Mar 2010 22:24:08 +0000 (22:24 +0000)
PLC/Methods/AddNode.py
PLC/Methods/UpdateNode.py
PLC/Namespace.py [new file with mode: 0644]
PLC/Peers.py

index 8403162..90cf14f 100644 (file)
@@ -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}):
index 04d1036..dbcc2b4 100644 (file)
@@ -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 (file)
index 0000000..2d41fea
--- /dev/null
@@ -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
index b2cb738..e78f568 100644 (file)
@@ -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):
         """