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