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 iface['interface_id'] = interface['interface_id']
41 iface['node_id'] = interface['node_id']
42 iface['ipv4'] = interface['ip']
44 iface['bwlimit'] = str(int(interface['bwlimit'])/1000)
46 # xxx not sure how to code that no limit was set
48 interfaces[iface['interface_id']] = iface
51 def get_links(self, filter={}):
53 if not self.api.config.SFA_AGGREGATE_TYPE.lower() == 'vini':
58 for (site_id1, site_id2) in topology:
60 if not site_id1 in self.sites or site_id2 not in self.sites:
62 site1 = self.sites[site_id1]
63 site2 = self.sites[site_id2]
65 site1_hrn = self.api.hrn + '.' + site1['login_base']
66 site2_hrn = self.api.hrn + '.' + site2['login_base']
68 node1 = self.nodes[site1['node_ids'][0]]
69 node2 = self.nodes[site2['node_ids'][0]]
72 # just get first interface of the first node
73 if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id']))
74 if1_ipv4 = self.interfaces[node1['interface_ids'][0]]['ip']
75 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
76 if2_ipv4 = self.interfaces[node2['interface_ids'][0]]['ip']
78 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
79 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
82 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
83 link['interface1'] = if1
84 link['interface2'] = if2
85 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
86 link['component_id'] = PlXrn(auth=self.api.hrn, interface=link['component_name']).get_urn()
87 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
88 links[link['component_name']] = link
92 def get_node_tags(self, filter={}):
94 for node_tag in self.api.driver.GetNodeTags(filter):
95 node_tags[node_tag['node_tag_id']] = node_tag
98 def get_pl_initscripts(self, filter={}):
100 filter.update({'enabled': True})
101 for initscript in self.api.driver.GetInitScripts(filter):
102 pl_initscripts[initscript['initscript_id']] = initscript
103 return pl_initscripts
106 def get_slice_and_slivers(self, slice_xrn):
108 Returns a dict of slivers keyed on the sliver's node_id
113 return (slice, slivers)
114 slice_urn = hrn_to_urn(slice_xrn, 'slice')
115 slice_hrn, _ = urn_to_hrn(slice_xrn)
116 slice_name = hrn_to_pl_slicename(slice_hrn)
117 slices = self.api.driver.GetSlices(slice_name)
119 return (slice, slivers)
122 # sort slivers by node id
123 for node_id in slice['node_ids']:
124 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
125 'name': slice['name'],
126 'type': 'plab-vserver',
128 slivers[node_id]= sliver
130 # sort sliver attributes by node id
131 tags = self.api.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
133 # most likely a default/global sliver attribute (node_id == None)
134 if tag['node_id'] not in slivers:
135 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
136 'name': 'plab-vserver',
138 slivers[tag['node_id']] = sliver
139 slivers[tag['node_id']]['tags'].append(tag)
141 return (slice, slivers)
143 def get_nodes (self, slice=None,slivers=[]):
146 if slice and 'node_ids' in slice and slice['node_ids']:
147 filter['node_id'] = slice['node_ids']
148 tags_filter=filter.copy()
150 filter.update({'peer_id': None})
151 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'])
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()
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-vserver'})]
187 # only doing this because protogeni rspec needs
188 # to advertise available initscripts
189 rspec_node['pl_initscripts'] = pl_initscripts.values()
190 # add site/interface info to nodes.
191 # assumes that sites, interfaces and tags have already been prepared.
192 site = sites_dict[node['site_id']]
193 if site['longitude'] and site['latitude']:
194 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
195 rspec_node['location'] = location
196 rspec_node['interfaces'] = []
198 for if_id in node['interface_ids']:
199 interface = Interface(interfaces[if_id])
200 interface['ipv4'] = interface['ipv4']
201 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count))
202 rspec_node['interfaces'].append(interface)
205 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
206 rspec_node['tags'] = tags
207 if node['node_id'] in slivers:
209 sliver = slivers[node['node_id']]
210 rspec_node['sliver_id'] = sliver['sliver_id']
211 rspec_node['client_id'] = node['hostname']
212 rspec_node['slivers'] = [sliver]
214 # slivers always provide the ssh service
215 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
216 service = Services({'login': login})
217 rspec_node['services'] = [service]
218 rspec_nodes.append(rspec_node)
222 def get_rspec(self, slice_xrn=None, version = None):
224 version_manager = VersionManager()
225 version = version_manager.get_version(version)
227 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
229 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
231 slice, slivers = self.get_slice_and_slivers(slice_xrn)
232 rspec = RSpec(version=rspec_version, user_options=self.user_options)
233 if slice and 'expires' in slice:
234 rspec.xml.set('expires', epochparse(slice['expires']))
235 rspec.version.add_nodes(self.get_nodes(slice, slivers))
236 rspec.version.add_links(self.get_links(slice))
238 # add sliver defaults
239 default_sliver_attribs = slivers.get(None, [])
240 for sliver_attrib in default_sliver_attribs:
241 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])