add node tags to PGv2 and GENIv3 RSpecs
[sfa.git] / sfa / rspecs / elements / versions / pgv2Node.py
1 from sfa.util.xrn import Xrn
2 from sfa.util.xml import XpathFilter
3
4 from sfa.rspecs.elements.node import NodeElement
5 from sfa.rspecs.elements.sliver import Sliver
6 from sfa.rspecs.elements.location import Location
7 from sfa.rspecs.elements.hardware_type import HardwareType
8 from sfa.rspecs.elements.disk_image import DiskImage
9 from sfa.rspecs.elements.interface import Interface
10 from sfa.rspecs.elements.bwlimit import BWlimit
11 from sfa.rspecs.elements.pltag import PLTag
12 from sfa.rspecs.elements.versions.pgv2Services import PGv2Services     
13 from sfa.rspecs.elements.versions.pgv2SliverType import PGv2SliverType     
14 from sfa.rspecs.elements.versions.pgv2Interface import PGv2Interface     
15 from sfa.rspecs.elements.granularity import Granularity
16
17 from sfa.planetlab.plxrn import xrn_to_hostname
18
19 class PGv2Node:
20     @staticmethod
21     def add_nodes(xml, nodes):
22         node_elems = []
23         for node in nodes:
24             node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
25             node_elem = xml.add_instance('node', node, node_fields)
26             node_elems.append(node_elem)
27             # set component name
28             if node.get('component_id'):
29                 component_name = xrn_to_hostname(node['component_id'])
30                 node_elem.set('component_name', component_name)
31             # set hardware types
32             if node.get('hardware_types'):
33                 for hardware_type in node.get('hardware_types', []): 
34                     node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
35             # set location
36             if node.get('location'):
37                 node_elem.add_instance('location', node['location'], Location.fields)       
38
39             # set granularity
40             if node['exclusive'] == "true":
41                 granularity = node.get('granularity')
42                 node_elem.add_instance('granularity', granularity, granularity.fields)
43             # set interfaces
44             PGv2Interface.add_interfaces(node_elem, node.get('interfaces'))
45             #if node.get('interfaces'):
46             #    for interface in  node.get('interfaces', []):
47             #        node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
48             # set available element
49             if node.get('available'):
50                 available_elem = node_elem.add_element('available', now=node['available'])
51             # add services
52             PGv2Services.add_services(node_elem, node.get('services', [])) 
53             # add slivers
54             slivers = node.get('slivers', [])
55             if not slivers:
56                 # we must still advertise the available sliver types
57                 slivers = Sliver({'type': 'plab-vserver'})
58                 # we must also advertise the available initscripts
59                 slivers['tags'] = []
60                 if node.get('pl_initscripts'): 
61                     for initscript in node.get('pl_initscripts', []):
62                         slivers['tags'].append({'name': 'initscript', 'value': initscript['name']})
63             PGv2SliverType.add_slivers(node_elem, slivers)
64
65             # advertise the node tags
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             PGv2SliverType.add_slivers(node_elem, node.get('slivers', []))
72
73         return node_elems
74
75     @staticmethod
76     def get_nodes(xml, filter={}):
77         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
78         node_elems = xml.xpath(xpath)
79         return PGv2Node.get_node_objs(node_elems)
80
81     @staticmethod
82     def get_nodes_with_slivers(xml, filter={}):
83         xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]' 
84         node_elems = xml.xpath(xpath)        
85         return PGv2Node.get_node_objs(node_elems)
86
87     @staticmethod
88     def get_node_objs(node_elems):
89         nodes = []
90         for node_elem in node_elems:
91             node = NodeElement(node_elem.attrib, node_elem)
92             nodes.append(node) 
93             if 'component_id' in node_elem.attrib:
94                 node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
95             
96             # get hardware types
97             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
98             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
99             
100             # get location
101             location_elems = node_elem.xpath('./default:location | ./location')
102             locations = [location_elem.get_instance(Location) for location_elem in location_elems]
103             if len(locations) > 0:
104                 node['location'] = locations[0]
105
106             # get granularity
107             granularity_elems = node_elem.xpath('./default:granularity | ./granularity')
108             if len(granularity_elems) > 0:
109                 node['granularity'] = granularity_elems[0].get_instance(Granularity)
110
111             # get interfaces
112             iface_elems = node_elem.xpath('./default:interface | ./interface')
113             node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
114
115             # get services
116             node['services'] = PGv2Services.get_services(node_elem)
117             
118             # get slivers
119             node['slivers'] = PGv2SliverType.get_slivers(node_elem)    
120             available_elems = node_elem.xpath('./default:available | ./available')
121             if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
122                 if available_elems[0].attrib.get('now', '').lower() == 'true': 
123                     node['boot_state'] = 'boot'
124                 else: 
125                     node['boot_state'] = 'disabled' 
126         return nodes
127
128
129     @staticmethod
130     def add_slivers(xml, slivers):
131         component_ids = []
132         for sliver in slivers:
133             filter = {}
134             if isinstance(sliver, str):
135                 filter['component_id'] = '*%s*' % sliver
136                 sliver = {}
137             elif 'component_id' in sliver and sliver['component_id']:
138                 filter['component_id'] = '*%s*' % sliver['component_id']
139             if not filter: 
140                 continue
141             nodes = PGv2Node.get_nodes(xml, filter)
142             if not nodes:
143                 continue
144             node = nodes[0]
145             PGv2SliverType.add_slivers(node, sliver)
146
147     @staticmethod
148     def remove_slivers(xml, hostnames):
149         for hostname in hostnames:
150             nodes = PGv2Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
151             for node in nodes:
152                 slivers = PGv2SliverType.get_slivers(node.element)
153                 for sliver in slivers:
154                     node.element.remove(sliver.element) 
155 if __name__ == '__main__':
156     from sfa.rspecs.rspec import RSpec
157     import pdb
158     r = RSpec('/tmp/emulab.rspec')
159     r2 = RSpec(version = 'ProtoGENI')
160     nodes = PGv2Node.get_nodes(r.xml)
161     PGv2Node.add_nodes(r2.xml.root, nodes)
162     #pdb.set_trace()
163         
164