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']
43 if interface['bwlimit']:
44 iface['bwlimit'] = str(int(interface['bwlimit'])/1000)
45 interfaces[iface['interface_id']] = iface
48 def get_links(self, filter={}):
50 if not self.api.config.SFA_AGGREGATE_TYPE.lower() == 'vini':
55 for (site_id1, site_id2) in topology:
57 if not site_id1 in self.sites or site_id2 not in self.sites:
59 site1 = self.sites[site_id1]
60 site2 = self.sites[site_id2]
62 site1_hrn = self.api.hrn + '.' + site1['login_base']
63 site2_hrn = self.api.hrn + '.' + site2['login_base']
65 node1 = self.nodes[site1['node_ids'][0]]
66 node2 = self.nodes[site2['node_ids'][0]]
69 # just get first interface of the first node
70 if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id']))
71 if1_ipv4 = self.interfaces[node1['interface_ids'][0]]['ip']
72 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
73 if2_ipv4 = self.interfaces[node2['interface_ids'][0]]['ip']
75 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
76 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
79 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
80 link['interface1'] = if1
81 link['interface2'] = if2
82 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
83 link['component_id'] = PlXrn(auth=self.api.hrn, interface=link['component_name']).get_urn()
84 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
85 links[link['component_name']] = link
89 def get_node_tags(self, filter={}):
91 for node_tag in self.api.driver.GetNodeTags(filter):
92 node_tags[node_tag['node_tag_id']] = node_tag
95 def get_pl_initscripts(self, filter={}):
97 filter.update({'enabled': True})
98 for initscript in self.api.driver.GetInitScripts(filter):
99 pl_initscripts[initscript['initscript_id']] = initscript
100 return pl_initscripts
103 def get_slice_and_slivers(self, slice_xrn):
105 Returns a dict of slivers keyed on the sliver's node_id
110 return (slice, slivers)
111 slice_urn = hrn_to_urn(slice_xrn, 'slice')
112 slice_hrn, _ = urn_to_hrn(slice_xrn)
113 slice_name = hrn_to_pl_slicename(slice_hrn)
114 slices = self.api.driver.GetSlices(slice_name)
116 return (slice, slivers)
119 # sort slivers by node id
120 for node_id in slice['node_ids']:
121 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
122 'name': slice['name'],
123 'type': 'plab-vserver',
125 slivers[node_id]= sliver
127 # sort sliver attributes by node id
128 tags = self.api.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
130 # most likely a default/global sliver attribute (node_id == None)
131 if tag['node_id'] not in slivers:
132 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
133 'name': 'plab-vserver',
135 slivers[tag['node_id']] = sliver
136 slivers[tag['node_id']]['tags'].append(tag)
138 return (slice, slivers)
140 def get_nodes (self, slice=None,slivers=[]):
143 if slice and 'node_ids' in slice and slice['node_ids']:
144 filter['node_id'] = slice['node_ids']
145 tags_filter=filter.copy()
147 filter.update({'peer_id': None})
148 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'])
159 sites_dict = self.get_sites({'site_id': site_ids})
161 interfaces = self.get_interfaces({'interface_id':interface_ids})
163 node_tags = self.get_node_tags(tags_filter)
165 pl_initscripts = self.get_pl_initscripts()
169 # skip whitelisted nodes
170 if node['slice_ids_whitelist']:
171 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
174 # xxx how to retrieve site['login_base']
175 site_id=node['site_id']
176 site=sites_dict[site_id]
177 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
178 rspec_node['component_name'] = node['hostname']
179 rspec_node['component_manager_id'] = self.api.hrn
180 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
181 rspec_node['boot_state'] = node['boot_state']
182 rspec_node['exclusive'] = 'False'
183 rspec_node['hardware_types']= [HardwareType({'name': 'plab-vserver'})]
184 # only doing this because protogeni rspec needs
185 # to advertise available initscripts
186 rspec_node['pl_initscripts'] = pl_initscripts.values()
187 # add site/interface info to nodes.
188 # assumes that sites, interfaces and tags have already been prepared.
189 site = sites_dict[node['site_id']]
190 if site['longitude'] and site['latitude']:
191 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
192 rspec_node['location'] = location
193 rspec_node['interfaces'] = []
195 for if_id in node['interface_ids']:
196 interface = Interface(interfaces[if_id])
197 interface['ipv4'] = interface['ipv4']
198 interface['component_id'] = PlXrn(auth=self.api.hrn, interface='node%s:eth%s' % (node['node_id'], if_count))
199 rspec_node['interfaces'].append(interface)
202 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
203 rspec_node['tags'] = tags
204 if node['node_id'] in slivers:
206 sliver = slivers[node['node_id']]
207 rspec_node['sliver_id'] = sliver['sliver_id']
208 rspec_node['client_id'] = node['hostname']
209 rspec_node['slivers'] = [sliver]
211 # slivers always provide the ssh service
212 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22'})
213 service = Services({'login': login})
214 rspec_node['services'] = [service]
215 rspec_nodes.append(rspec_node)
219 def get_rspec(self, slice_xrn=None, version = None):
221 version_manager = VersionManager()
222 version = version_manager.get_version(version)
224 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
226 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
228 slice, slivers = self.get_slice_and_slivers(slice_xrn)
229 rspec = RSpec(version=rspec_version, user_options=self.user_options)
230 if slice and 'expires' in slice:
231 rspec.xml.set('expires', epochparse(slice['expires']))
232 rspec.version.add_nodes(self.get_nodes(slice, slivers))
233 rspec.version.add_links(self.get_links(slice))
235 # add sliver defaults
236 default_sliver_attribs = slivers.get(None, [])
237 for sliver_attrib in default_sliver_attribs:
238 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])