1 # -*- coding: utf-8 -*-
3 # Copyright 2018 University of Bristol - High Performance Networks Research
7 # Contributors: Anderson Bravalheri, Dimitrios Gkounis, Abubakar Siddique
8 # Muqaddas, Navdeep Uniyal, Reza Nejabati and Dimitra Simeonidou
10 # Licensed under the Apache License, Version 2.0 (the "License"); you may
11 # not use this file except in compliance with the License. You may obtain
12 # a copy of the License at
14 # http://www.apache.org/licenses/LICENSE-2.0
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19 # License for the specific language governing permissions and limitations
22 # For those usages not covered by the Apache License, Version 2.0 please
23 # contact with: <highperformance-networks@bristol.ac.uk>
25 # Neither the name of the University of Bristol nor the names of its
26 # contributors may be used to endorse or promote products derived from
27 # this software without specific prior written permission.
29 # This work has been performed in the context of DCMS UK 5G Testbeds
30 # & Trials Programme and in the framework of the Metro-Haul project -
31 # funded by the European Commission under Grant number 761727 through the
32 # Horizon 2020 and 5G-PPP programmes.
34 # pylint: disable=W0621
36 from __future__
import unicode_literals
39 from itertools
import izip
41 from textwrap
import wrap
43 from six
.moves
import range
45 from ...tests
.db_helpers
import uuid
, sha1
52 # In the following functions, the identifiers should be simple integers
55 def wim(identifier
=0):
56 return {'name': 'wim%d' % identifier
,
57 'uuid': uuid('wim%d' % identifier
),
58 'wim_url': 'localhost',
62 def tenant(identifier
=0):
63 return {'name': 'tenant%d' % identifier
,
64 'uuid': uuid('tenant%d' % identifier
)}
67 def wim_account(wim
, tenant
):
68 return {'name': 'wim-account%d%d' % (tenant
, wim
),
69 'uuid': uuid('wim-account%d%d' % (tenant
, wim
)),
70 'user': 'user%d%d' % (tenant
, wim
),
71 'password': 'password%d%d' % (tenant
, wim
),
72 'wim_id': uuid('wim%d' % wim
),
76 def wim_tenant_association(wim
, tenant
):
77 return {'nfvo_tenant_id': uuid('tenant%d' % tenant
),
78 'wim_id': uuid('wim%d' % wim
),
79 'wim_account_id': uuid('wim-account%d%d' % (tenant
, wim
))}
82 def wim_set(identifier
=0, tenant
=0):
83 """Records necessary to create a WIM and connect it to a tenant"""
85 {'wims': [wim(identifier
)]},
86 {'wim_accounts': [wim_account(identifier
, tenant
)]},
87 {'wim_nfvo_tenants': [wim_tenant_association(identifier
, tenant
)]}
91 def _datacenter_to_switch_port(dc_id
, port
=None):
93 switch
= ':'.join(wrap(('%0' + str(digits
) + 'x') % int(dc_id
), 2))
94 return (switch
, str((port
or int(dc_id
)) + 1))
97 def datacenter(identifier
, external_ports_config
=False):
98 config
= '' if not external_ports_config
else json
.dumps({
99 'external_connections': [
101 'provider:physical_network': 'provider',
102 'encapsulation_type': 'vlan'},
104 dict(izip(('switch', 'port'),
105 _datacenter_to_switch_port(identifier
)))}
108 return {'uuid': uuid('dc%d' % identifier
),
109 'name': 'dc%d' % identifier
,
111 'vim_url': 'localhost',
115 def datacenter_account(datacenter
, tenant
):
116 return {'name': 'dc-account%d%d' % (tenant
, datacenter
),
117 'uuid': uuid('dc-account%d%d' % (tenant
, datacenter
)),
118 'datacenter_id': uuid('dc%d' % datacenter
),
122 def datacenter_tenant_association(datacenter
, tenant
):
123 return {'nfvo_tenant_id': uuid('tenant%d' % tenant
),
124 'datacenter_id': uuid('dc%d' % datacenter
),
125 'datacenter_tenant_id':
126 uuid('dc-account%d%d' % (tenant
, datacenter
))}
129 def datacenter_set(identifier
=0, tenant
=0):
130 """Records necessary to create a datacenter and connect it to a tenant"""
132 {'datacenters': [datacenter(identifier
)]},
133 {'datacenter_tenants': [datacenter_account(identifier
, tenant
)]},
134 {'tenants_datacenters': [
135 datacenter_tenant_association(identifier
, tenant
)
140 def wim_port_mapping(wim
, datacenter
,
141 pop_dpid
='AA:AA:AA:AA:AA:AA:AA:AA', pop_port
=None,
142 wan_dpid
='BB:BB:BB:BB:BB:BB:BB:BB', wan_port
=None):
143 mapping_info
= {'mapping_type': 'dpid-port',
144 'wan_switch_dpid': wan_dpid
,
145 'wan_switch_port': (str(wan_port
) if wan_port
else
146 str(int(datacenter
) + int(wim
) + 1))}
147 id_
= 'dpid-port|' + sha1(json
.dumps(mapping_info
, sort_keys
=True))
149 return {'wim_id': uuid('wim%d' % wim
),
150 'datacenter_id': uuid('dc%d' % datacenter
),
151 'pop_switch_dpid': pop_dpid
,
152 'pop_switch_port': (str(pop_port
) if pop_port
else
153 str(int(datacenter
) + int(wim
) + 1)),
154 # ^ Datacenter router have one port managed by each WIM
155 'wan_service_endpoint_id': id_
,
156 # ^ WIM managed router have one port connected to each DC
157 'wan_service_mapping_info': json
.dumps(mapping_info
)}
160 def processed_port_mapping(wim
, datacenter
,
162 pop_dpid
='AA:AA:AA:AA:AA:AA:AA:AA',
163 wan_dpid
='BB:BB:BB:BB:BB:BB:BB:BB'):
164 """Emulate the response of the Persistence class, where the records in the
165 data base are grouped by wim and datacenter
168 'wim_id': uuid('wim%d' % wim
),
169 'datacenter_id': uuid('dc%d' % datacenter
),
170 'pop_wan_mappings': [
171 {'pop_switch_dpid': pop_dpid
,
172 'pop_switch_port': wim
+ 1 + i
,
173 'wan_service_endpoint_id':
174 sha1('dpid-port|%s|%d' % (wan_dpid
, datacenter
+ 1 + i
)),
175 'wan_service_mapping_info': {
176 'mapping_type': 'dpid-port',
177 'wan_switch_dpid': wan_dpid
,
178 'wan_switch_port': datacenter
+ 1 + i
}}
179 for i
in range(num_pairs
)
184 def consistent_set(num_wims
=NUM_WIMS
, num_tenants
=NUM_TENANTS
,
185 num_datacenters
=NUM_DATACENTERS
,
186 external_ports_config
=False):
188 {'nfvo_tenants': [tenant(i
) for i
in range(num_tenants
)]},
189 {'wims': [wim(j
) for j
in range(num_wims
)]},
192 for i
in range(num_tenants
)
193 for j
in range(num_wims
)
195 {'wim_nfvo_tenants': [
196 wim_tenant_association(j
, i
)
197 for i
in range(num_tenants
)
198 for j
in range(num_wims
)
201 datacenter(k
, external_ports_config
)
202 for k
in range(num_datacenters
)
204 {'datacenter_tenants': [
205 datacenter_account(k
, i
)
206 for i
in range(num_tenants
)
207 for k
in range(num_datacenters
)
209 {'tenants_datacenters': [
210 datacenter_tenant_association(k
, i
)
211 for i
in range(num_tenants
)
212 for k
in range(num_datacenters
)
214 {'wim_port_mappings': [
215 (wim_port_mapping(j
, k
, *_datacenter_to_switch_port(k
))
216 if external_ports_config
else wim_port_mapping(j
, k
))
217 for j
in range(num_wims
)
218 for k
in range(num_datacenters
)
223 def instance_nets(num_datacenters
=2, num_links
=2, status
='BUILD'):
224 """Example of multi-site deploy with N datacenters and M WAN links between
225 them (e.g M = 2 -> back and forth)
228 {'uuid': uuid('net%d%d' % (k
, l
)),
229 'datacenter_id': uuid('dc%d' % k
),
230 'datacenter_tenant_id': uuid('dc-account0%d' % k
),
231 'instance_scenario_id': uuid('nsr0'),
232 # ^ instance_scenario_id == NS Record id
233 'sce_net_id': uuid('vld%d' % l
),
234 # ^ scenario net id == VLD id
238 for k
in range(num_datacenters
)
239 for l
in range(num_links
)
243 def wim_actions(action
='CREATE', status
='SCHEDULED',
244 action_id
=None, instance
=0,
245 wim
=0, tenant
=0, num_links
=1):
246 """Create a list of actions for the WIM,
249 action: type of action (CREATE) by default
250 wim: WIM fixture index to create actions for
251 tenant: tenant fixture index to create actions for
252 num_links: number of WAN links to be established by each WIM
255 action_id
= action_id
or 'ACTION-{}'.format(time())
260 'wim_internal_id': uuid('-wim-net%d%d%d' % (wim
, instance
, link
)),
261 'wim_account_id': uuid('wim-account%d%d' % (tenant
, wim
)),
262 'instance_action_id': action_id
,
263 'item': 'instance_wim_nets',
264 'item_id': uuid('wim-net%d%d%d' % (wim
, instance
, link
)),
267 'created_at': time(),
268 'modified_at': time(),
271 for link
in range(num_links
)
275 def instance_action(tenant
=0, instance
=0, action_id
=None,
276 num_tasks
=1, num_done
=0, num_failed
=0):
277 action_id
= action_id
or 'ACTION-{}'.format(time())
281 'tenant_id': uuid('tenant%d' % tenant
),
282 'instance_id': uuid('nsr%d' % instance
),
283 'number_tasks': num_tasks
,
284 'number_done': num_done
,
285 'number_failed': num_failed
,
289 def instance_wim_nets(instance
=0, wim
=0, num_links
=1,
290 status
='SCHEDULED_CREATION'):
291 """Example of multi-site deploy with N wims and M WAN links between
292 them (e.g M = 2 -> back and forth)
296 {'uuid': uuid('wim-net%d%d%d' % (wim
, instance
, l
)),
297 'wim_id': uuid('wim%d' % wim
),
298 'wim_account_id': uuid('wim-account%d' % wim
),
299 'wim_internal_id': uuid('-net%d%d' % (wim
, l
)),
300 'instance_scenario_id': uuid('nsr%d' % instance
),
301 # ^ instance_scenario_id == NS Record id
302 'sce_net_id': uuid('vld%d' % l
),
303 # ^ scenario net id == VLD id
306 for l
in range(num_links
)
310 def instance_vm(instance
=0, vim_info
=None):
311 vim_info
= {'OS-EXT-SRV-ATTR:hypervisor_hostname': 'host%d' % instance
}
313 'uuid': uuid('vm%d' % instance
),
314 'instance_vnf_id': uuid('vnf%d' % instance
),
315 'vm_id': uuid('vm%d' % instance
),
316 'vim_vm_id': uuid('vm%d' % instance
),
318 'vim_info': vim_info
,
322 def instance_interface(instance
=0, interface
=0, datacenter
=0, link
=0):
324 'uuid': uuid('interface%d%d' % (instance
, interface
)),
325 'instance_vm_id': uuid('vm%d' % instance
),
326 'instance_net_id': uuid('net%d%d' % (datacenter
, link
)),
327 'interface_id': uuid('iface%d' % interface
),