Adding missing variable
[osm/RO.git] / RO-VIM-openstack / osm_rovim_openstack / tests / test_vimconn_openstack.py
1 # -*- coding: utf-8 -*-
2
3 ##
4 # Copyright 2017 Intel Corporation.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
16 # under the License.
17 #
18 # For those usages not covered by the Apache License, Version 2.0 please
19 # contact with: nfvlabs@tid.es
20 ##
21
22 """
23 This module contains unit tests for the OpenStack VIM connector
24 Run this directly with python2 or python3.
25 """
26 import copy
27 from copy import deepcopy
28 import logging
29 import unittest
30
31 import mock
32 from mock import MagicMock, patch
33 from neutronclient.v2_0.client import Client
34 from osm_ro_plugin import vimconn
35 from osm_ro_plugin.vimconn import VimConnConnectionException, VimConnException
36 from osm_rovim_openstack.vimconn_openstack import vimconnector
37
38 __author__ = "Igor D.C."
39 __date__ = "$23-aug-2017 23:59:59$"
40
41 # Variables Used in TestNewVmInstance Class
42 name = "basicvm"
43 description = "my firewall"
44 start = True
45 image_id = "408b73-e9cc-5a6a-t270-82cc4811bd4a"
46 flavor_id = "208b73-e9cc-5a6a-t270-82cc4811bd4a"
47 affinity_group_list = []
48 net_list = []
49 cloud_config = {}
50 disk_list = []
51 disk_list2 = [
52 {"size": 10, "image_id": image_id},
53 {"size": 20},
54 ]
55 availability_zone_index = 0
56 availability_zone_list = ["nova"]
57 floating_network_vim_id = "108b73-e9cc-5a6a-t270-82cc4811bd4a"
58 net_id = "83372685-f67f-49fd-8722-eabb7692fc22"
59 net2_id = "46472685-f67f-49fd-8722-eabb7692fc22"
60 mac_address = "00:00:5e:00:53:af"
61 port_id = "03372685-f67f-49fd-8722-eabb7692fc22"
62 time_return_value = 156570000
63 port2_id = "17472685-f67f-49fd-8722-eabb7692fc22"
64 root_vol_id = "tc408b73-r9cc-5a6a-a270-82cc4811bd4a"
65 ip_addr1 = "20.3.4.5"
66 volume_id = "ac408b73-b9cc-4a6a-a270-82cc4811bd4a"
67 volume_id2 = "o4e0e83-b9uu-4akk-a234-89cc4811bd4a"
68 volume_id3 = "44e0e83-t9uu-4akk-a234-p9cc4811bd4a"
69
70
71 class TestSfcOperations(unittest.TestCase):
72 @mock.patch("logging.getLogger", autospec=True)
73 def setUp(self, mock_logger):
74 # Instantiate dummy VIM connector so we can test it
75 # It throws exception because of dummy parameters,
76 # We are disabling the logging of exception not to print them to console.
77 mock_logger = logging.getLogger()
78 mock_logger.disabled = True
79 self.vimconn = vimconnector(
80 "123",
81 "openstackvim",
82 "456",
83 "789",
84 "http://dummy.url",
85 None,
86 "user",
87 "pass",
88 )
89
90 def _test_new_sfi(
91 self,
92 create_sfc_port_pair,
93 sfc_encap,
94 ingress_ports=["5311c75d-d718-4369-bbda-cdcc6da60fcc"],
95 egress_ports=["230cdf1b-de37-4891-bc07-f9010cf1f967"],
96 ):
97 # input to VIM connector
98 name = "osm_sfi"
99 # + ingress_ports
100 # + egress_ports
101 # TODO(igordc): must be changed to NSH in Queens (MPLS is a workaround)
102 correlation = "nsh"
103 if sfc_encap is not None:
104 if not sfc_encap:
105 correlation = None
106
107 # what OpenStack is assumed to respond (patch OpenStack"s return value)
108 dict_from_neutron = {
109 "port_pair": {
110 "id": "3d7ddc13-923c-4332-971e-708ed82902ce",
111 "name": name,
112 "description": "",
113 "tenant_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
114 "project_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
115 "ingress": ingress_ports[0] if len(ingress_ports) else None,
116 "egress": egress_ports[0] if len(egress_ports) else None,
117 "service_function_parameters": {"correlation": correlation},
118 }
119 }
120 create_sfc_port_pair.return_value = dict_from_neutron
121
122 # what the VIM connector is expected to
123 # send to OpenStack based on the input
124 dict_to_neutron = {
125 "port_pair": {
126 "name": name,
127 "ingress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
128 "egress": "230cdf1b-de37-4891-bc07-f9010cf1f967",
129 "service_function_parameters": {"correlation": correlation},
130 }
131 }
132
133 # call the VIM connector
134 if sfc_encap is None:
135 result = self.vimconn.new_sfi(name, ingress_ports, egress_ports)
136 else:
137 result = self.vimconn.new_sfi(name, ingress_ports, egress_ports, sfc_encap)
138
139 # assert that the VIM connector made the expected call to OpenStack
140 create_sfc_port_pair.assert_called_with(dict_to_neutron)
141 # assert that the VIM connector had the expected result / return value
142 self.assertEqual(result, dict_from_neutron["port_pair"]["id"])
143
144 def _test_new_sf(self, create_sfc_port_pair_group):
145 # input to VIM connector
146 name = "osm_sf"
147 instances = [
148 "bbd01220-cf72-41f2-9e70-0669c2e5c4cd",
149 "12ba215e-3987-4892-bd3a-d0fd91eecf98",
150 "e25a7c79-14c8-469a-9ae1-f601c9371ffd",
151 ]
152
153 # what OpenStack is assumed to respond (patch OpenStack"s return value)
154 dict_from_neutron = {
155 "port_pair_group": {
156 "id": "3d7ddc13-923c-4332-971e-708ed82902ce",
157 "name": name,
158 "description": "",
159 "tenant_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
160 "project_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
161 "port_pairs": instances,
162 "group_id": 1,
163 "port_pair_group_parameters": {
164 "lb_fields": [],
165 "ppg_n_tuple_mapping": {
166 "ingress_n_tuple": {},
167 "egress_n_tuple": {},
168 },
169 },
170 }
171 }
172 create_sfc_port_pair_group.return_value = dict_from_neutron
173
174 # what the VIM connector is expected to
175 # send to OpenStack based on the input
176 dict_to_neutron = {
177 "port_pair_group": {
178 "name": name,
179 "port_pairs": [
180 "bbd01220-cf72-41f2-9e70-0669c2e5c4cd",
181 "12ba215e-3987-4892-bd3a-d0fd91eecf98",
182 "e25a7c79-14c8-469a-9ae1-f601c9371ffd",
183 ],
184 }
185 }
186
187 # call the VIM connector
188 result = self.vimconn.new_sf(name, instances)
189
190 # assert that the VIM connector made the expected call to OpenStack
191 create_sfc_port_pair_group.assert_called_with(dict_to_neutron)
192 # assert that the VIM connector had the expected result / return value
193 self.assertEqual(result, dict_from_neutron["port_pair_group"]["id"])
194
195 def _test_new_sfp(self, create_sfc_port_chain, sfc_encap, spi):
196 # input to VIM connector
197 name = "osm_sfp"
198 classifications = [
199 "2bd2a2e5-c5fd-4eac-a297-d5e255c35c19",
200 "00f23389-bdfa-43c2-8b16-5815f2582fa8",
201 ]
202 sfs = [
203 "2314daec-c262-414a-86e3-69bb6fa5bc16",
204 "d8bfdb5d-195e-4f34-81aa-6135705317df",
205 ]
206
207 # TODO(igordc): must be changed to NSH in Queens (MPLS is a workaround)
208 correlation = "nsh"
209 chain_id = 33
210 if spi:
211 chain_id = spi
212
213 # what OpenStack is assumed to respond (patch OpenStack"s return value)
214 dict_from_neutron = {
215 "port_chain": {
216 "id": "5bc05721-079b-4b6e-a235-47cac331cbb6",
217 "name": name,
218 "description": "",
219 "tenant_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
220 "project_id": "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c",
221 "chain_id": chain_id,
222 "flow_classifiers": classifications,
223 "port_pair_groups": sfs,
224 "chain_parameters": {"correlation": correlation},
225 }
226 }
227 create_sfc_port_chain.return_value = dict_from_neutron
228
229 # what the VIM connector is expected to
230 # send to OpenStack based on the input
231 dict_to_neutron = {
232 "port_chain": {
233 "name": name,
234 "flow_classifiers": [
235 "2bd2a2e5-c5fd-4eac-a297-d5e255c35c19",
236 "00f23389-bdfa-43c2-8b16-5815f2582fa8",
237 ],
238 "port_pair_groups": [
239 "2314daec-c262-414a-86e3-69bb6fa5bc16",
240 "d8bfdb5d-195e-4f34-81aa-6135705317df",
241 ],
242 "chain_parameters": {"correlation": correlation},
243 }
244 }
245 if spi:
246 dict_to_neutron["port_chain"]["chain_id"] = spi
247
248 # call the VIM connector
249 if sfc_encap is None:
250 dict_to_neutron["port_chain"]["chain_parameters"] = {"correlation": "mpls"}
251 if spi is None:
252 result = self.vimconn.new_sfp(
253 name, classifications, sfs, sfc_encap=False
254 )
255 else:
256 result = self.vimconn.new_sfp(
257 name, classifications, sfs, sfc_encap=False, spi=spi
258 )
259 else:
260 if spi is None:
261 result = self.vimconn.new_sfp(name, classifications, sfs, sfc_encap)
262 else:
263 result = self.vimconn.new_sfp(
264 name, classifications, sfs, sfc_encap, spi
265 )
266
267 # assert that the VIM connector made the expected call to OpenStack
268 create_sfc_port_chain.assert_called_with(dict_to_neutron)
269 # assert that the VIM connector had the expected result / return value
270 self.assertEqual(result, dict_from_neutron["port_chain"]["id"])
271
272 def _test_new_classification(self, create_sfc_flow_classifier, ctype):
273 # input to VIM connector
274 name = "osm_classification"
275 definition = {
276 "ethertype": "IPv4",
277 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
278 "protocol": "tcp",
279 "source_ip_prefix": "192.168.2.0/24",
280 "source_port_range_max": 99,
281 "source_port_range_min": 50,
282 }
283
284 # what OpenStack is assumed to respond (patch OpenStack"s return value)
285 dict_from_neutron = {"flow_classifier": copy.copy(definition)}
286 dict_from_neutron["flow_classifier"][
287 "id"
288 ] = "7735ec2c-fddf-4130-9712-32ed2ab6a372"
289 dict_from_neutron["flow_classifier"]["name"] = name
290 dict_from_neutron["flow_classifier"]["description"] = ""
291 dict_from_neutron["flow_classifier"][
292 "tenant_id"
293 ] = "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c"
294 dict_from_neutron["flow_classifier"][
295 "project_id"
296 ] = "130b1e97-b0f1-40a8-8804-b6ad9b8c3e0c"
297 create_sfc_flow_classifier.return_value = dict_from_neutron
298
299 # what the VIM connector is expected to
300 # send to OpenStack based on the input
301 dict_to_neutron = {"flow_classifier": copy.copy(definition)}
302 dict_to_neutron["flow_classifier"]["name"] = "osm_classification"
303
304 # call the VIM connector
305 result = self.vimconn.new_classification(name, ctype, definition)
306
307 # assert that the VIM connector made the expected call to OpenStack
308 create_sfc_flow_classifier.assert_called_with(dict_to_neutron)
309 # assert that the VIM connector had the expected result / return value
310 self.assertEqual(result, dict_from_neutron["flow_classifier"]["id"])
311
312 @mock.patch.object(Client, "create_sfc_flow_classifier")
313 def test_new_classification(self, create_sfc_flow_classifier):
314 self._test_new_classification(
315 create_sfc_flow_classifier, "legacy_flow_classifier"
316 )
317
318 @mock.patch.object(Client, "create_sfc_flow_classifier")
319 def test_new_classification_unsupported_type(self, create_sfc_flow_classifier):
320 self.assertRaises(
321 vimconn.VimConnNotSupportedException,
322 self._test_new_classification,
323 create_sfc_flow_classifier,
324 "h265",
325 )
326
327 @mock.patch.object(Client, "create_sfc_port_pair")
328 def test_new_sfi_with_sfc_encap(self, create_sfc_port_pair):
329 self._test_new_sfi(create_sfc_port_pair, True)
330
331 @mock.patch.object(Client, "create_sfc_port_pair")
332 def test_new_sfi_without_sfc_encap(self, create_sfc_port_pair):
333 self._test_new_sfi(create_sfc_port_pair, False)
334
335 @mock.patch.object(Client, "create_sfc_port_pair")
336 def test_new_sfi_default_sfc_encap(self, create_sfc_port_pair):
337 self._test_new_sfi(create_sfc_port_pair, None)
338
339 @mock.patch.object(Client, "create_sfc_port_pair")
340 def test_new_sfi_bad_ingress_ports(self, create_sfc_port_pair):
341 ingress_ports = [
342 "5311c75d-d718-4369-bbda-cdcc6da60fcc",
343 "a0273f64-82c9-11e7-b08f-6328e53f0fa7",
344 ]
345 self.assertRaises(
346 vimconn.VimConnNotSupportedException,
347 self._test_new_sfi,
348 create_sfc_port_pair,
349 True,
350 ingress_ports=ingress_ports,
351 )
352 ingress_ports = []
353 self.assertRaises(
354 vimconn.VimConnNotSupportedException,
355 self._test_new_sfi,
356 create_sfc_port_pair,
357 True,
358 ingress_ports=ingress_ports,
359 )
360
361 @mock.patch.object(Client, "create_sfc_port_pair")
362 def test_new_sfi_bad_egress_ports(self, create_sfc_port_pair):
363 egress_ports = [
364 "230cdf1b-de37-4891-bc07-f9010cf1f967",
365 "b41228fe-82c9-11e7-9b44-17504174320b",
366 ]
367 self.assertRaises(
368 vimconn.VimConnNotSupportedException,
369 self._test_new_sfi,
370 create_sfc_port_pair,
371 True,
372 egress_ports=egress_ports,
373 )
374 egress_ports = []
375 self.assertRaises(
376 vimconn.VimConnNotSupportedException,
377 self._test_new_sfi,
378 create_sfc_port_pair,
379 True,
380 egress_ports=egress_ports,
381 )
382
383 @mock.patch.object(vimconnector, "get_sfi")
384 @mock.patch.object(Client, "create_sfc_port_pair_group")
385 def test_new_sf(self, create_sfc_port_pair_group, get_sfi):
386 get_sfi.return_value = {"sfc_encap": True}
387 self._test_new_sf(create_sfc_port_pair_group)
388
389 @mock.patch.object(vimconnector, "get_sfi")
390 @mock.patch.object(Client, "create_sfc_port_pair_group")
391 def test_new_sf_inconsistent_sfc_encap(self, create_sfc_port_pair_group, get_sfi):
392 get_sfi.return_value = {"sfc_encap": "nsh"}
393 self.assertRaises(
394 vimconn.VimConnNotSupportedException,
395 self._test_new_sf,
396 create_sfc_port_pair_group,
397 )
398
399 @mock.patch.object(Client, "create_sfc_port_chain")
400 def test_new_sfp_with_sfc_encap(self, create_sfc_port_chain):
401 self._test_new_sfp(create_sfc_port_chain, True, None)
402
403 @mock.patch.object(Client, "create_sfc_port_chain")
404 def test_new_sfp_without_sfc_encap(self, create_sfc_port_chain):
405 self._test_new_sfp(create_sfc_port_chain, None, None)
406 self._test_new_sfp(create_sfc_port_chain, None, 25)
407
408 @mock.patch.object(Client, "create_sfc_port_chain")
409 def test_new_sfp_default_sfc_encap(self, create_sfc_port_chain):
410 self._test_new_sfp(create_sfc_port_chain, None, None)
411
412 @mock.patch.object(Client, "create_sfc_port_chain")
413 def test_new_sfp_with_sfc_encap_spi(self, create_sfc_port_chain):
414 self._test_new_sfp(create_sfc_port_chain, True, 25)
415
416 @mock.patch.object(Client, "create_sfc_port_chain")
417 def test_new_sfp_default_sfc_encap_spi(self, create_sfc_port_chain):
418 self._test_new_sfp(create_sfc_port_chain, None, 25)
419
420 @mock.patch.object(Client, "list_sfc_flow_classifiers")
421 def test_get_classification_list(self, list_sfc_flow_classifiers):
422 # what OpenStack is assumed to return to the VIM connector
423 list_sfc_flow_classifiers.return_value = {
424 "flow_classifiers": [
425 {
426 "source_port_range_min": 2000,
427 "destination_ip_prefix": "192.168.3.0/24",
428 "protocol": "udp",
429 "description": "",
430 "ethertype": "IPv4",
431 "l7_parameters": {},
432 "source_port_range_max": 2000,
433 "destination_port_range_min": 3000,
434 "source_ip_prefix": "192.168.2.0/24",
435 "logical_destination_port": None,
436 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
437 "destination_port_range_max": None,
438 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
439 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
440 "id": "22198366-d4e8-4d6b-b4d2-637d5d6cbb7d",
441 "name": "fc1",
442 }
443 ]
444 }
445
446 # call the VIM connector
447 filter_dict = {"protocol": "tcp", "ethertype": "IPv4"}
448 result = self.vimconn.get_classification_list(filter_dict.copy())
449
450 # assert that VIM connector called OpenStack with the expected filter
451 list_sfc_flow_classifiers.assert_called_with(**filter_dict)
452 # assert that the VIM connector successfully
453 # translated and returned the OpenStack result
454 self.assertEqual(
455 result,
456 [
457 {
458 "id": "22198366-d4e8-4d6b-b4d2-637d5d6cbb7d",
459 "name": "fc1",
460 "description": "",
461 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
462 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
463 "ctype": "legacy_flow_classifier",
464 "definition": {
465 "source_port_range_min": 2000,
466 "destination_ip_prefix": "192.168.3.0/24",
467 "protocol": "udp",
468 "ethertype": "IPv4",
469 "l7_parameters": {},
470 "source_port_range_max": 2000,
471 "destination_port_range_min": 3000,
472 "source_ip_prefix": "192.168.2.0/24",
473 "logical_destination_port": None,
474 "destination_port_range_max": None,
475 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
476 },
477 }
478 ],
479 )
480
481 def _test_get_sfi_list(self, list_port_pair, correlation, sfc_encap):
482 # what OpenStack is assumed to return to the VIM connector
483 list_port_pair.return_value = {
484 "port_pairs": [
485 {
486 "ingress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
487 "description": "",
488 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
489 "egress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
490 "service_function_parameters": {"correlation": correlation},
491 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
492 "id": "c121ebdd-7f2d-4213-b933-3325298a6966",
493 "name": "osm_sfi",
494 }
495 ]
496 }
497
498 # call the VIM connector
499 filter_dict = {"name": "osm_sfi", "description": ""}
500 result = self.vimconn.get_sfi_list(filter_dict.copy())
501
502 # assert that VIM connector called OpenStack with the expected filter
503 list_port_pair.assert_called_with(**filter_dict)
504 # assert that the VIM connector successfully
505 # translated and returned the OpenStack result
506 self.assertEqual(
507 result,
508 [
509 {
510 "ingress_ports": ["5311c75d-d718-4369-bbda-cdcc6da60fcc"],
511 "description": "",
512 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
513 "egress_ports": ["5311c75d-d718-4369-bbda-cdcc6da60fcc"],
514 "sfc_encap": sfc_encap,
515 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
516 "id": "c121ebdd-7f2d-4213-b933-3325298a6966",
517 "name": "osm_sfi",
518 }
519 ],
520 )
521
522 @mock.patch.object(Client, "list_sfc_port_pairs")
523 def test_get_sfi_list_with_sfc_encap(self, list_sfc_port_pairs):
524 self._test_get_sfi_list(list_sfc_port_pairs, "nsh", True)
525
526 @mock.patch.object(Client, "list_sfc_port_pairs")
527 def test_get_sfi_list_without_sfc_encap(self, list_sfc_port_pairs):
528 self._test_get_sfi_list(list_sfc_port_pairs, None, False)
529
530 @mock.patch.object(Client, "list_sfc_port_pair_groups")
531 def test_get_sf_list(self, list_sfc_port_pair_groups):
532 # what OpenStack is assumed to return to the VIM connector
533 list_sfc_port_pair_groups.return_value = {
534 "port_pair_groups": [
535 {
536 "port_pairs": [
537 "08fbdbb0-82d6-11e7-ad95-9bb52fbec2f2",
538 "0d63799c-82d6-11e7-8deb-a746bb3ae9f5",
539 ],
540 "description": "",
541 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
542 "port_pair_group_parameters": {},
543 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
544 "id": "f4a0bde8-82d5-11e7-90e1-a72b762fa27f",
545 "name": "osm_sf",
546 }
547 ]
548 }
549
550 # call the VIM connector
551 filter_dict = {"name": "osm_sf", "description": ""}
552 result = self.vimconn.get_sf_list(filter_dict.copy())
553
554 # assert that VIM connector called OpenStack with the expected filter
555 list_sfc_port_pair_groups.assert_called_with(**filter_dict)
556 # assert that the VIM connector successfully
557 # translated and returned the OpenStack result
558 self.assertEqual(
559 result,
560 [
561 {
562 "sfis": [
563 "08fbdbb0-82d6-11e7-ad95-9bb52fbec2f2",
564 "0d63799c-82d6-11e7-8deb-a746bb3ae9f5",
565 ],
566 "description": "",
567 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
568 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
569 "id": "f4a0bde8-82d5-11e7-90e1-a72b762fa27f",
570 "name": "osm_sf",
571 }
572 ],
573 )
574
575 def _test_get_sfp_list(self, list_sfc_port_chains, correlation, sfc_encap):
576 # what OpenStack is assumed to return to the VIM connector
577 list_sfc_port_chains.return_value = {
578 "port_chains": [
579 {
580 "port_pair_groups": [
581 "7d8e3bf8-82d6-11e7-a032-8ff028839d25",
582 "7dc9013e-82d6-11e7-a5a6-a3a8d78a5518",
583 ],
584 "flow_classifiers": [
585 "1333c2f4-82d7-11e7-a5df-9327f33d104e",
586 "1387ab44-82d7-11e7-9bb0-476337183905",
587 ],
588 "description": "",
589 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
590 "chain_parameters": {"correlation": correlation},
591 "chain_id": 40,
592 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
593 "id": "821bc9be-82d7-11e7-8ce3-23a08a27ab47",
594 "name": "osm_sfp",
595 }
596 ]
597 }
598
599 # call the VIM connector
600 filter_dict = {"name": "osm_sfp", "description": ""}
601 result = self.vimconn.get_sfp_list(filter_dict.copy())
602
603 # assert that VIM connector called OpenStack with the expected filter
604 list_sfc_port_chains.assert_called_with(**filter_dict)
605 # assert that the VIM connector successfully
606 # translated and returned the OpenStack result
607 self.assertEqual(
608 result,
609 [
610 {
611 "service_functions": [
612 "7d8e3bf8-82d6-11e7-a032-8ff028839d25",
613 "7dc9013e-82d6-11e7-a5a6-a3a8d78a5518",
614 ],
615 "classifications": [
616 "1333c2f4-82d7-11e7-a5df-9327f33d104e",
617 "1387ab44-82d7-11e7-9bb0-476337183905",
618 ],
619 "description": "",
620 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
621 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
622 "sfc_encap": sfc_encap,
623 "spi": 40,
624 "id": "821bc9be-82d7-11e7-8ce3-23a08a27ab47",
625 "name": "osm_sfp",
626 }
627 ],
628 )
629
630 @mock.patch.object(Client, "list_sfc_port_chains")
631 def test_get_sfp_list_with_sfc_encap(self, list_sfc_port_chains):
632 self._test_get_sfp_list(list_sfc_port_chains, "nsh", True)
633
634 @mock.patch.object(Client, "list_sfc_port_chains")
635 def test_get_sfp_list_without_sfc_encap(self, list_sfc_port_chains):
636 self._test_get_sfp_list(list_sfc_port_chains, None, False)
637
638 @mock.patch.object(Client, "list_sfc_flow_classifiers")
639 def test_get_classification(self, list_sfc_flow_classifiers):
640 # what OpenStack is assumed to return to the VIM connector
641 list_sfc_flow_classifiers.return_value = {
642 "flow_classifiers": [
643 {
644 "source_port_range_min": 2000,
645 "destination_ip_prefix": "192.168.3.0/24",
646 "protocol": "udp",
647 "description": "",
648 "ethertype": "IPv4",
649 "l7_parameters": {},
650 "source_port_range_max": 2000,
651 "destination_port_range_min": 3000,
652 "source_ip_prefix": "192.168.2.0/24",
653 "logical_destination_port": None,
654 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
655 "destination_port_range_max": None,
656 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
657 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
658 "id": "22198366-d4e8-4d6b-b4d2-637d5d6cbb7d",
659 "name": "fc1",
660 }
661 ]
662 }
663
664 # call the VIM connector
665 result = self.vimconn.get_classification("22198366-d4e8-4d6b-b4d2-637d5d6cbb7d")
666
667 # assert that VIM connector called OpenStack with the expected filter
668 list_sfc_flow_classifiers.assert_called_with(
669 id="22198366-d4e8-4d6b-b4d2-637d5d6cbb7d"
670 )
671 # assert that VIM connector successfully returned the OpenStack result
672 self.assertEqual(
673 result,
674 {
675 "id": "22198366-d4e8-4d6b-b4d2-637d5d6cbb7d",
676 "name": "fc1",
677 "description": "",
678 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
679 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
680 "ctype": "legacy_flow_classifier",
681 "definition": {
682 "source_port_range_min": 2000,
683 "destination_ip_prefix": "192.168.3.0/24",
684 "protocol": "udp",
685 "ethertype": "IPv4",
686 "l7_parameters": {},
687 "source_port_range_max": 2000,
688 "destination_port_range_min": 3000,
689 "source_ip_prefix": "192.168.2.0/24",
690 "logical_destination_port": None,
691 "destination_port_range_max": None,
692 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
693 },
694 },
695 )
696
697 @mock.patch.object(Client, "list_sfc_flow_classifiers")
698 def test_get_classification_many_results(self, list_sfc_flow_classifiers):
699 # what OpenStack is assumed to return to the VIM connector
700 list_sfc_flow_classifiers.return_value = {
701 "flow_classifiers": [
702 {
703 "source_port_range_min": 2000,
704 "destination_ip_prefix": "192.168.3.0/24",
705 "protocol": "udp",
706 "description": "",
707 "ethertype": "IPv4",
708 "l7_parameters": {},
709 "source_port_range_max": 2000,
710 "destination_port_range_min": 3000,
711 "source_ip_prefix": "192.168.2.0/24",
712 "logical_destination_port": None,
713 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
714 "destination_port_range_max": None,
715 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
716 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
717 "id": "22198366-d4e8-4d6b-b4d2-637d5d6cbb7d",
718 "name": "fc1",
719 },
720 {
721 "source_port_range_min": 1000,
722 "destination_ip_prefix": "192.168.3.0/24",
723 "protocol": "udp",
724 "description": "",
725 "ethertype": "IPv4",
726 "l7_parameters": {},
727 "source_port_range_max": 1000,
728 "destination_port_range_min": 3000,
729 "source_ip_prefix": "192.168.2.0/24",
730 "logical_destination_port": None,
731 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
732 "destination_port_range_max": None,
733 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
734 "logical_source_port": "aaab0ab0-1452-4636-bb3b-11dca833fa2b",
735 "id": "3196bafc-82dd-11e7-a205-9bf6c14b0721",
736 "name": "fc2",
737 },
738 ]
739 }
740
741 # call the VIM connector
742 self.assertRaises(
743 vimconn.VimConnConflictException,
744 self.vimconn.get_classification,
745 "3196bafc-82dd-11e7-a205-9bf6c14b0721",
746 )
747
748 # assert the VIM connector called OpenStack with the expected filter
749 list_sfc_flow_classifiers.assert_called_with(
750 id="3196bafc-82dd-11e7-a205-9bf6c14b0721"
751 )
752
753 @mock.patch.object(Client, "list_sfc_flow_classifiers")
754 def test_get_classification_no_results(self, list_sfc_flow_classifiers):
755 # what OpenStack is assumed to return to the VIM connector
756 list_sfc_flow_classifiers.return_value = {"flow_classifiers": []}
757
758 # call the VIM connector
759 self.assertRaises(
760 vimconn.VimConnNotFoundException,
761 self.vimconn.get_classification,
762 "3196bafc-82dd-11e7-a205-9bf6c14b0721",
763 )
764
765 # assert the VIM connector called OpenStack with the expected filter
766 list_sfc_flow_classifiers.assert_called_with(
767 id="3196bafc-82dd-11e7-a205-9bf6c14b0721"
768 )
769
770 @mock.patch.object(Client, "list_sfc_port_pairs")
771 def test_get_sfi(self, list_sfc_port_pairs):
772 # what OpenStack is assumed to return to the VIM connector
773 list_sfc_port_pairs.return_value = {
774 "port_pairs": [
775 {
776 "ingress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
777 "description": "",
778 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
779 "egress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
780 "service_function_parameters": {"correlation": "nsh"},
781 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
782 "id": "c121ebdd-7f2d-4213-b933-3325298a6966",
783 "name": "osm_sfi1",
784 },
785 ]
786 }
787
788 # call the VIM connector
789 result = self.vimconn.get_sfi("c121ebdd-7f2d-4213-b933-3325298a6966")
790
791 # assert the VIM connector called OpenStack with the expected filter
792 list_sfc_port_pairs.assert_called_with(
793 id="c121ebdd-7f2d-4213-b933-3325298a6966"
794 )
795 # assert the VIM connector successfully returned the OpenStack result
796 self.assertEqual(
797 result,
798 {
799 "ingress_ports": ["5311c75d-d718-4369-bbda-cdcc6da60fcc"],
800 "egress_ports": ["5311c75d-d718-4369-bbda-cdcc6da60fcc"],
801 "sfc_encap": True,
802 "description": "",
803 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
804 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
805 "id": "c121ebdd-7f2d-4213-b933-3325298a6966",
806 "name": "osm_sfi1",
807 },
808 )
809
810 @mock.patch.object(Client, "list_sfc_port_pairs")
811 def test_get_sfi_many_results(self, list_sfc_port_pairs):
812 # what OpenStack is assumed to return to the VIM connector
813 list_sfc_port_pairs.return_value = {
814 "port_pairs": [
815 {
816 "ingress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
817 "description": "",
818 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
819 "egress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
820 "service_function_parameters": {"correlation": "nsh"},
821 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
822 "id": "c121ebdd-7f2d-4213-b933-3325298a6966",
823 "name": "osm_sfi1",
824 },
825 {
826 "ingress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
827 "description": "",
828 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
829 "egress": "5311c75d-d718-4369-bbda-cdcc6da60fcc",
830 "service_function_parameters": {"correlation": "nsh"},
831 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
832 "id": "c0436d92-82db-11e7-8f9c-5fa535f1261f",
833 "name": "osm_sfi2",
834 },
835 ]
836 }
837
838 # call the VIM connector
839 self.assertRaises(
840 vimconn.VimConnConflictException,
841 self.vimconn.get_sfi,
842 "c0436d92-82db-11e7-8f9c-5fa535f1261f",
843 )
844
845 # assert that VIM connector called OpenStack with the expected filter
846 list_sfc_port_pairs.assert_called_with(
847 id="c0436d92-82db-11e7-8f9c-5fa535f1261f"
848 )
849
850 @mock.patch.object(Client, "list_sfc_port_pairs")
851 def test_get_sfi_no_results(self, list_sfc_port_pairs):
852 # what OpenStack is assumed to return to the VIM connector
853 list_sfc_port_pairs.return_value = {"port_pairs": []}
854
855 # call the VIM connector
856 self.assertRaises(
857 vimconn.VimConnNotFoundException,
858 self.vimconn.get_sfi,
859 "b22892fc-82d9-11e7-ae85-0fea6a3b3757",
860 )
861
862 # assert that VIM connector called OpenStack with the expected filter
863 list_sfc_port_pairs.assert_called_with(
864 id="b22892fc-82d9-11e7-ae85-0fea6a3b3757"
865 )
866
867 @mock.patch.object(Client, "list_sfc_port_pair_groups")
868 def test_get_sf(self, list_sfc_port_pair_groups):
869 # what OpenStack is assumed to return to the VIM connector
870 list_sfc_port_pair_groups.return_value = {
871 "port_pair_groups": [
872 {
873 "port_pairs": ["08fbdbb0-82d6-11e7-ad95-9bb52fbec2f2"],
874 "description": "",
875 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
876 "port_pair_group_parameters": {},
877 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
878 "id": "aabba8a6-82d9-11e7-a18a-d3c7719b742d",
879 "name": "osm_sf1",
880 }
881 ]
882 }
883
884 # call the VIM connector
885 result = self.vimconn.get_sf("b22892fc-82d9-11e7-ae85-0fea6a3b3757")
886
887 # assert that VIM connector called OpenStack with the expected filter
888 list_sfc_port_pair_groups.assert_called_with(
889 id="b22892fc-82d9-11e7-ae85-0fea6a3b3757"
890 )
891 # assert that VIM connector successfully returned the OpenStack result
892 self.assertEqual(
893 result,
894 {
895 "description": "",
896 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
897 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
898 "sfis": ["08fbdbb0-82d6-11e7-ad95-9bb52fbec2f2"],
899 "id": "aabba8a6-82d9-11e7-a18a-d3c7719b742d",
900 "name": "osm_sf1",
901 },
902 )
903
904 @mock.patch.object(Client, "list_sfc_port_pair_groups")
905 def test_get_sf_many_results(self, list_sfc_port_pair_groups):
906 # what OpenStack is assumed to return to the VIM connector
907 list_sfc_port_pair_groups.return_value = {
908 "port_pair_groups": [
909 {
910 "port_pairs": ["08fbdbb0-82d6-11e7-ad95-9bb52fbec2f2"],
911 "description": "",
912 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
913 "port_pair_group_parameters": {},
914 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
915 "id": "aabba8a6-82d9-11e7-a18a-d3c7719b742d",
916 "name": "osm_sf1",
917 },
918 {
919 "port_pairs": ["0d63799c-82d6-11e7-8deb-a746bb3ae9f5"],
920 "description": "",
921 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
922 "port_pair_group_parameters": {},
923 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
924 "id": "b22892fc-82d9-11e7-ae85-0fea6a3b3757",
925 "name": "osm_sf2",
926 },
927 ]
928 }
929
930 # call the VIM connector
931 self.assertRaises(
932 vimconn.VimConnConflictException,
933 self.vimconn.get_sf,
934 "b22892fc-82d9-11e7-ae85-0fea6a3b3757",
935 )
936
937 # assert that VIM connector called OpenStack with the expected filter
938 list_sfc_port_pair_groups.assert_called_with(
939 id="b22892fc-82d9-11e7-ae85-0fea6a3b3757"
940 )
941
942 @mock.patch.object(Client, "list_sfc_port_pair_groups")
943 def test_get_sf_no_results(self, list_sfc_port_pair_groups):
944 # what OpenStack is assumed to return to the VIM connector
945 list_sfc_port_pair_groups.return_value = {"port_pair_groups": []}
946
947 # call the VIM connector
948 self.assertRaises(
949 vimconn.VimConnNotFoundException,
950 self.vimconn.get_sf,
951 "b22892fc-82d9-11e7-ae85-0fea6a3b3757",
952 )
953
954 # assert that VIM connector called OpenStack with the expected filter
955 list_sfc_port_pair_groups.assert_called_with(
956 id="b22892fc-82d9-11e7-ae85-0fea6a3b3757"
957 )
958
959 @mock.patch.object(Client, "list_sfc_port_chains")
960 def test_get_sfp(self, list_sfc_port_chains):
961 # what OpenStack is assumed to return to the VIM connector
962 list_sfc_port_chains.return_value = {
963 "port_chains": [
964 {
965 "port_pair_groups": ["7d8e3bf8-82d6-11e7-a032-8ff028839d25"],
966 "flow_classifiers": ["1333c2f4-82d7-11e7-a5df-9327f33d104e"],
967 "description": "",
968 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
969 "chain_parameters": {"correlation": "nsh"},
970 "chain_id": 40,
971 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
972 "id": "821bc9be-82d7-11e7-8ce3-23a08a27ab47",
973 "name": "osm_sfp1",
974 }
975 ]
976 }
977
978 # call the VIM connector
979 result = self.vimconn.get_sfp("821bc9be-82d7-11e7-8ce3-23a08a27ab47")
980
981 # assert that VIM connector called OpenStack with the expected filter
982 list_sfc_port_chains.assert_called_with(
983 id="821bc9be-82d7-11e7-8ce3-23a08a27ab47"
984 )
985 # assert that VIM connector successfully returned the OpenStack result
986 self.assertEqual(
987 result,
988 {
989 "service_functions": ["7d8e3bf8-82d6-11e7-a032-8ff028839d25"],
990 "classifications": ["1333c2f4-82d7-11e7-a5df-9327f33d104e"],
991 "description": "",
992 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
993 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
994 "sfc_encap": True,
995 "spi": 40,
996 "id": "821bc9be-82d7-11e7-8ce3-23a08a27ab47",
997 "name": "osm_sfp1",
998 },
999 )
1000
1001 @mock.patch.object(Client, "list_sfc_port_chains")
1002 def test_get_sfp_many_results(self, list_sfc_port_chains):
1003 # what OpenStack is assumed to return to the VIM connector
1004 list_sfc_port_chains.return_value = {
1005 "port_chains": [
1006 {
1007 "port_pair_groups": ["7d8e3bf8-82d6-11e7-a032-8ff028839d25"],
1008 "flow_classifiers": ["1333c2f4-82d7-11e7-a5df-9327f33d104e"],
1009 "description": "",
1010 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
1011 "chain_parameters": {"correlation": "nsh"},
1012 "chain_id": 40,
1013 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
1014 "id": "821bc9be-82d7-11e7-8ce3-23a08a27ab47",
1015 "name": "osm_sfp1",
1016 },
1017 {
1018 "port_pair_groups": ["7d8e3bf8-82d6-11e7-a032-8ff028839d25"],
1019 "flow_classifiers": ["1333c2f4-82d7-11e7-a5df-9327f33d104e"],
1020 "description": "",
1021 "tenant_id": "8f3019ef06374fa880a0144ad4bc1d7b",
1022 "chain_parameters": {"correlation": "nsh"},
1023 "chain_id": 50,
1024 "project_id": "8f3019ef06374fa880a0144ad4bc1d7b",
1025 "id": "5d002f38-82de-11e7-a770-f303f11ce66a",
1026 "name": "osm_sfp2",
1027 },
1028 ]
1029 }
1030
1031 # call the VIM connector
1032 self.assertRaises(
1033 vimconn.VimConnConflictException,
1034 self.vimconn.get_sfp,
1035 "5d002f38-82de-11e7-a770-f303f11ce66a",
1036 )
1037
1038 # assert that VIM connector called OpenStack with the expected filter
1039 list_sfc_port_chains.assert_called_with(
1040 id="5d002f38-82de-11e7-a770-f303f11ce66a"
1041 )
1042
1043 @mock.patch.object(Client, "list_sfc_port_chains")
1044 def test_get_sfp_no_results(self, list_sfc_port_chains):
1045 # what OpenStack is assumed to return to the VIM connector
1046 list_sfc_port_chains.return_value = {"port_chains": []}
1047
1048 # call the VIM connector
1049 self.assertRaises(
1050 vimconn.VimConnNotFoundException,
1051 self.vimconn.get_sfp,
1052 "5d002f38-82de-11e7-a770-f303f11ce66a",
1053 )
1054
1055 # assert that VIM connector called OpenStack with the expected filter
1056 list_sfc_port_chains.assert_called_with(
1057 id="5d002f38-82de-11e7-a770-f303f11ce66a"
1058 )
1059
1060 @mock.patch.object(Client, "delete_sfc_flow_classifier")
1061 def test_delete_classification(self, delete_sfc_flow_classifier):
1062 result = self.vimconn.delete_classification(
1063 "638f957c-82df-11e7-b7c8-132706021464"
1064 )
1065 delete_sfc_flow_classifier.assert_called_with(
1066 "638f957c-82df-11e7-b7c8-132706021464"
1067 )
1068 self.assertEqual(result, "638f957c-82df-11e7-b7c8-132706021464")
1069
1070 @mock.patch.object(Client, "delete_sfc_port_pair")
1071 def test_delete_sfi(self, delete_sfc_port_pair):
1072 result = self.vimconn.delete_sfi("638f957c-82df-11e7-b7c8-132706021464")
1073 delete_sfc_port_pair.assert_called_with("638f957c-82df-11e7-b7c8-132706021464")
1074 self.assertEqual(result, "638f957c-82df-11e7-b7c8-132706021464")
1075
1076 @mock.patch.object(Client, "delete_sfc_port_pair_group")
1077 def test_delete_sf(self, delete_sfc_port_pair_group):
1078 result = self.vimconn.delete_sf("638f957c-82df-11e7-b7c8-132706021464")
1079 delete_sfc_port_pair_group.assert_called_with(
1080 "638f957c-82df-11e7-b7c8-132706021464"
1081 )
1082 self.assertEqual(result, "638f957c-82df-11e7-b7c8-132706021464")
1083
1084 @mock.patch.object(Client, "delete_sfc_port_chain")
1085 def test_delete_sfp(self, delete_sfc_port_chain):
1086 result = self.vimconn.delete_sfp("638f957c-82df-11e7-b7c8-132706021464")
1087 delete_sfc_port_chain.assert_called_with("638f957c-82df-11e7-b7c8-132706021464")
1088 self.assertEqual(result, "638f957c-82df-11e7-b7c8-132706021464")
1089
1090
1091 class Status:
1092 def __init__(self, s):
1093 self.status = s
1094
1095 def __str__(self):
1096 return self.status
1097
1098
1099 class CopyingMock(MagicMock):
1100 def __call__(self, *args, **kwargs):
1101 args = deepcopy(args)
1102 kwargs = deepcopy(kwargs)
1103 return super(CopyingMock, self).__call__(*args, **kwargs)
1104
1105
1106 class TestNewVmInstance(unittest.TestCase):
1107 @patch("logging.getLogger", autospec=True)
1108 def setUp(self, mock_logger):
1109 # Instantiate dummy VIM connector so we can test it
1110 # It throws exception because of dummy parameters,
1111 # We are disabling the logging of exception not to print them to console.
1112 mock_logger = logging.getLogger()
1113 mock_logger.disabled = True
1114 self.vimconn = vimconnector(
1115 "123",
1116 "openstackvim",
1117 "456",
1118 "789",
1119 "http://dummy.url",
1120 None,
1121 "user",
1122 "pass",
1123 )
1124 self.vimconn.neutron = CopyingMock()
1125 self.vimconn.nova = CopyingMock()
1126 self.vimconn.cinder = CopyingMock()
1127 self.server = MagicMock(object, autospec=True)
1128 self.server.tenant_id = "408b73-r9cc-5a6a-a270-82cc4811bd4a"
1129 self.server.id = "908b73-e9cc-5a6a-t270-82cc4811bd4a"
1130 self.vimconn.config["security_groups"] = "default"
1131 self.vimconn.config["keypair"] = "my_keypair"
1132 self.vimconn.security_groups_id = "12345"
1133 self.vimconn.nova.api_version.get_string.return_value = "2.32"
1134
1135 @patch.object(vimconnector, "_get_ids_from_name")
1136 def test_prepare_port_dict_security_security_groups_exists_in_config(
1137 self, mock_get_ids
1138 ):
1139 """In VIM config security_groups exists, net port_security is True
1140 no_port_security_extension does not exist.
1141 """
1142 self.vimconn.config = {"security_groups": "example_security_group"}
1143 net = {"port_security": True}
1144 port_dict = {}
1145 result_dict = {"security_groups": "12345"}
1146
1147 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1148 self.assertDictEqual(result_dict, port_dict)
1149 mock_get_ids.assert_not_called()
1150
1151 @patch.object(vimconnector, "_get_ids_from_name")
1152 def test_prepare_port_dict_security_security_groups_exists_in_config_no_security_groups_id(
1153 self, mock_get_ids
1154 ):
1155 """In VIM config Security_groups exists, net port_security is True, vim security_groups_id does not exist,
1156 no_port_security_extension does not exist.
1157 """
1158 self.vimconn.config = {"security_groups": "example_security_group"}
1159 self.vimconn.security_groups_id = None
1160 net = {"port_security": True}
1161 port_dict = {}
1162 result_dict = {"security_groups": None}
1163
1164 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1165 self.assertDictEqual(result_dict, port_dict)
1166 mock_get_ids.assert_called()
1167
1168 @patch.object(vimconnector, "_get_ids_from_name")
1169 def test_prepare_port_dict_security_security_groups_exists_security_extension_true_in_config(
1170 self, mock_get_ids
1171 ):
1172 """In VIM config security_groups exists, net port_security is True, in VIM security_groups_id exists,
1173 no_port_security_extension set to True.
1174 """
1175 self.vimconn.config = {
1176 "security_groups": "example_security_group",
1177 "no_port_security_extension": True,
1178 }
1179 net = {"port_security": True}
1180 port_dict = {}
1181 result_dict = {}
1182
1183 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1184 self.assertDictEqual(result_dict, port_dict)
1185 mock_get_ids.assert_not_called()
1186
1187 @patch.object(vimconnector, "_get_ids_from_name")
1188 def test_prepare_port_dict_security_no_security_groups_in_config(
1189 self, mock_get_ids
1190 ):
1191 """In VIM config security_group does not exist, net port_security True, in VIM security_groups_id exists,
1192 no_port_security_extension does not exist."""
1193 self.vimconn.config = {}
1194 net = {"port_security": True}
1195 port_dict = {}
1196 result_dict = {}
1197
1198 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1199 self.assertDictEqual(result_dict, port_dict)
1200 mock_get_ids.assert_not_called()
1201
1202 @patch.object(vimconnector, "_get_ids_from_name")
1203 def test_prepare_port_dict_security_no_security_groups_security_extension_true_in_config(
1204 self, mock_get_ids
1205 ):
1206 """Security_group does not exist, net port_security is True, in VIM security_groups_id exists,
1207 no_port_security_extension set to True."""
1208 self.vimconn.config = {"no_port_security_extension": True}
1209 net = {"port_security": True}
1210 port_dict = {}
1211 result_dict = {}
1212
1213 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1214 self.assertDictEqual(result_dict, port_dict)
1215 mock_get_ids.assert_not_called()
1216
1217 @patch.object(vimconnector, "_get_ids_from_name")
1218 def test_prepare_port_dict_security_security_groups_exists_net_port_security_false(
1219 self, mock_get_ids
1220 ):
1221 """In VIM config security_group exists, net port_security False, security_groups_id exists,
1222 no_port_security_extension does not exist."""
1223 self.vimconn.config = {"security_groups": "example_security_group"}
1224 net = {"port_security": False}
1225 port_dict = {}
1226 result_dict = {}
1227
1228 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1229 self.assertDictEqual(result_dict, port_dict)
1230 mock_get_ids.assert_not_called()
1231
1232 @patch.object(vimconnector, "_get_ids_from_name")
1233 def test_prepare_port_dict_security_net_port_security_false_port_security_extension_true(
1234 self, mock_get_ids
1235 ):
1236 """In VIM config security_group exists, net port_security False, security_groups_id exists,
1237 no_port_security_extension set to True."""
1238 self.vimconn.config = {
1239 "security_groups": "example_security_group",
1240 "no_port_security_extension": True,
1241 }
1242 net = {"port_security": False}
1243 port_dict = {}
1244 result_dict = {}
1245
1246 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
1247 self.assertDictEqual(result_dict, port_dict)
1248 mock_get_ids.assert_not_called()
1249
1250 def test_prepare_port_dict_binding_net_type_virtual(self):
1251 """net type is virtual."""
1252 net = {"type": "virtual"}
1253 port_dict = {}
1254 result_dict = {}
1255 self.vimconn._prepare_port_dict_binding(net, port_dict)
1256 self.assertDictEqual(result_dict, port_dict)
1257
1258 def test_prepare_port_dict_binding_net_type_vf(self):
1259 """net type is VF, vim_type is not VIO."""
1260 net = {"type": "VF"}
1261 self.vimconn.vim_type = None
1262 port_dict = {}
1263 result_dict = {"binding:vnic_type": "direct"}
1264 self.vimconn._prepare_port_dict_binding(net, port_dict)
1265 self.assertDictEqual(port_dict, result_dict)
1266
1267 def test_prepare_port_dict_binding_net_type_sriov_vim_type_vio(self):
1268 """net type is SR-IOV, vim_type is VIO."""
1269 net = {"type": "SR-IOV"}
1270 self.vimconn.vim_type = "VIO"
1271 port_dict = {}
1272 result_dict = {
1273 "binding:vnic_type": "direct",
1274 "port_security_enabled": False,
1275 "provider_security_groups": [],
1276 "security_groups": [],
1277 }
1278 self.vimconn._prepare_port_dict_binding(net, port_dict)
1279 self.assertDictEqual(port_dict, result_dict)
1280
1281 def test_prepare_port_dict_binding_net_type_passthrough(self):
1282 """net type is pci-passthrough."""
1283 net = {"type": "PCI-PASSTHROUGH"}
1284 port_dict = {}
1285 result_dict = {
1286 "binding:vnic_type": "direct-physical",
1287 }
1288 self.vimconn._prepare_port_dict_binding(net, port_dict)
1289 self.assertDictEqual(port_dict, result_dict)
1290
1291 def test_prepare_port_dict_binding_no_net_type(self):
1292 """net type is missing."""
1293 net = {}
1294 port_dict = {}
1295 with self.assertRaises(VimConnException) as err:
1296 self.vimconn._prepare_port_dict_binding(net, port_dict)
1297 self.assertEqual(str(err.exception), "Type is missing in the network details.")
1298
1299 def test_set_fixed_ip(self):
1300 """new_port has fixed ip."""
1301 net = {}
1302 new_port = {
1303 "port": {
1304 "fixed_ips": [{"ip_address": "10.1.2.3"}, {"ip_address": "20.1.2.3"}]
1305 }
1306 }
1307 result = {"ip": "10.1.2.3"}
1308 self.vimconn._set_fixed_ip(new_port, net)
1309 self.assertDictEqual(net, result)
1310
1311 def test_set_fixed_ip_no_fixed_ip(self):
1312 """new_port does not have fixed ip."""
1313 net = {}
1314 new_port = {"port": {}}
1315 result = {"ip": None}
1316 self.vimconn._set_fixed_ip(new_port, net)
1317 self.assertDictEqual(net, result)
1318
1319 def test_set_fixed_ip_raise_exception(self):
1320 """new_port does not have port details."""
1321 net = {}
1322 new_port = {}
1323 with self.assertRaises(Exception) as err:
1324 self.vimconn._set_fixed_ip(new_port, net)
1325 self.assertEqual(type(err.exception), KeyError)
1326
1327 def test_prepare_port_dict_mac_ip_addr(self):
1328 """mac address and ip address exist."""
1329 net = {
1330 "mac_address": mac_address,
1331 "ip_address": "10.0.1.5",
1332 }
1333 port_dict = {}
1334 result_dict = {
1335 "mac_address": mac_address,
1336 "fixed_ips": [{"ip_address": "10.0.1.5"}],
1337 }
1338 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
1339 self.assertDictEqual(port_dict, result_dict)
1340
1341 def test_prepare_port_dict_mac_ip_addr_no_mac_and_ip(self):
1342 """mac address and ip address does not exist."""
1343 net = {}
1344 port_dict = {}
1345 result_dict = {}
1346 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
1347 self.assertDictEqual(port_dict, result_dict)
1348
1349 def test_create_new_port(self):
1350 """new port has id and mac address."""
1351 new_port = {
1352 "port": {
1353 "id": port_id,
1354 "mac_address": mac_address,
1355 },
1356 }
1357 self.vimconn.neutron.create_port.return_value = new_port
1358 net, port_dict, created_items = {}, {}, {}
1359 expected_result = new_port
1360 expected_net = {
1361 "mac_adress": mac_address,
1362 "vim_id": port_id,
1363 }
1364 expected_created_items = {f"port:{port_id}": True}
1365 result = self.vimconn._create_new_port(port_dict, created_items, net)
1366 self.assertDictEqual(result, expected_result)
1367 self.assertEqual(net, expected_net)
1368 self.assertEqual(created_items, expected_created_items)
1369 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
1370
1371 def test_create_new_port_without_mac_or_id(self):
1372 """new port does not have mac address or ID."""
1373 new_port = {}
1374 self.vimconn.neutron.create_port.return_value = new_port
1375 net, port_dict, created_items = {}, {}, {}
1376 with self.assertRaises(KeyError):
1377 self.vimconn._create_new_port(port_dict, created_items, net)
1378 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
1379
1380 def test_create_new_port_neutron_create_port_raises_exception(self):
1381 """Neutron create port raises exception."""
1382 self.vimconn.neutron.create_port.side_effect = VimConnException(
1383 "New port is not created."
1384 )
1385 net, port_dict, created_items = {}, {}, {}
1386 with self.assertRaises(VimConnException):
1387 self.vimconn._create_new_port(port_dict, created_items, net)
1388 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
1389
1390 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1391 @patch.object(vimconnector, "_prepare_port_dict_binding")
1392 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1393 @patch.object(vimconnector, "_create_new_port")
1394 @patch.object(vimconnector, "_set_fixed_ip")
1395 def test_create_port(
1396 self,
1397 mock_set_fixed_ip,
1398 mock_create_new_port,
1399 mock_prepare_port_dict_mac_ip_addr,
1400 mock_prepare_port_dict_binding,
1401 mock_prepare_port_dict_security_groups,
1402 ):
1403 """Net has name, type, net-id."""
1404
1405 net = {
1406 "net_id": net_id,
1407 "name": "management",
1408 "type": "virtual",
1409 }
1410 created_items = {}
1411 new_port = {
1412 "port": {
1413 "id": net_id,
1414 "mac_address": mac_address,
1415 "name": "management",
1416 "fixed_ips": [{"ip_address": ip_addr1}],
1417 },
1418 }
1419 mock_create_new_port.return_value = new_port
1420 expected_port = {
1421 "port-id": net_id,
1422 "tag": "management",
1423 }
1424 port_dict = {
1425 "network_id": net_id,
1426 "name": "management",
1427 "admin_state_up": True,
1428 }
1429
1430 new_port_result, port_result = self.vimconn._create_port(
1431 net, name, created_items
1432 )
1433
1434 self.assertDictEqual(new_port_result, new_port)
1435 self.assertDictEqual(port_result, expected_port)
1436
1437 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1438 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1439 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1440 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
1441 mock_set_fixed_ip.assert_called_once_with(new_port, net)
1442
1443 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1444 @patch.object(vimconnector, "_prepare_port_dict_binding")
1445 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1446 @patch.object(vimconnector, "_create_new_port")
1447 @patch.object(vimconnector, "_set_fixed_ip")
1448 def test_create_port_no_port_name(
1449 self,
1450 mock_set_fixed_ip,
1451 mock_create_new_port,
1452 mock_prepare_port_dict_mac_ip_addr,
1453 mock_prepare_port_dict_binding,
1454 mock_prepare_port_dict_security_groups,
1455 ):
1456 """Net has no name."""
1457 net = {
1458 "net_id": net_id,
1459 "type": "virtual",
1460 }
1461 created_items = {}
1462 new_port = {
1463 "port": {
1464 "id": net_id,
1465 "mac_address": mac_address,
1466 "name": name,
1467 "fixed_ips": [{"ip_address": ip_addr1}],
1468 },
1469 }
1470 mock_create_new_port.return_value = new_port
1471 expected_port = {
1472 "port-id": net_id,
1473 "tag": name,
1474 }
1475 port_dict = {
1476 "network_id": net_id,
1477 "admin_state_up": True,
1478 "name": name,
1479 }
1480
1481 new_port_result, port_result = self.vimconn._create_port(
1482 net, name, created_items
1483 )
1484
1485 self.assertDictEqual(new_port_result, new_port)
1486 self.assertDictEqual(port_result, expected_port)
1487
1488 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1489 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1490 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1491 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
1492 mock_set_fixed_ip.assert_called_once_with(new_port, net)
1493
1494 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1495 @patch.object(vimconnector, "_prepare_port_dict_binding")
1496 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1497 @patch.object(vimconnector, "_create_new_port")
1498 @patch.object(vimconnector, "_set_fixed_ip")
1499 def test_create_port_nova_api_version_smaller_than_232(
1500 self,
1501 mock_set_fixed_ip,
1502 mock_create_new_port,
1503 mock_prepare_port_dict_mac_ip_addr,
1504 mock_prepare_port_dict_binding,
1505 mock_prepare_port_dict_security_groups,
1506 ):
1507 """Nova api version is smaller than 2.32."""
1508 self.vimconn.nova.api_version.get_string.return_value = "2.30"
1509 net = {
1510 "net_id": net_id,
1511 "type": "virtual",
1512 }
1513 created_items = {}
1514 new_port = {
1515 "port": {
1516 "id": net_id,
1517 "mac_address": mac_address,
1518 "name": name,
1519 "fixed_ips": [{"ip_address": ip_addr1}],
1520 },
1521 }
1522 mock_create_new_port.return_value = new_port
1523 expected_port = {
1524 "port-id": net_id,
1525 }
1526 port_dict = {
1527 "network_id": net_id,
1528 "admin_state_up": True,
1529 "name": name,
1530 }
1531
1532 new_port_result, port_result = self.vimconn._create_port(
1533 net, name, created_items
1534 )
1535
1536 self.assertDictEqual(new_port_result, new_port)
1537 self.assertDictEqual(port_result, expected_port)
1538
1539 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1540 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1541 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1542 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
1543 mock_set_fixed_ip.assert_called_once_with(new_port, net)
1544
1545 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1546 @patch.object(vimconnector, "_prepare_port_dict_binding")
1547 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1548 @patch.object(vimconnector, "_create_new_port")
1549 @patch.object(vimconnector, "_set_fixed_ip")
1550 def test_create_port_create_new_port_raise_exception(
1551 self,
1552 mock_set_fixed_ip,
1553 mock_create_new_port,
1554 mock_prepare_port_dict_mac_ip_addr,
1555 mock_prepare_port_dict_binding,
1556 mock_prepare_port_dict_security_groups,
1557 ):
1558 """_create_new_port method raises exception."""
1559 net = {
1560 "net_id": net_id,
1561 "type": "virtual",
1562 }
1563 created_items = {}
1564 mock_create_new_port.side_effect = Exception
1565 port_dict = {
1566 "network_id": net_id,
1567 "admin_state_up": True,
1568 "name": name,
1569 }
1570
1571 with self.assertRaises(Exception):
1572 self.vimconn._create_port(net, name, created_items)
1573
1574 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1575 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1576 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1577 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
1578 mock_set_fixed_ip.assert_not_called()
1579
1580 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1581 @patch.object(vimconnector, "_prepare_port_dict_binding")
1582 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1583 @patch.object(vimconnector, "_create_new_port")
1584 @patch.object(vimconnector, "_set_fixed_ip")
1585 def test_create_port_create_sec_groups_raises_exception(
1586 self,
1587 mock_set_fixed_ip,
1588 mock_create_new_port,
1589 mock_prepare_port_dict_mac_ip_addr,
1590 mock_prepare_port_dict_binding,
1591 mock_prepare_port_dict_security_groups,
1592 ):
1593 """_prepare_port_dict_security_groups method raises exception."""
1594 net = {
1595 "net_id": net_id,
1596 "type": "virtual",
1597 }
1598 created_items = {}
1599 mock_prepare_port_dict_security_groups.side_effect = Exception
1600 port_dict = {
1601 "network_id": net_id,
1602 "admin_state_up": True,
1603 "name": name,
1604 }
1605
1606 with self.assertRaises(Exception):
1607 self.vimconn._create_port(net, name, created_items)
1608
1609 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1610
1611 mock_prepare_port_dict_binding.assert_not_called()
1612 mock_prepare_port_dict_mac_ip_addr.assert_not_called()
1613 mock_create_new_port.assert_not_called()
1614 mock_set_fixed_ip.assert_not_called()
1615
1616 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1617 @patch.object(vimconnector, "_prepare_port_dict_binding")
1618 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1619 @patch.object(vimconnector, "_create_new_port")
1620 @patch.object(vimconnector, "_set_fixed_ip")
1621 def test_create_port_create_port_dict_binding_raise_exception(
1622 self,
1623 mock_set_fixed_ip,
1624 mock_create_new_port,
1625 mock_prepare_port_dict_mac_ip_addr,
1626 mock_prepare_port_dict_binding,
1627 mock_prepare_port_dict_security_groups,
1628 ):
1629 """_prepare_port_dict_binding method raises exception."""
1630
1631 net = {
1632 "net_id": net_id,
1633 "type": "virtual",
1634 }
1635 created_items = {}
1636 mock_prepare_port_dict_binding.side_effect = Exception
1637 port_dict = {
1638 "network_id": net_id,
1639 "admin_state_up": True,
1640 "name": name,
1641 }
1642
1643 with self.assertRaises(Exception):
1644 self.vimconn._create_port(net, name, created_items)
1645
1646 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1647
1648 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1649
1650 mock_prepare_port_dict_mac_ip_addr.assert_not_called()
1651 mock_create_new_port.assert_not_called()
1652 mock_set_fixed_ip.assert_not_called()
1653
1654 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1655 @patch.object(vimconnector, "_prepare_port_dict_binding")
1656 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1657 @patch.object(vimconnector, "_create_new_port")
1658 @patch.object(vimconnector, "_set_fixed_ip")
1659 def test_create_port_create_port_mac_ip_addr_raise_exception(
1660 self,
1661 mock_set_fixed_ip,
1662 mock_create_new_port,
1663 mock_prepare_port_dict_mac_ip_addr,
1664 mock_prepare_port_dict_binding,
1665 mock_prepare_port_dict_security_groups,
1666 ):
1667 """prepare_port_dict_mac_ip_addr method raises exception."""
1668 net = {
1669 "net_id": net_id,
1670 "type": "virtual",
1671 }
1672 created_items = {}
1673 mock_prepare_port_dict_mac_ip_addr.side_effect = Exception
1674 port_dict = {
1675 "network_id": net_id,
1676 "admin_state_up": True,
1677 "name": name,
1678 }
1679
1680 with self.assertRaises(Exception):
1681 self.vimconn._create_port(net, name, created_items)
1682
1683 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1684 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1685 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1686
1687 mock_create_new_port.assert_not_called()
1688 mock_set_fixed_ip.assert_not_called()
1689
1690 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
1691 @patch.object(vimconnector, "_prepare_port_dict_binding")
1692 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
1693 @patch.object(vimconnector, "_create_new_port")
1694 @patch.object(vimconnector, "_set_fixed_ip")
1695 def test_create_port_create_port_set_fixed_ip_raise_exception(
1696 self,
1697 mock_set_fixed_ip,
1698 mock_create_new_port,
1699 mock_prepare_port_dict_mac_ip_addr,
1700 mock_prepare_port_dict_binding,
1701 mock_prepare_port_dict_security_groups,
1702 ):
1703 """_set_fixed_ip method raises exception."""
1704 net = {
1705 "net_id": net_id,
1706 "type": "virtual",
1707 }
1708 created_items = {}
1709 mock_set_fixed_ip.side_effect = VimConnException(
1710 "Port detail is missing in new_port."
1711 )
1712 port_dict = {
1713 "network_id": net_id,
1714 "admin_state_up": True,
1715 "name": name,
1716 }
1717 new_port = {
1718 "port": {
1719 "id": net_id,
1720 "mac_address": mac_address,
1721 "name": name,
1722 "fixed_ips": [{"ip_address": ip_addr1}],
1723 },
1724 }
1725 mock_create_new_port.return_value = new_port
1726
1727 with self.assertRaises(VimConnException):
1728 self.vimconn._create_port(net, name, created_items)
1729
1730 mock_prepare_port_dict_security_groups.assert_called_once_with(net, port_dict)
1731 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
1732 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
1733 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
1734 mock_set_fixed_ip.assert_called_once_with(new_port, net)
1735
1736 @patch.object(vimconnector, "_reload_connection")
1737 @patch.object(vimconnector, "_create_port")
1738 def test_prepare_network_for_vm_instance_no_net_id(
1739 self, mock_create_port, mock_reload_connection
1740 ):
1741 """Nets do not have net_id"""
1742 mock_reload_connection.side_effect = None
1743 created_items = {}
1744 net_list = [
1745 {
1746 "use": "mgmt",
1747 "port_security": False,
1748 "exit_on_floating_ip_error": False,
1749 "port_security_disable_strategy": "full",
1750 },
1751 {
1752 "port_security": True,
1753 "exit_on_floating_ip_error": False,
1754 "floating_ip": True,
1755 },
1756 ]
1757 net_list_vim = []
1758 external_network, no_secured_ports = [], []
1759 expected_external_network, expected_no_secured_ports = [], []
1760 expected_net_list_vim = []
1761
1762 self.vimconn._prepare_network_for_vminstance(
1763 name,
1764 net_list,
1765 created_items,
1766 net_list_vim,
1767 external_network,
1768 no_secured_ports,
1769 )
1770 self.assertEqual(expected_net_list_vim, net_list_vim)
1771 self.assertEqual(external_network, expected_external_network)
1772 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1773
1774 mock_create_port.assert_not_called()
1775
1776 @patch.object(vimconnector, "_reload_connection")
1777 @patch.object(vimconnector, "_create_port")
1778 def test_prepare_network_for_vm_instance_empty_net_list(
1779 self, mock_create_port, mock_reload_connection
1780 ):
1781 """Net list is empty."""
1782 mock_reload_connection.side_effect = None
1783 created_items = {}
1784 net_list_vim = []
1785 external_network, no_secured_ports = [], []
1786 expected_external_network, expected_no_secured_ports = [], []
1787 expected_net_list_vim = []
1788
1789 self.vimconn._prepare_network_for_vminstance(
1790 name,
1791 net_list,
1792 created_items,
1793 net_list_vim,
1794 external_network,
1795 no_secured_ports,
1796 )
1797 self.assertEqual(expected_net_list_vim, net_list_vim)
1798 self.assertEqual(external_network, expected_external_network)
1799 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1800
1801 mock_create_port.assert_not_called()
1802
1803 @patch.object(vimconnector, "_reload_connection")
1804 @patch.object(vimconnector, "_create_port")
1805 def test_prepare_network_for_vm_instance_use_floating_ip_false_mgmt_net(
1806 self, mock_create_port, mock_reload_connection
1807 ):
1808 """Nets have net-id, floating_ip False, mgmt network."""
1809 mock_reload_connection.side_effect = None
1810 created_items = {}
1811 net_list = [
1812 {
1813 "net_id": net2_id,
1814 "floating_ip": False,
1815 "use": "mgmt",
1816 }
1817 ]
1818 net_list_vim = []
1819 mock_create_port.side_effect = [
1820 (
1821 {
1822 "port": {
1823 "id": port2_id,
1824 "mac_address": mac_address,
1825 "name": name,
1826 },
1827 },
1828 {"port-dict": port2_id},
1829 ),
1830 ]
1831 external_network, no_secured_ports = [], []
1832 expected_external_network, expected_no_secured_ports = [], []
1833 expected_net_list_vim = [{"port-dict": port2_id}]
1834 self.vimconn._prepare_network_for_vminstance(
1835 name,
1836 net_list,
1837 created_items,
1838 net_list_vim,
1839 external_network,
1840 no_secured_ports,
1841 )
1842 self.assertEqual(expected_net_list_vim, net_list_vim)
1843 self.assertEqual(external_network, expected_external_network)
1844 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1845
1846 mock_create_port.assert_called_once_with(
1847 {
1848 "net_id": net2_id,
1849 "floating_ip": False,
1850 "use": "mgmt",
1851 },
1852 name,
1853 created_items,
1854 )
1855
1856 @patch.object(vimconnector, "_reload_connection")
1857 def test_prepare_network_for_vm_instance_mgmt_net_net_port_security_and_floating_ip_true(
1858 self, mock_reload_connection
1859 ):
1860 """Nets have net-id, use_floating_ip False in VIM config, mgmt network, net floating_ip is True."""
1861 self.vimconn.config["use_floating_ip"] = False
1862 mock_create_port = CopyingMock()
1863 mock_reload_connection.side_effect = None
1864 created_items = {}
1865 net_list = [
1866 {
1867 "net_id": net2_id,
1868 "floating_ip": True,
1869 "use": "mgmt",
1870 }
1871 ]
1872 net_list_vim = []
1873 mock_create_port.side_effect = [
1874 (
1875 {
1876 "port": {
1877 "id": port2_id,
1878 "mac_address": mac_address,
1879 "name": name,
1880 },
1881 },
1882 {"port-dict": port2_id},
1883 ),
1884 ]
1885 external_network, no_secured_ports = [], []
1886 expected_external_network = [
1887 {
1888 "net_id": net2_id,
1889 "floating_ip": True,
1890 "use": "mgmt",
1891 "exit_on_floating_ip_error": True,
1892 },
1893 ]
1894 expected_no_secured_ports = []
1895 expected_net_list_vim = [{"port-dict": port2_id}]
1896 with patch.object(vimconnector, "_create_port", mock_create_port):
1897 self.vimconn._prepare_network_for_vminstance(
1898 name,
1899 net_list,
1900 created_items,
1901 net_list_vim,
1902 external_network,
1903 no_secured_ports,
1904 )
1905 self.assertEqual(expected_net_list_vim, net_list_vim)
1906 self.assertEqual(external_network, expected_external_network)
1907 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1908
1909 mock_create_port.assert_called_once_with(
1910 {
1911 "net_id": net2_id,
1912 "floating_ip": True,
1913 "use": "mgmt",
1914 },
1915 name,
1916 created_items,
1917 )
1918
1919 @patch.object(vimconnector, "_reload_connection")
1920 def test_prepare_network_for_vm_instance_use_floating_ip_true_mgmt_net_port_security_false(
1921 self, mock_reload_connection
1922 ):
1923 """Nets have net-id, use_floating_ip is True in VIM config, mgmt network, net port security is False."""
1924 mock_create_port = CopyingMock()
1925 self.vimconn.config["use_floating_ip"] = True
1926 self.vimconn.config["no_port_security_extension"] = False
1927 mock_reload_connection.side_effect = None
1928 created_items = {}
1929
1930 net_list = [
1931 {
1932 "net_id": net2_id,
1933 "use": "mgmt",
1934 "port_security": False,
1935 "exit_on_floating_ip_error": False,
1936 "port_security_disable_strategy": "full",
1937 }
1938 ]
1939 net_list_vim = []
1940 mock_create_port.side_effect = [
1941 (
1942 {
1943 "port": {
1944 "id": port2_id,
1945 "mac_address": mac_address,
1946 "name": name,
1947 },
1948 },
1949 {"port-dict": port2_id},
1950 ),
1951 ]
1952 external_network, no_secured_ports = [], []
1953 expected_external_network = [
1954 {
1955 "net_id": net2_id,
1956 "use": "mgmt",
1957 "port_security": False,
1958 "exit_on_floating_ip_error": False,
1959 "port_security_disable_strategy": "full",
1960 "floating_ip": True,
1961 },
1962 ]
1963 expected_no_secured_ports = [(port2_id, "full")]
1964 expected_net_list_vim = [{"port-dict": port2_id}]
1965 with patch.object(vimconnector, "_create_port", mock_create_port):
1966 self.vimconn._prepare_network_for_vminstance(
1967 name,
1968 net_list,
1969 created_items,
1970 net_list_vim,
1971 external_network,
1972 no_secured_ports,
1973 )
1974
1975 mock_create_port.assert_called_once_with(
1976 {
1977 "net_id": net2_id,
1978 "use": "mgmt",
1979 "port_security": False,
1980 "exit_on_floating_ip_error": False,
1981 "port_security_disable_strategy": "full",
1982 },
1983 name,
1984 created_items,
1985 )
1986 self.assertEqual(expected_net_list_vim, net_list_vim)
1987 self.assertEqual(external_network, expected_external_network)
1988 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1989
1990 @patch.object(vimconnector, "_reload_connection")
1991 def test_prepare_network_for_vm_instance_use_fip_true_non_mgmt_net_port_security_false(
1992 self, mock_reload_connection
1993 ):
1994 """Nets have net-id, use_floating_ip True in VIM config, non-mgmt network, port security is False."""
1995 mock_create_port = CopyingMock()
1996 self.vimconn.config["use_floating_ip"] = True
1997 self.vimconn.config["no_port_security_extension"] = False
1998 mock_reload_connection.side_effect = None
1999 created_items = {}
2000
2001 net_list = [
2002 {
2003 "net_id": net2_id,
2004 "use": "other",
2005 "port_security": False,
2006 "port_security_disable_strategy": "full",
2007 }
2008 ]
2009 net_list_vim = []
2010 mock_create_port.side_effect = [
2011 (
2012 {
2013 "port": {
2014 "id": port2_id,
2015 "mac_address": mac_address,
2016 "name": name,
2017 },
2018 },
2019 {"port-dict": port2_id},
2020 ),
2021 ]
2022 external_network, no_secured_ports = [], []
2023 expected_external_network = []
2024 expected_no_secured_ports = [(port2_id, "full")]
2025 expected_net_list_vim = [{"port-dict": port2_id}]
2026 with patch.object(vimconnector, "_create_port", mock_create_port):
2027 self.vimconn._prepare_network_for_vminstance(
2028 name,
2029 net_list,
2030 created_items,
2031 net_list_vim,
2032 external_network,
2033 no_secured_ports,
2034 )
2035
2036 mock_create_port.assert_called_once_with(
2037 {
2038 "net_id": net2_id,
2039 "use": "other",
2040 "port_security": False,
2041 "port_security_disable_strategy": "full",
2042 },
2043 name,
2044 created_items,
2045 )
2046 self.assertEqual(expected_net_list_vim, net_list_vim)
2047 self.assertEqual(external_network, expected_external_network)
2048 self.assertEqual(expected_no_secured_ports, no_secured_ports)
2049
2050 @patch.object(vimconnector, "_reload_connection")
2051 def test_prepare_network_for_vm_instance_use_fip_true_non_mgmt_net_port_security_true(
2052 self, mock_reload_connection
2053 ):
2054 """Nets have net-id, use_floating_ip is True in VIM config, non-mgmt network, net port security is True."""
2055 mock_create_port = CopyingMock()
2056 self.vimconn.config["use_floating_ip"] = True
2057 self.vimconn.config["no_port_security_extension"] = True
2058 mock_reload_connection.side_effect = None
2059 created_items = {}
2060
2061 net_list = [
2062 {
2063 "net_id": net2_id,
2064 "use": "other",
2065 "port_security": True,
2066 "port_security_disable_strategy": "full",
2067 }
2068 ]
2069 net_list_vim = []
2070 mock_create_port.side_effect = [
2071 (
2072 {
2073 "port": {
2074 "id": port2_id,
2075 "mac_address": mac_address,
2076 "name": name,
2077 },
2078 },
2079 {"port-dict": port2_id},
2080 ),
2081 ]
2082 external_network, no_secured_ports = [], []
2083 expected_external_network = []
2084 expected_no_secured_ports = []
2085 expected_net_list_vim = [{"port-dict": port2_id}]
2086 with patch.object(vimconnector, "_create_port", mock_create_port):
2087 self.vimconn._prepare_network_for_vminstance(
2088 name,
2089 net_list,
2090 created_items,
2091 net_list_vim,
2092 external_network,
2093 no_secured_ports,
2094 )
2095
2096 mock_create_port.assert_called_once_with(
2097 {
2098 "net_id": net2_id,
2099 "use": "other",
2100 "port_security": True,
2101 "port_security_disable_strategy": "full",
2102 },
2103 name,
2104 created_items,
2105 )
2106 self.assertEqual(expected_net_list_vim, net_list_vim)
2107 self.assertEqual(external_network, expected_external_network)
2108 self.assertEqual(expected_no_secured_ports, no_secured_ports)
2109
2110 @patch.object(vimconnector, "_reload_connection")
2111 def test_prepare_network_for_vm_instance_create_port_raise_exception(
2112 self, mock_reload_connection
2113 ):
2114 """_create_port method raise exception."""
2115 mock_create_port = CopyingMock()
2116 self.vimconn.config["use_floating_ip"] = True
2117 self.vimconn.config["no_port_security_extension"] = True
2118 mock_reload_connection.side_effect = None
2119 created_items = {}
2120
2121 net_list = [
2122 {
2123 "net_id": net2_id,
2124 "use": "other",
2125 "port_security": True,
2126 "port_security_disable_strategy": "full",
2127 }
2128 ]
2129 net_list_vim = []
2130 mock_create_port.side_effect = KeyError
2131 external_network, no_secured_ports = [], []
2132 expected_external_network = []
2133 expected_no_secured_ports = []
2134 expected_net_list_vim = []
2135 with patch.object(vimconnector, "_create_port", mock_create_port):
2136 with self.assertRaises(Exception) as err:
2137 self.vimconn._prepare_network_for_vminstance(
2138 name,
2139 net_list,
2140 created_items,
2141 net_list_vim,
2142 external_network,
2143 no_secured_ports,
2144 )
2145
2146 self.assertEqual(type(err.exception), KeyError)
2147
2148 mock_create_port.assert_called_once_with(
2149 {
2150 "net_id": net2_id,
2151 "use": "other",
2152 "port_security": True,
2153 "port_security_disable_strategy": "full",
2154 },
2155 name,
2156 created_items,
2157 )
2158 self.assertEqual(expected_net_list_vim, net_list_vim)
2159 self.assertEqual(external_network, expected_external_network)
2160 self.assertEqual(expected_no_secured_ports, no_secured_ports)
2161
2162 @patch.object(vimconnector, "_reload_connection")
2163 def test_prepare_network_for_vm_instance_reload_connection_raise_exception(
2164 self, mock_reload_connection
2165 ):
2166 """_reload_connection method raises exception."""
2167 mock_create_port = CopyingMock()
2168 mock_reload_connection.side_effect = VimConnConnectionException(
2169 "Connection failed."
2170 )
2171 self.vimconn.config["use_floating_ip"] = True
2172 self.vimconn.config["no_port_security_extension"] = True
2173 created_items = {}
2174
2175 net_list = [
2176 {
2177 "net_id": net2_id,
2178 "use": "other",
2179 "port_security": True,
2180 "port_security_disable_strategy": "full",
2181 }
2182 ]
2183 net_list_vim = []
2184 mock_create_port.side_effect = None
2185 external_network, no_secured_ports = [], []
2186 expected_external_network = []
2187 expected_no_secured_ports = []
2188 expected_net_list_vim = []
2189 with patch.object(vimconnector, "_create_port", mock_create_port):
2190 with self.assertRaises(Exception) as err:
2191 self.vimconn._prepare_network_for_vminstance(
2192 name,
2193 net_list,
2194 created_items,
2195 net_list_vim,
2196 external_network,
2197 no_secured_ports,
2198 )
2199
2200 self.assertEqual(type(err.exception), VimConnConnectionException)
2201 self.assertEqual(str(err.exception), "Connection failed.")
2202 mock_reload_connection.assert_called_once()
2203 mock_create_port.assert_not_called()
2204 self.assertEqual(expected_net_list_vim, net_list_vim)
2205 self.assertEqual(external_network, expected_external_network)
2206 self.assertEqual(expected_no_secured_ports, no_secured_ports)
2207
2208 def test_prepare_persistent_root_volumes_vim_using_volume_id(self):
2209 """Existing persistent root volume with vim_volume_id."""
2210 vm_av_zone = ["nova"]
2211 base_disk_index = ord("a")
2212 disk = {"vim_volume_id": volume_id}
2213 block_device_mapping = {}
2214 existing_vim_volumes = []
2215 created_items = {}
2216 expected_boot_vol_id = None
2217 expected_block_device_mapping = {"vda": volume_id}
2218 expected_existing_vim_volumes = [{"id": volume_id}]
2219 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
2220 name,
2221 vm_av_zone,
2222 disk,
2223 base_disk_index,
2224 block_device_mapping,
2225 existing_vim_volumes,
2226 created_items,
2227 )
2228 self.assertEqual(boot_volume_id, expected_boot_vol_id)
2229 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2230 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2231 self.vimconn.cinder.volumes.create.assert_not_called()
2232
2233 def test_prepare_persistent_non_root_volumes_vim_using_volume_id(self):
2234 """Existing persistent non root volume with vim_volume_id."""
2235 vm_av_zone = ["nova"]
2236 base_disk_index = ord("b")
2237 disk = {"vim_volume_id": volume_id}
2238 block_device_mapping = {}
2239 existing_vim_volumes = []
2240 created_items = {}
2241 expected_block_device_mapping = {"vdb": volume_id}
2242 expected_existing_vim_volumes = [{"id": volume_id}]
2243 self.vimconn._prepare_non_root_persistent_volumes(
2244 name,
2245 disk,
2246 vm_av_zone,
2247 block_device_mapping,
2248 base_disk_index,
2249 existing_vim_volumes,
2250 created_items,
2251 )
2252 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2253 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2254 self.vimconn.cinder.volumes.create.assert_not_called()
2255
2256 def test_prepare_persistent_root_volumes_using_vim_id(self):
2257 """Existing persistent root volume with vim_id."""
2258 vm_av_zone = ["nova"]
2259 base_disk_index = ord("a")
2260 disk = {"vim_id": volume_id}
2261 block_device_mapping = {}
2262 existing_vim_volumes = []
2263 created_items = {}
2264 expected_boot_vol_id = None
2265 expected_block_device_mapping = {"vda": volume_id}
2266 expected_existing_vim_volumes = [{"id": volume_id}]
2267 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
2268 name,
2269 vm_av_zone,
2270 disk,
2271 base_disk_index,
2272 block_device_mapping,
2273 existing_vim_volumes,
2274 created_items,
2275 )
2276 self.assertEqual(boot_volume_id, expected_boot_vol_id)
2277 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2278 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2279 self.vimconn.cinder.volumes.create.assert_not_called()
2280
2281 def test_prepare_persistent_non_root_volumes_using_vim_id(self):
2282 """Existing persistent root volume with vim_id."""
2283 vm_av_zone = ["nova"]
2284 base_disk_index = ord("b")
2285 disk = {"vim_id": volume_id}
2286 block_device_mapping = {}
2287 existing_vim_volumes = []
2288 created_items = {}
2289
2290 expected_block_device_mapping = {"vdb": volume_id}
2291 expected_existing_vim_volumes = [{"id": volume_id}]
2292 self.vimconn._prepare_non_root_persistent_volumes(
2293 name,
2294 disk,
2295 vm_av_zone,
2296 block_device_mapping,
2297 base_disk_index,
2298 existing_vim_volumes,
2299 created_items,
2300 )
2301
2302 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2303 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2304 self.vimconn.cinder.volumes.create.assert_not_called()
2305
2306 def test_prepare_persistent_root_volumes_create(self):
2307 """Create persistent root volume."""
2308 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
2309 vm_av_zone = ["nova"]
2310 base_disk_index = ord("a")
2311 disk = {"size": 10, "image_id": image_id}
2312 block_device_mapping = {}
2313 existing_vim_volumes = []
2314 created_items = {}
2315 expected_boot_vol_id = volume_id2
2316 expected_block_device_mapping = {"vda": volume_id2}
2317 expected_existing_vim_volumes = []
2318 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
2319 name,
2320 vm_av_zone,
2321 disk,
2322 base_disk_index,
2323 block_device_mapping,
2324 existing_vim_volumes,
2325 created_items,
2326 )
2327 self.assertEqual(boot_volume_id, expected_boot_vol_id)
2328 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2329 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2330 self.vimconn.cinder.volumes.create.assert_called_once_with(
2331 size=10,
2332 name="basicvmvda",
2333 imageRef=image_id,
2334 availability_zone=["nova"],
2335 )
2336 self.assertEqual(created_items, {f"volume:{volume_id2}": True})
2337
2338 def test_prepare_persistent_non_root_volumes_create(self):
2339 """Create persistent non-root volume."""
2340 self.vimconn.cinder = CopyingMock()
2341 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
2342 vm_av_zone = ["nova"]
2343 base_disk_index = ord("a")
2344 disk = {"size": 10}
2345 block_device_mapping = {}
2346 existing_vim_volumes = []
2347 created_items = {}
2348 expected_block_device_mapping = {"vda": volume_id2}
2349 expected_existing_vim_volumes = []
2350 self.vimconn._prepare_non_root_persistent_volumes(
2351 name,
2352 disk,
2353 vm_av_zone,
2354 block_device_mapping,
2355 base_disk_index,
2356 existing_vim_volumes,
2357 created_items,
2358 )
2359
2360 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2361 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2362 self.vimconn.cinder.volumes.create.assert_called_once_with(
2363 size=10, name="basicvmvda", availability_zone=["nova"]
2364 )
2365 self.assertEqual(created_items, {f"volume:{volume_id2}": True})
2366
2367 def test_prepare_persistent_root_volumes_create_raise_exception(self):
2368 """Create persistent root volume raise exception."""
2369 self.vimconn.cinder.volumes.create.side_effect = Exception
2370 vm_av_zone = ["nova"]
2371 base_disk_index = ord("a")
2372 disk = {"size": 10, "image_id": image_id}
2373 block_device_mapping = {}
2374 existing_vim_volumes = []
2375 created_items = {}
2376
2377 with self.assertRaises(Exception):
2378 result = self.vimconn._prepare_persistent_root_volumes(
2379 name,
2380 vm_av_zone,
2381 disk,
2382 base_disk_index,
2383 block_device_mapping,
2384 existing_vim_volumes,
2385 created_items,
2386 )
2387
2388 self.assertEqual(result, None)
2389
2390 self.vimconn.cinder.volumes.create.assert_called_once_with(
2391 size=10,
2392 name="basicvmvda",
2393 imageRef=image_id,
2394 availability_zone=["nova"],
2395 )
2396 self.assertEqual(existing_vim_volumes, [])
2397 self.assertEqual(block_device_mapping, {})
2398 self.assertEqual(created_items, {})
2399
2400 def test_prepare_persistent_non_root_volumes_create_raise_exception(self):
2401 """Create persistent non-root volume raise exception."""
2402 self.vimconn.cinder.volumes.create.side_effect = Exception
2403 vm_av_zone = ["nova"]
2404 base_disk_index = ord("b")
2405 disk = {"size": 10}
2406 block_device_mapping = {}
2407 existing_vim_volumes = []
2408 created_items = {}
2409
2410 with self.assertRaises(Exception):
2411 self.vimconn._prepare_non_root_persistent_volumes(
2412 name,
2413 disk,
2414 vm_av_zone,
2415 block_device_mapping,
2416 base_disk_index,
2417 existing_vim_volumes,
2418 created_items,
2419 )
2420
2421 self.vimconn.cinder.volumes.create.assert_called_once_with(
2422 size=10, name="basicvmvdb", availability_zone=["nova"]
2423 )
2424 self.assertEqual(existing_vim_volumes, [])
2425 self.assertEqual(block_device_mapping, {})
2426 self.assertEqual(created_items, {})
2427
2428 @patch("time.sleep")
2429 def test_wait_for_created_volumes_availability_volume_status_available(
2430 self, mock_sleep
2431 ):
2432 """Created volume status is available."""
2433 elapsed_time = 5
2434 created_items = {f"volume:{volume_id2}": True}
2435 self.vimconn.cinder.volumes.get.return_value.status = "available"
2436
2437 result = self.vimconn._wait_for_created_volumes_availability(
2438 elapsed_time, created_items
2439 )
2440 self.assertEqual(result, elapsed_time)
2441 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2442 mock_sleep.assert_not_called()
2443
2444 @patch("time.sleep")
2445 def test_wait_for_existing_volumes_availability_volume_status_available(
2446 self, mock_sleep
2447 ):
2448 """Existing volume status is available."""
2449 elapsed_time = 5
2450 existing_vim_volumes = [{"id": volume_id2}]
2451 self.vimconn.cinder.volumes.get.return_value.status = "available"
2452
2453 result = self.vimconn._wait_for_existing_volumes_availability(
2454 elapsed_time, existing_vim_volumes
2455 )
2456 self.assertEqual(result, elapsed_time)
2457 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2458 mock_sleep.assert_not_called()
2459
2460 @patch("time.sleep")
2461 def test_wait_for_created_volumes_availability_status_processing_multiple_volumes(
2462 self, mock_sleep
2463 ):
2464 """Created volume status is processing."""
2465 elapsed_time = 5
2466 created_items = {
2467 f"volume:{volume_id2}": True,
2468 f"volume:{volume_id3}": True,
2469 }
2470 self.vimconn.cinder.volumes.get.side_effect = [
2471 Status("processing"),
2472 Status("available"),
2473 Status("available"),
2474 ]
2475
2476 result = self.vimconn._wait_for_created_volumes_availability(
2477 elapsed_time, created_items
2478 )
2479 self.assertEqual(result, 10)
2480 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
2481 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
2482 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
2483 self.assertEqual(_call_mock_get_volumes[2][0], (volume_id3,))
2484 mock_sleep.assert_called_with(5)
2485 self.assertEqual(1, mock_sleep.call_count)
2486
2487 @patch("time.sleep")
2488 def test_wait_for_existing_volumes_availability_status_processing_multiple_volumes(
2489 self, mock_sleep
2490 ):
2491 """Existing volume status is processing."""
2492 elapsed_time = 5
2493 existing_vim_volumes = [
2494 {"id": volume_id2},
2495 {"id": "44e0e83-b9uu-4akk-t234-p9cc4811bd4a"},
2496 ]
2497 self.vimconn.cinder.volumes.get.side_effect = [
2498 Status("processing"),
2499 Status("available"),
2500 Status("available"),
2501 ]
2502
2503 result = self.vimconn._wait_for_existing_volumes_availability(
2504 elapsed_time, existing_vim_volumes
2505 )
2506 self.assertEqual(result, 10)
2507 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
2508 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
2509 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
2510 self.assertEqual(
2511 _call_mock_get_volumes[2][0], ("44e0e83-b9uu-4akk-t234-p9cc4811bd4a",)
2512 )
2513 mock_sleep.assert_called_with(5)
2514 self.assertEqual(1, mock_sleep.call_count)
2515
2516 @patch("time.sleep")
2517 def test_wait_for_created_volumes_availability_volume_status_processing_timeout(
2518 self, mock_sleep
2519 ):
2520 """Created volume status is processing, elapsed time greater than timeout (1800)."""
2521 elapsed_time = 1805
2522 created_items = {f"volume:{volume_id2}": True}
2523 self.vimconn.cinder.volumes.get.side_effect = [
2524 Status("processing"),
2525 Status("processing"),
2526 ]
2527 with patch("time.sleep", mock_sleep):
2528 result = self.vimconn._wait_for_created_volumes_availability(
2529 elapsed_time, created_items
2530 )
2531 self.assertEqual(result, 1805)
2532 self.vimconn.cinder.volumes.get.assert_not_called()
2533 mock_sleep.assert_not_called()
2534
2535 @patch("time.sleep")
2536 def test_wait_for_existing_volumes_availability_volume_status_processing_timeout(
2537 self, mock_sleep
2538 ):
2539 """Exsiting volume status is processing, elapsed time greater than timeout (1800)."""
2540 elapsed_time = 1805
2541 existing_vim_volumes = [{"id": volume_id2}]
2542 self.vimconn.cinder.volumes.get.side_effect = [
2543 Status("processing"),
2544 Status("processing"),
2545 ]
2546
2547 result = self.vimconn._wait_for_existing_volumes_availability(
2548 elapsed_time, existing_vim_volumes
2549 )
2550 self.assertEqual(result, 1805)
2551 self.vimconn.cinder.volumes.get.assert_not_called()
2552 mock_sleep.assert_not_called()
2553
2554 @patch("time.sleep")
2555 def test_wait_for_created_volumes_availability_cinder_raise_exception(
2556 self, mock_sleep
2557 ):
2558 """Cinder get volumes raises exception for created volumes."""
2559 elapsed_time = 1000
2560 created_items = {f"volume:{volume_id2}": True}
2561 self.vimconn.cinder.volumes.get.side_effect = Exception
2562 with self.assertRaises(Exception):
2563 result = self.vimconn._wait_for_created_volumes_availability(
2564 elapsed_time, created_items
2565 )
2566 self.assertEqual(result, 1000)
2567 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2568 mock_sleep.assert_not_called()
2569
2570 @patch("time.sleep")
2571 def test_wait_for_existing_volumes_availability_cinder_raise_exception(
2572 self, mock_sleep
2573 ):
2574 """Cinder get volumes raises exception for existing volumes."""
2575 elapsed_time = 1000
2576 existing_vim_volumes = [{"id": volume_id2}]
2577 self.vimconn.cinder.volumes.get.side_effect = Exception
2578 with self.assertRaises(Exception):
2579 result = self.vimconn._wait_for_existing_volumes_availability(
2580 elapsed_time, existing_vim_volumes
2581 )
2582 self.assertEqual(result, 1000)
2583 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2584 mock_sleep.assert_not_called()
2585
2586 @patch("time.sleep")
2587 def test_wait_for_created_volumes_availability_no_volume_in_created_items(
2588 self, mock_sleep
2589 ):
2590 """Created_items dict does not have volume-id."""
2591 elapsed_time = 10
2592 created_items = {}
2593
2594 self.vimconn.cinder.volumes.get.side_effect = [None]
2595
2596 result = self.vimconn._wait_for_created_volumes_availability(
2597 elapsed_time, created_items
2598 )
2599 self.assertEqual(result, 10)
2600 self.vimconn.cinder.volumes.get.assert_not_called()
2601 mock_sleep.assert_not_called()
2602
2603 @patch("time.sleep")
2604 def test_wait_for_existing_volumes_availability_no_volume_in_existing_vim_volumes(
2605 self, mock_sleep
2606 ):
2607 """Existing_vim_volumes list does not have volume."""
2608 elapsed_time = 10
2609 existing_vim_volumes = []
2610
2611 self.vimconn.cinder.volumes.get.side_effect = [None]
2612
2613 result = self.vimconn._wait_for_existing_volumes_availability(
2614 elapsed_time, existing_vim_volumes
2615 )
2616 self.assertEqual(result, 10)
2617 self.vimconn.cinder.volumes.get.assert_not_called()
2618 mock_sleep.assert_not_called()
2619
2620 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2621 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2622 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2623 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2624 def test_prepare_disk_for_vm_instance(
2625 self,
2626 mock_existing_vol_availability,
2627 mock_created_vol_availability,
2628 mock_non_root_volumes,
2629 mock_root_volumes,
2630 ):
2631 """Prepare disks for VM instance successfully."""
2632 existing_vim_volumes = []
2633 created_items = {}
2634 block_device_mapping = {}
2635 vm_av_zone = ["nova"]
2636
2637 mock_root_volumes.return_value = root_vol_id
2638 mock_created_vol_availability.return_value = 10
2639 mock_existing_vol_availability.return_value = 15
2640 self.vimconn.cinder = CopyingMock()
2641
2642 self.vimconn._prepare_disk_for_vminstance(
2643 name,
2644 existing_vim_volumes,
2645 created_items,
2646 vm_av_zone,
2647 block_device_mapping,
2648 disk_list2,
2649 )
2650 self.vimconn.cinder.volumes.set_bootable.assert_called_once_with(
2651 root_vol_id, True
2652 )
2653 mock_created_vol_availability.assert_called_once_with(0, created_items)
2654 mock_existing_vol_availability.assert_called_once_with(10, existing_vim_volumes)
2655 self.assertEqual(mock_root_volumes.call_count, 1)
2656 self.assertEqual(mock_non_root_volumes.call_count, 1)
2657 mock_root_volumes.assert_called_once_with(
2658 name="basicvm",
2659 vm_av_zone=["nova"],
2660 disk={"size": 10, "image_id": image_id},
2661 base_disk_index=97,
2662 block_device_mapping={},
2663 existing_vim_volumes=[],
2664 created_items={},
2665 )
2666 mock_non_root_volumes.assert_called_once_with(
2667 name="basicvm",
2668 disk={"size": 20},
2669 vm_av_zone=["nova"],
2670 base_disk_index=98,
2671 block_device_mapping={},
2672 existing_vim_volumes=[],
2673 created_items={},
2674 )
2675
2676 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2677 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2678 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2679 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2680 def test_prepare_disk_for_vm_instance_timeout_exceeded(
2681 self,
2682 mock_existing_vol_availability,
2683 mock_created_vol_availability,
2684 mock_non_root_volumes,
2685 mock_root_volumes,
2686 ):
2687 """Timeout exceeded while waiting for disks."""
2688 existing_vim_volumes = []
2689 created_items = {}
2690 vm_av_zone = ["nova"]
2691 block_device_mapping = {}
2692
2693 mock_root_volumes.return_value = root_vol_id
2694 mock_created_vol_availability.return_value = 1700
2695 mock_existing_vol_availability.return_value = 1900
2696
2697 with self.assertRaises(VimConnException) as err:
2698 self.vimconn._prepare_disk_for_vminstance(
2699 name,
2700 existing_vim_volumes,
2701 created_items,
2702 vm_av_zone,
2703 block_device_mapping,
2704 disk_list2,
2705 )
2706 self.assertEqual(
2707 str(err.exception), "Timeout creating volumes for instance basicvm"
2708 )
2709 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2710 mock_created_vol_availability.assert_called_once_with(0, created_items)
2711 mock_existing_vol_availability.assert_called_once_with(
2712 1700, existing_vim_volumes
2713 )
2714 self.assertEqual(mock_root_volumes.call_count, 1)
2715 self.assertEqual(mock_non_root_volumes.call_count, 1)
2716 mock_root_volumes.assert_called_once_with(
2717 name="basicvm",
2718 vm_av_zone=["nova"],
2719 disk={"size": 10, "image_id": image_id},
2720 base_disk_index=97,
2721 block_device_mapping={},
2722 existing_vim_volumes=[],
2723 created_items={},
2724 )
2725 mock_non_root_volumes.assert_called_once_with(
2726 name="basicvm",
2727 disk={"size": 20},
2728 vm_av_zone=["nova"],
2729 base_disk_index=98,
2730 block_device_mapping={},
2731 existing_vim_volumes=[],
2732 created_items={},
2733 )
2734
2735 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2736 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2737 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2738 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2739 def test_prepare_disk_for_vm_instance_empty_disk_list(
2740 self,
2741 mock_existing_vol_availability,
2742 mock_created_vol_availability,
2743 mock_non_root_volumes,
2744 mock_root_volumes,
2745 ):
2746 """Disk list is empty."""
2747 existing_vim_volumes = []
2748 created_items = {}
2749 block_device_mapping = {}
2750 vm_av_zone = ["nova"]
2751 mock_created_vol_availability.return_value = 2
2752 mock_existing_vol_availability.return_value = 3
2753
2754 self.vimconn._prepare_disk_for_vminstance(
2755 name,
2756 existing_vim_volumes,
2757 created_items,
2758 vm_av_zone,
2759 block_device_mapping,
2760 disk_list,
2761 )
2762 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2763 mock_created_vol_availability.assert_called_once_with(0, created_items)
2764 mock_existing_vol_availability.assert_called_once_with(2, existing_vim_volumes)
2765 mock_root_volumes.assert_not_called()
2766 mock_non_root_volumes.assert_not_called()
2767
2768 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2769 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2770 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2771 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2772 def test_prepare_disk_for_vm_instance_persistent_root_volume_error(
2773 self,
2774 mock_existing_vol_availability,
2775 mock_created_vol_availability,
2776 mock_non_root_volumes,
2777 mock_root_volumes,
2778 ):
2779 """Persistent root volumes preparation raises error."""
2780 existing_vim_volumes = []
2781 created_items = {}
2782 vm_av_zone = ["nova"]
2783 block_device_mapping = {}
2784
2785 mock_root_volumes.side_effect = Exception()
2786 mock_created_vol_availability.return_value = 10
2787 mock_existing_vol_availability.return_value = 15
2788
2789 with self.assertRaises(Exception):
2790 self.vimconn._prepare_disk_for_vminstance(
2791 name,
2792 existing_vim_volumes,
2793 created_items,
2794 vm_av_zone,
2795 block_device_mapping,
2796 disk_list2,
2797 )
2798 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2799 mock_created_vol_availability.assert_not_called()
2800 mock_existing_vol_availability.assert_not_called()
2801 mock_root_volumes.assert_called_once_with(
2802 name="basicvm",
2803 vm_av_zone=["nova"],
2804 disk={"size": 10, "image_id": image_id},
2805 base_disk_index=97,
2806 block_device_mapping={},
2807 existing_vim_volumes=[],
2808 created_items={},
2809 )
2810 mock_non_root_volumes.assert_not_called()
2811
2812 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2813 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2814 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2815 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2816 def test_prepare_disk_for_vm_instance_non_root_volume_error(
2817 self,
2818 mock_existing_vol_availability,
2819 mock_created_vol_availability,
2820 mock_non_root_volumes,
2821 mock_root_volumes,
2822 ):
2823 """Non-root volumes preparation raises error."""
2824 existing_vim_volumes = []
2825 created_items = {}
2826 vm_av_zone = ["nova"]
2827 block_device_mapping = {}
2828
2829 mock_root_volumes.return_value = root_vol_id
2830 mock_non_root_volumes.side_effect = Exception
2831
2832 with self.assertRaises(Exception):
2833 self.vimconn._prepare_disk_for_vminstance(
2834 name,
2835 existing_vim_volumes,
2836 created_items,
2837 vm_av_zone,
2838 block_device_mapping,
2839 disk_list2,
2840 )
2841 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2842 mock_created_vol_availability.assert_not_called()
2843 mock_existing_vol_availability.assert_not_called()
2844 self.assertEqual(mock_root_volumes.call_count, 1)
2845 self.assertEqual(mock_non_root_volumes.call_count, 1)
2846 mock_root_volumes.assert_called_once_with(
2847 name="basicvm",
2848 vm_av_zone=["nova"],
2849 disk={"size": 10, "image_id": image_id},
2850 base_disk_index=97,
2851 block_device_mapping={},
2852 existing_vim_volumes=[],
2853 created_items={},
2854 )
2855 mock_non_root_volumes.assert_called_once_with(
2856 name="basicvm",
2857 disk={"size": 20},
2858 vm_av_zone=["nova"],
2859 base_disk_index=98,
2860 block_device_mapping={},
2861 existing_vim_volumes=[],
2862 created_items={},
2863 )
2864
2865 def test_find_external_network_for_floating_ip_no_external_network(self):
2866 """External network could not be found."""
2867 self.vimconn.neutron.list_networks.return_value = {
2868 "networks": [
2869 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": False}
2870 ]
2871 }
2872 with self.assertRaises(VimConnException) as err:
2873 self.vimconn._find_the_external_network_for_floating_ip()
2874 self.assertEqual(
2875 str(err.exception),
2876 "Cannot create floating_ip automatically since no external network is present",
2877 )
2878
2879 def test_find_external_network_for_floating_one_external_network(self):
2880 """One external network has been found."""
2881 self.vimconn.neutron.list_networks.return_value = {
2882 "networks": [
2883 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True}
2884 ]
2885 }
2886 expected_result = "408b73-r9cc-5a6a-a270-82cc4811bd4a"
2887 result = self.vimconn._find_the_external_network_for_floating_ip()
2888 self.assertEqual(result, expected_result)
2889
2890 def test_find_external_network_for_floating_neutron_raises_exception(self):
2891 """Neutron list networks raises exception."""
2892 self.vimconn.neutron.list_networks.side_effect = Exception
2893 with self.assertRaises(Exception):
2894 self.vimconn._find_the_external_network_for_floating_ip()
2895
2896 def test_find_external_network_for_floating_several_external_network(self):
2897 """Several exernal networks has been found."""
2898 self.vimconn.neutron.list_networks.return_value = {
2899 "networks": [
2900 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True},
2901 {"id": "608b73-y9cc-5a6a-a270-12cc4811bd4a", "router:external": True},
2902 ]
2903 }
2904 with self.assertRaises(VimConnException) as err:
2905 self.vimconn._find_the_external_network_for_floating_ip()
2906 self.assertEqual(
2907 str(err.exception),
2908 "Cannot create floating_ip automatically since multiple external networks are present",
2909 )
2910
2911 def test_neutron_create_float_ip(self):
2912 """Floating ip creation is successful."""
2913 param = {"net_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a"}
2914 created_items = {}
2915 self.vimconn.neutron.create_floatingip.return_value = {
2916 "floatingip": {"id": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2917 }
2918 expected_created_items = {
2919 "floating_ip:308b73-t9cc-1a6a-a270-12cc4811bd4a": True
2920 }
2921 self.vimconn._neutron_create_float_ip(param, created_items)
2922 self.assertEqual(created_items, expected_created_items)
2923
2924 def test_neutron_create_float_ip_exception_occured(self):
2925 """Floating ip could not be created."""
2926 param = {
2927 "floatingip": {
2928 "floating_network_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a",
2929 "tenant_id": "308b73-19cc-8a6a-a270-02cc4811bd9a",
2930 }
2931 }
2932 created_items = {}
2933 self.vimconn.neutron = CopyingMock()
2934 self.vimconn.neutron.create_floatingip.side_effect = Exception(
2935 "Neutron floating ip create exception occured."
2936 )
2937 with self.assertRaises(VimConnException) as err:
2938 self.vimconn._neutron_create_float_ip(param, created_items)
2939 self.assertEqual(created_items, {})
2940 self.assertEqual(
2941 str(err.exception),
2942 "Exception: Cannot create new floating_ip Neutron floating ip create exception occured.",
2943 )
2944
2945 @patch.object(vimconnector, "_neutron_create_float_ip")
2946 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2947 def test_create_floating_ip_pool_id_available(
2948 self, mock_find_ext_network, mock_create_float_ip
2949 ):
2950 """Floating ip creation, ip pool is available."""
2951 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2952 created_items = {}
2953 expected_param = {
2954 "floatingip": {
2955 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2956 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2957 }
2958 }
2959 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2960 mock_find_ext_network.assert_not_called()
2961 mock_create_float_ip.assert_called_once_with(expected_param, {})
2962
2963 @patch.object(vimconnector, "_neutron_create_float_ip")
2964 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2965 def test_create_floating_ip_finding_pool_id(
2966 self, mock_find_ext_network, mock_create_float_ip
2967 ):
2968 """Floating ip creation, pool id need to be found."""
2969 floating_network = {"floating_ip": True}
2970 created_items = {}
2971 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
2972 expected_param = {
2973 "floatingip": {
2974 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2975 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2976 }
2977 }
2978 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2979 mock_find_ext_network.assert_called_once()
2980 mock_create_float_ip.assert_called_once_with(expected_param, {})
2981
2982 @patch.object(vimconnector, "_neutron_create_float_ip")
2983 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2984 def test_create_floating_ip_neutron_create_floating_ip_exception(
2985 self, mock_find_ext_network, mock_create_float_ip
2986 ):
2987 """Neutron creat floating ip raises error."""
2988 floating_network = {"floating_ip": True}
2989 created_items = {}
2990 mock_create_float_ip.side_effect = VimConnException(
2991 "Can not create floating ip."
2992 )
2993 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
2994 expected_param = {
2995 "floatingip": {
2996 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2997 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2998 }
2999 }
3000
3001 with self.assertRaises(VimConnException) as err:
3002 self.vimconn._create_floating_ip(
3003 floating_network, self.server, created_items
3004 )
3005 self.assertEqual(str(err.exception), "Can not create floating ip.")
3006 mock_find_ext_network.assert_called_once()
3007 mock_create_float_ip.assert_called_once_with(expected_param, {})
3008
3009 @patch.object(vimconnector, "_neutron_create_float_ip")
3010 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
3011 def test_create_floating_ip_can_not_find_pool_id(
3012 self, mock_find_ext_network, mock_create_float_ip
3013 ):
3014 """Floating ip creation, pool id could not be found."""
3015 floating_network = {"floating_ip": True}
3016 created_items = {}
3017 mock_find_ext_network.side_effect = VimConnException(
3018 "Cannot create floating_ip automatically since no external network is present"
3019 )
3020 with self.assertRaises(VimConnException) as err:
3021 self.vimconn._create_floating_ip(
3022 floating_network, self.server, created_items
3023 )
3024 self.assertEqual(
3025 str(err.exception),
3026 "Cannot create floating_ip automatically since no external network is present",
3027 )
3028 mock_find_ext_network.assert_called_once()
3029 mock_create_float_ip.assert_not_called()
3030
3031 def test_find_floating_ip_get_free_floating_ip(self):
3032 """Get free floating ips successfully."""
3033 floating_ips = [
3034 {
3035 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
3036 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3037 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3038 }
3039 ]
3040 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3041 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3042
3043 result = self.vimconn._find_floating_ip(
3044 self.server, floating_ips, floating_network
3045 )
3046 self.assertEqual(result, expected_result)
3047
3048 def test_find_floating_ip_different_floating_network_id(self):
3049 """Floating network id is different with floating_ip of floating network."""
3050 floating_ips = [
3051 {
3052 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3053 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3054 }
3055 ]
3056 floating_network = {"floating_ip": "508b73-t9cc-1a6a-a270-12cc4811bd4a"}
3057
3058 result = self.vimconn._find_floating_ip(
3059 self.server, floating_ips, floating_network
3060 )
3061 self.assertEqual(result, None)
3062
3063 def test_find_floating_ip_different_fip_tenant(self):
3064 """Items in floating_ips has port_id, tenant_is is not same with server tenant id."""
3065 floating_ips = [
3066 {
3067 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3068 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3069 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3070 "tenant_id": self.server.id,
3071 }
3072 ]
3073 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3074 mock_create_floating_ip = CopyingMock()
3075 with patch.object(vimconnector, "_create_floating_ip", mock_create_floating_ip):
3076 result = self.vimconn._find_floating_ip(
3077 self.server, floating_ips, floating_network
3078 )
3079 self.assertEqual(result, None)
3080
3081 @patch("time.sleep")
3082 def test_assign_floating_ip(self, mock_sleep):
3083 """Assign floating ip successfully."""
3084 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3085 floating_network = {"vim_id": floating_network_vim_id}
3086 fip = {
3087 "port_id": floating_network_vim_id,
3088 "floating_network_id": "p08b73-e9cc-5a6a-t270-82cc4811bd4a",
3089 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3090 "tenant_id": "k08b73-e9cc-5a6a-t270-82cc4811bd4a",
3091 }
3092 self.vimconn.neutron.update_floatingip.side_effect = None
3093 self.vimconn.neutron.show_floatingip.return_value = fip
3094 expected_result = fip
3095
3096 result = self.vimconn._assign_floating_ip(free_floating_ip, floating_network)
3097 self.assertEqual(result, expected_result)
3098 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3099 free_floating_ip,
3100 {"floatingip": {"port_id": floating_network_vim_id}},
3101 )
3102 mock_sleep.assert_called_once_with(5)
3103 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
3104
3105 @patch("time.sleep")
3106 def test_assign_floating_ip_update_floating_ip_exception(self, mock_sleep):
3107 """Neutron update floating ip raises exception."""
3108 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3109 floating_network = {"vim_id": floating_network_vim_id}
3110 self.vimconn.neutron = CopyingMock()
3111 self.vimconn.neutron.update_floatingip.side_effect = Exception(
3112 "Floating ip is not updated."
3113 )
3114
3115 with self.assertRaises(Exception) as err:
3116 result = self.vimconn._assign_floating_ip(
3117 free_floating_ip, floating_network
3118 )
3119 self.assertEqual(result, None)
3120 self.assertEqual(str(err.exception), "Floating ip is not updated.")
3121
3122 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3123 free_floating_ip,
3124 {"floatingip": {"port_id": floating_network_vim_id}},
3125 )
3126 mock_sleep.assert_not_called()
3127 self.vimconn.neutron.show_floatingip.assert_not_called()
3128
3129 @patch("time.sleep")
3130 def test_assign_floating_ip_show_floating_ip_exception(self, mock_sleep):
3131 """Neutron show floating ip raises exception."""
3132 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3133 floating_network = {"vim_id": floating_network_vim_id}
3134 self.vimconn.neutron.update_floatingip.side_effect = None
3135 self.vimconn.neutron.show_floatingip.side_effect = Exception(
3136 "Floating ip could not be shown."
3137 )
3138
3139 with self.assertRaises(Exception) as err:
3140 result = self.vimconn._assign_floating_ip(
3141 free_floating_ip, floating_network
3142 )
3143 self.assertEqual(result, None)
3144 self.assertEqual(str(err.exception), "Floating ip could not be shown.")
3145 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3146 free_floating_ip,
3147 {"floatingip": {"port_id": floating_network_vim_id}},
3148 )
3149 mock_sleep.assert_called_once_with(5)
3150 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
3151
3152 @patch("random.shuffle")
3153 @patch.object(vimconnector, "_find_floating_ip")
3154 def test_get_free_floating_ip(self, mock_find_floating_ip, mock_shuffle):
3155 """Get free floating ip successfully."""
3156 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3157 created_items = {}
3158 floating_ips = [
3159 {
3160 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3161 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3162 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3163 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3164 },
3165 {
3166 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
3167 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3168 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
3169 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3170 },
3171 ]
3172 self.vimconn.neutron.list_floatingips.return_value = {
3173 "floatingips": floating_ips
3174 }
3175 mock_find_floating_ip.return_value = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3176 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3177
3178 result = self.vimconn._get_free_floating_ip(
3179 self.server, floating_network, created_items
3180 )
3181 self.assertEqual(result, expected_result)
3182 mock_shuffle.assert_called_once_with(floating_ips)
3183 mock_find_floating_ip.assert_called_once_with(
3184 self.server, floating_ips, floating_network, created_items
3185 )
3186
3187 @patch("random.shuffle")
3188 @patch.object(vimconnector, "_find_floating_ip")
3189 def test_get_free_floating_ip_list_floating_ip_exception(
3190 self, mock_find_floating_ip, mock_shuffle
3191 ):
3192 """Neutron list floating IPs raises exception."""
3193 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3194 created_items = {}
3195 self.vimconn.neutron = CopyingMock()
3196 self.vimconn.neutron.list_floatingips.side_effect = Exception(
3197 "Floating ips could not be listed."
3198 )
3199 with self.assertRaises(Exception) as err:
3200 result = self.vimconn._get_free_floating_ip(
3201 self.server, floating_network, created_items
3202 )
3203 self.assertEqual(result, None)
3204 self.assertEqual(str(err.exception), "Floating ips could not be listed.")
3205 mock_shuffle.assert_not_called()
3206 mock_find_floating_ip.assert_not_called()
3207
3208 @patch("random.shuffle")
3209 @patch.object(vimconnector, "_find_floating_ip")
3210 def test_get_free_floating_ip_find_floating_ip_exception(
3211 self, mock_find_floating_ip, mock_shuffle
3212 ):
3213 """_find_floating_ip method raises exception."""
3214 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3215 created_items = {}
3216 floating_ips = [
3217 {
3218 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3219 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3220 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3221 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3222 },
3223 {
3224 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
3225 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3226 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
3227 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3228 },
3229 ]
3230 self.vimconn.neutron = CopyingMock()
3231 self.vimconn.neutron.list_floatingips.return_value = {
3232 "floatingips": floating_ips
3233 }
3234 mock_find_floating_ip.side_effect = Exception(
3235 "Free floating ip could not be found."
3236 )
3237
3238 with self.assertRaises(Exception) as err:
3239 result = self.vimconn._get_free_floating_ip(
3240 self.server, floating_network, created_items
3241 )
3242 self.assertEqual(result, None)
3243 self.assertEqual(str(err.exception), "Free floating ip could not be found.")
3244 mock_shuffle.assert_called_once_with(floating_ips)
3245 mock_find_floating_ip.assert_called_once_with(
3246 self.server, floating_ips, floating_network, created_items
3247 )
3248
3249 @patch.object(vimconnector, "_create_floating_ip")
3250 @patch.object(vimconnector, "_get_free_floating_ip")
3251 @patch.object(vimconnector, "_assign_floating_ip")
3252 def test_prepare_external_network_for_vm_instance(
3253 self,
3254 mock_assign_floating_ip,
3255 mock_get_free_floating_ip,
3256 mock_create_floating_ip,
3257 ):
3258 """Prepare external network successfully."""
3259 external_network = [
3260 {
3261 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3262 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3263 },
3264 ]
3265 created_items = {}
3266 vm_start_time = time_return_value
3267 mock_get_free_floating_ip.side_effect = ["y08b73-o9cc-1a6a-a270-12cc4811bd4u"]
3268 mock_assign_floating_ip.return_value = {
3269 "floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}
3270 }
3271 self.vimconn.neutron = CopyingMock()
3272 self.vimconn.nova = CopyingMock()
3273 self.vimconn.neutron.show_floatingip.return_value = {
3274 "floatingip": {"port_id": ""}
3275 }
3276
3277 self.vimconn._prepare_external_network_for_vminstance(
3278 external_network, self.server, created_items, vm_start_time
3279 )
3280
3281 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3282 mock_get_free_floating_ip.assert_called_once_with(
3283 self.server,
3284 {
3285 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3286 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3287 },
3288 created_items,
3289 )
3290 self.vimconn.neutron.show_floatingip.assert_called_once_with(
3291 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3292 )
3293 self.vimconn.nova.servers.get.assert_not_called()
3294 mock_create_floating_ip.assert_not_called()
3295 mock_assign_floating_ip.assert_called_once_with(
3296 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3297 {
3298 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3299 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3300 },
3301 )
3302
3303 @patch("time.time")
3304 @patch("time.sleep")
3305 @patch.object(vimconnector, "_create_floating_ip")
3306 @patch.object(vimconnector, "_get_free_floating_ip")
3307 @patch.object(vimconnector, "_assign_floating_ip")
3308 def test_prepare_external_network_for_vm_instance_no_free_floating_ip(
3309 self,
3310 mock_assign_floating_ip,
3311 mock_get_free_floating_ip,
3312 mock_create_floating_ip,
3313 mock_sleep,
3314 mock_time,
3315 ):
3316 """There is not any free floating ip."""
3317 floating_network = {
3318 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3319 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3320 }
3321 external_network = [floating_network]
3322
3323 created_items = {}
3324 vm_start_time = time_return_value
3325 mock_get_free_floating_ip.return_value = None
3326 mock_assign_floating_ip.return_value = {}
3327 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3328 self.vimconn.neutron.show_floatingip.return_value = {}
3329
3330 with self.assertRaises(KeyError):
3331 self.vimconn._prepare_external_network_for_vminstance(
3332 external_network, self.server, created_items, vm_start_time
3333 )
3334
3335 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3336 mock_get_free_floating_ip.assert_called_with(
3337 self.server,
3338 {
3339 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3340 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3341 },
3342 created_items,
3343 )
3344 self.vimconn.neutron.show_floatingip.assert_called_with(None)
3345 mock_sleep.assert_not_called()
3346 mock_time.assert_not_called()
3347 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
3348 mock_create_floating_ip.assert_called_with(
3349 floating_network, self.server, created_items
3350 )
3351 self.assertEqual(mock_create_floating_ip.call_count, 4)
3352 mock_assign_floating_ip.assert_not_called()
3353 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3354
3355 @patch("time.time")
3356 @patch("time.sleep")
3357 @patch.object(vimconnector, "_create_floating_ip")
3358 @patch.object(vimconnector, "_get_free_floating_ip")
3359 @patch.object(vimconnector, "_assign_floating_ip")
3360 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_false(
3361 self,
3362 mock_assign_floating_ip,
3363 mock_get_free_floating_ip,
3364 mock_create_floating_ip,
3365 mock_sleep,
3366 mock_time,
3367 ):
3368 """There is not any free floating ip, create_floating ip method raise exception
3369 exit_on_floating_ip_error set to False."""
3370 floating_network = {
3371 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3372 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3373 "exit_on_floating_ip_error": False,
3374 }
3375 external_network = [floating_network]
3376
3377 created_items = {}
3378 vm_start_time = time_return_value
3379 mock_get_free_floating_ip.return_value = None
3380 mock_assign_floating_ip.return_value = {}
3381 mock_create_floating_ip.side_effect = VimConnException(
3382 "Can not create floating ip."
3383 )
3384 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3385 self.vimconn.neutron.show_floatingip.return_value = {}
3386
3387 self.vimconn._prepare_external_network_for_vminstance(
3388 external_network, self.server, created_items, vm_start_time
3389 )
3390 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3391 mock_get_free_floating_ip.assert_called_with(
3392 self.server,
3393 {
3394 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3395 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3396 "exit_on_floating_ip_error": False,
3397 },
3398 created_items,
3399 )
3400 self.vimconn.neutron.show_floatingip.assert_not_called()
3401 mock_sleep.assert_not_called()
3402 mock_time.assert_not_called()
3403 self.vimconn.nova.servers.get.assert_not_called()
3404 mock_create_floating_ip.assert_called_with(
3405 floating_network, self.server, created_items
3406 )
3407 self.assertEqual(mock_create_floating_ip.call_count, 1)
3408 mock_assign_floating_ip.assert_not_called()
3409
3410 @patch("time.time")
3411 @patch("time.sleep")
3412 @patch.object(vimconnector, "_create_floating_ip")
3413 @patch.object(vimconnector, "_get_free_floating_ip")
3414 @patch.object(vimconnector, "_assign_floating_ip")
3415 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_true(
3416 self,
3417 mock_assign_floating_ip,
3418 mock_get_free_floating_ip,
3419 mock_create_floating_ip,
3420 mock_sleep,
3421 mock_time,
3422 ):
3423 """There is not any free floating ip, create_floating ip method raise exception
3424 exit_on_floating_ip_error set to False."""
3425 floating_network = {
3426 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3427 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3428 "exit_on_floating_ip_error": True,
3429 }
3430 external_network = [floating_network]
3431
3432 created_items = {}
3433 vm_start_time = time_return_value
3434 mock_get_free_floating_ip.return_value = None
3435 mock_assign_floating_ip.return_value = {}
3436 mock_create_floating_ip.side_effect = VimConnException(
3437 "Can not create floating ip."
3438 )
3439 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3440 self.vimconn.neutron.show_floatingip.return_value = {}
3441 with self.assertRaises(VimConnException):
3442 self.vimconn._prepare_external_network_for_vminstance(
3443 external_network, self.server, created_items, vm_start_time
3444 )
3445 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3446 mock_get_free_floating_ip.assert_called_with(
3447 self.server,
3448 {
3449 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3450 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3451 "exit_on_floating_ip_error": True,
3452 },
3453 created_items,
3454 )
3455 self.vimconn.neutron.show_floatingip.assert_not_called()
3456 mock_sleep.assert_not_called()
3457 mock_time.assert_not_called()
3458 self.vimconn.nova.servers.get.assert_not_called()
3459 mock_create_floating_ip.assert_called_with(
3460 floating_network, self.server, created_items
3461 )
3462 self.assertEqual(mock_create_floating_ip.call_count, 1)
3463 mock_assign_floating_ip.assert_not_called()
3464
3465 @patch.object(vimconnector, "_create_floating_ip")
3466 @patch.object(vimconnector, "_get_free_floating_ip")
3467 @patch.object(vimconnector, "_assign_floating_ip")
3468 def test_prepare_external_network_for_vm_instance_fip_has_port_id(
3469 self,
3470 mock_assign_floating_ip,
3471 mock_get_free_floating_ip,
3472 mock_create_floating_ip,
3473 ):
3474 """Neutron show floating ip return the fip with port_id and floating network vim_id
3475 is different from port_id."""
3476 floating_network = {
3477 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3478 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3479 }
3480 external_network = [floating_network]
3481 created_items = {}
3482 vm_start_time = 150
3483 mock_get_free_floating_ip.side_effect = [
3484 "t08b73-o9cc-1a6a-a270-12cc4811bd4u",
3485 "r08b73-o9cc-1a6a-a270-12cc4811bd4u",
3486 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3487 ]
3488 mock_assign_floating_ip.side_effect = [
3489 {"floatingip": {"port_id": "k08b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3490 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3491 ]
3492 self.vimconn.neutron = CopyingMock()
3493 self.vimconn.nova = CopyingMock()
3494 self.vimconn.neutron.show_floatingip.side_effect = [
3495 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3496 {"floatingip": {"port_id": ""}},
3497 {"floatingip": {"port_id": ""}},
3498 ]
3499 self.vimconn._prepare_external_network_for_vminstance(
3500 external_network, self.server, created_items, vm_start_time
3501 )
3502 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
3503 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3504 self.assertEqual(
3505 _call_mock_get_free_floating_ip[0][0],
3506 (
3507 self.server,
3508 floating_network,
3509 created_items,
3510 ),
3511 )
3512 self.assertEqual(
3513 _call_mock_get_free_floating_ip[1][0],
3514 (
3515 self.server,
3516 floating_network,
3517 created_items,
3518 ),
3519 )
3520 self.assertEqual(
3521 _call_mock_get_free_floating_ip[2][0],
3522 (
3523 self.server,
3524 floating_network,
3525 created_items,
3526 ),
3527 )
3528 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
3529 self.vimconn.nova.servers.get.assert_not_called()
3530 mock_create_floating_ip.assert_not_called()
3531 self.assertEqual(mock_assign_floating_ip.call_count, 2)
3532 _call_mock_assign_floating_ip = mock_assign_floating_ip.call_args_list
3533 self.assertEqual(
3534 _call_mock_assign_floating_ip[0][0],
3535 ("r08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
3536 )
3537 self.assertEqual(
3538 _call_mock_assign_floating_ip[1][0],
3539 ("y08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
3540 )
3541
3542 @patch("time.time")
3543 @patch("time.sleep")
3544 @patch.object(vimconnector, "_create_floating_ip")
3545 @patch.object(vimconnector, "_get_free_floating_ip")
3546 @patch.object(vimconnector, "_assign_floating_ip")
3547 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_error(
3548 self,
3549 mock_assign_floating_ip,
3550 mock_get_free_floating_ip,
3551 mock_create_floating_ip,
3552 mock_sleep,
3553 mock_time,
3554 ):
3555 """Neutron show floating ip gives exception, exit_on_floating_ip_error set to True,
3556 VM status is in error."""
3557 floating_network = {
3558 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3559 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3560 "exit_on_floating_ip_error": True,
3561 }
3562 external_network = [floating_network]
3563 created_items = {}
3564 vm_start_time = time_return_value
3565
3566 mock_time.side_effect = [156570150, 156570800, 156571200]
3567
3568 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3569 self.vimconn.neutron.show_floatingip.side_effect = [
3570 Exception("Floating ip could not be shown.")
3571 ] * 4
3572 with self.assertRaises(Exception) as err:
3573 self.vimconn._prepare_external_network_for_vminstance(
3574 external_network, self.server, created_items, vm_start_time
3575 )
3576 self.assertEqual(
3577 str(err.exception),
3578 "Cannot create floating_ip: Exception Floating ip could not be shown.",
3579 )
3580
3581 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3582 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3583 self.assertEqual(
3584 _call_mock_get_free_floating_ip[0][0],
3585 (
3586 self.server,
3587 floating_network,
3588 created_items,
3589 ),
3590 )
3591 self.assertEqual(
3592 _call_mock_get_free_floating_ip[1][0],
3593 (
3594 self.server,
3595 floating_network,
3596 created_items,
3597 ),
3598 )
3599 self.assertEqual(
3600 _call_mock_get_free_floating_ip[2][0],
3601 (
3602 self.server,
3603 floating_network,
3604 created_items,
3605 ),
3606 )
3607 self.assertEqual(
3608 _call_mock_get_free_floating_ip[3][0],
3609 (
3610 self.server,
3611 floating_network,
3612 created_items,
3613 ),
3614 )
3615
3616 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3617 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3618 mock_create_floating_ip.assert_not_called()
3619 mock_assign_floating_ip.assert_not_called()
3620 mock_time.assert_not_called()
3621 mock_sleep.assert_not_called()
3622
3623 @patch("time.time")
3624 @patch("time.sleep")
3625 @patch.object(vimconnector, "_create_floating_ip")
3626 @patch.object(vimconnector, "_get_free_floating_ip")
3627 @patch.object(vimconnector, "_assign_floating_ip")
3628 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_active(
3629 self,
3630 mock_assign_floating_ip,
3631 mock_get_free_floating_ip,
3632 mock_create_floating_ip,
3633 mock_sleep,
3634 mock_time,
3635 ):
3636 """Neutron show floating ip gives exception, exit_on_floating_ip_error is set to False,
3637 VM status is in active."""
3638 floating_network = {
3639 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3640 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3641 "exit_on_floating_ip_error": False,
3642 }
3643 external_network = [floating_network]
3644 created_items = {}
3645 vm_start_time = time_return_value
3646
3647 mock_time.side_effect = [156570150, 156570800, 156571200]
3648
3649 self.vimconn.nova.servers.get.return_value.status = "ACTIVE"
3650 self.vimconn.neutron.show_floatingip.side_effect = [
3651 Exception("Floating ip could not be shown.")
3652 ] * 4
3653
3654 self.vimconn._prepare_external_network_for_vminstance(
3655 external_network, self.server, created_items, vm_start_time
3656 )
3657 # self.assertEqual(str(err.exception), "Cannot create floating_ip")
3658
3659 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3660 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3661 self.assertEqual(
3662 _call_mock_get_free_floating_ip[0][0],
3663 (
3664 self.server,
3665 floating_network,
3666 created_items,
3667 ),
3668 )
3669 self.assertEqual(
3670 _call_mock_get_free_floating_ip[1][0],
3671 (
3672 self.server,
3673 floating_network,
3674 created_items,
3675 ),
3676 )
3677 self.assertEqual(
3678 _call_mock_get_free_floating_ip[2][0],
3679 (
3680 self.server,
3681 floating_network,
3682 created_items,
3683 ),
3684 )
3685 self.assertEqual(
3686 _call_mock_get_free_floating_ip[3][0],
3687 (
3688 self.server,
3689 floating_network,
3690 created_items,
3691 ),
3692 )
3693
3694 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3695 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3696 mock_create_floating_ip.assert_not_called()
3697 mock_assign_floating_ip.assert_not_called()
3698 mock_time.assert_not_called()
3699 mock_sleep.assert_not_called()
3700
3701 @patch("time.time")
3702 @patch("time.sleep")
3703 @patch.object(vimconnector, "_create_floating_ip")
3704 @patch.object(vimconnector, "_get_free_floating_ip")
3705 @patch.object(vimconnector, "_assign_floating_ip")
3706 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_exit_on_error(
3707 self,
3708 mock_assign_floating_ip,
3709 mock_get_free_floating_ip,
3710 mock_create_floating_ip,
3711 mock_sleep,
3712 mock_time,
3713 ):
3714 """Neutron show floating ip gives exception, but exit_on_floating_ip_error is set to True.
3715 VM status is not ACTIVE or ERROR, server timeout happened."""
3716 floating_network = {
3717 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3718 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3719 "exit_on_floating_ip_error": True,
3720 }
3721 external_network = [floating_network]
3722 created_items = {}
3723 vm_start_time = time_return_value
3724 mock_get_free_floating_ip.side_effect = None
3725 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3726 self.vimconn.nova.servers.get.return_value.status = "OTHER"
3727 self.vimconn.neutron.show_floatingip.side_effect = [
3728 Exception("Floating ip could not be shown.")
3729 ] * 5
3730
3731 with self.assertRaises(VimConnException) as err:
3732 self.vimconn._prepare_external_network_for_vminstance(
3733 external_network, self.server, created_items, vm_start_time
3734 )
3735 self.assertEqual(
3736 str(err.exception),
3737 "Cannot create floating_ip: Exception Floating ip could not be shown.",
3738 )
3739
3740 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
3741 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3742 self.assertEqual(
3743 _call_mock_get_free_floating_ip[0][0],
3744 (
3745 self.server,
3746 floating_network,
3747 created_items,
3748 ),
3749 )
3750 self.assertEqual(
3751 _call_mock_get_free_floating_ip[1][0],
3752 (
3753 self.server,
3754 floating_network,
3755 created_items,
3756 ),
3757 )
3758 self.assertEqual(
3759 _call_mock_get_free_floating_ip[2][0],
3760 (
3761 self.server,
3762 floating_network,
3763 created_items,
3764 ),
3765 )
3766
3767 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
3768 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3769 mock_create_floating_ip.assert_not_called()
3770 mock_assign_floating_ip.assert_not_called()
3771 self.assertEqual(mock_time.call_count, 3)
3772 self.assertEqual(mock_sleep.call_count, 2)
3773
3774 @patch("time.time")
3775 @patch("time.sleep")
3776 @patch.object(vimconnector, "_create_floating_ip")
3777 @patch.object(vimconnector, "_get_free_floating_ip")
3778 @patch.object(vimconnector, "_assign_floating_ip")
3779 def test_prepare_external_network_for_vm_instance_assign_floating_ip_exception_exit_on_error(
3780 self,
3781 mock_assign_floating_ip,
3782 mock_get_free_floating_ip,
3783 mock_create_floating_ip,
3784 mock_sleep,
3785 mock_time,
3786 ):
3787 """Assign floating ip method gives exception, exit_on_floating_ip_error is set to True.
3788 VM status is in ERROR."""
3789 floating_network = {
3790 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3791 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3792 "exit_on_floating_ip_error": True,
3793 }
3794 external_network = [floating_network]
3795 created_items = {}
3796 vm_start_time = time_return_value
3797
3798 mock_get_free_floating_ip.side_effect = [
3799 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3800 ] * 4
3801
3802 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3803
3804 mock_assign_floating_ip.side_effect = [
3805 Exception("Floating ip could not be assigned.")
3806 ] * 4
3807
3808 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3809 self.vimconn.neutron.show_floatingip.side_effect = [
3810 {"floatingip": {"port_id": ""}}
3811 ] * 4
3812
3813 with self.assertRaises(VimConnException) as err:
3814 self.vimconn._prepare_external_network_for_vminstance(
3815 external_network, self.server, created_items, vm_start_time
3816 )
3817 self.assertEqual(
3818 str(err.exception),
3819 "Cannot create floating_ip: Exception Floating ip could not be assigned.",
3820 )
3821
3822 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3823 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3824 self.assertEqual(
3825 _call_mock_get_free_floating_ip[0][0],
3826 (
3827 self.server,
3828 floating_network,
3829 created_items,
3830 ),
3831 )
3832 self.assertEqual(
3833 _call_mock_get_free_floating_ip[1][0],
3834 (
3835 self.server,
3836 floating_network,
3837 created_items,
3838 ),
3839 )
3840 self.assertEqual(
3841 _call_mock_get_free_floating_ip[2][0],
3842 (
3843 self.server,
3844 floating_network,
3845 created_items,
3846 ),
3847 )
3848
3849 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3850 self.vimconn.neutron.show_floatingip.assert_called_with(
3851 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3852 )
3853 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
3854 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3855 mock_time.assert_not_called()
3856 mock_sleep.assert_not_called()
3857 mock_create_floating_ip.assert_not_called()
3858
3859 @patch("time.time")
3860 @patch("time.sleep")
3861 @patch.object(vimconnector, "_create_floating_ip")
3862 @patch.object(vimconnector, "_get_free_floating_ip")
3863 @patch.object(vimconnector, "_assign_floating_ip")
3864 def test_prepare_external_network_for_vm_instance_empty_external_network_list(
3865 self,
3866 mock_assign_floating_ip,
3867 mock_get_free_floating_ip,
3868 mock_create_floating_ip,
3869 mock_sleep,
3870 mock_time,
3871 ):
3872 """External network list is empty."""
3873 external_network = []
3874 created_items = {}
3875 vm_start_time = time_return_value
3876
3877 self.vimconn._prepare_external_network_for_vminstance(
3878 external_network, self.server, created_items, vm_start_time
3879 )
3880 mock_create_floating_ip.assert_not_called()
3881 mock_time.assert_not_called()
3882 mock_sleep.assert_not_called()
3883 mock_assign_floating_ip.assert_not_called()
3884 mock_get_free_floating_ip.assert_not_called()
3885 self.vimconn.neutron.show.show_floatingip.assert_not_called()
3886 self.vimconn.nova.servers.get.assert_not_called()
3887
3888 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3889 def test_update_port_security_for_vm_instance(self, mock_wait_for_vm):
3890 """no_secured_ports has port and the port has allow-address-pairs."""
3891 no_secured_ports = [(port2_id, "allow-address-pairs")]
3892
3893 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3894
3895 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3896
3897 self.vimconn.neutron.update_port.assert_called_once_with(
3898 port2_id,
3899 {"port": {"allowed_address_pairs": [{"ip_address": "0.0.0.0/0"}]}},
3900 )
3901
3902 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3903 def test_update_port_security_for_vm_instance_no_allowed_address_pairs(
3904 self, mock_wait_for_vm
3905 ):
3906 """no_secured_ports has port and the port does not have allow-address-pairs."""
3907 no_secured_ports = [(port2_id, "something")]
3908
3909 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3910
3911 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3912
3913 self.vimconn.neutron.update_port.assert_called_once_with(
3914 port2_id,
3915 {"port": {"port_security_enabled": False, "security_groups": None}},
3916 )
3917
3918 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3919 def test_update_port_security_for_vm_instance_wait_for_vm_raise_exception(
3920 self, mock_wait_for_vm
3921 ):
3922 """__wait_for_vm raises timeout exception."""
3923 no_secured_ports = [(port2_id, "something")]
3924
3925 mock_wait_for_vm.side_effect = VimConnException("Timeout waiting for instance.")
3926
3927 with self.assertRaises(VimConnException) as err:
3928 self.vimconn._update_port_security_for_vminstance(
3929 no_secured_ports, self.server
3930 )
3931 self.assertEqual(str(err.exception), "Timeout waiting for instance.")
3932
3933 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3934
3935 self.vimconn.neutron.update_port.assert_not_called()
3936
3937 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3938 def test_update_port_security_for_vm_instance_neutron_update_port_raise_exception(
3939 self, mock_wait_for_vm
3940 ):
3941 """neutron_update_port method raises exception."""
3942 no_secured_ports = [(port2_id, "something")]
3943
3944 self.vimconn.neutron.update_port.side_effect = Exception(
3945 "Port security could not be updated."
3946 )
3947
3948 with self.assertRaises(VimConnException) as err:
3949 self.vimconn._update_port_security_for_vminstance(
3950 no_secured_ports, self.server
3951 )
3952 self.assertEqual(
3953 str(err.exception),
3954 "It was not possible to disable port security for port 17472685-f67f-49fd-8722-eabb7692fc22",
3955 )
3956 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3957
3958 self.vimconn.neutron.update_port.assert_called_once_with(
3959 port2_id,
3960 {"port": {"port_security_enabled": False, "security_groups": None}},
3961 )
3962
3963 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3964 def test_update_port_security_for_vm_instance_empty_port_list(
3965 self, mock_wait_for_vm
3966 ):
3967 """no_secured_ports list does not have any ports."""
3968 no_secured_ports = []
3969
3970 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3971
3972 mock_wait_for_vm.assert_not_called()
3973
3974 self.vimconn.neutron.update_port.assert_not_called()
3975
3976 @patch("time.time")
3977 @patch.object(vimconnector, "_reload_connection")
3978 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3979 @patch.object(vimconnector, "_create_user_data")
3980 @patch.object(vimconnector, "_get_vm_availability_zone")
3981 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3982 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3983 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3984 @patch.object(vimconnector, "delete_vminstance")
3985 @patch.object(vimconnector, "_format_exception")
3986 def test_new_vm_instance(
3987 self,
3988 mock_format_exception,
3989 mock_delete_vm_instance,
3990 mock_prepare_external_network,
3991 mock_update_port_security,
3992 mock_prepare_disk_for_vm_instance,
3993 mock_get_vm_availability_zone,
3994 mock_create_user_data,
3995 mock_prepare_network_for_vm_instance,
3996 mock_reload_connection,
3997 mock_time,
3998 ):
3999 """New VM instance creation is successful."""
4000
4001 mock_create_user_data.return_value = True, "userdata"
4002
4003 mock_get_vm_availability_zone.return_value = "nova"
4004
4005 self.vimconn.nova.servers.create.return_value = self.server
4006
4007 mock_time.return_value = time_return_value
4008
4009 expected_result = self.server.id, {}
4010
4011 result = self.vimconn.new_vminstance(
4012 name,
4013 description,
4014 start,
4015 image_id,
4016 flavor_id,
4017 affinity_group_list,
4018 net_list,
4019 cloud_config,
4020 disk_list2,
4021 availability_zone_index,
4022 availability_zone_list,
4023 )
4024 self.assertEqual(result, expected_result)
4025
4026 mock_reload_connection.assert_called_once()
4027 mock_prepare_network_for_vm_instance.assert_called_once_with(
4028 name=name,
4029 net_list=net_list,
4030 created_items={},
4031 net_list_vim=[],
4032 external_network=[],
4033 no_secured_ports=[],
4034 )
4035 mock_create_user_data.assert_called_once_with(cloud_config)
4036 mock_get_vm_availability_zone.assert_called_once_with(
4037 availability_zone_index, availability_zone_list
4038 )
4039 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4040 name=name,
4041 existing_vim_volumes=[],
4042 created_items={},
4043 vm_av_zone="nova",
4044 block_device_mapping={},
4045 disk_list=disk_list2,
4046 )
4047 self.vimconn.nova.servers.create.assert_called_once_with(
4048 name=name,
4049 image=image_id,
4050 flavor=flavor_id,
4051 nics=[],
4052 security_groups="default",
4053 availability_zone="nova",
4054 key_name="my_keypair",
4055 userdata="userdata",
4056 config_drive=True,
4057 block_device_mapping={},
4058 scheduler_hints={},
4059 )
4060 mock_time.assert_called_once()
4061 mock_update_port_security.assert_called_once_with([], self.server)
4062 mock_prepare_external_network.assert_called_once_with(
4063 external_network=[],
4064 server=self.server,
4065 created_items={},
4066 vm_start_time=time_return_value,
4067 )
4068 mock_delete_vm_instance.assert_not_called()
4069 mock_format_exception.assert_not_called()
4070
4071 @patch("time.time")
4072 @patch.object(vimconnector, "_reload_connection")
4073 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4074 @patch.object(vimconnector, "_create_user_data")
4075 @patch.object(vimconnector, "_get_vm_availability_zone")
4076 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4077 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4078 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4079 @patch.object(vimconnector, "delete_vminstance")
4080 @patch.object(vimconnector, "_format_exception")
4081 def test_new_vm_instance_create_user_data_fails(
4082 self,
4083 mock_format_exception,
4084 mock_delete_vm_instance,
4085 mock_prepare_external_network,
4086 mock_update_port_security,
4087 mock_prepare_disk_for_vm_instance,
4088 mock_get_vm_availability_zone,
4089 mock_create_user_data,
4090 mock_prepare_network_for_vm_instance,
4091 mock_reload_connection,
4092 mock_time,
4093 ):
4094 """New VM instance creation failed because of user data creation failure."""
4095
4096 mock_create_user_data.side_effect = Exception(
4097 "User data could not be retrieved."
4098 )
4099
4100 mock_get_vm_availability_zone.return_value = "nova"
4101
4102 self.vimconn.nova.servers.create.return_value = self.server
4103
4104 mock_time.return_value = time_return_value
4105
4106 self.vimconn.new_vminstance(
4107 name,
4108 description,
4109 start,
4110 image_id,
4111 flavor_id,
4112 affinity_group_list,
4113 net_list,
4114 cloud_config,
4115 disk_list,
4116 availability_zone_index,
4117 availability_zone_list,
4118 )
4119
4120 mock_reload_connection.assert_called_once()
4121 mock_prepare_network_for_vm_instance.assert_called_once_with(
4122 name=name,
4123 net_list=net_list,
4124 created_items={},
4125 net_list_vim=[],
4126 external_network=[],
4127 no_secured_ports=[],
4128 )
4129 mock_create_user_data.assert_called_once_with(cloud_config)
4130 mock_get_vm_availability_zone.assert_not_called()
4131 mock_prepare_disk_for_vm_instance.assert_not_called()
4132 self.vimconn.nova.servers.create.assert_not_called()
4133 mock_time.assert_not_called()
4134 mock_update_port_security.assert_not_called()
4135 mock_prepare_external_network.assert_not_called()
4136 mock_delete_vm_instance.assert_called_once_with(None, {})
4137 mock_format_exception.assert_called_once()
4138 arg = mock_format_exception.call_args[0][0]
4139 self.assertEqual(str(arg), "User data could not be retrieved.")
4140
4141 @patch("time.time")
4142 @patch.object(vimconnector, "_reload_connection")
4143 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4144 @patch.object(vimconnector, "_create_user_data")
4145 @patch.object(vimconnector, "_get_vm_availability_zone")
4146 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4147 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4148 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4149 @patch.object(vimconnector, "delete_vminstance")
4150 @patch.object(vimconnector, "_format_exception")
4151 def test_new_vm_instance_external_network_exception(
4152 self,
4153 mock_format_exception,
4154 mock_delete_vm_instance,
4155 mock_prepare_external_network,
4156 mock_update_port_security,
4157 mock_prepare_disk_for_vm_instance,
4158 mock_get_vm_availability_zone,
4159 mock_create_user_data,
4160 mock_prepare_network_for_vm_instance,
4161 mock_reload_connection,
4162 mock_time,
4163 ):
4164 """New VM instance creation, external network connection has failed as floating
4165 ip could not be created."""
4166
4167 mock_create_user_data.return_value = True, "userdata"
4168
4169 mock_get_vm_availability_zone.return_value = "nova"
4170
4171 self.vimconn.nova.servers.create.return_value = self.server
4172
4173 mock_time.return_value = time_return_value
4174
4175 mock_prepare_external_network.side_effect = VimConnException(
4176 "Can not create floating ip."
4177 )
4178
4179 self.vimconn.new_vminstance(
4180 name,
4181 description,
4182 start,
4183 image_id,
4184 flavor_id,
4185 affinity_group_list,
4186 net_list,
4187 cloud_config,
4188 disk_list2,
4189 availability_zone_index,
4190 availability_zone_list,
4191 )
4192
4193 mock_reload_connection.assert_called_once()
4194 mock_prepare_network_for_vm_instance.assert_called_once_with(
4195 name=name,
4196 net_list=net_list,
4197 created_items={},
4198 net_list_vim=[],
4199 external_network=[],
4200 no_secured_ports=[],
4201 )
4202 mock_create_user_data.assert_called_once_with(cloud_config)
4203 mock_get_vm_availability_zone.assert_called_once_with(
4204 availability_zone_index, availability_zone_list
4205 )
4206 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4207 name=name,
4208 existing_vim_volumes=[],
4209 created_items={},
4210 vm_av_zone="nova",
4211 block_device_mapping={},
4212 disk_list=disk_list2,
4213 )
4214 self.vimconn.nova.servers.create.assert_called_once_with(
4215 name=name,
4216 image=image_id,
4217 flavor=flavor_id,
4218 nics=[],
4219 security_groups="default",
4220 availability_zone="nova",
4221 key_name="my_keypair",
4222 userdata="userdata",
4223 config_drive=True,
4224 block_device_mapping={},
4225 scheduler_hints={},
4226 )
4227 mock_time.assert_called_once()
4228 mock_update_port_security.assert_called_once_with([], self.server)
4229 mock_prepare_external_network.assert_called_once_with(
4230 external_network=[],
4231 server=self.server,
4232 created_items={},
4233 vm_start_time=time_return_value,
4234 )
4235 mock_delete_vm_instance.assert_called_once_with(self.server.id, {})
4236 mock_format_exception.assert_called_once()
4237 arg = mock_format_exception.call_args[0][0]
4238 self.assertEqual(str(arg), "Can not create floating ip.")
4239
4240 @patch("time.time")
4241 @patch.object(vimconnector, "_reload_connection")
4242 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4243 @patch.object(vimconnector, "_create_user_data")
4244 @patch.object(vimconnector, "_get_vm_availability_zone")
4245 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4246 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4247 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4248 @patch.object(vimconnector, "delete_vminstance")
4249 @patch.object(vimconnector, "_format_exception")
4250 def test_new_vm_instance_with_affinity_group(
4251 self,
4252 mock_format_exception,
4253 mock_delete_vm_instance,
4254 mock_prepare_external_network,
4255 mock_update_port_security,
4256 mock_prepare_disk_for_vm_instance,
4257 mock_get_vm_availability_zone,
4258 mock_create_user_data,
4259 mock_prepare_network_for_vm_instance,
4260 mock_reload_connection,
4261 mock_time,
4262 ):
4263 """New VM creation with affinity group."""
4264 affinity_group_list = [
4265 {"affinity_group_id": "38b73-e9cc-5a6a-t270-82cc4811bd4a"}
4266 ]
4267 mock_create_user_data.return_value = True, "userdata"
4268 mock_get_vm_availability_zone.return_value = "nova"
4269 self.vimconn.nova.servers.create.return_value = self.server
4270 mock_time.return_value = time_return_value
4271 expected_result = self.server.id, {}
4272
4273 result = self.vimconn.new_vminstance(
4274 name,
4275 description,
4276 start,
4277 image_id,
4278 flavor_id,
4279 affinity_group_list,
4280 net_list,
4281 cloud_config,
4282 disk_list2,
4283 availability_zone_index,
4284 availability_zone_list,
4285 )
4286 self.assertEqual(result, expected_result)
4287
4288 mock_reload_connection.assert_called_once()
4289 mock_prepare_network_for_vm_instance.assert_called_once_with(
4290 name=name,
4291 net_list=net_list,
4292 created_items={},
4293 net_list_vim=[],
4294 external_network=[],
4295 no_secured_ports=[],
4296 )
4297 mock_create_user_data.assert_called_once_with(cloud_config)
4298 mock_get_vm_availability_zone.assert_called_once_with(
4299 availability_zone_index, availability_zone_list
4300 )
4301 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4302 name=name,
4303 existing_vim_volumes=[],
4304 created_items={},
4305 vm_av_zone="nova",
4306 block_device_mapping={},
4307 disk_list=disk_list2,
4308 )
4309 self.vimconn.nova.servers.create.assert_called_once_with(
4310 name=name,
4311 image=image_id,
4312 flavor=flavor_id,
4313 nics=[],
4314 security_groups="default",
4315 availability_zone="nova",
4316 key_name="my_keypair",
4317 userdata="userdata",
4318 config_drive=True,
4319 block_device_mapping={},
4320 scheduler_hints={"group": "38b73-e9cc-5a6a-t270-82cc4811bd4a"},
4321 )
4322 mock_time.assert_called_once()
4323 mock_update_port_security.assert_called_once_with([], self.server)
4324 mock_prepare_external_network.assert_called_once_with(
4325 external_network=[],
4326 server=self.server,
4327 created_items={},
4328 vm_start_time=time_return_value,
4329 )
4330 mock_delete_vm_instance.assert_not_called()
4331 mock_format_exception.assert_not_called()
4332
4333 @patch("time.time")
4334 @patch.object(vimconnector, "_reload_connection")
4335 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4336 @patch.object(vimconnector, "_create_user_data")
4337 @patch.object(vimconnector, "_get_vm_availability_zone")
4338 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4339 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4340 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4341 @patch.object(vimconnector, "delete_vminstance")
4342 @patch.object(vimconnector, "_format_exception")
4343 def test_new_vm_instance_nova_server_create_failed(
4344 self,
4345 mock_format_exception,
4346 mock_delete_vm_instance,
4347 mock_prepare_external_network,
4348 mock_update_port_security,
4349 mock_prepare_disk_for_vm_instance,
4350 mock_get_vm_availability_zone,
4351 mock_create_user_data,
4352 mock_prepare_network_for_vm_instance,
4353 mock_reload_connection,
4354 mock_time,
4355 ):
4356 """New VM(server) creation failed."""
4357
4358 mock_create_user_data.return_value = True, "userdata"
4359
4360 mock_get_vm_availability_zone.return_value = "nova"
4361
4362 self.vimconn.nova.servers.create.side_effect = Exception(
4363 "Server could not be created."
4364 )
4365
4366 mock_time.return_value = time_return_value
4367
4368 self.vimconn.new_vminstance(
4369 name,
4370 description,
4371 start,
4372 image_id,
4373 flavor_id,
4374 affinity_group_list,
4375 net_list,
4376 cloud_config,
4377 disk_list2,
4378 availability_zone_index,
4379 availability_zone_list,
4380 )
4381
4382 mock_reload_connection.assert_called_once()
4383 mock_prepare_network_for_vm_instance.assert_called_once_with(
4384 name=name,
4385 net_list=net_list,
4386 created_items={},
4387 net_list_vim=[],
4388 external_network=[],
4389 no_secured_ports=[],
4390 )
4391 mock_create_user_data.assert_called_once_with(cloud_config)
4392 mock_get_vm_availability_zone.assert_called_once_with(
4393 availability_zone_index, availability_zone_list
4394 )
4395 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4396 name=name,
4397 existing_vim_volumes=[],
4398 created_items={},
4399 vm_av_zone="nova",
4400 block_device_mapping={},
4401 disk_list=disk_list2,
4402 )
4403
4404 self.vimconn.nova.servers.create.assert_called_once_with(
4405 name=name,
4406 image=image_id,
4407 flavor=flavor_id,
4408 nics=[],
4409 security_groups="default",
4410 availability_zone="nova",
4411 key_name="my_keypair",
4412 userdata="userdata",
4413 config_drive=True,
4414 block_device_mapping={},
4415 scheduler_hints={},
4416 )
4417 mock_time.assert_not_called()
4418 mock_update_port_security.assert_not_called()
4419 mock_prepare_external_network.assert_not_called()
4420 mock_delete_vm_instance.assert_called_once_with(None, {})
4421 mock_format_exception.assert_called_once()
4422 arg = mock_format_exception.call_args[0][0]
4423 self.assertEqual(str(arg), "Server could not be created.")
4424
4425 @patch("time.time")
4426 @patch.object(vimconnector, "_reload_connection")
4427 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4428 @patch.object(vimconnector, "_create_user_data")
4429 @patch.object(vimconnector, "_get_vm_availability_zone")
4430 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4431 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4432 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4433 @patch.object(vimconnector, "delete_vminstance")
4434 @patch.object(vimconnector, "_format_exception")
4435 def test_new_vm_instance_connection_exception(
4436 self,
4437 mock_format_exception,
4438 mock_delete_vm_instance,
4439 mock_prepare_external_network,
4440 mock_update_port_security,
4441 mock_prepare_disk_for_vm_instance,
4442 mock_get_vm_availability_zone,
4443 mock_create_user_data,
4444 mock_prepare_network_for_vm_instance,
4445 mock_reload_connection,
4446 mock_time,
4447 ):
4448 """Connection to Cloud API has failed."""
4449 mock_reload_connection.side_effect = Exception("Can not connect to Cloud APIs.")
4450 mock_create_user_data.return_value = True, "userdata"
4451 mock_get_vm_availability_zone.return_value = "nova"
4452 self.vimconn.nova.servers.create.return_value = self.server
4453 mock_time.return_value = time_return_value
4454
4455 self.vimconn.new_vminstance(
4456 name,
4457 description,
4458 start,
4459 image_id,
4460 flavor_id,
4461 affinity_group_list,
4462 net_list,
4463 cloud_config,
4464 disk_list,
4465 availability_zone_index,
4466 availability_zone_list,
4467 )
4468 mock_format_exception.assert_called_once()
4469 arg = mock_format_exception.call_args[0][0]
4470 self.assertEqual(str(arg), "Can not connect to Cloud APIs.")
4471 mock_reload_connection.assert_called_once()
4472 mock_prepare_network_for_vm_instance.assert_not_called()
4473 mock_create_user_data.assert_not_called()
4474 mock_get_vm_availability_zone.assert_not_called()
4475 mock_prepare_disk_for_vm_instance.assert_not_called()
4476 self.vimconn.nova.servers.create.assert_not_called()
4477 mock_time.assert_not_called()
4478 mock_update_port_security.assert_not_called()
4479 mock_prepare_external_network.assert_not_called()
4480 mock_delete_vm_instance.assert_called_once_with(None, {})
4481
4482
4483 if __name__ == "__main__":
4484 unittest.main()