2 # -*- coding: utf-8 -*-
3 from copy import deepcopy
6 from sfa.util.sfalogging import logger
7 from sfa.util.xrn import hrn_to_urn, urn_to_hrn
8 from sfa.rspecs.version import RSpecVersion
9 from sfa.rspecs.elements.element import Element
10 from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
11 from sfa.rspecs.elements.versions.sfav1Node import SFAv1Node
12 from sfa.rspecs.elements.versions.sfav1Sliver import SFAv1Sliver
13 from sfa.rspecs.elements.versions.sfav1Lease import SFAv1Lease
14 from sfa.rspecs.elements.versions.ofeliav1datapath import Ofeliav1Datapath
15 from sfa.rspecs.elements.versions.ofeliav1link import Ofeliav1Link
17 class Ofelia(RSpecVersion):
22 schema = 'https://github.com/fp7-ofelia/ocf/blob/ocf.rspecs/openflow/schemas/ad.xsd'
23 namespace = 'openflow'
25 namespaces = dict(extensions.items() + [('default', namespace)])
26 #template = '<RSpec type="%s"></RSpec>' % type
27 template = '<rspec></rspec>'
30 def get_networks(self):
31 raise Exception, "Not implemented"
32 network_elems = self.xml.xpath('//network')
33 networks = [network_elem.get_instance(fields=['name', 'slice']) for \
34 network_elem in network_elems]
38 def add_network(self, network):
39 raise Exception, "Not implemented"
40 network_tags = self.xml.xpath('//network[@name="%s"]' % network)
42 network_tag = self.xml.add_element('network', name=network)
44 network_tag = network_tags[0]
47 # These are all resources
48 # get_resources function can return all resources or a specific type of resource
49 def get_resources(self, filter=None, type=None):
51 if not type or type=='datapath':
52 datapaths = self.get_datapaths(filter)
53 for datapath in datapaths:
54 datapath['type']='datapath'
55 resources.extend(datapaths)
56 if not type or type=='link':
57 links = self.get_links(filter)
60 resources.extend(links)
64 def get_datapaths(self, filter=None):
65 return Ofeliav1Datapath.get_datapaths(self.xml, filter)
68 def get_links(self, filter=None):
69 return Ofeliav1Link.get_links(self.xml, filter)
71 # def get_link_requests(self):
72 # return PGv2Link.get_link_requests(self.xml)
74 # def add_links(self, links):
75 # networks = self.get_networks()
76 # if len(networks) > 0:
77 # xml = networks[0].element
80 # PGv2Link.add_links(xml, links)
82 # def add_link_requests(self, links):
83 # PGv2Link.add_link_requests(self.xml, links)
89 def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
90 # add slice name to network tag
91 network_tags = self.xml.xpath('//network')
93 network_tag = network_tags[0]
94 network_tag.set('slice', urn_to_hrn(sliver_urn)[0])
97 sliver = {'name':sliver_urn,
98 'pl_tags': attributes}
99 for hostname in hostnames:
101 sliver['name'] = sliver_urn
102 node_elems = self.get_nodes({'component_id': '*%s*' % hostname})
105 node_elem = node_elems[0]
106 SFAv1Sliver.add_slivers(node_elem.element, sliver)
108 # remove all nodes without slivers
110 for node_elem in self.get_nodes():
111 if not node_elem['slivers']:
112 parent = node_elem.element.getparent()
113 parent.remove(node_elem.element)
116 def remove_slivers(self, slivers, network=None, no_dupes=False):
117 SFAv1Node.remove_slivers(self.xml, slivers)
119 def get_slice_attributes(self, network=None):
121 nodes_with_slivers = self.get_nodes_with_slivers()
122 for default_attribute in self.get_default_sliver_attributes(network):
123 attribute = default_attribute.copy()
124 attribute['node_id'] = None
125 attributes.append(attribute)
126 for node in nodes_with_slivers:
127 nodename=node['component_name']
128 sliver_attributes = self.get_sliver_attributes(nodename, network)
129 for sliver_attribute in sliver_attributes:
130 sliver_attribute['node_id'] = nodename
131 attributes.append(sliver_attribute)
135 def add_sliver_attribute(self, component_id, name, value, network=None):
136 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
137 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
139 slivers = SFAv1Sliver.get_slivers(node)
142 SFAv1Sliver.add_sliver_attribute(sliver, name, value)
144 # should this be an assert / raise an exception?
145 logger.error("WARNING: failed to find component_id %s" % component_id)
147 def get_sliver_attributes(self, component_id, network=None):
148 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
150 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
152 slivers = SFAv1Sliver.get_slivers(node.element)
153 if slivers is not None and isinstance(slivers, list) and len(slivers) > 0:
155 attribs = SFAv1Sliver.get_sliver_attributes(sliver.element)
158 def remove_sliver_attribute(self, component_id, name, value, network=None):
159 attribs = self.get_sliver_attributes(component_id)
160 for attrib in attribs:
161 if attrib['name'] == name and attrib['value'] == value:
162 #attrib.element.delete()
163 parent = attrib.element.getparent()
164 parent.remove(attrib.element)
166 def add_default_sliver_attribute(self, name, value, network=None):
168 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
170 defaults = self.xml.xpath("//sliver_defaults")
173 network_tag = self.xml.xpath("//network[@name='%s']" % network)
175 network_tag = self.xml.xpath("//network")
176 if isinstance(network_tag, list):
177 network_tag = network_tag[0]
178 defaults = network_tag.add_element('sliver_defaults')
179 elif isinstance(defaults, list):
180 defaults = defaults[0]
181 SFAv1Sliver.add_sliver_attribute(defaults, name, value)
183 def get_default_sliver_attributes(self, network=None):
185 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
187 defaults = self.xml.xpath("//sliver_defaults")
188 if not defaults: return []
189 return SFAv1Sliver.get_sliver_attributes(defaults[0])
191 def remove_default_sliver_attribute(self, name, value, network=None):
192 attribs = self.get_default_sliver_attributes(network)
193 for attrib in attribs:
194 if attrib['name'] == name and attrib['value'] == value:
195 #attrib.element.delete()
196 parent = attrib.element.getparent()
197 parent.remove(attrib.element)
201 def merge(self, in_rspec):
203 Merge contents for specified rspec with current rspec
209 from sfa.rspecs.rspec import RSpec
210 if isinstance(in_rspec, RSpec):
213 rspec = RSpec(in_rspec)
214 if rspec.version.type.lower() == 'protogeni':
215 from sfa.rspecs.rspec_converter import RSpecConverter
216 in_rspec = RSpecConverter.to_sfa_rspec(rspec.toxml())
217 rspec = RSpec(in_rspec)
219 # just copy over all networks
220 current_networks = self.get_networks()
221 networks = rspec.version.get_networks()
222 for network in networks:
223 current_network = network.get('name')
224 if current_network and current_network not in current_networks:
225 self.xml.append(network.element)
226 current_networks.append(current_network)
228 if __name__ == '__main__':
231 from sfa.rspecs.rspec import RSpec
232 from sfa.rspecs.rspec_elements import *
233 print "main ofeliav1"
235 r = RSpec('/tmp/resources.rspec')
237 r = RSpec(sys.argv[1], version = 'OFELIA 1')
238 #print r.version.get_datapaths()
239 resources = r.version.get_resources()
240 pprint.pprint(resources)
242 #r.load_rspec_elements(SFAv1.elements)
243 #print r.get(RSpecElements.NODE)