2 from sfa.util.xrn import hrn_to_urn, urn_to_hrn, urn_to_sliver_id
3 from sfa.util.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename
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.util.topology import Topology
16 from sfa.rspecs.version_manager import VersionManager
17 from sfa.plc.vlink import get_tc_rate
18 from sfa.util.sfatime import epochparse
23 #panos new user options variable
26 def __init__(self, api):
29 def get_sites(self, filter={}):
31 for site in self.api.driver.GetSites(filter):
32 sites[site['site_id']] = site
35 def get_interfaces(self, filter={}):
37 for interface in self.api.driver.GetInterfaces(filter):
39 if interface['bwlimit']:
40 interface['bwlimit'] = str(int(interface['bwlimit'])/1000)
41 interfaces[interface['interface_id']] = interface
44 def get_links(self, sites, nodes, interfaces):
48 for (site_id1, site_id2) in topology:
49 site_id1 = int(site_id1)
50 site_id2 = int(site_id2)
52 if not site_id1 in sites or site_id2 not in sites:
54 site1 = sites[site_id1]
55 site2 = sites[site_id2]
57 site1_hrn = self.api.hrn + '.' + site1['login_base']
58 site2_hrn = self.api.hrn + '.' + site2['login_base']
60 for s1_node_id in site1['node_ids']:
61 for s2_node_id in site2['node_ids']:
62 if s1_node_id not in nodes or s2_node_id not in nodes:
64 node1 = nodes[s1_node_id]
65 node2 = nodes[s2_node_id]
67 # just get first interface of the first node
68 if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id']))
69 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
70 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
71 if2_ipv4 = interfaces[node2['interface_ids'][0]]['ip']
73 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
74 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
77 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
78 link['interface1'] = if1
79 link['interface2'] = if2
80 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
81 link['component_id'] = PlXrn(auth=self.api.hrn, interface=link['component_name']).get_urn()
82 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
87 def get_node_tags(self, filter={}):
89 for node_tag in self.api.driver.GetNodeTags(filter):
90 node_tags[node_tag['node_tag_id']] = node_tag
93 def get_pl_initscripts(self, filter={}):
95 filter.update({'enabled': True})
96 for initscript in self.api.driver.GetInitScripts(filter):
97 pl_initscripts[initscript['initscript_id']] = initscript
101 def get_slice_and_slivers(self, slice_xrn):
103 Returns a dict of slivers keyed on the sliver's node_id
108 return (slice, slivers)
109 slice_urn = hrn_to_urn(slice_xrn, 'slice')
110 slice_hrn, _ = urn_to_hrn(slice_xrn)
111 slice_name = hrn_to_pl_slicename(slice_hrn)
112 slices = self.api.driver.GetSlices(slice_name)
114 return (slice, slivers)
117 # sort slivers by node id
118 for node_id in slice['node_ids']:
119 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
120 'name': slice['name'],
121 'type': 'plab-vserver',
123 slivers[node_id]= sliver
125 # sort sliver attributes by node id
126 tags = self.api.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
128 # most likely a default/global sliver attribute (node_id == None)
129 if tag['node_id'] not in slivers:
130 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
131 'name': 'plab-vserver',
133 slivers[tag['node_id']] = sliver
134 slivers[tag['node_id']]['tags'].append(tag)
136 return (slice, slivers)
138 def get_nodes_and_links(self, slice=None,slivers=[], options={}):
141 if slice and 'node_ids' in slice and slice['node_ids']:
142 filter['node_id'] = slice['node_ids']
143 tags_filter=filter.copy()
145 geni_available = options.get('geni_available')
147 filter['boot_state'] = 'boot'
149 filter.update({'peer_id': None})
150 nodes = self.api.driver.GetNodes(filter)
157 site_ids.append(node['site_id'])
158 interface_ids.extend(node['interface_ids'])
159 tag_ids.extend(node['node_tag_ids'])
160 nodes_dict[node['node_id']] = node
163 sites_dict = self.get_sites({'site_id': site_ids})
165 interfaces = self.get_interfaces({'interface_id':interface_ids})
167 node_tags = self.get_node_tags(tags_filter)
169 pl_initscripts = self.get_pl_initscripts()
171 links = self.get_links(sites_dict, nodes_dict, interfaces)
175 # skip whitelisted nodes
176 if node['slice_ids_whitelist']:
177 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
180 # xxx how to retrieve site['login_base']
181 site_id=node['site_id']
182 site=sites_dict[site_id]
183 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
184 rspec_node['component_name'] = node['hostname']
185 rspec_node['component_manager_id'] = self.api.hrn
186 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
187 rspec_node['boot_state'] = node['boot_state']
188 rspec_node['exclusive'] = 'False'
189 rspec_node['hardware_types']= [HardwareType({'name': 'plab-pc'}),
190 HardwareType({'name': 'pc'})]
191 # only doing this because protogeni rspec needs
192 # to advertise available initscripts
193 rspec_node['pl_initscripts'] = pl_initscripts.values()
194 # add site/interface info to nodes.
195 # assumes that sites, interfaces and tags have already been prepared.
196 site = sites_dict[node['site_id']]
197 if site['longitude'] and site['latitude']:
198 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
199 rspec_node['location'] = location
200 rspec_node['interfaces'] = []
202 for if_id in node['interface_ids']:
203 interface = Interface(interfaces[if_id])
204 interface['ipv4'] = interface['ip']
205 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count)).get_urn()
206 rspec_node['interfaces'].append(interface)
209 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
210 rspec_node['tags'] = tags
211 if node['node_id'] in slivers:
213 sliver = slivers[node['node_id']]
214 rspec_node['sliver_id'] = sliver['sliver_id']
215 rspec_node['client_id'] = node['hostname']
216 rspec_node['slivers'] = [sliver]
218 # slivers always provide the ssh service
219 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
220 service = Services({'login': login})
221 rspec_node['services'] = [service]
222 rspec_nodes.append(rspec_node)
223 return (rspec_nodes, links)
226 def get_rspec(self, slice_xrn=None, version = None, options={}):
228 version_manager = VersionManager()
229 version = version_manager.get_version(version)
231 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
233 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
235 slice, slivers = self.get_slice_and_slivers(slice_xrn)
236 rspec = RSpec(version=rspec_version, user_options=options)
237 if slice and 'expires' in slice:
238 rspec.xml.set('expires', epochparse(slice['expires']))
240 nodes, links = self.get_nodes_and_links(slice, slivers)
241 rspec.version.add_nodes(nodes)
242 rspec.version.add_links(links)
244 # add sliver defaults
245 default_sliver_attribs = slivers.get(None, [])
246 for sliver_attrib in default_sliver_attribs:
247 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])