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 if s1_node_id not in nodes or s2_node_id not in nodes:
65 node1 = nodes[s1_node_id]
66 node2 = nodes[s2_node_id]
68 # just get first interface of the first node
69 if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id']))
70 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
71 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
72 if2_ipv4 = interfaces[node2['interface_ids'][0]]['ip']
74 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
75 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
78 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
79 link['interface1'] = if1
80 link['interface2'] = if2
81 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
82 link['component_id'] = PlXrn(auth=self.api.hrn, interface=link['component_name']).get_urn()
83 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
88 def get_node_tags(self, filter={}):
90 for node_tag in self.api.driver.GetNodeTags(filter):
91 node_tags[node_tag['node_tag_id']] = node_tag
94 def get_pl_initscripts(self, filter={}):
96 filter.update({'enabled': True})
97 for initscript in self.api.driver.GetInitScripts(filter):
98 pl_initscripts[initscript['initscript_id']] = initscript
102 def get_slice_and_slivers(self, slice_xrn):
104 Returns a dict of slivers keyed on the sliver's node_id
109 return (slice, slivers)
110 slice_urn = hrn_to_urn(slice_xrn, 'slice')
111 slice_hrn, _ = urn_to_hrn(slice_xrn)
112 slice_name = hrn_to_pl_slicename(slice_hrn)
113 slices = self.api.driver.GetSlices(slice_name)
115 return (slice, slivers)
118 # sort slivers by node id
119 for node_id in slice['node_ids']:
120 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
121 'name': slice['name'],
122 'type': 'plab-vserver',
124 slivers[node_id]= sliver
126 # sort sliver attributes by node id
127 tags = self.api.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
129 # most likely a default/global sliver attribute (node_id == None)
130 if tag['node_id'] not in slivers:
131 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
132 'name': 'plab-vserver',
134 slivers[tag['node_id']] = sliver
135 slivers[tag['node_id']]['tags'].append(tag)
137 return (slice, slivers)
139 def get_nodes_and_links(self, slice=None,slivers=[]):
142 if slice and 'node_ids' in slice and slice['node_ids']:
143 filter['node_id'] = slice['node_ids']
144 tags_filter=filter.copy()
146 filter.update({'peer_id': None})
147 nodes = self.api.driver.GetNodes(filter)
154 site_ids.append(node['site_id'])
155 interface_ids.extend(node['interface_ids'])
156 tag_ids.extend(node['node_tag_ids'])
157 nodes_dict[node['node_id']] = node
160 sites_dict = self.get_sites({'site_id': site_ids})
162 interfaces = self.get_interfaces({'interface_id':interface_ids})
164 node_tags = self.get_node_tags(tags_filter)
166 pl_initscripts = self.get_pl_initscripts()
168 links = self.get_links(sites_dict, nodes_dict, interfaces)
172 # skip whitelisted nodes
173 if node['slice_ids_whitelist']:
174 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
177 # xxx how to retrieve site['login_base']
178 site_id=node['site_id']
179 site=sites_dict[site_id]
180 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
181 rspec_node['component_name'] = node['hostname']
182 rspec_node['component_manager_id'] = self.api.hrn
183 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
184 rspec_node['boot_state'] = node['boot_state']
185 rspec_node['exclusive'] = 'False'
186 rspec_node['hardware_types']= [HardwareType({'name': 'plab-pc'}),
187 HardwareType({'name': 'pc'})]
188 # only doing this because protogeni rspec needs
189 # to advertise available initscripts
190 rspec_node['pl_initscripts'] = pl_initscripts.values()
191 # add site/interface info to nodes.
192 # assumes that sites, interfaces and tags have already been prepared.
193 site = sites_dict[node['site_id']]
194 if site['longitude'] and site['latitude']:
195 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
196 rspec_node['location'] = location
197 rspec_node['interfaces'] = []
199 for if_id in node['interface_ids']:
200 interface = Interface(interfaces[if_id])
201 interface['ipv4'] = interface['ip']
202 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count)).get_urn()
203 rspec_node['interfaces'].append(interface)
206 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
207 rspec_node['tags'] = tags
208 if node['node_id'] in slivers:
210 sliver = slivers[node['node_id']]
211 rspec_node['sliver_id'] = sliver['sliver_id']
212 rspec_node['client_id'] = node['hostname']
213 rspec_node['slivers'] = [sliver]
215 # slivers always provide the ssh service
216 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
217 service = Services({'login': login})
218 rspec_node['services'] = [service]
219 rspec_nodes.append(rspec_node)
220 return (rspec_nodes, links)
223 def get_rspec(self, slice_xrn=None, version = None):
225 version_manager = VersionManager()
226 version = version_manager.get_version(version)
228 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
230 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
232 slice, slivers = self.get_slice_and_slivers(slice_xrn)
233 rspec = RSpec(version=rspec_version, user_options=self.user_options)
234 if slice and 'expires' in slice:
235 rspec.xml.set('expires', epochparse(slice['expires']))
237 nodes, links = self.get_nodes_and_links(slice, slivers)
238 rspec.version.add_nodes(nodes)
239 rspec.version.add_links(links)
241 # add sliver defaults
242 default_sliver_attribs = slivers.get(None, [])
243 for sliver_attrib in default_sliver_attribs:
244 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])