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.login import Login
10 from sfa.rspecs.elements.location import Location
11 from sfa.rspecs.elements.interface import Interface
12 from sfa.rspecs.elements.services import Services
13 from sfa.rspecs.elements.pltag import PLTag
14 from sfa.util.topology import Topology
15 from sfa.rspecs.version_manager import VersionManager
16 from sfa.plc.vlink import get_tc_rate
17 from sfa.util.sfatime import epochparse
22 #panos new user options variable
25 def __init__(self, api, user_options={}):
27 self.user_options = user_options
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 iface['interface_id'] = interface['interface_id']
40 iface['node_id'] = interface['node_id']
41 iface['ipv4'] = interface['ip']
42 iface['bwlimit'] = str(int(interface['bwlimit'])/1000)
43 interfaces[iface['interface_id']] = iface
46 def get_links(self, filter={}):
48 if not self.api.config.SFA_AGGREGATE_TYPE.lower() == 'vini':
53 for (site_id1, site_id2) in topology:
55 if not site_id1 in self.sites or site_id2 not in self.sites:
57 site1 = self.sites[site_id1]
58 site2 = self.sites[site_id2]
60 site1_hrn = self.api.hrn + '.' + site1['login_base']
61 site2_hrn = self.api.hrn + '.' + site2['login_base']
63 node1 = self.nodes[site1['node_ids'][0]]
64 node2 = self.nodes[site2['node_ids'][0]]
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 = self.interfaces[node1['interface_ids'][0]]['ip']
70 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
71 if2_ipv4 = self.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')
83 links[link['component_name']] = link
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)
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 (self, slice=None,slivers=[]):
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 filter.update({'peer_id': None})
146 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'])
157 sites_dict = self.get_sites({'site_id': site_ids})
159 interfaces = self.get_interfaces({'interface_id':interface_ids})
161 node_tags = self.get_node_tags(tags_filter)
163 pl_initscripts = self.get_pl_initscripts()
167 # skip whitelisted nodes
168 if node['slice_ids_whitelist']:
169 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
172 # xxx how to retrieve site['login_base']
173 site_id=node['site_id']
174 site=sites_dict[site_id]
175 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
176 rspec_node['component_name'] = node['hostname']
177 rspec_node['component_manager_id'] = self.api.hrn
178 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
179 rspec_node['boot_state'] = node['boot_state']
180 rspec_node['exclusive'] = 'False'
181 rspec_node['hardware_types'].append(HardwareType({'name': 'plab-vserver'}))
182 # only doing this because protogeni rspec needs
183 # to advertise available initscripts
184 rspec_node['pl_initscripts'] = pl_initscripts.values()
185 # add site/interface info to nodes.
186 # assumes that sites, interfaces and tags have already been prepared.
187 site = sites_dict[node['site_id']]
188 if site['longitude'] and site['latitude']:
189 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
190 rspec_node['location'] = location
191 rspec_node['interfaces'] = []
193 for if_id in node['interface_ids']:
194 interface = Interface(interfaces[if_id])
195 interface['ipv4'] = interface['ipv4']
196 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count))
197 rspec_node['interfaces'].append(interface)
200 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
201 rspec_node['tags'] = tags
202 if node['node_id'] in slivers:
204 sliver = slivers[node['node_id']]
205 rspec_node['sliver_id'] = sliver['sliver_id']
206 rspec_node['client_id'] = node['hostname']
207 rspec_node['slivers'] = [sliver]
209 # slivers always provide the ssh service
210 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], port:'22'})
211 service = Services({'login': login})
212 rspec_node['services'].append(service)
213 rspec_nodes.append(rspec_node)
217 def get_rspec(self, slice_xrn=None, version = None):
219 version_manager = VersionManager()
220 version = version_manager.get_version(version)
222 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
224 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
226 slice, slivers = self.get_slice_and_slivers(slice_xrn)
227 rspec = RSpec(version=rspec_version, user_options=self.user_options)
228 if slice and 'expiration_date' in slice:
229 rspec.set('expires', epochparse(slice['expiration_date']))
230 rspec.version.add_nodes(self.get_nodes(slice), slivers)
231 rspec.version.add_links(self.get_links(slice))
233 # add sliver defaults
234 default_sliver_attribs = slivers.get(None, [])
235 for sliver_attrib in default_sliver_attribs:
236 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])