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, user_options={}):
28 self.user_options = user_options
30 def get_sites(self, filter={}):
32 for site in self.api.driver.GetSites(filter):
33 sites[site['site_id']] = site
36 def get_interfaces(self, filter={}):
38 for interface in self.api.driver.GetInterfaces(filter):
40 if interface['bwlimit']:
41 interface['bwlimit'] = str(int(interface['bwlimit'])/1000)
42 interfaces[interface['interface_id']] = interface
45 def get_links(self, sites, nodes, interfaces):
49 for (site_id1, site_id2) in topology:
50 site_id1 = int(site_id1)
51 site_id2 = int(site_id2)
53 if not site_id1 in sites or site_id2 not in sites:
55 site1 = sites[site_id1]
56 site2 = sites[site_id2]
58 site1_hrn = self.api.hrn + '.' + site1['login_base']
59 site2_hrn = self.api.hrn + '.' + site2['login_base']
61 for s1_node_id in site1['node_ids']:
62 for s2_node_id in site2['node_ids']:
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.api.hrn, interface='node%s:eth0' % (node1['node_id']))
68 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
69 if2_xrn = PlXrn(auth=self.api.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.api.hrn, interface=link['component_name']).get_urn()
81 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
86 def get_node_tags(self, filter={}):
88 for node_tag in self.api.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.api.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.api.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.api.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=[]):
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 filter.update({'peer_id': None})
145 nodes = self.api.driver.GetNodes(filter)
152 site_ids.append(node['site_id'])
153 interface_ids.extend(node['interface_ids'])
154 tag_ids.extend(node['node_tag_ids'])
155 nodes_dict[node['node_id']] = node
158 sites_dict = self.get_sites({'site_id': site_ids})
160 interfaces = self.get_interfaces({'interface_id':interface_ids})
162 node_tags = self.get_node_tags(tags_filter)
164 pl_initscripts = self.get_pl_initscripts()
166 links = self.get_links(sites_dict, nodes_dict, interfaces)
170 # skip whitelisted nodes
171 if node['slice_ids_whitelist']:
172 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
175 # xxx how to retrieve site['login_base']
176 site_id=node['site_id']
177 site=sites_dict[site_id]
178 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
179 rspec_node['component_name'] = node['hostname']
180 rspec_node['component_manager_id'] = self.api.hrn
181 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
182 rspec_node['boot_state'] = node['boot_state']
183 rspec_node['exclusive'] = 'False'
184 rspec_node['hardware_types']= [HardwareType({'name': 'plab-pc'}),
185 HardwareType({'name': 'pc'})]
186 # only doing this because protogeni rspec needs
187 # to advertise available initscripts
188 rspec_node['pl_initscripts'] = pl_initscripts.values()
189 # add site/interface info to nodes.
190 # assumes that sites, interfaces and tags have already been prepared.
191 site = sites_dict[node['site_id']]
192 if site['longitude'] and site['latitude']:
193 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
194 rspec_node['location'] = location
195 rspec_node['interfaces'] = []
197 for if_id in node['interface_ids']:
198 interface = Interface(interfaces[if_id])
199 interface['ipv4'] = interface['ip']
200 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count)).get_urn()
201 rspec_node['interfaces'].append(interface)
204 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
205 rspec_node['tags'] = tags
206 if node['node_id'] in slivers:
208 sliver = slivers[node['node_id']]
209 rspec_node['sliver_id'] = sliver['sliver_id']
210 rspec_node['client_id'] = node['hostname']
211 rspec_node['slivers'] = [sliver]
213 # slivers always provide the ssh service
214 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
215 service = Services({'login': login})
216 rspec_node['services'] = [service]
217 rspec_nodes.append(rspec_node)
218 return (rspec_nodes, links)
221 def get_rspec(self, slice_xrn=None, version = None):
223 version_manager = VersionManager()
224 version = version_manager.get_version(version)
226 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
228 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
230 slice, slivers = self.get_slice_and_slivers(slice_xrn)
231 rspec = RSpec(version=rspec_version, user_options=self.user_options)
232 if slice and 'expires' in slice:
233 rspec.xml.set('expires', epochparse(slice['expires']))
235 nodes, links = self.get_nodes_and_links(slice, slivers)
236 rspec.version.add_nodes(nodes)
237 rspec.version.add_links(links)
239 # add sliver defaults
240 default_sliver_attribs = slivers.get(None, [])
241 for sliver_attrib in default_sliver_attribs:
242 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])