ea59b3d5045a6d8955e0d6c74f62c16039660766
[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 NodeElement
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, rspec_content_type=None):
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             # add sliver tag in Request Rspec
107             if rspec_content_type == "request":
108                 node_elem.add_instance('sliver', '', [])
109
110     @staticmethod 
111     def add_slivers(xml, slivers):
112         component_ids = []
113         for sliver in slivers:
114             filter = {}
115             if isinstance(sliver, str):
116                 filter['component_id'] = '*%s*' % sliver
117                 sliver = {}
118             elif 'component_id' in sliver and sliver['component_id']:
119                 filter['component_id'] = '*%s*' % sliver['component_id']
120             if not filter:
121                 continue 
122             nodes = NITOSv1Node.get_nodes(xml, filter)
123             if not nodes:
124                 continue
125             node = nodes[0]
126             NITOSv1Sliver.add_slivers(node, sliver)
127
128     @staticmethod
129     def remove_slivers(xml, hostnames):
130         for hostname in hostnames:
131             nodes = NITOSv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
132             for node in nodes:
133                 slivers = NITOSv1Sliver.get_slivers(node.element)
134                 for sliver in slivers:
135                     node.element.remove(sliver.element)
136         
137     @staticmethod
138     def get_nodes(xml, filter=None):
139         if filter is None: filter={}
140         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
141         node_elems = xml.xpath(xpath)
142         return NITOSv1Node.get_node_objs(node_elems)
143
144     @staticmethod
145     def get_nodes_with_slivers(xml):
146         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
147         node_elems = xml.xpath(xpath)
148         return NITOSv1Node.get_node_objs(node_elems)
149
150
151     @staticmethod
152     def get_node_objs(node_elems):
153         nodes = []    
154         for node_elem in node_elems:
155             node = NodeElement(node_elem.attrib, node_elem)
156             if 'site_id' in node_elem.attrib:
157                 node['authority_id'] = node_elem.attrib['site_id']
158             # get location
159             location_elems = node_elem.xpath('./default:location | ./location')
160             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
161             if len(locations) > 0:
162                 node['location'] = locations[0]
163             # get bwlimit
164             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
165             bwlimits = [bwlimit_elem.get_instance(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 = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
171             node['interfaces'] = ifaces
172             # get services
173             node['services'] = PGv2Services.get_services(node_elem) 
174             # get slivers
175             node['slivers'] = NITOSv1Sliver.get_slivers(node_elem)
176             # get tags
177             node['tags'] =  NITOSv1PLTag.get_pl_tags(node_elem, ignore=NodeElement.fields+["hardware_type"])
178             # get hardware types
179             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
180             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
181
182             # temporary... play nice with old slice manager rspec
183             if not node['component_name']:
184                 hostname_elem = node_elem.find("hostname")
185                 if hostname_elem != None:
186                     node['component_name'] = hostname_elem.text
187
188             nodes.append(node)
189         return nodes            
190