2 from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn, urn_to_sliver_id
3 from sfa.util.sfatime import epochparse
5 from sfa.rspecs.rspec import RSpec
6 from sfa.rspecs.elements.hardware_type import HardwareType
7 from sfa.rspecs.elements.node import Node
8 from sfa.rspecs.elements.link import Link
9 from sfa.rspecs.elements.sliver import Sliver
10 from sfa.rspecs.elements.login import Login
11 from sfa.rspecs.elements.location import Location
12 from sfa.rspecs.elements.interface import Interface
13 from sfa.rspecs.elements.services import Services
14 from sfa.rspecs.elements.pltag import PLTag
15 from sfa.rspecs.version_manager import VersionManager
17 from sfa.util.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename
18 from sfa.plc.vlink import get_tc_rate
19 from sfa.plc.topology import Topology
24 def __init__(self, driver):
26 self.user_options = {}
28 def get_sites(self, filter={}):
30 for site in self.driver.GetSites(filter):
31 sites[site['site_id']] = site
34 def get_interfaces(self, filter={}):
36 for interface in self.driver.GetInterfaces(filter):
38 if interface['bwlimit']:
39 interface['bwlimit'] = str(int(interface['bwlimit'])/1000)
40 interfaces[interface['interface_id']] = interface
43 def get_links(self, sites, nodes, interfaces):
47 for (site_id1, site_id2) in topology:
48 site_id1 = int(site_id1)
49 site_id2 = int(site_id2)
51 if not site_id1 in sites or site_id2 not in sites:
53 site1 = sites[site_id1]
54 site2 = sites[site_id2]
56 site1_hrn = self.driver.hrn + '.' + site1['login_base']
57 site2_hrn = self.driver.hrn + '.' + site2['login_base']
59 for s1_node_id in site1['node_ids']:
60 for s2_node_id in site2['node_ids']:
61 if s1_node_id not in nodes or s2_node_id not in nodes:
63 node1 = nodes[s1_node_id]
64 node2 = nodes[s2_node_id]
66 # just get first interface of the first node
67 if1_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node1['node_id']))
68 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
69 if2_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node2['node_id']))
70 if2_ipv4 = interfaces[node2['interface_ids'][0]]['ip']
72 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
73 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
76 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
77 link['interface1'] = if1
78 link['interface2'] = if2
79 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
80 link['component_id'] = PlXrn(auth=self.driver.hrn, interface=link['component_name']).get_urn()
81 link['component_manager_id'] = hrn_to_urn(self.driver.hrn, 'authority+am')
86 def get_node_tags(self, filter={}):
88 for node_tag in self.driver.GetNodeTags(filter):
89 node_tags[node_tag['node_tag_id']] = node_tag
92 def get_pl_initscripts(self, filter={}):
94 filter.update({'enabled': True})
95 for initscript in self.driver.GetInitScripts(filter):
96 pl_initscripts[initscript['initscript_id']] = initscript
100 def get_slice_and_slivers(self, slice_xrn):
102 Returns a dict of slivers keyed on the sliver's node_id
107 return (slice, slivers)
108 slice_urn = hrn_to_urn(slice_xrn, 'slice')
109 slice_hrn, _ = urn_to_hrn(slice_xrn)
110 slice_name = hrn_to_pl_slicename(slice_hrn)
111 slices = self.driver.GetSlices(slice_name)
113 return (slice, slivers)
116 # sort slivers by node id
117 for node_id in slice['node_ids']:
118 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
119 'name': slice['name'],
120 'type': 'plab-vserver',
122 slivers[node_id]= sliver
124 # sort sliver attributes by node id
125 tags = self.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
127 # most likely a default/global sliver attribute (node_id == None)
128 if tag['node_id'] not in slivers:
129 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
130 'name': 'plab-vserver',
132 slivers[tag['node_id']] = sliver
133 slivers[tag['node_id']]['tags'].append(tag)
135 return (slice, slivers)
137 def get_nodes_and_links(self, slice=None,slivers=[], options={}):
140 if slice and 'node_ids' in slice and slice['node_ids']:
141 filter['node_id'] = slice['node_ids']
142 tags_filter=filter.copy()
144 geni_available = options.get('geni_available')
146 filter['boot_state'] = 'boot'
148 filter.update({'peer_id': None})
149 nodes = self.driver.GetNodes(filter)
156 site_ids.append(node['site_id'])
157 interface_ids.extend(node['interface_ids'])
158 tag_ids.extend(node['node_tag_ids'])
159 nodes_dict[node['node_id']] = node
162 sites_dict = self.get_sites({'site_id': site_ids})
164 interfaces = self.get_interfaces({'interface_id':interface_ids})
166 node_tags = self.get_node_tags(tags_filter)
168 pl_initscripts = self.get_pl_initscripts()
170 links = self.get_links(sites_dict, nodes_dict, interfaces)
174 # skip whitelisted nodes
175 if node['slice_ids_whitelist']:
176 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
179 # xxx how to retrieve site['login_base']
180 site_id=node['site_id']
181 site=sites_dict[site_id]
182 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site['login_base'], node['hostname'])
183 rspec_node['component_name'] = node['hostname']
184 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
185 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.driver.hrn, site['login_base']), 'authority+sa')
186 rspec_node['boot_state'] = node['boot_state']
187 rspec_node['exclusive'] = 'False'
188 rspec_node['hardware_types']= [HardwareType({'name': 'plab-pc'}),
189 HardwareType({'name': 'pc'})]
190 # only doing this because protogeni rspec needs
191 # to advertise available initscripts
192 rspec_node['pl_initscripts'] = pl_initscripts.values()
193 # add site/interface info to nodes.
194 # assumes that sites, interfaces and tags have already been prepared.
195 site = sites_dict[node['site_id']]
196 if site['longitude'] and site['latitude']:
197 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
198 rspec_node['location'] = location
199 rspec_node['interfaces'] = []
201 for if_id in node['interface_ids']:
202 interface = Interface(interfaces[if_id])
203 interface['ipv4'] = interface['ip']
204 interface['component_id'] = PlXrn(auth=self.driver.hrn,
205 interface='node%s:eth%s' % (node['node_id'], if_count)).get_urn()
206 # interfaces in the manifest need a client id
208 interface['client_id'] = "%s:%s" % (node['node_id'], if_id)
209 rspec_node['interfaces'].append(interface)
212 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
213 rspec_node['tags'] = tags
214 if node['node_id'] in slivers:
216 sliver = slivers[node['node_id']]
217 rspec_node['sliver_id'] = sliver['sliver_id']
218 rspec_node['client_id'] = node['hostname']
219 rspec_node['slivers'] = [sliver]
221 # slivers always provide the ssh service
222 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
223 service = Services({'login': login})
224 rspec_node['services'] = [service]
225 rspec_nodes.append(rspec_node)
226 return (rspec_nodes, links)
229 def get_rspec(self, slice_xrn=None, version = None, options={}):
231 version_manager = VersionManager()
232 version = version_manager.get_version(version)
234 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
236 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
238 slice, slivers = self.get_slice_and_slivers(slice_xrn)
239 rspec = RSpec(version=rspec_version, user_options=options)
240 if slice and 'expires' in slice:
241 rspec.xml.set('expires', epochparse(slice['expires']))
243 nodes, links = self.get_nodes_and_links(slice, slivers)
244 rspec.version.add_nodes(nodes)
245 rspec.version.add_links(links)
247 # add sliver defaults
248 default_sliver = slivers.get(None, [])
250 default_sliver_attribs = default_sliver.get('tags', [])
251 for attrib in default_sliver_attribs:
253 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])