From: Thierry Parmentelat Date: Sun, 6 Nov 2011 19:59:24 +0000 (+0100) Subject: Merge branch 'thgeneric' X-Git-Tag: sfa-1.1-2~1 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=89d0fa4efde57cb62445af75c16bdc42bc03693a;hp=561044a25626b0c874f644886539ede0053967fc Merge branch 'thgeneric' introduce the notion of driver, with PlDriver (that inherits PlShell) --- diff --git a/setup.py b/setup.py index 698b3883..a9735a0b 100755 --- a/setup.py +++ b/setup.py @@ -43,7 +43,6 @@ package_dirs = [ 'sfa/methods', 'sfa/generic', 'sfa/managers', - 'sfa/managers/vini', 'sfa/importer', 'sfa/plc', 'sfa/rspecs', diff --git a/sfa/rspecs/elements/bwlimit.py b/sfa/rspecs/elements/bwlimit.py new file mode 100644 index 00000000..027bb5b3 --- /dev/null +++ b/sfa/rspecs/elements/bwlimit.py @@ -0,0 +1,8 @@ +from sfa.rspecs.elements.element import Element + +class BWlimit(Element): + fields = { + 'units': None, + 'value': None, + } + diff --git a/sfa/rspecs/elements/component_manager.py b/sfa/rspecs/elements/component_manager.py new file mode 100644 index 00000000..ec9d85c9 --- /dev/null +++ b/sfa/rspecs/elements/component_manager.py @@ -0,0 +1,7 @@ +from sfa.rspecs.elements.element import Element + +class ComponentManager(Element): + fields = { + 'name': None, + } + diff --git a/sfa/rspecs/elements/disk_image.py b/sfa/rspecs/elements/disk_image.py new file mode 100644 index 00000000..3a810a58 --- /dev/null +++ b/sfa/rspecs/elements/disk_image.py @@ -0,0 +1,4 @@ +from sfa.rspecs.elements.element import Element + +class DiskImage(Element): + fields = {} diff --git a/sfa/rspecs/elements/element.py b/sfa/rspecs/elements/element.py index 401ca313..6757f8a8 100644 --- a/sfa/rspecs/elements/element.py +++ b/sfa/rspecs/elements/element.py @@ -1,85 +1,9 @@ -from lxml import etree +class Element(dict): -class Element: - def __init__(self, root_node, namespaces = None): - self.root_node = root_node - self.namespaces = namespaces + fields = {} - def xpath(self, xpath): - return this.root_node.xpath(xpath, namespaces=self.namespaces) + def __init__(self, fields={}, element=None): + self.element = element + dict.__init__(self, self.fields) + self.update(fields) - def add_element(self, name, attrs={}, parent=None, text=""): - """ - Wrapper around etree.SubElement(). Adds an element to - specified parent node. Adds element to root node is parent is - not specified. - """ - if parent == None: - parent = self.root_node - element = etree.SubElement(parent, name) - if text: - element.text = text - if isinstance(attrs, dict): - for attr in attrs: - element.set(attr, attrs[attr]) - return element - - def remove_element(self, element_name, root_node = None): - """ - Removes all occurences of an element from the tree. Start at - specified root_node if specified, otherwise start at tree's root. - """ - if not root_node: - root_node = self.root_node - - if not element_name.startswith('//'): - element_name = '//' + element_name - - elements = root_node.xpath('%s ' % element_name, namespaces=self.namespaces) - for element in elements: - parent = element.getparent() - parent.remove(element) - - - def add_attribute(self, elem, name, value): - """ - Add attribute to specified etree element - """ - opt = etree.SubElement(elem, name) - opt.text = value - - def remove_attribute(self, elem, name, value): - """ - Removes an attribute from an element - """ - if not elem == None: - opts = elem.iterfind(name) - if opts is not None: - for opt in opts: - if opt.text == value: - elem.remove(opt) - - def get_attributes(self, elem=None, depth=None): - if elem == None: - elem = self.root_node - attrs = dict(elem.attrib) - attrs['text'] = str(elem.text).strip() - if depth is None or isinstance(depth, int) and depth > 0: - for child_elem in list(elem): - key = str(child_elem.tag) - if key not in attrs: - attrs[key] = [self.get_attributes(child_elem, recursive)] - else: - attrs[key].append(self.get_attributes(child_elem, recursive)) - return attrs - - def attributes_list(self, elem): - # convert a list of attribute tags into list of tuples - # (tagnme, text_value) - opts = [] - if not elem == None: - for e in elem: - opts.append((e.tag, e.text)) - return opts - - diff --git a/sfa/rspecs/elements/execute.py b/sfa/rspecs/elements/execute.py new file mode 100644 index 00000000..43e6e626 --- /dev/null +++ b/sfa/rspecs/elements/execute.py @@ -0,0 +1,7 @@ +from sfa.rspecs.elements.element import Element + +class Execute(Element): + fields = { + 'shell': None, + 'command': None, + } diff --git a/sfa/rspecs/elements/hardware_type.py b/sfa/rspecs/elements/hardware_type.py new file mode 100644 index 00000000..8dd959c2 --- /dev/null +++ b/sfa/rspecs/elements/hardware_type.py @@ -0,0 +1,7 @@ +from sfa.rspecs.elements.element import Element + +class HardwareType(Element): + + fields = { + 'name': None, + } diff --git a/sfa/rspecs/elements/install.py b/sfa/rspecs/elements/install.py new file mode 100644 index 00000000..1df60b68 --- /dev/null +++ b/sfa/rspecs/elements/install.py @@ -0,0 +1,8 @@ +from sfa.rspecs.elements.element import Element + +class Install(Element): + fields = { + 'file_type': None, + 'url': None, + 'install_path': None, + } diff --git a/sfa/rspecs/elements/interface.py b/sfa/rspecs/elements/interface.py index 2aadf4db..7617ade0 100644 --- a/sfa/rspecs/elements/interface.py +++ b/sfa/rspecs/elements/interface.py @@ -1,13 +1,12 @@ -class Interface(dict): - element = None +from sfa.rspecs.elements.element import Element + +class Interface(Element): fields = {'component_id': None, 'role': None, 'client_id': None, 'ipv4': None, - } - def __init__(self, fields={}, element=None): - self.element = element - dict.__init__(self, Interface.fields) - self.update(fields) - + 'bwlimit': None, + 'node_id': None, + 'interface_id': None + } diff --git a/sfa/rspecs/elements/link.py b/sfa/rspecs/elements/link.py index d916d22f..02a8d102 100644 --- a/sfa/rspecs/elements/link.py +++ b/sfa/rspecs/elements/link.py @@ -1,7 +1,6 @@ -from sfa.rspecs.elements.interface import Interface +from sfa.rspecs.elements.element import Element -class Link(dict): - element = None +class Link(Element): fields = { 'client_id': None, 'component_id': None, @@ -15,9 +14,3 @@ class Link(dict): 'packet_loss': None, 'description': None, } - - def __init__(self, fields={}, element=None): - self.element = element - dict.__init__(self, Link.fields) - self.update(fields) - diff --git a/sfa/rspecs/elements/link_type.py b/sfa/rspecs/elements/link_type.py new file mode 100644 index 00000000..882903d1 --- /dev/null +++ b/sfa/rspecs/elements/link_type.py @@ -0,0 +1,6 @@ +from sfa.rspecs.elements.element import Element + +class LinkType(Element): + fields = { + 'name': None, + } diff --git a/sfa/rspecs/elements/location.py b/sfa/rspecs/elements/location.py new file mode 100644 index 00000000..a5a92603 --- /dev/null +++ b/sfa/rspecs/elements/location.py @@ -0,0 +1,9 @@ +from sfa.rspecs.elements.element import Element + +class Location(Element): + + fields = { + 'country': None, + 'longitude': None, + 'latitude': None, + } diff --git a/sfa/rspecs/elements/login.py b/sfa/rspecs/elements/login.py new file mode 100644 index 00000000..a64c7598 --- /dev/null +++ b/sfa/rspecs/elements/login.py @@ -0,0 +1,8 @@ +from sfa.rspecs.elements.element import Element + +class Login(Element): + fields = { + 'authentication': None, + 'hostname': None, + 'port': None + } diff --git a/sfa/rspecs/elements/network.py b/sfa/rspecs/elements/network.py index 6a358a46..362b9ffb 100644 --- a/sfa/rspecs/elements/network.py +++ b/sfa/rspecs/elements/network.py @@ -1,11 +1,9 @@ from sfa.rspecs.elements.element import Element -from sfa.util.sfalogging import logger - + class Network(Element): - - def get_networks(*args, **kwds): - logger.info("sfa.rspecs.networks: get_networks not implemented") - - def add_networks(*args, **kwds): - logger.info("sfa.rspecs.networks: add_network not implemented") - + + fields = { + 'name': None, + } + + diff --git a/sfa/rspecs/elements/node.py b/sfa/rspecs/elements/node.py index db6e1196..a2e11cd5 100644 --- a/sfa/rspecs/elements/node.py +++ b/sfa/rspecs/elements/node.py @@ -1,13 +1,22 @@ from sfa.rspecs.elements.element import Element -from sfa.util.faults import SfaNotImplemented -from sfa.util.sfalogging import logger class Node(Element): - - def get_nodes(*args): - logger.info("sfa.rspecs.nodes: get_nodes not implemented") - def add_nodes(*args): - logger.info("sfa.rspecs.nodes: add_nodes not implemented") + fields = { + 'component_id': None, + 'component_name': None, + 'component_manager_id': None, + 'authority_id': None, + 'exclusive': None, + 'location': None, + 'bw_unallocated': None, + 'bw_limit': None, + 'boot_state': None, + 'slivers': [], + 'hardware_type': [], + 'disk_image': [], + 'interfaces': [], + 'tags': [], + } diff --git a/sfa/rspecs/elements/pl_tag.py b/sfa/rspecs/elements/pl_tag.py new file mode 100644 index 00000000..51b1e765 --- /dev/null +++ b/sfa/rspecs/elements/pl_tag.py @@ -0,0 +1,9 @@ +from sfa.rspecs.elements.element import Element + +class PLTag(Element): + + fields = { + 'name': None, + 'value': None, + } + diff --git a/sfa/rspecs/elements/property.py b/sfa/rspecs/elements/property.py new file mode 100644 index 00000000..97a1ffcb --- /dev/null +++ b/sfa/rspecs/elements/property.py @@ -0,0 +1,12 @@ +from sfa.rspecs.elements.element import Element + +class Property(Element): + + fields = { + 'source_id': None, + 'dest_id': None, + 'capacity': None, + 'latency': None, + 'packet_loss': None, + } + diff --git a/sfa/rspecs/elements/services.py b/sfa/rspecs/elements/services.py new file mode 100644 index 00000000..a48be27a --- /dev/null +++ b/sfa/rspecs/elements/services.py @@ -0,0 +1,10 @@ +from sfa.rspecs.elements.element import Element + +class Services(Element): + + fields = { + 'install': [], + 'execute': [], + 'login': [], + } + diff --git a/sfa/rspecs/elements/sliver.py b/sfa/rspecs/elements/sliver.py index 67105dc1..febb0681 100644 --- a/sfa/rspecs/elements/sliver.py +++ b/sfa/rspecs/elements/sliver.py @@ -1,29 +1,9 @@ from sfa.rspecs.elements.element import Element -from sfa.util.sfalogging import logger -class Slivers(Element): - - def get_slivers(*args, **kwds): - logger.debug("sfa.rspecs.slivers: get_slivers not implemented") - - def add_slivers(*args, **kwds): - logger.debug("sfa.rspecs.slivers: add_slivers not implemented") - - def remove_slivers(*args, **kwds): - logger.debug("sfa.rspecs.slivers: remove_slivers not implemented") - - def get_sliver_defaults(*args, **kwds): - logger.debug("sfa.rspecs.slivers: get_sliver_defaults not implemented") - - def add_default_sliver_attribute(*args, **kwds): - logger.debug("sfa.rspecs.slivers: add_default_sliver_attributes not implemented") - - def add_sliver_attribute(*args, **kwds): - logger.debug("sfa.rspecs.slivers: add_sliver_attribute not implemented") - - def remove_default_sliver_attribute(*args, **kwds): - logger.debug("sfa.rspecs.slivers: remove_default_sliver_attributes not implemented") - - def remove_sliver_attribute(*args, **kwds): - logger.debuv("sfa.rspecs.slivers: remove_sliver_attribute not implemented") +class Sliver(Element): + fields = { + 'name': None, + 'tags': [], + 'slice_id': None, + } diff --git a/sfa/rspecs/elements/tag.py b/sfa/rspecs/elements/tag.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/sfa/rspecs/elements/tag.py @@ -0,0 +1 @@ + diff --git a/sfa/rspecs/elements/versions/element_version.py b/sfa/rspecs/elements/versions/element_version.py new file mode 100644 index 00000000..e69de29b diff --git a/sfa/rspecs/elements/versions/pgv2Link.py b/sfa/rspecs/elements/versions/pgv2Link.py index aeef7602..db28f6ce 100644 --- a/sfa/rspecs/elements/versions/pgv2Link.py +++ b/sfa/rspecs/elements/versions/pgv2Link.py @@ -3,16 +3,18 @@ from sfa.util.plxrn import PlXrn from sfa.util.xrn import Xrn from sfa.rspecs.elements.link import Link from sfa.rspecs.elements.interface import Interface +from sfa.rspecs.elements.link_type import LinkType +from sfa.rspecs.elements.component_manager import ComponentManager +from sfa.rspecs.elements.property import Property from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements class PGv2Link: - elements = { 'link': RSpecElement(RSpecElements.LINK, '//default:link | //link'), 'component_manager': RSpecElement(RSpecElements.COMPONENT_MANAGER, './default:component_manager | ./component_manager'), 'link_type': RSpecElement(RSpecElements.LINK_TYPE, './default:link_type | ./link_type'), 'property': RSpecElement(RSpecElements.PROPERTY, './default:property | ./property'), - 'interface_ref': RSpecElement(RSpecElements.INTERFACE_REF, './default:interface_ref | ./interface_ref') + 'interface_ref': RSpecElement(RSpecElements.INTERFACE_REF, './default:interface_ref | ./interface_ref'), } @staticmethod diff --git a/sfa/rspecs/elements/versions/pgv2Node.py b/sfa/rspecs/elements/versions/pgv2Node.py new file mode 100644 index 00000000..e69de29b diff --git a/sfa/rspecs/elements/versions/pgv2Services.py b/sfa/rspecs/elements/versions/pgv2Services.py new file mode 100644 index 00000000..741fbac0 --- /dev/null +++ b/sfa/rspecs/elements/versions/pgv2Services.py @@ -0,0 +1,65 @@ +from lxml import etree +from sfa.util.plxrn import PlXrn +from sfa.util.xrn import Xrn +from sfa.rspecs.elements.execute import Execute +from sfa.rspecs.elements.install import Install +from sfa.rspecs.elements.login import Login +from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements + +class PGv2Services: + elements = { + 'services': RSpecElement(RSpecElements.SERVICES, '//default:services | //services'), + 'install': RSpecElement(RspecElements.INSTALL, './default:install | ./install'), + 'execute': RSpecElement(RspecElements.INSTALL, './default:execute | ./execute'), + 'login': RSpecElement(RspecElements.INSTALL, './default:login | ./login'), + } + + @staticmethod + def add_services(xml, services): + for service in services: + service_elem = etree.SubElement(xml, 'service') + for install in service.get('install', []): + install_elem = etree.SubElement(service_elem, 'install') + for field in Install.fields: + if field in install: + install_elem.set(field, install[field]) + for execute in service.get('execute', []): + execute_elem = etree.SubElement(service_elem, 'execute') + for field in Execute.fields: + if field in execute: + execute_elem.set(field, execute[field]) + for login in service.get('login', []): + login_elem = etree.SubElement(service_elem, 'login') + for field in Login.fields: + if field in login: + login_elem.set(field, login[field]) + + + @staticmethod + def get_services(xml): + services = [] + for services_elem in xml.xpath(PGv2Services.elements['services'].path): + service = Services(services_elem.attrib, services_elem) + + # get install elements + service['install'] = [] + for install_elem in xml.xpath(PGv2Services.elements['install'].path): + install = Install(install_elem.attrib, install_elem) + service['install'].append(install) + + # get execute elements + service['execute'] = [] + for execute_elem in xml.xpath(PGv2Services.elements['execute'].path): + execute = Execute(execute_elem.attrib, execute_elem) + service['execute'].append(execute) + + # get login elements + service['login'] = [] + for login_elem in xml.xpath(PGv2Services.elements['login'].path): + login = Login(login_elem.attrib, login_elem) + service['login'].append(login) + + services.append(service) + + return services + diff --git a/sfa/rspecs/elements/versions/pgv2SliverType.py b/sfa/rspecs/elements/versions/pgv2SliverType.py new file mode 100644 index 00000000..e69de29b diff --git a/sfa/rspecs/elements/versions/sfav1Network.py b/sfa/rspecs/elements/versions/sfav1Network.py new file mode 100644 index 00000000..b529ad57 --- /dev/null +++ b/sfa/rspecs/elements/versions/sfav1Network.py @@ -0,0 +1,32 @@ + + +from lxml import etree +from sfa.util.plxrn import PlXrn +from sfa.util.xrn import Xrn +from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements + +class SFAv1Network: + elements = { + 'network': RSpecElement(RSpecElements.NETWORK, '//network'), + } + + @staticmethod + def add_network(xml, network): + found = False + network_objs = SFAv1Network.get_networks(xml) + for network_obj in network_objs: + if network_obj['name'] == network['name']: + found = True + network_elem = network_obj.element + if not found: + network_elem = etree.SubElement(xml, 'network', name = network['name']) + return network_elem + + @staticmethod + def get_networks(xml): + networks = [] + network_elems = xml.xpath(SFAv1Network.elements['network'].path) + for network_elem in network_elems: + network = Network({'name': network_elem.attrib.get('name', None)}, network_elem) + networks.append(network) + return networks diff --git a/sfa/rspecs/elements/versions/sfav1Node.py b/sfa/rspecs/elements/versions/sfav1Node.py new file mode 100644 index 00000000..b8fe27ef --- /dev/null +++ b/sfa/rspecs/elements/versions/sfav1Node.py @@ -0,0 +1,134 @@ + +from lxml import etree +from sfa.util.plxrn import PlXrn +from sfa.util.xrn import Xrn +from sfa.rspecs.elements.node import Node +from sfa.rspecs.elements.sliver import Sliver +from sfa.rspecs.elements.network import Network +from sfa.rspecs.elements.location import Location +from sfa.rspecs.elements.hardware_type import HardwareType +from sfa.rspecs.elements.disk_image import DiskImage +from sfa.rspecs.elements.interface import Interface +from sfa.rspecs.elements.bwlimit import BWlimit +from sfa.rspecs.elements.pl_tag import PLTag +from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements +from sfa.rspecs.elements.versions.sfav1Network import SFAv1Network + +class SFAv1Node: + + elements = { + 'node': RSpecElement(RSpecElements.NODE, '//default:node | //node'), + 'sliver': RSpecElement(RSpecElements.SLIVER, './default:sliver | ./sliver'), + 'interface': RSpecElement(RSpecElements.INTERFACE, './default:interface | ./interface'), + 'location': RSpecElement(RSpecElements.LOCATION, './default:location | ./location'), + 'bw_limit': RSpecElement(RSpecElements.BWLIMIT, './default:bw_limit | ./bw_limit'), + } + + @staticmethod + def add_nodes(xml, nodes): + network_elems = SFAv1Network.get_networks(xml) + if len(network_elems) > 0: + network_elem = network_elems[0] + elif len(nodes) > 0 and nodes[0].get('component_manager_id'): + network_elem = SFAv1Network.add_network(xml.root, {'name': nodes[0]['component_manager_id']}) + + + node_elems = [] + for node in nodes: + node_elem = etree.SubElement(network_elem, 'node') + node_elems.append(node_elem) + network = None + if 'component_manager_id' in node and node['component_manager_id']: + node_elem.set('component_manager_id', node['component_manager_id']) + network = Xrn(node['component_manager_id']).get_hrn() + if 'component_id' in node and node['component_id']: + node_elem.set('component_id', node['component_id']) + xrn = Xrn(node['component_id']) + node_elem.set('component_name', xrn.get_leaf()) + hostname_tag = etree.SubElement(node_elem, 'hostname').text = xrn.get_leaf() + if 'authority_id' in node and node['authority_id']: + node_elem.set('site_id', node['authority_id']) + if 'boot_state' in node and node['boot_state']: + node_elem.set('boot_state', node['boot_state']) + if 'location' in node and node['location']: + location_elem = etree.SubElement(node_elem, 'location') + for field in Location.fields: + if field in node['location'] and node['location'][field]: + location_elem.set(field, node['location'][field]) + + if 'interfaces' in node and node['interfaces']: + i = 0 + for interface in node['interfaces']: + if 'bwlimit' in interface and interface['bwlimit']: + bwlimit = etree.SubElement(node_elem, 'bw_limit', units='kbps').text = str(interface['bwlimit']/1000) + comp_id = PlXrn(auth=network, interface='node%s:eth%s' % (interface['node_id'], i)).get_urn() + ipaddr = interface['ipv4'] + interface_elem = etree.SubElement(node_elem, 'interface', component_id=comp_id, ipv4=ipaddr) + i+=1 + if 'bw_unallocated' in node and node['bw_unallocated']: + bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000) + + if 'tags' in node: + for tag in node['tags']: + # expose this hard wired list of tags, plus the ones that are marked 'sfa' in their category + if tag['name'] in ['fcdistro', 'arch']: + tag_element = etree.SubElement(node_elem, tag['name']).text=tag['value'] + + if 'slivers' in node: + for sliver in node['slivers']: + sliver_elem = etree.SubElement(node_elem, 'sliver') + if 'name' in sliver and sliver['name']: + sliver_elem.set('name', sliver['name']) + + @staticmethod + def add_slivers(xml, slivers): + pass + + @staticmethod + def get_nodes(xml): + nodes = [] + node_elems = xml.xpath(SFAv1Node.elements['node'].path) + for node_elem in node_elems: + node = Node(node_elem.attrib, node_elem) + if 'site_id' in node_elem.attrib: + node['authority_id'] = node_elem.attrib['site_id'] + + # set the location + location_elems = node_elem.xpath(SFAv1Node.elements['location'].path, xml.namespaces) + if len(location_elems) > 0: + node['location'] = Location(location_elems[0].attrib, location_elems[0]) + + # set the bwlimit + bwlimit_elems = node_elem.xpath(SFAv1Node.elements['bw_limit'].path, xml.namespaces) + if len(bwlimit_elems) > 0: + bwlimit = BWlimit(bwlimit_elems[0].attrib, bwlimit_elems[0]) + node['bwlimit'] = bwlimit + + # set the interfaces + interface_elems = node_elem.xpath(SFAv1Node.elements['interface'].path, xml.namespaces) + node['interfaces'] = [] + for interface_elem in interface_elems: + node['interfaces'].append(Interface(interface_elem.attrib, interface_elem)) + + # set the slivers + sliver_elems = node_elem.xpath(SFAv1Node.elements['sliver'].path, xml.namespaces) + node['slivers'] = [] + for sliver_elem in sliver_elems: + node['slivers'].append(Sliver(sliver_elem.attrib, sliver_elem)) + + # set tags + node['tags'] = [] + for child in node_elem.iterchildren(): + if child.tag not in SFAv1Node.elements: + tag = PLTag({'name': child.tag, 'value': child.text}, child) + node['tags'].append(tag) + nodes.append(node) + return nodes + + @staticmethod + def get_nodes_with_slivers(xml): + nodes = SFAv1Node.get_nodes(xml) + nodes_with_slivers = [node for node in nodes if node['slivers']] + return nodes_with_slivers + + diff --git a/sfa/rspecs/elements/versions/sfav1Sliver.py b/sfa/rspecs/elements/versions/sfav1Sliver.py new file mode 100644 index 00000000..e69de29b diff --git a/sfa/rspecs/rspec_elements.py b/sfa/rspecs/rspec_elements.py index 3226f589..096412e0 100644 --- a/sfa/rspecs/rspec_elements.py +++ b/sfa/rspecs/rspec_elements.py @@ -1,18 +1,24 @@ from sfa.util.enumeration import Enum # recognized top level rspec elements -RSpecElements = Enum(NETWORK='NETWORK', - COMPONENT_MANAGER='COMPONENT_MANAGER', - SLIVER='SLIVER', - SLIVER_TYPE='SLIVER_TYPE', - NODE='NODE', - INTERFACE='INTERFACE', - INTERFACE_REF='INTERFACE_REF', - LINK='LINK', - LINK_TYPE='LINK_TYPE', - SERVICE='SERVICE', - PROPERTY='PROPERTY' - ) +RSpecElements = Enum( + BWLIMIT='BWLIMIT', + EXECUTE='EXECUTE', + NETWORK='NETWORK', + COMPONENT_MANAGER='COMPONENT_MANAGER', + INSTALL='INSTALL', + INTERFACE='INTERFACE', + INTERFACE_REF='INTERFACE_REF', + LOCATION='LOCATION', + LOGIN='LOGIN', + LINK='LINK', + LINK_TYPE='LINK_TYPE', + NODE='NODE', + PROPERTY='PROPERTY', + SERVICES='SERVICES', + SLIVER='SLIVER', + SLIVER_TYPE='SLIVER_TYPE', +) class RSpecElement: def __init__(self, element_type, path):