if not self.sfa:
self._sliceapi = self.plcapi
else:
- import sfiapi
- self._sliceapi = sfiapi.sfiapi()
+ from nepi.util import sfiapi
+ self._sliceapi = sfiapi.sfiapi(self.slice_id)
return self._sliceapi
@property
def slice_id(self):
if not self._slice_id:
- self._slice_id = self.plcapi.GetSliceId(self.slicename)
+ self._slice_id = self.sliceapi.GetSliceId(self.slicename)
return self._slice_id
@property
candidates &= set(map(operator.itemgetter('node_id'),
self._sliceapi.GetNodeTags(filters=tagfilter, fields=fields)))
-
+
# filter by vsys tags - special case since it doesn't follow
# the usual semantics
if self.required_vsys:
hostnames = dict(map(operator.itemgetter('node_id','hostname'),
self._api.GetNodes(list(candidates), ['node_id','hostname'])
))
+
def resolvable(node_id):
try:
addr = socket.gethostbyname(hostnames[node_id])
filters = kw.pop('filters',{})
filters.update(kw)
return _retry(self.mcapi.GetSliceTags)(self.auth, filters, *fieldstuple)
-
def GetInterfaces(self, interfaceIdOrIp=None, fields=None, **kw):
if fields is not None:
def UpdateSlice(self, sliceIdOrName, **kw):
return _retry(self.mcapi.UpdateSlice)(self.auth, sliceIdOrName, kw)
-
def StartMulticall(self):
self.threadlocal.mc = xmlrpclib.MultiCall(self.mcapi)
slice_id = None
slices = self.GetSlices(slicename, fields=('slice_id',))
if slices:
- slice_id = slices[0]['slice_id']
+ slice_id = slices[0]['slice_id']
# If it wasn't found, don't remember this failure, keep trying
return slice_id
+++ /dev/null
-class SFIAPI(object):
- def __init__(self):
- self._slice_nodes = dict()
- self._all_nodes = dict()
-
- def GetSliceNodes(self, slicename):
- return None
-
- def AddSliceNodes(self, slicename, nodes=None):
- pass
-
- def GetNodeTags(self, nodeTagId=None, fields=None, **kw):
- pass
-
- def GetNodes(self, filters=basefilters, fields=('node_id','interface_ids')) ))
-
-def sfiapi():
- return SFIAPI()
-
def xmldecode(s):
return s.replace(u'�',u'\x00').encode("utf8")
-def get_text(p_tag, name):
- tags = p_tag.getElementsByTagName(name)
+def get_child_text(tag, name):
+ tags = tag.getElementsByTagName(name)
if not tags:
return ""
- return xmldecode(tags[0].childNodes[0].nodeValue)
+ return get_text(tags[0])
+
+def get_name(tag):
+ return xmldecode(tag.tagName)
+
+def get_text(tag):
+ text = ''.join(t.nodeValue for t in tag.childNodes if t.nodeType == t.TEXT_NODE)
+ return xmldecode(text)
+
+def set_text(doc, tag, text):
+ ttag = doc.createTextNode(text)
+ tag.appendChild(ttag)
def get_attribute(p_tag, name):
return xmldecode(p_tag.getAttribute(name))
+def has_sliver(node_tag):
+ sliver_tag = node_tag.getElementsByTagName("sliver")
+ return len(sliver_tag) > 0
class SFAResourcesParser(object):
- def from_xml(self, xml):
+ def resources_from_xml(self, xml):
data = dict()
doc = minidom.parseString(xml)
rspec_tag = doc.getElementsByTagName("RSpec")[0]
data.update(node_data)
return data
- def nodes_from_xml(self, doc, network_tag):
+ def slice_info_from_xml(self, xml):
+ nodes_data = dict()
+ doc = minidom.parseString(xml)
+ rspec_tag = doc.getElementsByTagName("RSpec")[0]
+ network_tags = rspec_tag.getElementsByTagName("network")
+ for network_tag in network_tags:
+ if network_tag.nodeType == doc.ELEMENT_NODE:
+ node_data = self.nodes_from_xml(doc, network_tag, in_sliver = True)
+ nodes_data.update(node_data)
+ nodes_data = set(nodes_data.keys())
+ tags_data = self.slice_tags_from_xml(doc, rspec_tag)
+ return tags_data, nodes_data
+
+ def nodes_from_xml(self, doc, network_tag, in_sliver = False):
nodes_data = dict()
- network_name = get_attribute(network_tag, "name")
+ network_name = get_attribute(network_tag, 'name')
node_tags = network_tag.getElementsByTagName('node')
for node_tag in node_tags:
if node_tag.nodeType == doc.ELEMENT_NODE:
+ if in_sliver and not has_sliver(node_tag):
+ continue
node_data = dict()
node_data['network_name'] = network_name
node_name = get_attribute(node_tag, 'component_name')
'response', 'loadw', 'country', 'load', 'mem', 'slices',
'region', 'asnumber', 'bw', 'hrn', 'city', 'responsew',
'bwy', 'cpu']:
- node_data[name] = get_text(node_tag, name)
+ node_data[name] = get_child_text(node_tag, name)
iface_tags = node_tag.getElementsByTagName('interface')
ifaces_data = dict()
for iface_tag in iface_tags:
if iface_tag.nodeType == doc.ELEMENT_NODE:
for name in ['component_id', 'ipv4']:
ifaces_data[name] = get_attribute(iface_tag, name)
- node_data['interfaces'] = ifaces_data
+ node_data['interfaces'] = ifaces_data
return nodes_data
+ def slice_tags_from_xml(self, doc, rspec_tag):
+ tags_data = dict()
+ sliver_tag = rspec_tag.getElementsByTagName('sliver_defaults')
+ if len(sliver_tag) == 0:
+ return tags_data
+ for child_tag in sliver_tag[0].childNodes:
+ if child_tag.nodeType == doc.ELEMENT_NODE:
+ name = get_name(child_tag)
+ value = get_text(child_tag)
+ tags_data[name] = value
+ return tags_data
+
+ def create_slice_xml(self, node_data, slice_tags):
+ doc = minidom.Document()
+ rspec_tag = doc.createElement("RSpec")
+ doc.appendChild(rspec_tag)
+ rspec_tag.setAttribute("type", "SFA")
+ slice_defaults_tag = self.slice_defaults_xml(doc, slice_tags)
+
+ networks = dict()
+ for k, data in node_data.iteritems():
+ network_name = data["network_name"]
+ if network_name not in networks:
+ networks[network_name] = dict()
+ networks[network_name][k] = data
+
+ for n, netdata in networks.iteritems():
+ network_tag = doc.createElement("testbeds")
+ network_tag.setAttribute("name", n)
+ rspec_tag.appendChild(network_tag)
+ for k, data in netdata.iteritems():
+ node_tag = doc.createElement("node")
+ node_tag.setAttribute("component_manager_id", data["component_manager_id"])
+ node_tag.setAttribute("component_id", data["component_id"])
+ node_tag.setAttribute("component_name", data["component_name"])
+ node_tag.setAttribute("boot_state", data["boot_state"])
+ node_tag.setAttribute("site_id", data["site_id"])
+ hostname_tag = doc.createElement("hostname")
+ set_text(doc, hostname_tag, data["hostname"])
+ node_tag.appendChild(hostname_tag)
+ sliver_tag = doc.createElement("sliver")
+ node_tag.appendChild(sliver_tag)
+ network_tag.appendChild(node_tag)
+ network_tag.appendChild(slice_defaults_tag)
+ return doc.toxml()
+
+ def slice_defaults_xml(self, doc, slice_tags):
+ slice_defaults_tag = doc.createElement("sliver_defaults")
+ for name, value in slice_tags.iteritems():
+ tag = doc.createElement(name)
+ set_text(doc, tag, value)
+ slice_defaults_tag.appendChild(tag)
+ return slice_defaults_tag
+
"""
if __name__ == "__main__":
path = sys.argv[1]
xml = fd.read()
fd.close()
p = SFAResourcesParser()
- data = p.from_xml(xml)
- print data.keys()
+ tags, nodes = p.slice_info_from_xml(xml)
+ print tags, nodes
"""
--- /dev/null
+# -*- coding: utf-8 -*-
+
+from nepi.util.parser import sfa
+
+class SFIAPI(object):
+ def __init__(self):
+ self._slice_tags = dict()
+ self._slice_nodes = set()
+ self._all_nodes = dict()
+ self._slice_id = None
+
+ def FetchSliceInfo(self, slice_id):
+ self._slice_id = slice_id
+ p = sfa.SFAResourcesParser()
+ import commands
+ xml = commands.getoutput("sfi.py resources")
+ self._all_nodes = p.resources_from_xml(xml)
+ xml = commands.getoutput("sfi.py resources %s" % slice_id)
+ self._slice_tags, self._slice_nodes = p.slice_info_from_xml(xml)
+
+ def GetSliceNodes(self, slicename):
+ return list(self._slice_nodes)
+
+ def GetNodeInfo(self, node_id):
+ info = self.GetNodes(node_id)
+ tags = self.GetNodeTags(node_id=node_id, fields=('tagname','value'))
+ return info, tags
+
+ def GetSliceId(self, slicename):
+ return self._slice_id
+
+ def GetSliceVnetSysTag(self, slicename):
+ return self._slice_tags.get('vsys_net')
+
+ def GetNodeTags(self, node_id=None, fields=None, **kw):
+ nodes = self._all_nodes
+ if node_id is not None:
+ node_ids = node_id
+ if not isinstance(node_id, list):
+ node_ids = [node_ids]
+ nodes = self._FilterByNodeId(nodes, node_ids)
+ else:
+ filters = kw.pop('filters',{})
+ if '|slice_ids' in filters:
+ nodes = self._FilterByNodeId(nodes, self._slice_nodes)
+ del filters['|slice_ids']
+ nodes = self._FilterByFilters(nodes, filters)
+ tagnames = kw.pop('tagname',[])
+ return self._GetTagInfo(nodes, tagnames, fields)
+
+ def GetNodes(self, nodeIdOrName=None, fields=[], **kw):
+ #TODO: filter - peer
+ # field - interface_ids
+ nodes = self._all_nodes
+ if nodeIdOrName is not None:
+ node_ids = nodeIdOrName
+ if not isinstance(nodeIdOrName, list):
+ node_ids = [node_ids]
+ nodes = self._FilterByNodeId(nodes, node_ids)
+ else:
+ filters = kw.pop('filters',{})
+ if '|slice_ids' in filters:
+ nodes = self._FilterByNodeId(nodes, self._slice_nodes)
+ del filters['|slice_ids']
+ nodes = self._FilterByFilters(nodes, filters)
+ return self._GetNodeInfo(nodes, fields)
+
+ def _FilterByNodeId(self, nodes, node_ids):
+ return dict((k, nodes[k]) for k in node_ids if k in nodes)
+
+ def _FilterByFilters(self, nodes, filters):
+ def has_all_tags(node_id):
+ data = nodes[node_id]
+ for name, value in filters.iteritems():
+ #if (name == '>last_contact' and data['lastcontact'] > value) or \
+ if (not name in data or data[tag] != value):
+ return False
+ return True
+ return dict((k, value) for k, value in nodes.iteritems() if has_all_tags(k))
+
+ def _GetNodeInfo(self, nodes, fields):
+ result = list()
+ for k, data in nodes.iteritems():
+ r_data = dict()
+ result.append(r_data)
+ for f in fields:
+ if f == "node_id":
+ value = k
+ else:
+ value = data[f]
+ r_data[f] = value
+ return result
+
+ def _GetTagInfo(self, nodes, tagnames, fields):
+ result = list()
+ for k, data in nodes.iteritems():
+ for name, value in data.iteritems():
+ r_data = dict()
+ if tagnames and name not in tagnames:
+ continue
+ for f in fields:
+ if f == "node_id":
+ val = k
+ if f == "tagname":
+ val = name
+ if f == "value":
+ val = value
+ r_data[f] = val
+ result.append(r_data)
+ return result
+
+ def AddSliceNodes(self, slicename, nodes=None):
+ import os, commands, tempfile
+ nodes = set(nodes)
+ nodes.update(self._slice_nodes)
+ nodes_data = dict((k, self._all_nodes[k]) for k in nodes)
+ p = sfa.SFAResourcesParser()
+ xml = p.create_slice_xml(nodes_data, self._slice_tags)
+ fh, fname = tempfile.mkstemp()
+ os.write(fh, xml)
+ os.close(fh)
+ out = commands.getoutput("sfi.py create %s %s" % (self._slice_id, fname))
+ os.remove(fname)
+ #print out
+
+def sfiapi(slice_id):
+ api = SFIAPI()
+ api.FetchSliceInfo(slice_id)
+ return api
+