fefc9a159eb5c3ad41dee813b23aa23880f541ba
[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.plxrn import xrn_to_hostname
4 from sfa.util.xrn import Xrn
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.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 class SFAv1Node:
19
20     @staticmethod
21     def add_nodes(xml, nodes):
22         network_elems = xml.xpath('//network')
23         if len(network_elems) > 0:
24             network_elem = network_elems[0]
25         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
26             network_urn = nodes[0]['component_manager_id']
27             network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn())
28         else:
29             network_elem = xml
30
31         node_elems = []       
32         for node in nodes:
33             node_fields = ['component_manager_id', 'component_id', 'boot_state']
34             node_elem = network_elem.add_instance('node', node, node_fields)
35             node_elems.append(node_elem)
36
37             # determine network hrn
38             network_hrn = None 
39             if 'component_manager_id' in node and node['component_manager_id']:
40                 network_hrn = Xrn(node['component_manager_id']).get_hrn()
41
42             # set component_name attribute and  hostname element
43             if 'component_id' in node and node['component_id']:
44                 component_name = xrn_to_hostname(node['component_id'])
45                 node_elem.set('component_name', component_name)
46                 hostname_elem = node_elem.add_element('hostname')
47                 hostname_elem.set_text(component_name)
48
49             # set site id
50             if 'authority_id' in node and node['authority_id']:
51                 node_elem.set('site_id', node['authority_id'])
52
53             # add locaiton
54             location = node.get('location')
55             if location:
56                 node_elem.add_instance('location', location, Location.fields)
57
58             if isinstance(node.get('interfaces'), list):
59                 for interface in node.get('interfaces', []):
60                     node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
61             
62             #if 'bw_unallocated' in node and node['bw_unallocated']:
63             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
64
65             PGv2Services.add_services(node_elem, node.get('services', []))
66             tags = node.get('tags', [])
67             if tags:
68                 for tag in tags:
69                     tag_elem = node_elem.add_element(tag['tagname'])
70                     tag_elem.set_text(tag['value'])
71             SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
72
73     @staticmethod 
74     def add_slivers(xml, slivers):
75         component_ids = []
76         for sliver in slivers:
77             filter = {}
78             if isinstance(sliver, str):
79                 filter['component_id'] = '*%s*' % sliver
80                 sliver = {}
81             elif 'component_id' in sliver and sliver['component_id']:
82                 filter['component_id'] = '*%s*' % sliver['component_id']
83             if not filter:
84                 continue 
85             nodes = SFAv1Node.get_nodes(xml, filter)
86             if not nodes:
87                 continue
88             node = nodes[0]
89             SFAv1Sliver.add_slivers(node, sliver)
90
91     @staticmethod
92     def remove_slivers(xml, hostnames):
93         for hostname in hostnames:
94             nodes = SFAv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
95             for node in nodes:
96                 slivers = SFAv1Sliver.get_slivers(node.element)
97                 for sliver in slivers:
98                     node.element.remove(sliver.element)
99         
100     @staticmethod
101     def get_nodes(xml, filter={}):
102         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
103         node_elems = xml.xpath(xpath)
104         return SFAv1Node.get_node_objs(node_elems)
105
106     @staticmethod
107     def get_nodes_with_slivers(xml):
108         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
109         node_elems = xml.xpath(xpath)
110         return SFAv1Node.get_node_objs(node_elems)
111
112
113     @staticmethod
114     def get_node_objs(node_elems):
115         nodes = []    
116         for node_elem in node_elems:
117             node = Node(node_elem.attrib, node_elem)
118             if 'site_id' in node_elem.attrib:
119                 node['authority_id'] = node_elem.attrib['site_id']
120             # get location
121             location_elems = node_elem.xpath('./default:location | ./location')
122             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
123             if len(locations) > 0:
124                 node['location'] = locations[0]
125             # get bwlimit
126             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
127             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
128             if len(bwlimits) > 0:
129                 node['bwlimit'] = bwlimits[0]
130             # get interfaces
131             iface_elems = node_elem.xpath('./default:interface | ./interface')
132             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
133             node['interfaces'] = ifaces
134             # get services
135             node['services'] = PGv2Services.get_services(node_elem) 
136             # get slivers
137             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
138             # get tags
139             node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields+["hardware_type"])
140             # get hardware types
141             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
142             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
143
144             # temporary... play nice with old slice manager rspec
145             if not node['component_name']:
146                 hostname_elem = node_elem.find("hostname")
147                 if hostname_elem != None:
148                     node['component_name'] = hostname_elem.text
149
150             nodes.append(node)
151         return nodes            
152