Merge branch 'upstreammaster'
[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             for tag in node.get('tags', []):
66                 tag_elem = node_elem.add_element(tag['tagname'])
67                 tag_elem.set_text(tag['value'])
68             SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
69
70     @staticmethod 
71     def add_slivers(xml, slivers):
72         component_ids = []
73         for sliver in slivers:
74             filter = {}
75             if isinstance(sliver, str):
76                 filter['component_id'] = '*%s*' % sliver
77                 sliver = {}
78             elif 'component_id' in sliver and sliver['component_id']:
79                 filter['component_id'] = '*%s*' % sliver['component_id']
80             if not filter:
81                 continue 
82             nodes = SFAv1Node.get_nodes(xml, filter)
83             if not nodes:
84                 continue
85             node = nodes[0]
86             SFAv1Sliver.add_slivers(node, sliver)
87
88     @staticmethod
89     def remove_slivers(xml, hostnames):
90         for hostname in hostnames:
91             nodes = SFAv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
92             for node in nodes:
93                 slivers = SFAv1Slivers.get_slivers(node.element)
94                 for sliver in slivers:
95                     node.element.remove(sliver.element)
96         
97     @staticmethod
98     def get_nodes(xml, filter={}):
99         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
100         node_elems = xml.xpath(xpath)
101         return SFAv1Node.get_node_objs(node_elems)
102
103     @staticmethod
104     def get_nodes_with_slivers(xml):
105         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
106         node_elems = xml.xpath(xpath)
107         return SFAv1Node.get_node_objs(node_elems)
108
109
110     @staticmethod
111     def get_node_objs(node_elems):
112         nodes = []    
113         for node_elem in node_elems:
114             node = Node(node_elem.attrib, node_elem)
115             if 'site_id' in node_elem.attrib:
116                 node['authority_id'] = node_elem.attrib['site_id']
117             # get location
118             location_elems = node_elem.xpath('./default:location | ./location')
119             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
120             if len(locations) > 0:
121                 node['location'] = locations[0]
122             # get bwlimit
123             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
124             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
125             if len(bwlimits) > 0:
126                 node['bwlimit'] = bwlimits[0]
127             # get interfaces
128             iface_elems = node_elem.xpath('./default:interface | ./interface')
129             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
130             node['interfaces'] = ifaces
131             # get services
132             node['services'] = PGv2Services.get_services(node_elem) 
133             # get slivers
134             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
135             # get tags
136             node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields)
137             nodes.append(node)
138         return nodes            
139