First draft of the Nitos federation with SFA
[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 from sfa.nitos.nitosxrn import xrn_to_hostname
20
21 class NITOSv1Node:
22
23     @staticmethod
24     def add_nodes(xml, nodes):
25         network_elems = xml.xpath('//network')
26         if len(network_elems) > 0:
27             network_elem = network_elems[0]
28         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
29             network_urn = nodes[0]['component_manager_id']
30             network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn())
31         else:
32             network_elem = xml
33
34         node_elems = []       
35         for node in nodes:
36             node_fields = ['component_manager_id', '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_to_hostname(node['component_id'])
48                 node_elem.set('component_name', component_name)
49                 hostname_elem = node_elem.add_element('hostname')
50                 hostname_elem.set_text(component_name)
51
52             # set site id
53             if 'authority_id' in node and node['authority_id']:
54                 node_elem.set('site_id', node['authority_id'])
55
56             # add locaiton
57             location = node.get('location')
58             if location:
59                 node_elem.add_instance('location', location, Location.fields)
60
61             # add 3D Position of the node
62             position_3d = node.get('position_3d')
63             if position_3d:
64                 node_elem.add_instance('position_3d', position_3d, Position3D.fields)
65
66
67             # add granularity of the reservation system
68             granularity = node.get('granularity')['grain']
69             if granularity:
70                 #node_elem.add_instance('granularity', granularity, granularity.fields)
71                 granularity_elem = node_elem.add_element('granularity')
72                 granularity_elem.set_text(str(granularity))
73             # add hardware type
74             #hardware_type = node.get('hardware_type')
75             #if hardware_type:
76             #    node_elem.add_instance('hardware_type', hardware_type)
77             hardware_type_elem = node_elem.add_element('hardware_type')
78             hardware_type_elem.set_text(node.get('hardware_type'))
79
80
81             if isinstance(node.get('interfaces'), list):
82                 for interface in node.get('interfaces', []):
83                     node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
84             
85             #if 'bw_unallocated' in node and node['bw_unallocated']:
86             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
87
88             PGv2Services.add_services(node_elem, node.get('services', []))
89             tags = node.get('tags', [])
90             if tags:
91                 for tag in tags:
92                     tag_elem = node_elem.add_element(tag['tagname'])
93                     tag_elem.set_text(tag['value'])
94             NITOSv1Sliver.add_slivers(node_elem, node.get('slivers', []))
95
96     @staticmethod 
97     def add_slivers(xml, slivers):
98         component_ids = []
99         for sliver in slivers:
100             filter = {}
101             if isinstance(sliver, str):
102                 filter['component_id'] = '*%s*' % sliver
103                 sliver = {}
104             elif 'component_id' in sliver and sliver['component_id']:
105                 filter['component_id'] = '*%s*' % sliver['component_id']
106             if not filter:
107                 continue 
108             nodes = NITOSv1Node.get_nodes(xml, filter)
109             if not nodes:
110                 continue
111             node = nodes[0]
112             NITOSv1Sliver.add_slivers(node, sliver)
113
114     @staticmethod
115     def remove_slivers(xml, hostnames):
116         for hostname in hostnames:
117             nodes = NITOSv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
118             for node in nodes:
119                 slivers = NITOSv1Sliver.get_slivers(node.element)
120                 for sliver in slivers:
121                     node.element.remove(sliver.element)
122         
123     @staticmethod
124     def get_nodes(xml, filter={}):
125         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
126         node_elems = xml.xpath(xpath)
127         return NITOSv1Node.get_node_objs(node_elems)
128
129     @staticmethod
130     def get_nodes_with_slivers(xml):
131         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
132         node_elems = xml.xpath(xpath)
133         return NITOSv1Node.get_node_objs(node_elems)
134
135
136     @staticmethod
137     def get_node_objs(node_elems):
138         nodes = []    
139         for node_elem in node_elems:
140             node = Node(node_elem.attrib, node_elem)
141             if 'site_id' in node_elem.attrib:
142                 node['authority_id'] = node_elem.attrib['site_id']
143             # get location
144             location_elems = node_elem.xpath('./default:location | ./location')
145             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
146             if len(locations) > 0:
147                 node['location'] = locations[0]
148             # get bwlimit
149             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
150             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
151             if len(bwlimits) > 0:
152                 node['bwlimit'] = bwlimits[0]
153             # get interfaces
154             iface_elems = node_elem.xpath('./default:interface | ./interface')
155             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
156             node['interfaces'] = ifaces
157             # get services
158             node['services'] = PGv2Services.get_services(node_elem) 
159             # get slivers
160             node['slivers'] = NITOSv1Sliver.get_slivers(node_elem)
161             # get tags
162             node['tags'] =  NITOSv1PLTag.get_pl_tags(node_elem, ignore=Node.fields+["hardware_type"])
163             # get hardware types
164             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
165             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
166
167             # temporary... play nice with old slice manager rspec
168             if not node['component_name']:
169                 hostname_elem = node_elem.find("hostname")
170                 if hostname_elem != None:
171                     node['component_name'] = hostname_elem.text
172
173             nodes.append(node)
174         return nodes            
175