autopep8
[sfa.git] / sfa / rspecs / elements / versions / sfav1Node.py
1 from sfa.util.sfalogging import logger
2 from sfa.util.xml import XpathFilter
3 from sfa.util.xrn import Xrn, get_leaf
4
5 from sfa.rspecs.elements.element import Element
6 from sfa.rspecs.elements.node import NodeElement
7 from sfa.rspecs.elements.sliver import Sliver
8 from sfa.rspecs.elements.location import Location
9 from sfa.rspecs.elements.hardware_type import HardwareType
10 from sfa.rspecs.elements.disk_image import DiskImage
11 from sfa.rspecs.elements.interface import Interface
12 from sfa.rspecs.elements.bwlimit import BWlimit
13 from sfa.rspecs.elements.pltag import PLTag
14 from sfa.rspecs.elements.versions.sfav1Sliver import SFAv1Sliver
15 from sfa.rspecs.elements.versions.sfav1PLTag import SFAv1PLTag
16 from sfa.rspecs.elements.versions.pgv2Services import PGv2Services
17
18
19 class SFAv1Node:
20
21     @staticmethod
22     def add_nodes(xml, nodes, rspec_content_type=None):
23         network_elems = xml.xpath('//network')
24         if len(network_elems) > 0:
25             network_elem = network_elems[0]
26         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
27             network_urn = nodes[0]['component_manager_id']
28             network_elem = xml.add_element(
29                 'network', name=Xrn(network_urn).get_hrn())
30         else:
31             network_elem = xml
32
33         node_elems = []
34         for node in nodes:
35             node_fields = ['component_manager_id',
36                            'component_id', 'boot_state']
37             node_elem = network_elem.add_instance('node', node, node_fields)
38             node_elems.append(node_elem)
39
40             # determine network hrn
41             network_hrn = None
42             if 'component_manager_id' in node and node['component_manager_id']:
43                 network_hrn = Xrn(node['component_manager_id']).get_hrn()
44
45             # set component_name attribute and  hostname element
46             if 'component_id' in node and node['component_id']:
47                 component_name = Xrn.unescape(
48                     get_leaf(Xrn(node['component_id']).get_hrn()))
49                 node_elem.set('component_name', component_name)
50                 hostname_elem = node_elem.add_element('hostname')
51                 hostname_elem.set_text(component_name)
52
53             # set site id
54             if 'authority_id' in node and node['authority_id']:
55                 node_elem.set('site_id', node['authority_id'])
56
57             # add locaiton
58             location = node.get('location')
59             if location:
60                 node_elem.add_instance('location', location, Location.fields)
61
62             # add exclusive tag to distinguish between Reservable and Shared
63             # nodes
64             exclusive_elem = node_elem.add_element('exclusive')
65             if node.get('exclusive') and node.get('exclusive') == 'true':
66                 exclusive_elem.set_text('TRUE')
67                 # add granularity of the reservation system
68                 granularity = node.get('granularity')
69                 if granularity:
70                     node_elem.add_instance(
71                         'granularity', granularity, granularity.fields)
72             else:
73                 exclusive_elem.set_text('FALSE')
74
75             if isinstance(node.get('interfaces'), list):
76                 for interface in node.get('interfaces', []):
77                     node_elem.add_instance('interface', interface, [
78                                            'component_id', 'client_id', 'ipv4'])
79
80             # if 'bw_unallocated' in node and node['bw_unallocated']:
81             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
82
83             PGv2Services.add_services(node_elem, node.get('services', []))
84             tags = node.get('tags', [])
85             if tags:
86                 for tag in tags:
87                     # backdoor for FITeagle
88                     # Alexander Willner <alexander.willner@tu-berlin.de>
89                     if tag['tagname'] == "fiteagle_settings":
90                         tag_elem = node_elem.add_element(tag['tagname'])
91                         for subtag in tag['value']:
92                             subtag_elem = tag_elem.add_element('setting')
93                             subtag_elem.set('name', str(subtag['tagname']))
94                             subtag_elem.set('description', str(
95                                 subtag['description']))
96                             subtag_elem.set_text(subtag['value'])
97                     else:
98                         tag_elem = node_elem.add_element(tag['tagname'])
99                         tag_elem.set_text(tag['value'])
100             SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
101
102             # add sliver tag in Request Rspec
103             if rspec_content_type == "request":
104                 node_elem.add_instance('sliver', '', [])
105
106     @staticmethod
107     def add_slivers(xml, slivers):
108         component_ids = []
109         for sliver in slivers:
110             filter = {}
111             if isinstance(sliver, str):
112                 filter['component_id'] = '*%s*' % sliver
113                 sliver = {}
114             elif 'component_id' in sliver and sliver['component_id']:
115                 filter['component_id'] = '*%s*' % sliver['component_id']
116             if not filter:
117                 continue
118             nodes = SFAv1Node.get_nodes(xml, filter)
119             if not nodes:
120                 continue
121             node = nodes[0]
122             SFAv1Sliver.add_slivers(node, sliver)
123
124     @staticmethod
125     def remove_slivers(xml, hostnames):
126         for hostname in hostnames:
127             nodes = SFAv1Node.get_nodes(
128                 xml, {'component_id': '*%s*' % hostname})
129             for node in nodes:
130                 slivers = SFAv1Sliver.get_slivers(node.element)
131                 for sliver in slivers:
132                     node.element.remove(sliver.element)
133
134     @staticmethod
135     def get_nodes(xml, filter=None):
136         if filter is None:
137             filter = {}
138         xpath = '//node%s | //default:node%s' % (
139             XpathFilter.xpath(filter), XpathFilter.xpath(filter))
140         node_elems = xml.xpath(xpath)
141         return SFAv1Node.get_node_objs(node_elems)
142
143     @staticmethod
144     def get_nodes_with_slivers(xml):
145         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]'
146         node_elems = xml.xpath(xpath)
147         return SFAv1Node.get_node_objs(node_elems)
148
149     @staticmethod
150     def get_node_objs(node_elems):
151         nodes = []
152         for node_elem in node_elems:
153             node = NodeElement(node_elem.attrib, node_elem)
154             if 'site_id' in node_elem.attrib:
155                 node['authority_id'] = node_elem.attrib['site_id']
156             # get location
157             location_elems = node_elem.xpath('./default:location | ./location')
158             locations = [dict(loc_elem.get_instance(Location))
159                          for loc_elem in location_elems]
160             if len(locations) > 0:
161                 node['location'] = locations[0]
162             # get bwlimit
163             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
164             bwlimits = [bwlimit_elem.get_instance(
165                 BWlimit) for bwlimit_elem in bwlimit_elems]
166             if len(bwlimits) > 0:
167                 node['bwlimit'] = bwlimits[0]
168             # get interfaces
169             iface_elems = node_elem.xpath('./default:interface | ./interface')
170             ifaces = [dict(iface_elem.get_instance(Interface))
171                       for iface_elem in iface_elems]
172             node['interfaces'] = ifaces
173             # get services
174             node['services'] = PGv2Services.get_services(node_elem)
175             # get slivers
176             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
177             # get tags
178             node['tags'] = SFAv1PLTag.get_pl_tags(
179                 node_elem, ignore=NodeElement.fields + ["hardware_type"])
180             # get hardware types
181             hardware_type_elems = node_elem.xpath(
182                 './default:hardware_type | ./hardware_type')
183             node['hardware_types'] = [dict(hw_type.get_instance(
184                 HardwareType)) for hw_type in hardware_type_elems]
185
186             # temporary... play nice with old slice manager rspec
187             if not node['component_name']:
188                 hostname_elem = node_elem.find("hostname")
189                 if hostname_elem != None:
190                     node['component_name'] = hostname_elem.text
191
192             nodes.append(node)
193         return nodes