2 # -*- coding: utf-8 -*-
3 from __future__ import print_function
5 from copy import deepcopy
8 from sfa.util.sfalogging import logger
9 from sfa.util.xrn import hrn_to_urn, urn_to_hrn
10 from sfa.rspecs.version import RSpecVersion
11 from sfa.rspecs.elements.element import Element
12 from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
13 from sfa.rspecs.elements.versions.sfav1Node import SFAv1Node
14 from sfa.rspecs.elements.versions.sfav1Sliver import SFAv1Sliver
15 from sfa.rspecs.elements.versions.sfav1Lease import SFAv1Lease
16 from sfa.rspecs.elements.versions.ofeliav1datapath import Ofeliav1Datapath
17 from sfa.rspecs.elements.versions.ofeliav1link import Ofeliav1Link
19 class Ofelia(RSpecVersion):
24 schema = 'https://github.com/fp7-ofelia/ocf/blob/ocf.rspecs/openflow/schemas/ad.xsd'
25 namespace = 'openflow'
27 namespaces = dict(list(extensions.items()) + [('default', namespace)])
28 #template = '<RSpec type="%s"></RSpec>' % type
29 template = '<rspec></rspec>'
32 def get_networks(self):
33 raise Exception("Not implemented")
34 network_elems = self.xml.xpath('//network')
35 networks = [network_elem.get_instance(fields=['name', 'slice']) for \
36 network_elem in network_elems]
40 def add_network(self, network):
41 raise Exception("Not implemented")
42 network_tags = self.xml.xpath('//network[@name="%s"]' % network)
44 network_tag = self.xml.add_element('network', name=network)
46 network_tag = network_tags[0]
49 # These are all resources
50 # get_resources function can return all resources or a specific type of resource
51 def get_resources(self, filter=None, type=None):
53 if not type or type=='datapath':
54 datapaths = self.get_datapaths(filter)
55 for datapath in datapaths:
56 datapath['type']='datapath'
57 resources.extend(datapaths)
58 if not type or type=='link':
59 links = self.get_links(filter)
62 resources.extend(links)
66 def get_datapaths(self, filter=None):
67 return Ofeliav1Datapath.get_datapaths(self.xml, filter)
70 def get_links(self, filter=None):
71 return Ofeliav1Link.get_links(self.xml, filter)
73 # def get_link_requests(self):
74 # return PGv2Link.get_link_requests(self.xml)
76 # def add_links(self, links):
77 # networks = self.get_networks()
78 # if len(networks) > 0:
79 # xml = networks[0].element
82 # PGv2Link.add_links(xml, links)
84 # def add_link_requests(self, links):
85 # PGv2Link.add_link_requests(self.xml, links)
91 def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
92 if attributes is None: attributes=[]
93 # add slice name to network tag
94 network_tags = self.xml.xpath('//network')
96 network_tag = network_tags[0]
97 network_tag.set('slice', urn_to_hrn(sliver_urn)[0])
100 sliver = {'name':sliver_urn,
101 'pl_tags': attributes}
102 for hostname in hostnames:
104 sliver['name'] = sliver_urn
105 node_elems = self.get_nodes({'component_id': '*%s*' % hostname})
108 node_elem = node_elems[0]
109 SFAv1Sliver.add_slivers(node_elem.element, sliver)
111 # remove all nodes without slivers
113 for node_elem in self.get_nodes():
114 if not node_elem['slivers']:
115 parent = node_elem.element.getparent()
116 parent.remove(node_elem.element)
119 def remove_slivers(self, slivers, network=None, no_dupes=False):
120 SFAv1Node.remove_slivers(self.xml, slivers)
122 def get_slice_attributes(self, network=None):
124 nodes_with_slivers = self.get_nodes_with_slivers()
125 for default_attribute in self.get_default_sliver_attributes(network):
126 attribute = default_attribute.copy()
127 attribute['node_id'] = None
128 attributes.append(attribute)
129 for node in nodes_with_slivers:
130 nodename=node['component_name']
131 sliver_attributes = self.get_sliver_attributes(nodename, network)
132 for sliver_attribute in sliver_attributes:
133 sliver_attribute['node_id'] = nodename
134 attributes.append(sliver_attribute)
138 def add_sliver_attribute(self, component_id, name, value, network=None):
139 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
140 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
142 slivers = SFAv1Sliver.get_slivers(node)
145 SFAv1Sliver.add_sliver_attribute(sliver, name, value)
147 # should this be an assert / raise an exception?
148 logger.error("WARNING: failed to find component_id %s" % component_id)
150 def get_sliver_attributes(self, component_id, network=None):
151 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
153 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
155 slivers = SFAv1Sliver.get_slivers(node.element)
156 if slivers is not None and isinstance(slivers, list) and len(slivers) > 0:
158 attribs = SFAv1Sliver.get_sliver_attributes(sliver.element)
161 def remove_sliver_attribute(self, component_id, name, value, network=None):
162 attribs = self.get_sliver_attributes(component_id)
163 for attrib in attribs:
164 if attrib['name'] == name and attrib['value'] == value:
165 #attrib.element.delete()
166 parent = attrib.element.getparent()
167 parent.remove(attrib.element)
169 def add_default_sliver_attribute(self, name, value, network=None):
171 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
173 defaults = self.xml.xpath("//sliver_defaults")
176 network_tag = self.xml.xpath("//network[@name='%s']" % network)
178 network_tag = self.xml.xpath("//network")
179 if isinstance(network_tag, list):
180 network_tag = network_tag[0]
181 defaults = network_tag.add_element('sliver_defaults')
182 elif isinstance(defaults, list):
183 defaults = defaults[0]
184 SFAv1Sliver.add_sliver_attribute(defaults, name, value)
186 def get_default_sliver_attributes(self, network=None):
188 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
190 defaults = self.xml.xpath("//sliver_defaults")
191 if not defaults: return []
192 return SFAv1Sliver.get_sliver_attributes(defaults[0])
194 def remove_default_sliver_attribute(self, name, value, network=None):
195 attribs = self.get_default_sliver_attributes(network)
196 for attrib in attribs:
197 if attrib['name'] == name and attrib['value'] == value:
198 #attrib.element.delete()
199 parent = attrib.element.getparent()
200 parent.remove(attrib.element)
204 def merge(self, in_rspec):
206 Merge contents for specified rspec with current rspec
212 from sfa.rspecs.rspec import RSpec
213 if isinstance(in_rspec, RSpec):
216 rspec = RSpec(in_rspec)
217 if rspec.version.type.lower() == 'protogeni':
218 from sfa.rspecs.rspec_converter import RSpecConverter
219 in_rspec = RSpecConverter.to_sfa_rspec(rspec.toxml())
220 rspec = RSpec(in_rspec)
222 # just copy over all networks
223 current_networks = self.get_networks()
224 networks = rspec.version.get_networks()
225 for network in networks:
226 current_network = network.get('name')
227 if current_network and current_network not in current_networks:
228 self.xml.append(network.element)
229 current_networks.append(current_network)
231 if __name__ == '__main__':
234 from sfa.rspecs.rspec import RSpec
235 from sfa.rspecs.rspec_elements import *
236 print("main ofeliav1")
238 r = RSpec('/tmp/resources.rspec')
240 r = RSpec(sys.argv[1], version = 'OFELIA 1')
241 #print r.version.get_datapaths()
242 resources = r.version.get_resources()
243 pprint.pprint(resources)
245 #r.load_rspec_elements(SFAv1.elements)
246 #print r.get(RSpecElements.NODE)