Merge Master in geni-v3 conflict resolution
[sfa.git] / sfa / rspecs / elements / versions / nitosv1Node.py
1 from sfa.util.sfalogging import logger
2 from sfa.util.xml import XpathFilter
3 from sfa.util.xrn import Xrn
4
5 from sfa.rspecs.elements.element import Element
6 from sfa.rspecs.elements.node import Node
7 from sfa.rspecs.elements.sliver import Sliver
8 from sfa.rspecs.elements.location import Location
9 from sfa.rspecs.elements.position_3d import Position3D
10 from sfa.rspecs.elements.hardware_type import HardwareType
11 from sfa.rspecs.elements.disk_image import DiskImage
12 from sfa.rspecs.elements.interface import Interface
13 from sfa.rspecs.elements.bwlimit import BWlimit
14 from sfa.rspecs.elements.pltag import PLTag
15 from sfa.rspecs.elements.versions.nitosv1Sliver import NITOSv1Sliver
16 from sfa.rspecs.elements.versions.nitosv1PLTag import NITOSv1PLTag
17 from sfa.rspecs.elements.versions.pgv2Services import PGv2Services
18
19
20 class NITOSv1Node:
21
22     @staticmethod
23     def add_nodes(xml, nodes):
24         network_elems = xml.xpath('//network')
25         if len(network_elems) > 0:
26             network_elem = network_elems[0]
27         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
28             network_urn = nodes[0]['component_manager_id']
29             network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn())
30         else:
31             network_elem = xml
32
33         # needs to be improuved to retreive the gateway addr dynamically.
34         gateway_addr = 'nitlab.inf.uth.gr'
35
36         node_elems = []       
37         for node in nodes:
38             node_fields = ['component_manager_id', 'component_id', 'boot_state']
39             node_elem = network_elem.add_instance('node', node, node_fields)
40             node_elems.append(node_elem)
41
42             # determine network hrn
43             network_hrn = None 
44             if 'component_manager_id' in node and node['component_manager_id']:
45                 network_hrn = Xrn(node['component_manager_id']).get_hrn()
46
47             # set component_name attribute and  hostname element
48             if 'component_id' in node and node['component_id']:
49                 component_name = Xrn(xrn=node['component_id']).get_leaf()
50                 node_elem.set('component_name', component_name)
51                 hostname_elem = node_elem.add_element('hostname')
52                 hostname_elem.set_text(component_name)
53
54             # set site id
55             if 'authority_id' in node and node['authority_id']:
56                 node_elem.set('site_id', node['authority_id'])
57
58             # add locaiton
59             location = node.get('location')
60             if location:
61                 node_elem.add_instance('location', location, Location.fields)
62
63             # add 3D Position of the node
64             position_3d = node.get('position_3d')
65             if position_3d:
66                 node_elem.add_instance('position_3d', position_3d, Position3D.fields)
67
68             # all nitos nodes are exculsive
69             exclusive_elem = node_elem.add_element('exclusive')
70             exclusive_elem.set_text('TRUE')
71  
72             # In order to access nitos nodes, one need to pass through the nitos gateway
73             # here we advertise Nitos access gateway address
74             gateway_elem = node_elem.add_element('gateway')
75             gateway_elem.set_text(gateway_addr)
76
77             # add granularity of the reservation system
78             granularity = node.get('granularity')['grain']
79             if granularity:
80                 #node_elem.add_instance('granularity', granularity, granularity.fields)
81                 granularity_elem = node_elem.add_element('granularity')
82                 granularity_elem.set_text(str(granularity))
83             # add hardware type
84             #hardware_type = node.get('hardware_type')
85             #if hardware_type:
86             #    node_elem.add_instance('hardware_type', hardware_type)
87             hardware_type_elem = node_elem.add_element('hardware_type')
88             hardware_type_elem.set_text(node.get('hardware_type'))
89
90
91             if isinstance(node.get('interfaces'), list):
92                 for interface in node.get('interfaces', []):
93                     node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
94             
95             #if 'bw_unallocated' in node and node['bw_unallocated']:
96             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
97
98             PGv2Services.add_services(node_elem, node.get('services', []))
99             tags = node.get('tags', [])
100             if tags:
101                 for tag in tags:
102                     tag_elem = node_elem.add_element(tag['tagname'])
103                     tag_elem.set_text(tag['value'])
104             NITOSv1Sliver.add_slivers(node_elem, node.get('slivers', []))
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 = NITOSv1Node.get_nodes(xml, filter)
119             if not nodes:
120                 continue
121             node = nodes[0]
122             NITOSv1Sliver.add_slivers(node, sliver)
123
124     @staticmethod
125     def remove_slivers(xml, hostnames):
126         for hostname in hostnames:
127             nodes = NITOSv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
128             for node in nodes:
129                 slivers = NITOSv1Sliver.get_slivers(node.element)
130                 for sliver in slivers:
131                     node.element.remove(sliver.element)
132         
133     @staticmethod
134     def get_nodes(xml, filter={}):
135         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
136         node_elems = xml.xpath(xpath)
137         return NITOSv1Node.get_node_objs(node_elems)
138
139     @staticmethod
140     def get_nodes_with_slivers(xml):
141         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
142         node_elems = xml.xpath(xpath)
143         return NITOSv1Node.get_node_objs(node_elems)
144
145
146     @staticmethod
147     def get_node_objs(node_elems):
148         nodes = []    
149         for node_elem in node_elems:
150             node = Node(node_elem.attrib, node_elem)
151             if 'site_id' in node_elem.attrib:
152                 node['authority_id'] = node_elem.attrib['site_id']
153             # get location
154             location_elems = node_elem.xpath('./default:location | ./location')
155             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
156             if len(locations) > 0:
157                 node['location'] = locations[0]
158             # get bwlimit
159             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
160             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
161             if len(bwlimits) > 0:
162                 node['bwlimit'] = bwlimits[0]
163             # get interfaces
164             iface_elems = node_elem.xpath('./default:interface | ./interface')
165             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
166             node['interfaces'] = ifaces
167             # get services
168             node['services'] = PGv2Services.get_services(node_elem) 
169             # get slivers
170             node['slivers'] = NITOSv1Sliver.get_slivers(node_elem)
171             # get tags
172             node['tags'] =  NITOSv1PLTag.get_pl_tags(node_elem, ignore=Node.fields+["hardware_type"])
173             # get hardware types
174             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
175             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
176
177             # temporary... play nice with old slice manager rspec
178             if not node['component_name']:
179                 hostname_elem = node_elem.find("hostname")
180                 if hostname_elem != None:
181                     node['component_name'] = hostname_elem.text
182
183             nodes.append(node)
184         return nodes            
185