Describe(): look for the slice based on its HRN
[sfa.git] / sfa / rspecs / elements / v3 / node.py
1 from sfa.util.xrn import Xrn, get_leaf
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.v3.services import Services     
13 from sfa.rspecs.elements.versions.pgv2SliverType import PGv2SliverType     
14 from sfa.rspecs.elements.versions.pgv2Interface import PGv2Interface     
15
16
17 class Node:
18     @staticmethod
19     def add_nodes(xml, nodes):
20         node_elems = []
21         for node in nodes:
22             node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
23             node_elem = xml.add_instance('node', node, node_fields)
24             node_elems.append(node_elem)
25             # set component name
26             if node.get('component_id'):
27                 component_name = Xrn.unescape(get_leaf(Xrn(node['component_id']).get_hrn()))
28                 node_elem.set('component_name', component_name)
29             # set hardware types
30             if node.get('hardware_types'):
31                 for hardware_type in node.get('hardware_types', []): 
32                     node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
33             # set location
34             if node.get('location'):
35                 node_elem.add_instance('location', node['location'], Location.fields)       
36             # set interfaces
37             PGv2Interface.add_interfaces(node_elem, node.get('interfaces'))
38             #if node.get('interfaces'):
39             #    for interface in  node.get('interfaces', []):
40             #        node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
41             # set available element
42             if node.get('available'):
43                 available_elem = node_elem.add_element('available', now=node['available'])
44             # add services
45             Services.add_services(node_elem, node.get('services', [])) 
46             # add slivers
47             slivers = node.get('slivers', [])
48             if not slivers:
49                 # we must still advertise the available sliver types
50                 slivers = Sliver({'type': 'plab-vserver'})
51                 # we must also advertise the available initscripts
52                 slivers['tags'] = []
53                 if node.get('pl_initscripts'): 
54                     for initscript in node.get('pl_initscripts', []):
55                         slivers['tags'].append({'name': 'initscript', 'value': initscript['name']})
56             PGv2SliverType.add_slivers(node_elem, slivers)
57         
58         return node_elems
59
60     @staticmethod
61     def get_nodes(xml, filter={}):
62         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
63         node_elems = xml.xpath(xpath)
64         return Node.get_node_objs(node_elems)
65
66     @staticmethod
67     def get_nodes_with_slivers(xml, filter={}):
68         xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]' 
69         node_elems = xml.xpath(xpath)        
70         return Node.get_node_objs(node_elems)
71
72     @staticmethod
73     def get_node_objs(node_elems):
74         nodes = []
75         for node_elem in node_elems:
76             node = NodeElement(node_elem.attrib, node_elem)
77             nodes.append(node) 
78             if 'component_id' in node_elem.attrib:
79                 node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
80             
81             # get hardware types
82             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
83             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
84             
85             # get location
86             location_elems = node_elem.xpath('./default:location | ./location')
87             locations = [location_elem.get_instance(Location) for location_elem in location_elems]
88             if len(locations) > 0:
89                 node['location'] = locations[0]
90
91             # get interfaces
92             iface_elems = node_elem.xpath('./default:interface | ./interface')
93             node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
94
95             # get services
96             node['services'] = Services.get_services(node_elem)
97             
98             # get slivers
99             node['slivers'] = PGv2SliverType.get_slivers(node_elem)    
100             available_elems = node_elem.xpath('./default:available | ./available')
101             if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
102                 if available_elems[0].attrib.get('now', '').lower() == 'true': 
103                     node['boot_state'] = 'boot'
104                 else: 
105                     node['boot_state'] = 'disabled' 
106         return nodes
107
108
109     @staticmethod
110     def add_slivers(xml, slivers):
111         component_ids = []
112         for sliver in slivers:
113             filter = {}
114             if isinstance(sliver, str):
115                 filter['component_id'] = '*%s*' % sliver
116                 sliver = {}
117             elif 'component_id' in sliver and sliver['component_id']:
118                 filter['component_id'] = '*%s*' % sliver['component_id']
119             if not filter: 
120                 continue
121             nodes = Node.get_nodes(xml, filter)
122             if not nodes:
123                 continue
124             node = nodes[0]
125             PGv2SliverType.add_slivers(node, sliver)
126
127     @staticmethod
128     def remove_slivers(xml, hostnames):
129         for hostname in hostnames:
130             nodes = Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
131             for node in nodes:
132                 slivers = PGv2SliverType.get_slivers(node.element)
133                 for sliver in slivers:
134                     node.element.remove(sliver.element) 
135 if __name__ == '__main__':
136     from sfa.rspecs.rspec import RSpec
137     import pdb
138     r = RSpec('/tmp/emulab.rspec')
139     r2 = RSpec(version = 'GENI')
140     nodes = Node.get_nodes(r.xml)
141     Node.add_nodes(r2.xml.root, nodes)
142     #pdb.set_trace()
143         
144