%define name sfa
%define version 1.1
-%define taglevel 2
+%define taglevel 3
%define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
%global python_sitearch %( python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)" )
[ "$1" -ge "1" ] && service sfa-cm restart || :
%changelog
+* Thu Nov 17 2011 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-1.1-3
+- ongoing refoactoring towards more genericity
+- passes tests again although known issues remain with attributes/tags
+
* Mon Nov 07 2011 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-1.1-2
- checkpoint tag: use SFA_GENERIC_FLAVOUR instead of SFA_*_TYPE
- improvements in the pgv2 rspecs
if key in fields:
self[key] = fields[key]
- @staticmethod
- def get_elements(xml, xpath, element_class=None, fields=None):
- """
- Search the specifed xml node for elements that match the
- specified xpath query.
- Returns a list of objects instanced by the specified element_class.
- """
- if not element_class:
- element_class = Element
- if not fields and hasattr(element_class, 'fields'):
- fields = element_class.fields
- elems = xml.xpath(xpath)
- objs = []
- for elem in elems:
- if not fields:
- obj = element_class(elem.attrib, elem)
- else:
- obj = element_class({}, elem)
- for field in fields:
- if field in elem.attrib:
- obj[field] = elem.attrib[field]
- objs.append(obj)
- return objs
-
- @staticmethod
- def add_elements(xml, name, objs, fields=None):
- """
- Adds a child node to the specified xml node based on
- the specified name , element class and object.
- """
- if not isinstance(objs, list):
- objs = [objs]
- elems = []
- for obj in objs:
- if not obj:
- continue
- if not fields:
- fields = obj.keys()
- elem = xml.add_element(name)
- for field in fields:
- if field in obj and obj[field]:
- elem.set(field, unicode(obj[field]))
- elems.append(elem)
- return elems
+ def __getattr__(self, attr):
+ if hasattr(self, attr):
+ return getattr(self, attr)
+ elif self.element is not None and hasattr(self.element, attr):
+ return getattr(self.element, attr)
+ raise AttributeError, "Element class has no attribute %s" % attr
@staticmethod
def add_links(xml, links):
for link in links:
- link_elems = Element.add(xml, 'link', link, ['component_name', 'component_id', 'client_id'])
- link_elem = link_elems[0]
+
+ link_elem = xml.add_instance('link', link, ['component_name', 'component_id', 'client_id'])
# set component manager element
if 'component_manager' in link and link['component_manager']:
cm_element = link_elem.add_element('component_manager', name=link['component_manager'])
# set interface_ref elements
for if_ref in [link['interface1'], link['interface2']]:
- Element.add(link_elem, 'interface_ref', if_ref, Interface.fields)
+ link_elem.add_instance('interface_ref', if_ref, Interface.fields)
# set property elements
prop1 = link_elem.add_element('property', source_id = link['interface1']['component_id'],
dest_id = link['interface2']['component_id'], capacity=link['capacity'],
link[attrib] = prop[attrib]
# get interfaces
- interfaces = Element.get(Interface, link_elem, './default:interface_ref | ./interface_ref')
+ iface_elems = link_elem.xpath('./default:interface_ref | ./interface_ref')
+ interfaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
if len(interfaces) > 1:
link['interface1'] = interfaces[0]
link['interface2'] = interfaces[1]
from sfa.util.plxrn import PlXrn, xrn_to_hostname
from sfa.util.xrn import Xrn
from sfa.util.xml import XpathFilter
-from sfa.rspecs.elements.element import Element
from sfa.rspecs.elements.node import Node
from sfa.rspecs.elements.sliver import Sliver
from sfa.rspecs.elements.location import Location
node_elems = []
for node in nodes:
node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
- elems = Element.add_elements(xml, 'node', node, node_fields)
- node_elem = elems[0]
+ node_elem = xml.add_instance('node', node, node_fields)
node_elems.append(node_elem)
# set component name
if node.get('component_id'):
component_name = xrn_to_hostname(node['component_id'])
node_elem.set('component_name', component_name)
- # set hardware types
- Element.add_elements(node_elem, 'hardware_type', node.get('hardware_types', []), HardwareType.fields)
- # set location
- location_elems = Element.add_elements(node_elem, 'location', node.get('location', []), Location.fields)
+ # set hardware types
+ for hardware_type in node.get('hardware_types', []):
+ node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
+ # set location
+ if node.get('location'):
+ node_elem.add_instance('location', node['location'], Location.fields)
# set interfaces
- interface_elems = Element.add_elements(node_elem, 'interface', node.get('interfaces', []), ['component_id', 'client_id', 'ipv4'])
+ for interface in node.get('interfaces', []):
+ node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4'])
# set available element
if node.get('boot_state', '').lower() == 'boot':
available_elem = node_elem.add_element('available', now='True')
@staticmethod
def get_nodes_with_slivers(xml, filter={}):
- xpath = '//node/sliver_type | //default:node/default:sliver_type'
+ xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]'
node_elems = xml.xpath(xpath)
return PGv2Node.get_node_objs(node_elems)
nodes.append(node)
if 'component_id' in node_elem.attrib:
node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
+
+ # get hardware types
+ hardware_type_elems = node_elem.xpath('./default:hardwate_type | ./hardware_type')
+ node['hardware_types'] = [hw_type.get_instnace(HardwareType) for hw_type in hardware_type_elems]
+
+ # get location
+ location_elems = node_elem.xpath('./default:location | ./location')
+ locations = [location_elem.get_instance(Location) for location_elem in location_elems]
+ if len(locations) > 0:
+ node['location'] = locations[0]
- node['hardware_types'] = Element.get_elements(node_elem, './default:hardwate_type | ./hardware_type', HardwareType)
- location_elems = Element.get_elements(node_elem, './default:location | ./location', Location)
- if len(location_elems) > 0:
- node['location'] = location_elems[0]
- node['interfaces'] = Element.get_elements(node_elem, './default:interface | ./interface', Interface)
+ # get interfaces
+ iface_elems = node_elem.xpath('./default:interface | ./interface')
+ node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
+
+ # get services
node['services'] = PGv2Services.get_services(node_elem)
+
+ # get slivers
node['slivers'] = PGv2SliverType.get_slivers(node_elem)
- available_elem = Element.get_elements(node_elem, './default:available | ./available', fields=['now'])
- if len(available_elem) > 0 and 'name' in available_elem[0]:
- if available_elem[0].get('now', '').lower() == 'true':
+ available_elems = node_elem.xpath('./default:available | ./available')
+ if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
+ if available_elems[0].attrib.get('now', '').lower() == 'true':
node['boot_state'] = 'boot'
else:
node['boot_state'] = 'disabled'
def add_services(xml, services):
if not services:
return
-
for service in services:
service_elem = xml.add_element('services')
- Element.add_elements(service_elem, 'install', service.get('install', []), Install.fields)
- Element.add_elements(service_elem, 'execute', service.get('execute', []), Execute.fields)
- Element.add_elements(service_elem, 'login', service.get('login', []), Login.fields)
+ child_elements = {'install': Install.fields,
+ 'execute': Execute.fields,
+ 'login': Login.fields}
+ for (name, fields) in child_elements.items():
+ objects = service.get(name)
+ if not objects:
+ continue
+ if isinstance(objects, basestring):
+ service_elem.add_instance(name, objects, fields)
+ elif isinstance(objects, list):
+ for obj in objects:
+ service_elem.add_instance(name, obj, fields)
@staticmethod
def get_services(xml):
services = []
for services_elem in xml.xpath('./default:services | ./services'):
service = Services(services_elem.attrib, services_elem)
- service['install'] = Element.get_elements(service_elem, './default:install | ./install', Install)
- service['execute'] = Element.get_elements(service_elem, './default:execute | ./execute', Execute)
- service['login'] = Element.get_elements(service_elem, './default:login | ./login', Login)
+ # get install
+ install_elems = xml.xpath('./default:install | ./install')
+ service['install'] = [install_elem.get_instance(Install) for install_elem in install_elems]
+ # get execute
+ execute_elems = xml.xpath('./default:execute | ./execute')
+ service['execute'] = [execute_elem.get_instance(Execute) for execute_elem in execute_elems]
+ # get login
+ login_elems = xml.xpath('./default:login | ./login')
+ service['login'] = [login_elem.get_instance(Login) for login_elem in login_elems]
services.append(service)
return services
if not isinstance(slivers, list):
slivers = [slivers]
for sliver in slivers:
- sliver_elem = Element.add_elements(xml, 'sliver_type', sliver, ['type', 'client_id'])
+ sliver_elem = xml.add_instance('sliver_type', sliver, ['type', 'client_id'])
PGv2SliverType.add_sliver_attributes(sliver_elem, sliver.get('pl_tags', []))
@staticmethod
@staticmethod
def add_nodes(xml, nodes):
- network_elems = Element.get_elements(xml, '//network', fields=['name'])
+ network_elems = xml.xpath('//network')
if len(network_elems) > 0:
network_elem = network_elems[0]
elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
- network_urn = nodes[0]['component_manager_id']
- network_elems = Element.add_elements(xml, 'network', {'name': Xrn(network_urn).get_hrn()})
- network_elem = network_elems[0]
+ network_urn = nodes[0]['component_manager_id']
+ network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn())
+ else:
+ network_elem = xml
node_elems = []
for node in nodes:
node_fields = ['component_manager_id', 'component_id', 'boot_state']
- elems = Element.add_elements(network_elem, 'node', node, node_fields)
- node_elem = elems[0]
+ node_elem = network_elem.add_instance('node', node, node_fields)
node_elems.append(node_elem)
# determine network hrn
if 'component_id' in node and node['component_id']:
component_name = xrn_to_hostname(node['component_id'])
node_elem.set('component_name', component_name)
- hostname_tag = node_elem.add_element('hostname')
- hostname_tag.set_text(component_name)
+ hostname_elem = node_elem.add_element('hostname')
+ hostname_elem.set_text(component_name)
# set site id
if 'authority_id' in node and node['authority_id']:
node_elem.set('site_id', node['authority_id'])
- location_elems = Element.add_elements(node_elem, 'location',
- node.get('location', []), Location.fields)
- interface_elems = Element.add_elements(node_elem, 'interface',
- node.get('interfaces', []), ['component_id', 'client_id', 'ipv4'])
+ # add locaiton
+ location = node.get('location')
+ if location:
+ node_elem.add_instance('location', location, Location.fields)
+
+ for interface in node.get('interfaces', []):
+ node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4'])
#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)
PGv2Services.add_services(node_elem, node.get('services', []))
- SFAv1PLTag.add_pl_tags(node_elem, node.get('tags', []))
+ for tag in node.get('tags', []):
+ tag_elem = node_elem.add_element(tag['tagname'])
+ tag_elem.set_text(tag['value'])
SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
@staticmethod
sliver = {}
elif 'component_id' in sliver and sliver['component_id']:
filter['component_id'] = '*%s*' % sliver['component_id']
- if not fliter:
+ if not filter:
continue
nodes = SFAv1Node.get_nodes(xml, filter)
if not nodes:
node_elems = xml.xpath(xpath)
return SFAv1Node.get_node_objs(node_elems)
- # xxx Thierry : an ugly hack to get the tests to pass again
- # probably this needs to be trashed
- # the original code returned the <sliver /> tag,
- # but we prefer the <node> father node instead as it already holds data
- # initially this was to preserve the nodename...
- # xxx I don't get the ' | //default:node/default:sliver' ...
- @staticmethod
- def get_nodes_with_slivers_thierry(xml):
- # dropping the ''
- xpath = '//node[count (sliver)>0]'
- node_elems = xml.xpath(xpath)
- # we need to check/recompute the node data
-
- return node_elems
-
@staticmethod
def get_nodes_with_slivers(xml):
- xpath = '//node/sliver | //default:node/default:sliver'
+ xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]'
node_elems = xml.xpath(xpath)
return SFAv1Node.get_node_objs(node_elems)
node = Node(node_elem.attrib, node_elem)
if 'site_id' in node_elem.attrib:
node['authority_id'] = node_elem.attrib['site_id']
- location_objs = Element.get_elements(node_elem, './default:location | ./location', Location)
- if len(location_objs) > 0:
- node['location'] = location_objs[0]
- bwlimit_objs = Element.get_elements(node_elem, './default:bw_limit | ./bw_limit', BWlimit)
- if len(bwlimit_objs) > 0:
- node['bwlimit'] = bwlimit_objs[0]
- node['interfaces'] = Element.get_elements(node_elem, './default:interface | ./interface', Interface)
+ # get location
+ location_elems = node_elem.xpath('./default:location | ./location')
+ locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]
+ if len(locations) > 0:
+ node['location'] = locations[0]
+ # get bwlimit
+ bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
+ bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
+ if len(bwlimits) > 0:
+ node['bwlimit'] = bwlimits[0]
+ # get interfaces
+ iface_elems = node_elem.xpath('./default:interface | ./interface')
+ ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
+ node['interfaces'] = ifaces
+ # get services
node['services'] = PGv2Services.get_services(node_elem)
+ # get slivers
node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
-#thierry node['tags'] = SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields.keys())
+ # get tags
node['tags'] = SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields)
nodes.append(node)
return nodes
class SFAv1PLTag:
@staticmethod
- def add_pl_tags(xml, pl_tags):
+ def add_pl_tag(xml, name, value):
for pl_tag in pl_tags:
- pl_tag_elem = xml.add_element(pl_tag['tagname'])
- pl_tag_elem.set_text(pl_tag['value'])
+ pl_tag_elem = xml.add_element(name)
+ pl_tag_elem.set_text(value)
@staticmethod
def get_pl_tags(xml, ignore=[]):
from sfa.util.xrn import Xrn
+from sfa.util.xml import XmlElement
from sfa.rspecs.elements.element import Element
from sfa.rspecs.elements.sliver import Sliver
from sfa.rspecs.elements.versions.sfav1PLTag import SFAv1PLTag
if not isinstance(slivers, list):
slivers = [slivers]
for sliver in slivers:
- sliver_elem = Element.add_elements(xml, 'sliver', sliver, ['name'])[0]
- SFAv1Sliver.add_sliver_attributes(sliver_elem, sliver.get('tags', []))
+ sliver_elem = xml.add_instance('sliver', sliver, ['name'])
+ for tag in sliver.get('tags', []):
+ SFAv1Sliver.add_sliver_attribute(sliver_elem, tag['tagname'], tag['value'])
if sliver.get('sliver_id'):
sliver_id_leaf = Xrn(sliver.get('sliver_id')).get_leaf()
sliver_id_parts = sliver_id_leaf.split(':')
sliver_elem.set('name', name)
@staticmethod
- def add_sliver_attributes(xml, attributes):
- SFAv1PLTag.add_pl_tags(xml, attributes)
-
+ def add_sliver_attribute(xml, name, value):
+ elem = xml.add_element(name)
+ elem.set_text(value)
+
+ @staticmethod
+ def get_sliver_attributes(xml):
+ attribs = []
+ for elem in xml.iterchildren():
+ if elem.tag not in Sliver.fields:
+ xml_element = XmlElement(elem, xml.namespaces)
+ instance = Element(xml_element)
+ instance['tagname'] = elem.tag
+ instance['value'] = elem.text
+ attribs.append(instance)
+ return attribs
+
@staticmethod
def get_slivers(xml, filter={}):
xpath = './default:sliver | ./sliver'
slivers.append(sliver)
return slivers
- @staticmethod
- def get_sliver_attributes(xml, filter={}):
- return SFAv1PLTag.get_pl_tags(xml, ignore=Sliver.fields)
from copy import deepcopy
from StringIO import StringIO
-from sfa.util.xrn import urn_to_sliver_id
+from sfa.util.xrn import Xrn, urn_to_sliver_id
from sfa.util.plxrn import hostname_to_urn, xrn_to_hostname
from sfa.rspecs.baseversion import BaseVersion
from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
namespaces = dict(extensions.items() + [('default', namespace)])
# Networks
- def get_network(self):
- network = None
- nodes = self.xml.xpath('//default:node[@component_manager_id][1]', namespaces=self.namespaces)
- if nodes:
- network = nodes[0].get('component_manager_id')
- return network
-
def get_networks(self):
- networks = self.xml.xpath('//default:node[@component_manager_id]/@component_manager_id', namespaces=self.namespaces)
- return set(networks)
+ networks = set()
+ nodes = self.xml.xpath('//default:node[@component_manager_id]', namespaces=self.namespaces)
+ for node in nodes:
+ if 'component_manager_id' in node:
+ network_urn = node.get('component_manager_id')
+ network_hrn = Xrn(network_urn).get_hrn()[0]
+ networks.add({'name': network_hrn})
+ return list(networks)
-
# Nodes
def get_nodes(self, filter=None):
# Network
def get_networks(self):
- return Element.get_elements(self.xml, '//network', Element)
+ network_elems = self.xml.xpath('//network')
+ networks = [network_elem.get_instance(fields=['name', 'slice']) for \
+ network_elem in network_elems]
+ return networks
+
def add_network(self, network):
network_tags = self.xml.xpath('//network[@name="%s"]' % network)
if not network_tags:
- network_tag = etree.SubElement(self.xml.root, 'network', name=network)
+ network_tag = self.xml.add_element('network', name=network)
else:
network_tag = network_tags[0]
return network_tag
network_tag.append(deepcopy(source_node_tag))
# Slivers
-
- def attributes_list(self, elem):
- # convert a list of attribute tags into list of tuples
- # (tagname, text_value)
- opts = []
- if elem is not None:
- for e in elem:
- opts.append((e.tag, str(e.text).strip()))
- return opts
-
- def get_default_sliver_attributes(self, network=None):
- if network:
- defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
- else:
- defaults = self.xml.xpath("//sliver_defaults")
- if not defaults: return []
- return self.attributes_list_thierry(defaults)
-
- def get_sliver_attributes(self, hostname, network=None):
- nodes = self.get_nodes({'component_id': '*%s*' %hostname})
- attribs = []
- if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
- node = nodes[0]
- sliver = node.xpath('./default:sliver', namespaces=self.namespaces)
- if sliver is not None and isinstance(sliver, list) and len(sliver) > 0:
- sliver = sliver[0]
- #attribs = self.attributes_list(sliver)
- return attribs
-
- def get_slice_attributes(self, network=None):
- slice_attributes = []
- nodes_with_slivers = self.get_nodes_with_slivers()
- for default_attribute in self.get_default_sliver_attributes(network):
- attribute = {'name': str(default_attribute[0]),
- 'value': str(default_attribute[1]),
- 'node_id': None}
- slice_attributes.append(attribute)
- for node in nodes_with_slivers:
- nodename=node.get('component_name')
- sliver_attributes = self.get_sliver_attributes(nodename, network)
- for sliver_attribute in sliver_attributes:
- attribute = {'name': str(sliver_attribute[0]), 'value': str(sliver_attribute[1]), 'node_id': node}
- slice_attributes.append(attribute)
- return slice_attributes
-
+
def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
# add slice name to network tag
network_tags = self.xml.xpath('//network')
if network_tags:
network_tag = network_tags[0]
network_tag.set('slice', urn_to_hrn(sliver_urn)[0])
-
+
# add slivers
sliver = {'name':sliver_urn,
'pl_tags': attributes}
if sliver_urn:
sliver['name'] = sliver_urn
node_elems = self.get_nodes({'component_id': '*%s*' % hostname})
- if not node_elems:
+ if not node_elems:
continue
node_elem = node_elems[0]
- SFAv1Sliver.add_slivers(node_elem.element, sliver)
+ SFAv1Sliver.add_slivers(node_elem.element, sliver)
# remove all nodes without slivers
if not append:
def remove_slivers(self, slivers, network=None, no_dupes=False):
SFAv1Node.remove_slivers(self.xml, slivers)
+
+ def get_slice_attributes(self, network=None):
+ slice_attributes = []
+ """
+ nodes_with_slivers = self.get_nodes_with_slivers()
+ for default_attribute in self.get_default_sliver_attributes(network):
+ attribute = {'name': str(default_attribute[0]),
+ 'value': str(default_attribute[1]),
+ 'node_id': None}
+ slice_attributes.append(attribute)
+ for node in nodes_with_slivers:
+ nodename=node.get('component_name')
+ sliver_attributes = self.get_sliver_attributes(nodename, network)
+ for sliver_attribute in sliver_attributes:
+ attribute = {'name': str(sliver_attribute[0]), 'value': str(sliver_attribute[1]), 'node_id': node}
+ slice_attributes.append(attribute)
+ """
+ return slice_attributes
+
+
+ def add_sliver_attribute(self, hostname, name, value, network=None):
+ nodes = self.get_nodes({'component_id': '*%s*' % hostname})
+ if not nodes:
+ node = nodes[0]
+ slivers = SFAv1Sliver.get_slivers(node)
+ if slivers:
+ sliver = slivers[0]
+ SFAv1Sliver.add_attribute(sliver, name, value)
+
+ def get_sliver_attributes(self, hostname, network=None):
+ nodes = self.get_nodes({'component_id': '*%s*' %hostname})
+ attribs = []
+ if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
+ node = nodes[0]
+ slivers = node.xpath('./default:sliver', namespaces=self.namespaces)
+ if slivers is not None and isinstance(slivers, list) and len(slivers) > 0:
+ sliver = slivers[0]
+ attribs = SFAv1Sliver.get_sliver_attributes(sliver)
+ return attribs
+
+ def remove_sliver_attribute(self, hostname, name, value, network=None):
+ attribs = self.get_sliver_attributes(hostname)
+ for attrib in attribs:
+ if attrib['tagname'] == name and attrib['value'] == value:
+ attrib.element.delete()
def add_default_sliver_attribute(self, name, value, network=None):
if network:
defaults = defaults[0]
self.xml.add_attribute(defaults, name, value)
- def add_sliver_attribute(self, hostname, name, value, network=None):
- node = self.get_node_element(hostname, network)
- sliver = node.find("sliver")
- self.xml.add_attribute(sliver, name, value)
-
+ def get_default_sliver_attributes(self, network=None):
+ if network:
+ defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
+ else:
+ defaults = self.xml.xpath("//sliver_defaults")
+ if not defaults: return []
+ return self.attributes_list_thierry(defaults)
+
def remove_default_sliver_attribute(self, name, value, network=None):
if network:
defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
defaults = self.xml.xpath("//sliver_defaults" % network)
self.xml.remove_attribute(defaults, name, value)
- def remove_sliver_attribute(self, hostname, name, value, network=None):
- node = self.get_node_element(hostname, network)
- sliver = node.find("sliver")
- self.xml.remove_attribute(sliver, name, value)
-
# Links
def get_links(self, network=None):
from lxml import etree
from StringIO import StringIO
from sfa.util.faults import InvalidXML
+from sfa.rspecs.elements.element import Element
class XpathFilter:
@staticmethod
xpath = '[' + xpath + ']'
return xpath
-class XmlNode:
- def __init__(self, node, namespaces):
- self.node = node
- self.text = node.text
+class XmlElement:
+ def __init__(self, element, namespaces):
+ self.element = element
+ self.tag = element.tag
+ self.text = element.text
+ self.attrib = element.attrib
self.namespaces = namespaces
- self.attrib = node.attrib
def xpath(self, xpath, namespaces=None):
if not namespaces:
namespaces = self.namespaces
- elems = self.node.xpath(xpath, namespaces=namespaces)
- return [XmlNode(elem, namespaces) for elem in elems]
+ elems = self.element.xpath(xpath, namespaces=namespaces)
+ return [XmlElement(elem, namespaces) for elem in elems]
def add_element(self, tagname, **kwds):
- element = etree.SubElement(self.node, tagname, **kwds)
- return XmlNode(element, self.namespaces)
+ element = etree.SubElement(self.element, tagname, **kwds)
+ return XmlElement(element, self.namespaces)
def append(self, elem):
- if isinstance(elem, XmlNode):
- self.node.append(elem.node)
+ if isinstance(elem, XmlElement):
+ self.element.append(elem.element)
else:
- self.node.append(elem)
+ self.element.append(elem)
def getparent(self):
- return XmlNode(self.node.getparent(), self.namespaces)
+ return XmlElement(self.element.getparent(), self.namespaces)
+
+ def get_instance(self, instance_class=None, fields=[]):
+ """
+ Returns an instance (dict) of this xml element. The instance
+ holds a reference this xml element.
+ """
+ if not instance_class:
+ instance_class = Element
+ if not fields and hasattr(instance_class, 'fields'):
+ fields = instance_class.fields
+
+ if not fields:
+ instance = instance_class(self.attrib, self)
+ else:
+ instance = instance_class({}, self)
+ for field in fields:
+ if field in self.attrib:
+ instance[field] = self.attrib[field]
+ return instance
+
+ def add_instance(self, name, instance, fields=[]):
+ """
+ Adds the specifed instance(s) as a child element of this xml
+ element.
+ """
+ if not fields and hasattr(instance, 'keys'):
+ fields = instance.keys()
+ elem = self.add_element(name)
+ for field in fields:
+ if field in instance and instance[field]:
+ elem.set(field, unicode(instance[field]))
+ return elem
def remove_elements(self, name):
"""
if not element_name.startswith('//'):
element_name = '//' + element_name
- elements = self.node.xpath('%s ' % name, namespaces=self.namespaces)
+ elements = self.element.xpath('%s ' % name, namespaces=self.namespaces)
for element in elements:
parent = element.getparent()
parent.remove(element)
+ def delete(self):
+ parent = self.getparent()
+ parent.remove(self)
+
def remove(self, element):
- if isinstance(element, XmlNode):
- self.node.remove(element.node)
+ if isinstance(element, XmlElement):
+ self.element.remove(element.element)
else:
- self.node.remove(element)
+ self.element.remove(element)
def get(self, key, *args):
- return self.node.get(key, *args)
+ return self.element.get(key, *args)
- def items(self): return self.node.items()
+ def items(self): return self.element.items()
def set(self, key, value):
- self.node.set(key, value)
+ self.element.set(key, value)
def set_text(self, text):
- self.node.text = text
+ self.element.text = text
def unset(self, key):
- del self.node.attrib[key]
+ del self.element.attrib[key]
def iterchildren(self):
- return self.node.iterchildren()
+ return self.element.iterchildren()
def toxml(self):
- return etree.tostring(self.node, encoding='UTF-8', pretty_print=True)
+ return etree.tostring(self.element, encoding='UTF-8', pretty_print=True)
def __str__(self):
return self.toxml()
self.schema = None
if isinstance(xml, basestring):
self.parse_xml(xml)
- if isinstance(xml, XmlNode):
+ if isinstance(xml, XmlElement):
self.root = xml
self.namespaces = xml.namespaces
elif isinstance(xml, etree._ElementTree) or isinstance(xml, etree._Element):
else:
self.namespaces['default'] = 'default'
- self.root = XmlNode(root, self.namespaces)
+ self.root = XmlElement(root, self.namespaces)
# set schema
for key in self.root.attrib.keys():
if key.endswith('schemaLocation'):
namespaces = self.namespaces
return self.root.xpath(xpath, namespaces=namespaces)
- def set(self, key, value, node=None):
- if not node:
- node = self.root
- return node.set(key, value)
+ def set(self, key, value, element=None):
+ if not element:
+ element = self.root
+ return element.set(key, value)
- def remove_attribute(self, name, node=None):
- if not node:
- node = self.root
- node.remove_attribute(name)
+ def remove_attribute(self, name, element=None):
+ if not element:
+ element = self.root
+ element.remove_attribute(name)
- def add_element(self, name, **kwds):
+ def add_element(self, *args, **kwds):
"""
Wrapper around etree.SubElement(). Adds an element to
specified parent node. Adds element to root node is parent is
not specified.
"""
- parent = self.root
- xmlnode = parent.add_element(name, *kwds)
- return xmlnode
+ return self.root.add_element(*args, **kwds)
- def remove_elements(self, name, node = None):
+ def remove_elements(self, name, element = 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 node:
- node = self.root
+ if not element:
+ element = self.root
+
+ element.remove_elements(name)
- node.remove_elements(name)
+ def add_instance(self, *args, **kwds):
+ return self.root.add_instance(*args, **kwds)
- def attributes_list(self, elem):
- # convert a list of attribute tags into list of tuples
- # (tagnme, text_value)
- opts = []
- if elem is not None:
- for e in elem:
- opts.append((e.tag, str(e.text).strip()))
- return opts
+ def get_instance(self, *args, **kwds):
+ return self.root.get_instnace(*args, **kwds)
def get_element_attributes(self, elem=None, depth=0):
if elem == None:
- elem = self.root_node
+ elem = self.root
if not hasattr(elem, 'attrib'):
# this is probably not an element node with attribute. could be just and an
# attribute, return it
return self.toxml()
def toxml(self):
- return etree.tostring(self.root.node, encoding='UTF-8', pretty_print=True)
+ return etree.tostring(self.root.element, encoding='UTF-8', pretty_print=True)
# XXX smbaker, for record.load_from_string
def todict(self, elem=None):