support pgv2 links in the ProtoGENI and SFA RSpec
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 20 Oct 2011 20:24:33 +0000 (16:24 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 20 Oct 2011 20:24:33 +0000 (16:24 -0400)
sfa/rspecs/elements/interface.py [new file with mode: 0644]
sfa/rspecs/elements/link.py
sfa/rspecs/elements/versions/pgv2Link.py [new file with mode: 0644]
sfa/rspecs/versions/pgv2.py
sfa/rspecs/versions/sfav1.py

diff --git a/sfa/rspecs/elements/interface.py b/sfa/rspecs/elements/interface.py
new file mode 100644 (file)
index 0000000..d2022d8
--- /dev/null
@@ -0,0 +1,11 @@
+class Interface(dict):
+    fields = {'component_id': None,
+              'role': None,
+              'client_id': None,
+              'ipv4': None 
+    }    
+    def __init__(self, fields={}):
+        dict.__init__(self, Interface.fields)
+        self.update(fields)
+        
+    
index 682232e..4722cf8 100644 (file)
@@ -1,14 +1,22 @@
-from sfa.rspec.elements.interface import Interface
+from sfa.rspecs.elements.interface import Interface
+
+class Link(dict):
+    
+    fields = {
+        'client_id': None, 
+        'component_id': None,
+        'component_name': None,
+        'component_manager': None,
+        'type': None,
+        'interface1': None,
+        'interface2': None,
+        'capacity': None,
+        'latency': None,
+        'packet_loss': None,
+        'description': None,
+    }
+    
+    def __init__(self, fields={}):
+        dict.__init__(self, Link.fields)
+        self.update(fields)
 
-class Link:
-    def __init__(self):
-        self.component_id = None
-        self.component_name = None
-        self.component_manager_id = None
-        self.type = None
-        self.endpoint1 = Interface()
-        self.endpoint2 = Interface()
-        self.capacity = None
-        self.latency = None
-        self.packet_loss = None
-        self.description = None
diff --git a/sfa/rspecs/elements/versions/pgv2Link.py b/sfa/rspecs/elements/versions/pgv2Link.py
new file mode 100644 (file)
index 0000000..ee34371
--- /dev/null
@@ -0,0 +1,61 @@
+from lxml import etree
+from sfa.rspecs.elements.link import Link
+from sfa.rspecs.elements.interface import Interface
+
+class PGv2Link:
+    
+    @staticmethod
+    def add_links(xml, links):
+        for link in links:
+            link_elem = etree.SubElement(xml, 'link')
+            for attrib in ['component_name', 'component_id', 'client_id']:
+                if attrib in link and link[attrib]:
+                    link_elem.set(attrib, link[attrib])
+            if 'component_manager' in link and link['component_manger']:
+                cm_element = etree.SubElement(xml, 'component_manager', name=link['component_manager'])
+            if_ref1 = etree.SubElement(xml, 'interface_ref', component_id=link['interface1']['component_id'])
+            if_ref2 = etree.SubElement(xml, 'interface_ref', component_id=link['interface2']['component_id'])
+            prop1 = etree.SubElement(xml, 'property', source_id = link['interface1']['component_id'],
+                dest_id = link['interface2']['component_id'], capacity=link['capacity'], 
+                latency=link['latency'], packet_loss=link['packet_loss'])
+            prop2 = etree.SubElement(xml, 'property', source_id = link['interface2']['component_id'],
+                dest_id = link['interface1']['component_id'], capacity=link['capacity'], 
+                latency=link['latency'], packet_loss=link['packet_loss'])
+            if 'type' in link and link['type']:
+                type_elem = etree.SubElement(xml, 'link_type', name=link['type'])             
+             
+    @staticmethod 
+    def get_links(xml, namespaces=None):
+        links = []
+        link_elems = xml.xpath('//default:link', namespaces=namespaces)
+        for link_elem in link_elems:
+            # set client_id, component_id, component_name
+            link = Link(link_elem.attrib)
+            # set component manager
+            cm = link_elem.xpath('./default:component_manager', namespaces=namespaces)
+            if len(cm) >  0:
+                cm = cm[0]
+                if  'name' in cm.attrib:
+                    link['component_manager'] = cm.attrib['name'] 
+            # set link type
+            link_types = link_elem.xpath('./default:link_type', namespaces=namespaces)
+            if len(link_types) > 0:
+                link_type = link_types[0]
+                if 'name' in link_type.attrib:
+                    link['type'] = link_type.attrib['name']
+          
+            # get capacity, latency and packet_loss and interfaces from first property  
+            props = link_elem.xpath('./default:property', namespaces=namespaces)
+            if len(props) > 0:
+                prop = props[0]
+                if 'source_id' in prop.attrib:
+                    link['interface1'] = Interface({'component_id': prop.attrib['source_id']}) 
+                if 'dest_id' in prop.attrib:
+                    link['interface2'] = Interface({'component_id': prop.attrib['dest_id']})
+                for attrib in ['capacity', 'latency', 'packet_loss']:
+                    if attrib in prop.attrib:
+                        link[attrib] = prop.attrib[attrib]
+            links.append(link)
+        return links 
+            
+        
index 1bf922d..97099d1 100644 (file)
@@ -5,7 +5,8 @@ from sfa.util.xrn import *
 from sfa.util.plxrn import hostname_to_urn, xrn_to_hostname 
 from sfa.rspecs.rspec_version import BaseVersion
 from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements
-
+from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
 class PGv2(BaseVersion):
     type = 'ProtoGENI'
     content_type = 'ad'
@@ -95,6 +96,13 @@ class PGv2(BaseVersion):
 
         return slice_attributes
 
+    def get_links(self, network=None):
+        links = PGv2Link.get_links(self.xml, self.namespaces)
+        return links
+
+    def add_links(self, links):
+        PGv2Link.add_links(self.xml, links)
+
     def attributes_list(self, elem):
         opts = []
         if elem is not None:
index 2481152..43ea6f3 100644 (file)
@@ -2,6 +2,7 @@ from lxml import etree
 from sfa.util.xrn import hrn_to_urn, urn_to_hrn
 from sfa.rspecs.rspec_version import BaseVersion
 from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements
+from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
 
 class SFAv1(BaseVersion):
     enabled = True
@@ -116,18 +117,8 @@ class SFAv1(BaseVersion):
         return nodes
 
     def get_links(self, network=None):
-        if network:
-            links = self.xml.xpath('//network[@name="%s"]/link' % network)
-        else:
-            links = self.xml.xpath('//link')
-        linklist = []
-        for link in links:
-            (end1, end2) = link.get("endpoints").split()
-            name = link.find("description")
-            linklist.append((name.text,
-                             self.get_site_nodes(end1, network),
-                             self.get_site_nodes(end2, network)))
-        return linklist
+        links = PGv2Link.get_links(self.xml, self.namespaces)
+        return links
 
     def get_link(self, fromnode, tonode, network=None):
         fromsite = fromnode.getparent()
@@ -222,9 +213,13 @@ class SFAv1(BaseVersion):
                 node_tag.set('component_name', node['hostname']) 
                 hostname_tag = etree.SubElement(node_tag, 'hostname').text = node['hostname']
             if 'interfaces' in node:
+                i = 0
                 for interface in node['interfaces']:
                     if 'bwlimit' in interface and interface['bwlimit']:
                         bwlimit = etree.SubElement(node_tag, 'bw_limit', units='kbps').text = str(interface['bwlimit']/1000)
+                    comp_id = hrn_to_urn(network, 'pc%s:eth%s' % (node['node_id'], i)) 
+                    interface_tag = etree.SubElement(node_tag, 'interface', component_id=comp_id)
+                    i+=1
             if 'bw_unallocated' in node:
                 bw_unallocated = etree.SubElement(node_tag, 'bw_unallocated', units='kbps').text = str(node['bw_unallocated']/1000) 
             if 'tags' in node:
@@ -251,16 +246,7 @@ class SFAv1(BaseVersion):
         pass
 
     def add_links(self, links):
-        for link in links:
-            network_tag = self.xml.root
-            if link.component_manager_id != None:
-                network_hrn, type = urn_to_hrn(link.component_manager_id)
-                network_tag = self.add_network(network) 
-
-            link_elem = etree.SubElement(network_tag, 'link')
-            link_elem.set('endpoints', '%s %s' % (link.endpoint1.name, link.endpoint2.name))
-            description = etree.SubElement(link_elem, 'description').text = link.description
-            bw_unallocated = etree.SubElement(link_elem, 'bw_unallocated', units='kbps').text = link.capacity  
+        PGv2Link.add_links(self.xml, links)
 
     def add_slivers(self, slivers, network=None, sliver_urn=None, no_dupes=False, append=False):
         # add slice name to network tag