From f21c95741c88265a6d40a067877c9fdea13d0ac9 Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Thu, 20 Oct 2011 16:24:33 -0400 Subject: [PATCH] support pgv2 links in the ProtoGENI and SFA RSpec --- sfa/rspecs/elements/interface.py | 11 +++++ sfa/rspecs/elements/link.py | 34 ++++++++----- sfa/rspecs/elements/versions/pgv2Link.py | 61 ++++++++++++++++++++++++ sfa/rspecs/versions/pgv2.py | 10 +++- sfa/rspecs/versions/sfav1.py | 30 ++++-------- 5 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 sfa/rspecs/elements/interface.py create mode 100644 sfa/rspecs/elements/versions/pgv2Link.py diff --git a/sfa/rspecs/elements/interface.py b/sfa/rspecs/elements/interface.py new file mode 100644 index 00000000..d2022d89 --- /dev/null +++ b/sfa/rspecs/elements/interface.py @@ -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) + + diff --git a/sfa/rspecs/elements/link.py b/sfa/rspecs/elements/link.py index 682232e1..4722cf83 100644 --- a/sfa/rspecs/elements/link.py +++ b/sfa/rspecs/elements/link.py @@ -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 index 00000000..ee343716 --- /dev/null +++ b/sfa/rspecs/elements/versions/pgv2Link.py @@ -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 + + diff --git a/sfa/rspecs/versions/pgv2.py b/sfa/rspecs/versions/pgv2.py index 1bf922d6..97099d19 100644 --- a/sfa/rspecs/versions/pgv2.py +++ b/sfa/rspecs/versions/pgv2.py @@ -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: diff --git a/sfa/rspecs/versions/sfav1.py b/sfa/rspecs/versions/sfav1.py index 2481152f..43ea6f31 100644 --- a/sfa/rspecs/versions/sfav1.py +++ b/sfa/rspecs/versions/sfav1.py @@ -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 -- 2.43.0