Merge branch 'master' into senslab2
[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 PlXrn, 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             for interface in node.get('interfaces', []):
59                 node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
60             
61             #if 'bw_unallocated' in node and node['bw_unallocated']:
62             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
63
64             PGv2Services.add_services(node_elem, node.get('services', []))
65             tags = node.get('tags', [])
66             if tags:
67                 for tag in tags:
68                     tag_elem = node_elem.add_element(tag['tagname'])
69                     tag_elem.set_text(tag['value'])
70             SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
71
72     @staticmethod 
73     def add_slivers(xml, slivers):
74         component_ids = []
75         for sliver in slivers:
76             filter = {}
77             if isinstance(sliver, str):
78                 filter['component_id'] = '*%s*' % sliver
79                 sliver = {}
80             elif 'component_id' in sliver and sliver['component_id']:
81                 filter['component_id'] = '*%s*' % sliver['component_id']
82             if not filter:
83                 continue 
84             nodes = SFAv1Node.get_nodes(xml, filter)
85             if not nodes:
86                 continue
87             node = nodes[0]
88             SFAv1Sliver.add_slivers(node, sliver)
89
90     @staticmethod
91     def remove_slivers(xml, hostnames):
92         for hostname in hostnames:
93             nodes = SFAv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
94             for node in nodes:
95                 slivers = SFAv1Sliver.get_slivers(node.element)
96                 for sliver in slivers:
97                     node.element.remove(sliver.element)
98         
99     @staticmethod
100     def get_nodes(xml, filter={}):
101         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
102         node_elems = xml.xpath(xpath)
103         return SFAv1Node.get_node_objs(node_elems)
104
105     @staticmethod
106     def get_nodes_with_slivers(xml):
107         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
108         node_elems = xml.xpath(xpath)
109         return SFAv1Node.get_node_objs(node_elems)
110
111
112     @staticmethod
113     def get_node_objs(node_elems):
114         nodes = []    
115         for node_elem in node_elems:
116             node = Node(node_elem.attrib, node_elem)
117             if 'site_id' in node_elem.attrib:
118                 node['authority_id'] = node_elem.attrib['site_id']
119             # get location
120             location_elems = node_elem.xpath('./default:location | ./location')
121             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
122             if len(locations) > 0:
123                 node['location'] = locations[0]
124             # get bwlimit
125             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
126             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
127             if len(bwlimits) > 0:
128                 node['bwlimit'] = bwlimits[0]
129             # get interfaces
130             iface_elems = node_elem.xpath('./default:interface | ./interface')
131             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
132             node['interfaces'] = ifaces
133             # get services
134             node['services'] = PGv2Services.get_services(node_elem) 
135             # get slivers
136             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
137             # get tags
138             node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields+["hardware_type"])
139             # get hardware types
140             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
141             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
142
143             # temporary... play nice with old slice manager rspec
144             if not node['component_name']:
145                 hostname_elem = node_elem.find("hostname")
146                 if hostname_elem != None:
147                     node['component_name'] = hostname_elem.text
148
149             nodes.append(node)
150         return nodes            
151