adding generic setting parameter for teagle
[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             # add exclusive tag to distinguish between Reservable and Shared nodes
61             exclusive_elem = node_elem.add_element('exclusive')
62             if node.get('exclusive') and node.get('exclusive') == 'true':
63                 exclusive_elem.set_text('TRUE')
64                 # add granularity of the reservation system
65                 granularity = node.get('granularity')
66                 if granularity:
67                     node_elem.add_instance('granularity', granularity, granularity.fields)
68             else:
69                 exclusive_elem.set_text('FALSE')
70
71
72             if isinstance(node.get('interfaces'), list):
73                 for interface in node.get('interfaces', []):
74                     node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
75             
76             #if 'bw_unallocated' in node and node['bw_unallocated']:
77             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
78
79             PGv2Services.add_services(node_elem, node.get('services', []))
80             tags = node.get('tags', [])
81             if tags:
82                 for tag in tags:
83                     if tag['tagname']=="settings":
84                         tag_elem = node_elem.add_element(tag['tagname'])
85                         for subtag in tag['value']:
86                             subtag_elem = tag_elem.add_element('setting')
87                             subtag_elem.set('name', str(subtag['tagname']))
88                             subtag_elem.set('description', str(subtag['description']))
89                             subtag_elem.set_text(subtag['value'])
90                     else:
91                         tag_elem = node_elem.add_element(tag['tagname'])
92                         tag_elem.set_text(tag['value'])
93             SFAv1Sliver.add_slivers(node_elem, node.get('slivers', []))
94
95     @staticmethod 
96     def add_slivers(xml, slivers):
97         component_ids = []
98         for sliver in slivers:
99             filter = {}
100             if isinstance(sliver, str):
101                 filter['component_id'] = '*%s*' % sliver
102                 sliver = {}
103             elif 'component_id' in sliver and sliver['component_id']:
104                 filter['component_id'] = '*%s*' % sliver['component_id']
105             if not filter:
106                 continue 
107             nodes = SFAv1Node.get_nodes(xml, filter)
108             if not nodes:
109                 continue
110             node = nodes[0]
111             SFAv1Sliver.add_slivers(node, sliver)
112
113     @staticmethod
114     def remove_slivers(xml, hostnames):
115         for hostname in hostnames:
116             nodes = SFAv1Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
117             for node in nodes:
118                 slivers = SFAv1Sliver.get_slivers(node.element)
119                 for sliver in slivers:
120                     node.element.remove(sliver.element)
121         
122     @staticmethod
123     def get_nodes(xml, filter={}):
124         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
125         node_elems = xml.xpath(xpath)
126         return SFAv1Node.get_node_objs(node_elems)
127
128     @staticmethod
129     def get_nodes_with_slivers(xml):
130         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
131         node_elems = xml.xpath(xpath)
132         return SFAv1Node.get_node_objs(node_elems)
133
134
135     @staticmethod
136     def get_node_objs(node_elems):
137         nodes = []    
138         for node_elem in node_elems:
139             node = Node(node_elem.attrib, node_elem)
140             if 'site_id' in node_elem.attrib:
141                 node['authority_id'] = node_elem.attrib['site_id']
142             # get location
143             location_elems = node_elem.xpath('./default:location | ./location')
144             locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
145             if len(locations) > 0:
146                 node['location'] = locations[0]
147             # get bwlimit
148             bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
149             bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
150             if len(bwlimits) > 0:
151                 node['bwlimit'] = bwlimits[0]
152             # get interfaces
153             iface_elems = node_elem.xpath('./default:interface | ./interface')
154             ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
155             node['interfaces'] = ifaces
156             # get services
157             node['services'] = PGv2Services.get_services(node_elem) 
158             # get slivers
159             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
160             # get tags
161             node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields+["hardware_type"])
162             # get hardware types
163             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
164             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
165
166             # temporary... play nice with old slice manager rspec
167             if not node['component_name']:
168                 hostname_elem = node_elem.find("hostname")
169                 if hostname_elem != None:
170                     node['component_name'] = hostname_elem.text
171
172             nodes.append(node)
173         return nodes            
174