2 from sfa.util.xrn import hrn_to_urn, urn_to_hrn
3 from sfa.util.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename, urn_to_sliver_id
5 from sfa.rspecs.rspec import RSpec
6 from sfa.rspecs.elements.hardware_type import HardwareType
7 from sfa.rspecs.elements.link import Link
8 from sfa.rspecs.elements.login import Login
9 from sfa.rspecs.elements.interface import Interface
10 from sfa.rspecs.elements.services import Services
11 from sfa.rspecs.elements.pltag import PLTag
12 from sfa.util.topology import Topology
13 from sfa.rspecs.version_manager import VersionManager
14 from sfa.plc.vlink import get_tc_rate
19 #panos new user options variable
22 def __init__(self, api, user_options={}):
24 self.user_options = user_options
26 def get_sites(self, filter={}):
28 for site in self.api.driver.GetSites(filter):
29 sites[site['site_id']] = site
32 def get_interfaces(self, filter={}):
34 for interface in self.api.driver.GetInterfaces(filter):
36 iface['interface_id'] = interface['interface_id']
37 iface['node_id'] = interface['node_id']
38 iface['ipv4'] = interface['ip']
39 iface['bwlimit'] = interface['bwlimit']
40 interfaces[iface['interface_id']] = iface
43 def get_links(self, filter={}):
45 if not self.api.config.SFA_AGGREGATE_TYPE.lower() == 'vini':
50 for (site_id1, site_id2) in topology:
52 if not site_id1 in self.sites or site_id2 not in self.sites:
54 site1 = self.sites[site_id1]
55 site2 = self.sites[site_id2]
57 site1_hrn = self.api.hrn + '.' + site1['login_base']
58 site2_hrn = self.api.hrn + '.' + site2['login_base']
60 node1 = self.nodes[site1['node_ids'][0]]
61 node2 = self.nodes[site2['node_ids'][0]]
64 # just get first interface of the first node
65 if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id']))
66 if1_ipv4 = self.interfaces[node1['interface_ids'][0]]['ip']
67 if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id']))
68 if2_ipv4 = self.interfaces[node2['interface_ids'][0]]['ip']
70 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
71 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
74 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
75 link['interface1'] = if1
76 link['interface2'] = if2
77 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
78 link['component_id'] = PlXrn(auth=self.api.hrn, interface=link['component_name']).get_urn()
79 link['component_manager_id'] = hrn_to_urn(self.api.hrn, 'authority+am')
80 links[link['component_name']] = link
84 def get_node_tags(self, filter={}):
86 for node_tag in self.api.driver.GetNodeTags(filter):
87 node_tags[node_tag['node_tag_id']] = node_tag
90 def get_pl_initscripts(self, filter={}):
92 filter.update({'enabled': True})
93 for initscript in self.api.driver.GetInitScripts(filter):
94 pl_initscripts[initscript['initscript_id']] = initscript
98 def get_slice_and_slivers(self, slice_xrn):
100 Returns a dict of slivers keyed on the sliver's node_id
105 return (slice, slivers)
106 slice_urn = hrn_to_urn(slice_xrn)
107 slice_hrn, _ = urn_to_hrn(slice_xrn)
108 slice_name = hrn_to_pl_slicename(slice_hrn)
109 slices = self.api.driver.GetSlices(slice_name)
111 return (slice, slivers)
114 # sort slivers by node id
115 for node_id in slice['node_ids']:
116 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], node_id),
117 'name': 'plab-vserver',
119 slivers[node_id]= sliver
121 # sort sliver attributes by node id
122 tags = self.api.driver.GetSliceTags({'slice_tag_id': slice['slice_tag_ids']})
124 # most likely a default/global sliver attribute (node_id == None)
125 if tag['node_id'] not in slivers:
126 sliver = Sliver({'sliver_id': urn_to_sliver_id(slice_urn, slice['slice_id'], ""),
127 'name': 'plab-vserver',
129 slivers[tag['node_id']] = sliver
130 slivers[tag['node_id']]['tags'].append(tag)
132 return (slice, slivers)
134 def get_nodes(self, slice=None):
136 if slice and 'node_ids' in slice and slice['node_ids']:
137 filter['node_id'] = slice['node_ids']
139 filter.update({'peer_id': None})
140 nodes = self.api.driver.GetNodes(filter)
146 site_ids.append(node['site_id'])
147 interface_ids.extend(node['interface_ids'])
148 tag_ids.extend(node['node_tag_ids'])
151 sites_dict = self.get_sites({'site_id': site_ids})
153 interfaces = self.get_interfaces({'interface_id':interface_ids})
155 slivers = self.get_slivers(slice)
157 node_tags = self.get_node_tags({'node_id': node_ids})
159 pl_initscripts = self.get_pl_initscripts()
163 # skip whitelisted nodes
164 if node['slice_ids_whitelist']:
165 if not slice or slice['slice_id'] not in node['slice_ids_whitelist']:
168 rspec_node['component_id'] = hostname_to_urn(self.api.hrn, site['login_base'], node['hostname'])
169 rspec_node['component_name'] = node['hostname']
170 rspec_node['component_manager_id'] = self.api.hrn
171 rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.api.hrn, site['login_base']), 'authority+sa')
172 rspec_node['boot_state'] = node['boot_state']
173 rspec_node['exclusive'] = 'False'
174 rspec_node['hardware_types'].append(HardwareType({'name': 'plab-vserver'}))
175 # only doing this because protogeni rspec needs
176 # to advertise available initscripts
177 rspec_node['pl_initscripts'] = pl_initscripts
178 # add site/interface info to nodes.
179 # assumes that sites, interfaces and tags have already been prepared.
180 site = sites_dict[node['site_id']]
181 location = Location({'longitude': site['longitude'], 'latitude': site['latitude']})
182 rspec_node['location'] = location
183 rspec_node['interfaces'] = []
184 for if_id in node['interface_ids']:
185 interface = Interface(interfaces[if_id])
186 interface['ipv4'] = interface['ip']
187 rspec_node['interfaces'].append(interface)
188 tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
189 rspec_node['tags'] = tags
190 if node['node_id'] in slivers:
192 sliver = slivers[node['node_id']]
193 rspec_node['sliver_id'] = sliver['sliver_id']
194 rspec_node['client_id'] = node['hostname']
195 rspec_node['slivers'] = [slivers[node['node_id']]]
197 # slivers always provide the ssh service
198 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], port:'22'})
199 service = Services({'login': login})
200 rspec_node['services'].append(service)
201 rspec_nodes.append(rspec_node)
205 def get_rspec(self, slice_xrn=None, version = None):
207 version_manager = VersionManager()
208 version = version_manager.get_version(version)
210 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
212 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
214 slice, slivers = self.get_slice_and_slivers(slice_xrn)
215 rspec = RSpec(version=rspec_version, user_options=self.user_options)
216 rspec.version.add_nodes(self.get_nodes(slice, slivers))
217 rspec.version.add_links(self.get_links(slice))
219 # add sliver defaults
220 default_sliver_attribs = slivers.get(None, [])
221 for sliver_attrib in default_sliver_attribs:
222 rspec.version.add_default_sliver_attribute(sliver_attrib['name'], sliver_attrib['value'])