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=None, sliver_urn=None, append=False):
90 if attributes is None: attributes=[]
91 # add slice name to network tag
92 network_tags = self.xml.xpath('//network')
94 network_tag = network_tags[0]
95 network_tag.set('slice', urn_to_hrn(sliver_urn)[0])
98 sliver = {'name':sliver_urn,
99 'pl_tags': attributes}
100 for hostname in hostnames:
102 sliver['name'] = sliver_urn
103 node_elems = self.get_nodes({'component_id': '*%s*' % hostname})
106 node_elem = node_elems[0]
107 SFAv1Sliver.add_slivers(node_elem.element, sliver)
109 # remove all nodes without slivers
111 for node_elem in self.get_nodes():
112 if not node_elem['slivers']:
113 parent = node_elem.element.getparent()
114 parent.remove(node_elem.element)
117 def remove_slivers(self, slivers, network=None, no_dupes=False):
118 SFAv1Node.remove_slivers(self.xml, slivers)
120 def get_slice_attributes(self, network=None):
122 nodes_with_slivers = self.get_nodes_with_slivers()
123 for default_attribute in self.get_default_sliver_attributes(network):
124 attribute = default_attribute.copy()
125 attribute['node_id'] = None
126 attributes.append(attribute)
127 for node in nodes_with_slivers:
128 nodename=node['component_name']
129 sliver_attributes = self.get_sliver_attributes(nodename, network)
130 for sliver_attribute in sliver_attributes:
131 sliver_attribute['node_id'] = nodename
132 attributes.append(sliver_attribute)
136 def add_sliver_attribute(self, component_id, name, value, network=None):
137 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
138 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
140 slivers = SFAv1Sliver.get_slivers(node)
143 SFAv1Sliver.add_sliver_attribute(sliver, name, value)
145 # should this be an assert / raise an exception?
146 logger.error("WARNING: failed to find component_id %s" % component_id)
148 def get_sliver_attributes(self, component_id, network=None):
149 nodes = self.get_nodes({'component_id': '*%s*' % component_id})
151 if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
153 slivers = SFAv1Sliver.get_slivers(node.element)
154 if slivers is not None and isinstance(slivers, list) and len(slivers) > 0:
156 attribs = SFAv1Sliver.get_sliver_attributes(sliver.element)
159 def remove_sliver_attribute(self, component_id, name, value, network=None):
160 attribs = self.get_sliver_attributes(component_id)
161 for attrib in attribs:
162 if attrib['name'] == name and attrib['value'] == value:
163 #attrib.element.delete()
164 parent = attrib.element.getparent()
165 parent.remove(attrib.element)
167 def add_default_sliver_attribute(self, name, value, network=None):
169 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
171 defaults = self.xml.xpath("//sliver_defaults")
174 network_tag = self.xml.xpath("//network[@name='%s']" % network)
176 network_tag = self.xml.xpath("//network")
177 if isinstance(network_tag, list):
178 network_tag = network_tag[0]
179 defaults = network_tag.add_element('sliver_defaults')
180 elif isinstance(defaults, list):
181 defaults = defaults[0]
182 SFAv1Sliver.add_sliver_attribute(defaults, name, value)
184 def get_default_sliver_attributes(self, network=None):
186 defaults = self.xml.xpath("//network[@name='%s']/sliver_defaults" % network)
188 defaults = self.xml.xpath("//sliver_defaults")
189 if not defaults: return []
190 return SFAv1Sliver.get_sliver_attributes(defaults[0])
192 def remove_default_sliver_attribute(self, name, value, network=None):
193 attribs = self.get_default_sliver_attributes(network)
194 for attrib in attribs:
195 if attrib['name'] == name and attrib['value'] == value:
196 #attrib.element.delete()
197 parent = attrib.element.getparent()
198 parent.remove(attrib.element)
202 def merge(self, in_rspec):
204 Merge contents for specified rspec with current rspec
210 from sfa.rspecs.rspec import RSpec
211 if isinstance(in_rspec, RSpec):
214 rspec = RSpec(in_rspec)
215 if rspec.version.type.lower() == 'protogeni':
216 from sfa.rspecs.rspec_converter import RSpecConverter
217 in_rspec = RSpecConverter.to_sfa_rspec(rspec.toxml())
218 rspec = RSpec(in_rspec)
220 # just copy over all networks
221 current_networks = self.get_networks()
222 networks = rspec.version.get_networks()
223 for network in networks:
224 current_network = network.get('name')
225 if current_network and current_network not in current_networks:
226 self.xml.append(network.element)
227 current_networks.append(current_network)
229 if __name__ == '__main__':
232 from sfa.rspecs.rspec import RSpec
233 from sfa.rspecs.rspec_elements import *
234 print "main ofeliav1"
236 r = RSpec('/tmp/resources.rspec')
238 r = RSpec(sys.argv[1], version = 'OFELIA 1')
239 #print r.version.get_datapaths()
240 resources = r.version.get_resources()
241 pprint.pprint(resources)
243 #r.load_rspec_elements(SFAv1.elements)
244 #print r.get(RSpecElements.NODE)