code for exposing country & city for a site
[sfa.git] / sfa / rspecs / versions / ofeliav1.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 from __future__ import print_function
4
5 from copy import deepcopy
6 from lxml import etree
7
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
18
19
20 class Ofelia(RSpecVersion):
21     enabled = True
22     type = 'OFELIA'
23     content_type = '*'
24     version = '1'
25     schema = 'https://github.com/fp7-ofelia/ocf/blob/ocf.rspecs/openflow/schemas/ad.xsd'
26     namespace = 'openflow'
27     extensions = {}
28     namespaces = dict(list(extensions.items()) + [('default', namespace)])
29     #template = '<RSpec type="%s"></RSpec>' % type
30     template = '<rspec></rspec>'
31
32     # Network
33     def get_networks(self):
34         raise Exception("Not implemented")
35         network_elems = self.xml.xpath('//network')
36         networks = [network_elem.get_instance(fields=['name', 'slice']) for
37                     network_elem in network_elems]
38         return networks
39
40     def add_network(self, network):
41         raise Exception("Not implemented")
42         network_tags = self.xml.xpath('//network[@name="%s"]' % network)
43         if not network_tags:
44             network_tag = self.xml.add_element('network', name=network)
45         else:
46             network_tag = network_tags[0]
47         return network_tag
48
49 # These are all resources
50 # get_resources function can return all resources or a specific type of
51 # resource
52     def get_resources(self, filter=None, type=None):
53         resources = list()
54         if not type or type == 'datapath':
55             datapaths = self.get_datapaths(filter)
56             for datapath in datapaths:
57                 datapath['type'] = 'datapath'
58             resources.extend(datapaths)
59         if not type or type == 'link':
60             links = self.get_links(filter)
61             for link in links:
62                 link['type'] = 'link'
63             resources.extend(links)
64         return resources
65
66     # Datapaths
67     def get_datapaths(self, filter=None):
68         return Ofeliav1Datapath.get_datapaths(self.xml, filter)
69
70     # Links
71     def get_links(self, filter=None):
72         return Ofeliav1Link.get_links(self.xml, filter)
73
74 #    def get_link_requests(self):
75 #        return PGv2Link.get_link_requests(self.xml)
76 #
77 #    def add_links(self, links):
78 #        networks = self.get_networks()
79 #        if len(networks) > 0:
80 #            xml = networks[0].element
81 #        else:
82 #            xml = self.xml
83 #        PGv2Link.add_links(xml, links)
84 #
85 #    def add_link_requests(self, links):
86 #        PGv2Link.add_link_requests(self.xml, links)
87
88     # Slivers
89
90     def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
91         if attributes is None:
92             attributes = []
93         # add slice name to network tag
94         network_tags = self.xml.xpath('//network')
95         if network_tags:
96             network_tag = network_tags[0]
97             network_tag.set('slice', urn_to_hrn(sliver_urn)[0])
98
99         # add slivers
100         sliver = {'name': sliver_urn,
101                   'pl_tags': attributes}
102         for hostname in hostnames:
103             if sliver_urn:
104                 sliver['name'] = sliver_urn
105             node_elems = self.get_nodes({'component_id': '*%s*' % hostname})
106             if not node_elems:
107                 continue
108             node_elem = node_elems[0]
109             SFAv1Sliver.add_slivers(node_elem.element, sliver)
110
111         # remove all nodes without slivers
112         if not append:
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)
117
118     def remove_slivers(self, slivers, network=None, no_dupes=False):
119         SFAv1Node.remove_slivers(self.xml, slivers)
120
121     def get_slice_attributes(self, network=None):
122         attributes = []
123         nodes_with_slivers = self.get_nodes_with_slivers()
124         for default_attribute in self.get_default_sliver_attributes(network):
125             attribute = default_attribute.copy()
126             attribute['node_id'] = None
127             attributes.append(attribute)
128         for node in nodes_with_slivers:
129             nodename = node['component_name']
130             sliver_attributes = self.get_sliver_attributes(nodename, network)
131             for sliver_attribute in sliver_attributes:
132                 sliver_attribute['node_id'] = nodename
133                 attributes.append(sliver_attribute)
134         return attributes
135
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:
139             node = nodes[0]
140             slivers = SFAv1Sliver.get_slivers(node)
141             if slivers:
142                 sliver = slivers[0]
143                 SFAv1Sliver.add_sliver_attribute(sliver, name, value)
144         else:
145             # should this be an assert / raise an exception?
146             logger.error("WARNING: failed to find component_id %s" %
147                          component_id)
148
149     def get_sliver_attributes(self, component_id, network=None):
150         nodes = self.get_nodes({'component_id': '*%s*' % component_id})
151         attribs = []
152         if nodes is not None and isinstance(nodes, list) and len(nodes) > 0:
153             node = nodes[0]
154             slivers = SFAv1Sliver.get_slivers(node.element)
155             if slivers is not None and isinstance(slivers, list) and len(slivers) > 0:
156                 sliver = slivers[0]
157                 attribs = SFAv1Sliver.get_sliver_attributes(sliver.element)
158         return attribs
159
160     def remove_sliver_attribute(self, component_id, name, value, network=None):
161         attribs = self.get_sliver_attributes(component_id)
162         for attrib in attribs:
163             if attrib['name'] == name and attrib['value'] == value:
164                 # attrib.element.delete()
165                 parent = attrib.element.getparent()
166                 parent.remove(attrib.element)
167
168     def add_default_sliver_attribute(self, name, value, network=None):
169         if network:
170             defaults = self.xml.xpath(
171                 "//network[@name='%s']/sliver_defaults" % network)
172         else:
173             defaults = self.xml.xpath("//sliver_defaults")
174         if not defaults:
175             if network:
176                 network_tag = self.xml.xpath("//network[@name='%s']" % network)
177             else:
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)
185
186     def get_default_sliver_attributes(self, network=None):
187         if network:
188             defaults = self.xml.xpath(
189                 "//network[@name='%s']/sliver_defaults" % network)
190         else:
191             defaults = self.xml.xpath("//sliver_defaults")
192         if not defaults:
193             return []
194         return SFAv1Sliver.get_sliver_attributes(defaults[0])
195
196     def remove_default_sliver_attribute(self, name, value, network=None):
197         attribs = self.get_default_sliver_attributes(network)
198         for attrib in attribs:
199             if attrib['name'] == name and attrib['value'] == value:
200                 # attrib.element.delete()
201                 parent = attrib.element.getparent()
202                 parent.remove(attrib.element)
203
204     # utility
205
206     def merge(self, in_rspec):
207         """
208         Merge contents for specified rspec with current rspec
209         """
210
211         if not in_rspec:
212             return
213
214         from sfa.rspecs.rspec import RSpec
215         if isinstance(in_rspec, RSpec):
216             rspec = in_rspec
217         else:
218             rspec = RSpec(in_rspec)
219         if rspec.version.type.lower() == 'protogeni':
220             from sfa.rspecs.rspec_converter import RSpecConverter
221             in_rspec = RSpecConverter.to_sfa_rspec(rspec.toxml())
222             rspec = RSpec(in_rspec)
223
224         # just copy over all networks
225         current_networks = self.get_networks()
226         networks = rspec.version.get_networks()
227         for network in networks:
228             current_network = network.get('name')
229             if current_network and current_network not in current_networks:
230                 self.xml.append(network.element)
231                 current_networks.append(current_network)
232
233 if __name__ == '__main__':
234     import sys
235     import pprint
236     from sfa.rspecs.rspec import RSpec
237     from sfa.rspecs.rspec_elements import *
238     print("main ofeliav1")
239     if len(sys.argv) != 2:
240         r = RSpec('/tmp/resources.rspec')
241     else:
242         r = RSpec(sys.argv[1], version='OFELIA 1')
243     # print r.version.get_datapaths()
244     resources = r.version.get_resources()
245     pprint.pprint(resources)
246
247     # r.load_rspec_elements(SFAv1.elements)
248     # print r.get(RSpecElements.NODE)