1"""
2:codeauthor: Alexandru Bleotu <alexandru.bleotu@morganstanley.com>
3
4Tests for cluster related functions in salt.utils.vmware
5"""
6
7import base64
8import logging
9import ssl
10
11import salt.utils.vmware
12from salt.exceptions import (
13    ArgumentValueError,
14    CommandExecutionError,
15    VMwareApiError,
16    VMwareConnectionError,
17    VMwareObjectRetrievalError,
18    VMwareRuntimeError,
19    VMwareSystemError,
20)
21from tests.support.mixins import LoaderModuleMockMixin
22from tests.support.mock import MagicMock, PropertyMock, call, patch
23from tests.support.unit import TestCase, skipIf
24
25try:
26    from pyVmomi import vim, vmodl  # pylint: disable=no-name-in-module
27
28    HAS_PYVMOMI = True
29except ImportError:
30    HAS_PYVMOMI = False
31
32try:
33    import gssapi
34
35    HAS_GSSAPI = True
36except ImportError:
37    HAS_GSSAPI = False
38
39log = logging.getLogger(__name__)
40
41
42@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
43class GetClusterTestCase(TestCase):
44    """
45    Tests for salt.utils.vmware.get_cluster
46    """
47
48    def setUp(self):
49        patches = (
50            ("salt.utils.vmware.get_managed_object_name", MagicMock()),
51            ("salt.utils.vmware.get_service_instance_from_managed_object", MagicMock()),
52            (
53                "salt.utils.vmware.get_mors_with_properties",
54                MagicMock(
55                    return_value=[{"name": "fake_cluster", "object": MagicMock()}]
56                ),
57            ),
58        )
59        for mod, mock in patches:
60            patcher = patch(mod, mock)
61            patcher.start()
62            self.addCleanup(patcher.stop)
63        self.mock_si = MagicMock()
64        self.mock_dc = MagicMock()
65        self.mock_cluster1 = MagicMock()
66        self.mock_cluster2 = MagicMock()
67        self.mock_entries = [
68            {"name": "fake_cluster1", "object": self.mock_cluster1},
69            {"name": "fake_cluster2", "object": self.mock_cluster2},
70        ]
71        for attr in (
72            "mock_si",
73            "mock_dc",
74            "mock_cluster1",
75            "mock_cluster2",
76            "mock_entries",
77        ):
78            self.addCleanup(delattr, self, attr)
79
80    def test_get_managed_object_name_call(self):
81        mock_get_managed_object_name = MagicMock()
82        with patch(
83            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
84        ):
85            salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
86        mock_get_managed_object_name.assert_called_once_with(self.mock_dc)
87
88    def test_get_service_instance_from_managed_object(self):
89        mock_dc_name = MagicMock()
90        mock_get_service_instance_from_managed_object = MagicMock()
91        with patch(
92            "salt.utils.vmware.get_managed_object_name",
93            MagicMock(return_value=mock_dc_name),
94        ):
95            with patch(
96                "salt.utils.vmware.get_service_instance_from_managed_object",
97                mock_get_service_instance_from_managed_object,
98            ):
99
100                salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
101        mock_get_service_instance_from_managed_object.assert_called_once_with(
102            self.mock_dc, name=mock_dc_name
103        )
104
105    def test_traversal_spec_init(self):
106        mock_dc_name = MagicMock()
107        mock_traversal_spec = MagicMock()
108        mock_traversal_spec_ini = MagicMock(return_value=mock_traversal_spec)
109        mock_get_service_instance_from_managed_object = MagicMock()
110        patch_traversal_spec_str = (
111            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec"
112        )
113
114        with patch(patch_traversal_spec_str, mock_traversal_spec_ini):
115            salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
116        mock_traversal_spec_ini.assert_has_calls(
117            [
118                call(path="childEntity", skip=False, type=vim.Folder),
119                call(
120                    path="hostFolder",
121                    skip=True,
122                    type=vim.Datacenter,
123                    selectSet=[mock_traversal_spec],
124                ),
125            ]
126        )
127
128    def test_get_mors_with_properties_call(self):
129        mock_get_mors_with_properties = MagicMock(
130            return_value=[{"name": "fake_cluster", "object": MagicMock()}]
131        )
132        mock_traversal_spec = MagicMock()
133        patch_traversal_spec_str = (
134            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec"
135        )
136        with patch(
137            "salt.utils.vmware.get_service_instance_from_managed_object",
138            MagicMock(return_value=self.mock_si),
139        ):
140
141            with patch(
142                "salt.utils.vmware.get_mors_with_properties",
143                mock_get_mors_with_properties,
144            ):
145                with patch(
146                    patch_traversal_spec_str,
147                    MagicMock(return_value=mock_traversal_spec),
148                ):
149
150                    salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
151        mock_get_mors_with_properties.assert_called_once_with(
152            self.mock_si,
153            vim.ClusterComputeResource,
154            container_ref=self.mock_dc,
155            property_list=["name"],
156            traversal_spec=mock_traversal_spec,
157        )
158
159    def test_get_mors_with_properties_returns_empty_array(self):
160        with patch(
161            "salt.utils.vmware.get_managed_object_name",
162            MagicMock(return_value="fake_dc"),
163        ):
164            with patch(
165                "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
166            ):
167                with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
168                    salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
169        self.assertEqual(
170            excinfo.exception.strerror,
171            "Cluster 'fake_cluster' was not found in datacenter 'fake_dc'",
172        )
173
174    def test_cluster_not_found(self):
175        with patch(
176            "salt.utils.vmware.get_managed_object_name",
177            MagicMock(return_value="fake_dc"),
178        ):
179            with patch(
180                "salt.utils.vmware.get_mors_with_properties",
181                MagicMock(return_value=self.mock_entries),
182            ):
183                with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
184                    salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster")
185        self.assertEqual(
186            excinfo.exception.strerror,
187            "Cluster 'fake_cluster' was not found in datacenter 'fake_dc'",
188        )
189
190    def test_cluster_found(self):
191        with patch(
192            "salt.utils.vmware.get_managed_object_name",
193            MagicMock(return_value="fake_dc"),
194        ):
195            with patch(
196                "salt.utils.vmware.get_mors_with_properties",
197                MagicMock(return_value=self.mock_entries),
198            ):
199                res = salt.utils.vmware.get_cluster(self.mock_dc, "fake_cluster2")
200        self.assertEqual(res, self.mock_cluster2)
201
202
203@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
204class CreateClusterTestCase(TestCase):
205    """
206    Tests for salt.utils.vmware.create_cluster
207    """
208
209    def setUp(self):
210        patches = (("salt.utils.vmware.get_managed_object_name", MagicMock()),)
211        for mod, mock in patches:
212            patcher = patch(mod, mock)
213            patcher.start()
214            self.addCleanup(patcher.stop)
215        self.mock_create_cluster_ex = MagicMock()
216        self.mock_dc = MagicMock(
217            hostFolder=MagicMock(CreateClusterEx=self.mock_create_cluster_ex)
218        )
219        self.mock_cluster_spec = MagicMock()
220        for attr in ("mock_create_cluster_ex", "mock_dc", "mock_cluster_spec"):
221            self.addCleanup(delattr, self, attr)
222
223    def test_get_managed_object_name(self):
224        mock_get_managed_object_name = MagicMock()
225        with patch(
226            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
227        ):
228            salt.utils.vmware.create_cluster(
229                self.mock_dc, "fake_cluster", self.mock_cluster_spec
230            )
231        mock_get_managed_object_name.assert_called_once_with(self.mock_dc)
232
233    def test_create_cluster_call(self):
234        salt.utils.vmware.create_cluster(
235            self.mock_dc, "fake_cluster", self.mock_cluster_spec
236        )
237        self.mock_create_cluster_ex.assert_called_once_with(
238            "fake_cluster", self.mock_cluster_spec
239        )
240
241    def test_create_cluster_raise_no_permission(self):
242        exc = vim.fault.NoPermission()
243        exc.privilegeId = "Fake privilege"
244        self.mock_dc.hostFolder.CreateClusterEx = MagicMock(side_effect=exc)
245        with self.assertRaises(VMwareApiError) as excinfo:
246            salt.utils.vmware.create_cluster(
247                self.mock_dc, "fake_cluster", self.mock_cluster_spec
248            )
249        self.assertEqual(
250            excinfo.exception.strerror,
251            "Not enough permissions. Required privilege: Fake privilege",
252        )
253
254    def test_create_cluster_raise_vim_fault(self):
255        exc = vim.fault.VimFault()
256        exc.msg = "VimFault msg"
257        self.mock_dc.hostFolder.CreateClusterEx = MagicMock(side_effect=exc)
258        with self.assertRaises(VMwareApiError) as excinfo:
259            salt.utils.vmware.create_cluster(
260                self.mock_dc, "fake_cluster", self.mock_cluster_spec
261            )
262        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
263
264    def test_create_cluster_raise_runtime_fault(self):
265        exc = vmodl.RuntimeFault()
266        exc.msg = "RuntimeFault msg"
267        self.mock_dc.hostFolder.CreateClusterEx = MagicMock(side_effect=exc)
268        with self.assertRaises(VMwareRuntimeError) as excinfo:
269            salt.utils.vmware.create_cluster(
270                self.mock_dc, "fake_cluster", self.mock_cluster_spec
271            )
272        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
273
274
275@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
276class UpdateClusterTestCase(TestCase):
277    """
278    Tests for salt.utils.vmware.update_cluster
279    """
280
281    def setUp(self):
282        patches = (
283            ("salt.utils.vmware.get_managed_object_name", MagicMock()),
284            ("salt.utils.vmware.wait_for_task", MagicMock()),
285        )
286        for mod, mock in patches:
287            patcher = patch(mod, mock)
288            patcher.start()
289            self.addCleanup(patcher.stop)
290        self.mock_task = MagicMock()
291        self.mock_reconfigure_compute_resource_task = MagicMock(
292            return_value=self.mock_task
293        )
294        self.mock_cluster = MagicMock(
295            ReconfigureComputeResource_Task=self.mock_reconfigure_compute_resource_task
296        )
297        self.mock_cluster_spec = MagicMock()
298        for attr in (
299            "mock_task",
300            "mock_reconfigure_compute_resource_task",
301            "mock_cluster",
302            "mock_cluster_spec",
303        ):
304            self.addCleanup(delattr, self, attr)
305
306    def test_get_managed_object_name(self):
307        mock_get_managed_object_name = MagicMock()
308        with patch(
309            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
310        ):
311            salt.utils.vmware.update_cluster(self.mock_cluster, self.mock_cluster_spec)
312        mock_get_managed_object_name.assert_called_once_with(self.mock_cluster)
313
314    def test_reconfigure_compute_resource_task_call(self):
315        salt.utils.vmware.update_cluster(self.mock_cluster, self.mock_cluster_spec)
316        self.mock_reconfigure_compute_resource_task.assert_called_once_with(
317            self.mock_cluster_spec, modify=True
318        )
319
320    def test_reconfigure_compute_resource_raise_no_permission(self):
321        exc = vim.fault.NoPermission()
322        exc.privilegeId = "Fake privilege"
323        self.mock_cluster.ReconfigureComputeResource_Task = MagicMock(side_effect=exc)
324        with self.assertRaises(VMwareApiError) as excinfo:
325            salt.utils.vmware.update_cluster(self.mock_cluster, self.mock_cluster_spec)
326        self.assertEqual(
327            excinfo.exception.strerror,
328            "Not enough permissions. Required privilege: Fake privilege",
329        )
330
331    def test_reconfigure_compute_resource_raise_vim_fault(self):
332        exc = vim.fault.VimFault()
333        exc.msg = "VimFault msg"
334        self.mock_cluster.ReconfigureComputeResource_Task = MagicMock(side_effect=exc)
335        with self.assertRaises(VMwareApiError) as excinfo:
336            salt.utils.vmware.update_cluster(self.mock_cluster, self.mock_cluster_spec)
337        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
338
339    def test_reconfigure_compute_resource_raise_runtime_fault(self):
340        exc = vmodl.RuntimeFault()
341        exc.msg = "RuntimeFault msg"
342        self.mock_cluster.ReconfigureComputeResource_Task = MagicMock(side_effect=exc)
343        with self.assertRaises(VMwareRuntimeError) as excinfo:
344            salt.utils.vmware.update_cluster(self.mock_cluster, self.mock_cluster_spec)
345        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
346
347    def test_wait_for_task_call(self):
348        mock_wait_for_task = MagicMock()
349        with patch(
350            "salt.utils.vmware.get_managed_object_name",
351            MagicMock(return_value="fake_cluster"),
352        ):
353            with patch("salt.utils.vmware.wait_for_task", mock_wait_for_task):
354                salt.utils.vmware.update_cluster(
355                    self.mock_cluster, self.mock_cluster_spec
356                )
357        mock_wait_for_task.assert_called_once_with(
358            self.mock_task, "fake_cluster", "ClusterUpdateTask"
359        )
360
361
362@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
363class WaitForTaskTestCase(TestCase):
364    """
365    Tests for salt.utils.vmware.wait_for_task
366    """
367
368    def setUp(self):
369        patches = (
370            ("salt.utils.vmware.time.time", MagicMock(return_value=1)),
371            ("salt.utils.vmware.time.sleep", MagicMock(return_value=None)),
372        )
373        for mod, mock in patches:
374            patcher = patch(mod, mock)
375            patcher.start()
376            self.addCleanup(patcher.stop)
377
378    def test_first_task_info_raise_no_permission(self):
379        exc = vim.fault.NoPermission()
380        exc.privilegeId = "Fake privilege"
381        mock_task = MagicMock()
382        type(mock_task).info = PropertyMock(side_effect=exc)
383        with self.assertRaises(VMwareApiError) as excinfo:
384            salt.utils.vmware.wait_for_task(
385                mock_task, "fake_instance_name", "task_type"
386            )
387        self.assertEqual(
388            excinfo.exception.strerror,
389            "Not enough permissions. Required privilege: Fake privilege",
390        )
391
392    def test_first_task_info_raise_vim_fault(self):
393        exc = vim.fault.VimFault()
394        exc.msg = "VimFault msg"
395        mock_task = MagicMock()
396        type(mock_task).info = PropertyMock(side_effect=exc)
397        with self.assertRaises(VMwareApiError) as excinfo:
398            salt.utils.vmware.wait_for_task(
399                mock_task, "fake_instance_name", "task_type"
400            )
401        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
402
403    def test_first_task_info_raise_runtime_fault(self):
404        exc = vmodl.RuntimeFault()
405        exc.msg = "RuntimeFault msg"
406        mock_task = MagicMock()
407        type(mock_task).info = PropertyMock(side_effect=exc)
408        with self.assertRaises(VMwareRuntimeError) as excinfo:
409            salt.utils.vmware.wait_for_task(
410                mock_task, "fake_instance_name", "task_type"
411            )
412        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
413
414    def test_inner_loop_task_info_raise_no_permission(self):
415        exc = vim.fault.NoPermission()
416        exc.privilegeId = "Fake privilege"
417        mock_task = MagicMock()
418        mock_info1 = MagicMock()
419        type(mock_task).info = PropertyMock(side_effect=[mock_info1, exc])
420        type(mock_info1).state = PropertyMock(side_effect=["running", "bad"])
421        with self.assertRaises(VMwareApiError) as excinfo:
422            salt.utils.vmware.wait_for_task(
423                mock_task, "fake_instance_name", "task_type"
424            )
425        self.assertEqual(
426            excinfo.exception.strerror,
427            "Not enough permissions. Required privilege: Fake privilege",
428        )
429
430    def test_inner_loop_task_info_raise_vim_fault(self):
431        exc = vim.fault.VimFault()
432        exc.msg = "VimFault msg"
433        mock_task = MagicMock()
434        mock_info1 = MagicMock()
435        type(mock_task).info = PropertyMock(side_effect=[mock_info1, exc])
436        type(mock_info1).state = PropertyMock(side_effect=["running", "bad"])
437        with self.assertRaises(VMwareApiError) as excinfo:
438            salt.utils.vmware.wait_for_task(
439                mock_task, "fake_instance_name", "task_type"
440            )
441        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
442
443    def test_inner_loop_task_info_raise_runtime_fault(self):
444        exc = vmodl.RuntimeFault()
445        exc.msg = "RuntimeFault msg"
446        mock_task = MagicMock()
447        mock_info1 = MagicMock()
448        type(mock_task).info = PropertyMock(side_effect=[mock_info1, exc])
449        type(mock_info1).state = PropertyMock(side_effect=["running", "bad"])
450        with self.assertRaises(VMwareRuntimeError) as excinfo:
451            salt.utils.vmware.wait_for_task(
452                mock_task, "fake_instance_name", "task_type"
453            )
454        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
455
456    def test_info_state_running(self):
457        # The 'bad' values are invalid in the while loop
458        mock_task = MagicMock()
459        prop_mock_state = PropertyMock(side_effect=["running", "bad", "bad", "success"])
460        prop_mock_result = PropertyMock()
461        type(mock_task.info).state = prop_mock_state
462        type(mock_task.info).result = prop_mock_result
463        salt.utils.vmware.wait_for_task(mock_task, "fake_instance_name", "task_type")
464        self.assertEqual(prop_mock_state.call_count, 4)
465        self.assertEqual(prop_mock_result.call_count, 1)
466
467    def test_info_state_running_continues_loop(self):
468        mock_task = MagicMock()
469        # The 'fake' values are required to match all the lookups and end the
470        # loop
471        prop_mock_state = PropertyMock(
472            side_effect=["running", "fake", "fake", "success"]
473        )
474        prop_mock_result = PropertyMock()
475        type(mock_task.info).state = prop_mock_state
476        type(mock_task.info).result = prop_mock_result
477        salt.utils.vmware.wait_for_task(mock_task, "fake_instance_name", "task_type")
478        self.assertEqual(prop_mock_state.call_count, 4)
479        self.assertEqual(prop_mock_result.call_count, 1)
480
481    def test_info_state_queued_continues_loop(self):
482        mock_task = MagicMock()
483        # The 'fake' values are required to match all the lookups and end the
484        # loop
485        prop_mock_state = PropertyMock(
486            side_effect=["fake", "queued", "fake", "fake", "success"]
487        )
488        prop_mock_result = PropertyMock()
489        type(mock_task.info).state = prop_mock_state
490        type(mock_task.info).result = prop_mock_result
491        salt.utils.vmware.wait_for_task(mock_task, "fake_instance_name", "task_type")
492        self.assertEqual(prop_mock_state.call_count, 5)
493        self.assertEqual(prop_mock_result.call_count, 1)
494
495    def test_info_state_success(self):
496        mock_task = MagicMock()
497        prop_mock_state = PropertyMock(return_value="success")
498        prop_mock_result = PropertyMock()
499        type(mock_task.info).state = prop_mock_state
500        type(mock_task.info).result = prop_mock_result
501        salt.utils.vmware.wait_for_task(mock_task, "fake_instance_name", "task_type")
502        self.assertEqual(prop_mock_state.call_count, 3)
503        self.assertEqual(prop_mock_result.call_count, 1)
504
505    def test_info_error_exception(self):
506        mock_task = MagicMock()
507        prop_mock_state = PropertyMock(return_value="error")
508        prop_mock_error = PropertyMock(side_effect=Exception("error exc"))
509        type(mock_task.info).state = prop_mock_state
510        type(mock_task.info).error = prop_mock_error
511        with self.assertRaises(Exception) as excinfo:
512            salt.utils.vmware.wait_for_task(
513                mock_task, "fake_instance_name", "task_type"
514            )
515        self.assertEqual(str(excinfo.exception), "error exc")
516
517    def test_info_error_no_permission(self):
518        exc = vim.fault.NoPermission()
519        exc.privilegeId = "Fake privilege"
520        mock_task = MagicMock()
521        prop_mock_state = PropertyMock(return_value="error")
522        prop_mock_error = PropertyMock(side_effect=exc)
523        type(mock_task.info).state = prop_mock_state
524        type(mock_task.info).error = prop_mock_error
525        with self.assertRaises(VMwareApiError) as excinfo:
526            salt.utils.vmware.wait_for_task(
527                mock_task, "fake_instance_name", "task_type"
528            )
529        self.assertEqual(
530            excinfo.exception.strerror,
531            "Not enough permissions. Required privilege: Fake privilege",
532        )
533
534    def test_info_error_vim_fault(self):
535        exc = vim.fault.VimFault()
536        exc.msg = "VimFault msg"
537        mock_task = MagicMock()
538        prop_mock_state = PropertyMock(return_value="error")
539        prop_mock_error = PropertyMock(side_effect=exc)
540        type(mock_task.info).state = prop_mock_state
541        type(mock_task.info).error = prop_mock_error
542        with self.assertRaises(VMwareApiError) as excinfo:
543            salt.utils.vmware.wait_for_task(
544                mock_task, "fake_instance_name", "task_type"
545            )
546        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
547
548    def test_info_error_system_fault(self):
549        exc = vmodl.fault.SystemError()
550        exc.msg = "SystemError msg"
551        mock_task = MagicMock()
552        prop_mock_state = PropertyMock(return_value="error")
553        prop_mock_error = PropertyMock(side_effect=exc)
554        type(mock_task.info).state = prop_mock_state
555        type(mock_task.info).error = prop_mock_error
556        with self.assertRaises(VMwareSystemError) as excinfo:
557            salt.utils.vmware.wait_for_task(
558                mock_task, "fake_instance_name", "task_type"
559            )
560        self.assertEqual(excinfo.exception.strerror, "SystemError msg")
561
562    def test_info_error_invalid_argument_no_fault_message(self):
563        exc = vmodl.fault.InvalidArgument()
564        exc.faultMessage = None
565        exc.msg = "InvalidArgumentFault msg"
566        mock_task = MagicMock()
567        prop_mock_state = PropertyMock(return_value="error")
568        prop_mock_error = PropertyMock(side_effect=exc)
569        type(mock_task.info).state = prop_mock_state
570        type(mock_task.info).error = prop_mock_error
571        with self.assertRaises(VMwareApiError) as excinfo:
572            salt.utils.vmware.wait_for_task(
573                mock_task, "fake_instance_name", "task_type"
574            )
575        self.assertEqual(excinfo.exception.strerror, "InvalidArgumentFault msg")
576
577    def test_info_error_invalid_argument_with_fault_message(self):
578        exc = vmodl.fault.InvalidArgument()
579        fault_message = vim.LocalizableMessage()
580        fault_message.message = "LocalFault msg"
581        exc.faultMessage = [fault_message]
582        exc.msg = "InvalidArgumentFault msg"
583        mock_task = MagicMock()
584        prop_mock_state = PropertyMock(return_value="error")
585        prop_mock_error = PropertyMock(side_effect=exc)
586        type(mock_task.info).state = prop_mock_state
587        type(mock_task.info).error = prop_mock_error
588        with self.assertRaises(VMwareApiError) as excinfo:
589            salt.utils.vmware.wait_for_task(
590                mock_task, "fake_instance_name", "task_type"
591            )
592        self.assertEqual(
593            excinfo.exception.strerror, "InvalidArgumentFault msg (LocalFault msg)"
594        )
595
596
597@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
598class GetMorsWithPropertiesTestCase(TestCase):
599    """
600    Tests for salt.utils.get_mors_with_properties
601    """
602
603    si = None
604    obj_type = None
605    prop_list = None
606    container_ref = None
607    traversal_spec = None
608
609    def setUp(self):
610        self.si = MagicMock()
611        self.obj_type = MagicMock()
612        self.prop_list = MagicMock()
613        self.container_ref = MagicMock()
614        self.traversal_spec = MagicMock()
615
616    def test_empty_content(self):
617        get_content = MagicMock(return_value=[])
618        with patch("salt.utils.vmware.get_content", get_content):
619            ret = salt.utils.vmware.get_mors_with_properties(
620                self.si,
621                self.obj_type,
622                self.prop_list,
623                self.container_ref,
624                self.traversal_spec,
625            )
626        get_content.assert_called_once_with(
627            self.si,
628            self.obj_type,
629            property_list=self.prop_list,
630            container_ref=self.container_ref,
631            traversal_spec=self.traversal_spec,
632            local_properties=False,
633        )
634        self.assertEqual(ret, [])
635
636    def test_local_properties_set(self):
637        obj_mock = MagicMock()
638        # obj.propSet
639        propSet_prop = PropertyMock(return_value=[])
640        type(obj_mock).propSet = propSet_prop
641        # obj.obj
642        inner_obj_mock = MagicMock()
643        obj_prop = PropertyMock(return_value=inner_obj_mock)
644        type(obj_mock).obj = obj_prop
645
646        get_content = MagicMock(return_value=[obj_mock])
647        with patch("salt.utils.vmware.get_content", get_content):
648            ret = salt.utils.vmware.get_mors_with_properties(
649                self.si,
650                self.obj_type,
651                self.prop_list,
652                self.container_ref,
653                self.traversal_spec,
654                local_properties=True,
655            )
656        get_content.assert_called_once_with(
657            self.si,
658            self.obj_type,
659            property_list=self.prop_list,
660            container_ref=self.container_ref,
661            traversal_spec=self.traversal_spec,
662            local_properties=True,
663        )
664
665    def test_one_element_content(self):
666        obj_mock = MagicMock()
667        # obj.propSet
668        propSet_prop = PropertyMock(return_value=[])
669        type(obj_mock).propSet = propSet_prop
670        # obj.obj
671        inner_obj_mock = MagicMock()
672        obj_prop = PropertyMock(return_value=inner_obj_mock)
673        type(obj_mock).obj = obj_prop
674        get_content = MagicMock(return_value=[obj_mock])
675        with patch("salt.utils.vmware.get_content", get_content):
676            ret = salt.utils.vmware.get_mors_with_properties(
677                self.si,
678                self.obj_type,
679                self.prop_list,
680                self.container_ref,
681                self.traversal_spec,
682            )
683            get_content.assert_called_once_with(
684                self.si,
685                self.obj_type,
686                property_list=self.prop_list,
687                container_ref=self.container_ref,
688                traversal_spec=self.traversal_spec,
689                local_properties=False,
690            )
691        self.assertEqual(propSet_prop.call_count, 1)
692        self.assertEqual(obj_prop.call_count, 1)
693        self.assertEqual(len(ret), 1)
694        self.assertDictEqual(ret[0], {"object": inner_obj_mock})
695
696    def test_multiple_element_content(self):
697        # obj1
698        obj1_mock = MagicMock()
699        # obj1.propSet
700        obj1_propSet_prop = PropertyMock(return_value=[])
701        type(obj1_mock).propSet = obj1_propSet_prop
702        # obj1.obj
703        obj1_inner_obj_mock = MagicMock()
704        obj1_obj_prop = PropertyMock(return_value=obj1_inner_obj_mock)
705        type(obj1_mock).obj = obj1_obj_prop
706        # obj2
707        obj2_mock = MagicMock()
708        # obj2.propSet
709        obj2_propSet_prop = PropertyMock(return_value=[])
710        type(obj2_mock).propSet = obj2_propSet_prop
711        # obj2.obj
712        obj2_inner_obj_mock = MagicMock()
713        obj2_obj_prop = PropertyMock(return_value=obj2_inner_obj_mock)
714        type(obj2_mock).obj = obj2_obj_prop
715
716        get_content = MagicMock(return_value=[obj1_mock, obj2_mock])
717        with patch("salt.utils.vmware.get_content", get_content):
718            ret = salt.utils.vmware.get_mors_with_properties(
719                self.si,
720                self.obj_type,
721                self.prop_list,
722                self.container_ref,
723                self.traversal_spec,
724            )
725        get_content.assert_called_once_with(
726            self.si,
727            self.obj_type,
728            property_list=self.prop_list,
729            container_ref=self.container_ref,
730            traversal_spec=self.traversal_spec,
731            local_properties=False,
732        )
733        self.assertEqual(obj1_propSet_prop.call_count, 1)
734        self.assertEqual(obj2_propSet_prop.call_count, 1)
735        self.assertEqual(obj1_obj_prop.call_count, 1)
736        self.assertEqual(obj2_obj_prop.call_count, 1)
737        self.assertEqual(len(ret), 2)
738        self.assertDictEqual(ret[0], {"object": obj1_inner_obj_mock})
739        self.assertDictEqual(ret[1], {"object": obj2_inner_obj_mock})
740
741    def test_one_elem_one_property(self):
742        obj_mock = MagicMock()
743
744        # property mock
745        prop_set_obj_mock = MagicMock()
746        prop_set_obj_name_prop = PropertyMock(return_value="prop_name")
747        prop_set_obj_val_prop = PropertyMock(return_value="prop_value")
748        type(prop_set_obj_mock).name = prop_set_obj_name_prop
749        type(prop_set_obj_mock).val = prop_set_obj_val_prop
750
751        # obj.propSet
752        propSet_prop = PropertyMock(return_value=[prop_set_obj_mock])
753        type(obj_mock).propSet = propSet_prop
754
755        # obj.obj
756        inner_obj_mock = MagicMock()
757        obj_prop = PropertyMock(return_value=inner_obj_mock)
758        type(obj_mock).obj = obj_prop
759
760        get_content = MagicMock(return_value=[obj_mock])
761        with patch("salt.utils.vmware.get_content", get_content):
762            ret = salt.utils.vmware.get_mors_with_properties(
763                self.si,
764                self.obj_type,
765                self.prop_list,
766                self.container_ref,
767                self.traversal_spec,
768                local_properties=False,
769            )
770        get_content.assert_called_once_with(
771            self.si,
772            self.obj_type,
773            property_list=self.prop_list,
774            container_ref=self.container_ref,
775            traversal_spec=self.traversal_spec,
776            local_properties=False,
777        )
778        self.assertEqual(propSet_prop.call_count, 1)
779        self.assertEqual(prop_set_obj_name_prop.call_count, 1)
780        self.assertEqual(prop_set_obj_val_prop.call_count, 1)
781        self.assertEqual(obj_prop.call_count, 1)
782        self.assertEqual(len(ret), 1)
783        self.assertDictEqual(
784            ret[0], {"prop_name": "prop_value", "object": inner_obj_mock}
785        )
786
787    def test_one_elem_multiple_properties(self):
788        obj_mock = MagicMock()
789
790        # property1  mock
791        prop_set_obj1_mock = MagicMock()
792        prop_set_obj1_name_prop = PropertyMock(return_value="prop_name1")
793        prop_set_obj1_val_prop = PropertyMock(return_value="prop_value1")
794        type(prop_set_obj1_mock).name = prop_set_obj1_name_prop
795        type(prop_set_obj1_mock).val = prop_set_obj1_val_prop
796
797        # property2  mock
798        prop_set_obj2_mock = MagicMock()
799        prop_set_obj2_name_prop = PropertyMock(return_value="prop_name2")
800        prop_set_obj2_val_prop = PropertyMock(return_value="prop_value2")
801        type(prop_set_obj2_mock).name = prop_set_obj2_name_prop
802        type(prop_set_obj2_mock).val = prop_set_obj2_val_prop
803
804        # obj.propSet
805        propSet_prop = PropertyMock(
806            return_value=[prop_set_obj1_mock, prop_set_obj2_mock]
807        )
808        type(obj_mock).propSet = propSet_prop
809
810        # obj.obj
811        inner_obj_mock = MagicMock()
812        obj_prop = PropertyMock(return_value=inner_obj_mock)
813        type(obj_mock).obj = obj_prop
814
815        get_content = MagicMock(return_value=[obj_mock])
816        with patch("salt.utils.vmware.get_content", get_content):
817            ret = salt.utils.vmware.get_mors_with_properties(
818                self.si,
819                self.obj_type,
820                self.prop_list,
821                self.container_ref,
822                self.traversal_spec,
823            )
824        get_content.assert_called_once_with(
825            self.si,
826            self.obj_type,
827            property_list=self.prop_list,
828            container_ref=self.container_ref,
829            traversal_spec=self.traversal_spec,
830            local_properties=False,
831        )
832        self.assertEqual(propSet_prop.call_count, 1)
833        self.assertEqual(prop_set_obj1_name_prop.call_count, 1)
834        self.assertEqual(prop_set_obj1_val_prop.call_count, 1)
835        self.assertEqual(prop_set_obj2_name_prop.call_count, 1)
836        self.assertEqual(prop_set_obj2_val_prop.call_count, 1)
837        self.assertEqual(obj_prop.call_count, 1)
838        self.assertEqual(len(ret), 1)
839        self.assertDictEqual(
840            ret[0],
841            {
842                "prop_name1": "prop_value1",
843                "prop_name2": "prop_value2",
844                "object": inner_obj_mock,
845            },
846        )
847
848
849@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
850class GetPropertiesOfManagedObjectTestCase(TestCase):
851    """
852    Tests for salt.utils.get_properties_of_managed_object
853    """
854
855    def setUp(self):
856        patches = (
857            ("salt.utils.vmware.get_service_instance_from_managed_object", MagicMock()),
858            (
859                "salt.utils.vmware.get_mors_with_properties",
860                MagicMock(return_value=[MagicMock()]),
861            ),
862        )
863        for mod, mock in patches:
864            patcher = patch(mod, mock)
865            patcher.start()
866            self.addCleanup(patcher.stop)
867        self.mock_si = MagicMock()
868        self.fake_mo_ref = vim.ManagedEntity("Fake")
869        self.mock_props = MagicMock()
870        self.mock_item_name = {"name": "fake_name"}
871        self.mock_item = MagicMock()
872
873    def test_get_service_instance_from_managed_object_call(self):
874        mock_get_instance_from_managed_object = MagicMock()
875        with patch(
876            "salt.utils.vmware.get_service_instance_from_managed_object",
877            mock_get_instance_from_managed_object,
878        ):
879
880            salt.utils.vmware.get_properties_of_managed_object(
881                self.fake_mo_ref, self.mock_props
882            )
883        mock_get_instance_from_managed_object.assert_called_once_with(self.fake_mo_ref)
884
885    def test_get_mors_with_properties_calls(self):
886        mock_get_mors_with_properties = MagicMock(return_value=[MagicMock()])
887        with patch(
888            "salt.utils.vmware.get_service_instance_from_managed_object",
889            MagicMock(return_value=self.mock_si),
890        ):
891
892            with patch(
893                "salt.utils.vmware.get_mors_with_properties",
894                mock_get_mors_with_properties,
895            ):
896                salt.utils.vmware.get_properties_of_managed_object(
897                    self.fake_mo_ref, self.mock_props
898                )
899        mock_get_mors_with_properties.assert_has_calls(
900            [
901                call(
902                    self.mock_si,
903                    vim.ManagedEntity,
904                    container_ref=self.fake_mo_ref,
905                    property_list=["name"],
906                    local_properties=True,
907                ),
908                call(
909                    self.mock_si,
910                    vim.ManagedEntity,
911                    container_ref=self.fake_mo_ref,
912                    property_list=self.mock_props,
913                    local_properties=True,
914                ),
915            ]
916        )
917
918    def test_managed_object_no_name_property(self):
919        with patch(
920            "salt.utils.vmware.get_mors_with_properties",
921            MagicMock(side_effect=[vmodl.query.InvalidProperty(), []]),
922        ):
923            with self.assertRaises(VMwareApiError) as excinfo:
924                salt.utils.vmware.get_properties_of_managed_object(
925                    self.fake_mo_ref, self.mock_props
926                )
927        self.assertEqual(
928            "Properties of managed object '<unnamed>' weren't retrieved",
929            excinfo.exception.strerror,
930        )
931
932    def test_no_items_named_object(self):
933        with patch(
934            "salt.utils.vmware.get_mors_with_properties",
935            MagicMock(side_effect=[[self.mock_item_name], []]),
936        ):
937            with self.assertRaises(VMwareApiError) as excinfo:
938                salt.utils.vmware.get_properties_of_managed_object(
939                    self.fake_mo_ref, self.mock_props
940                )
941        self.assertEqual(
942            "Properties of managed object 'fake_name' weren't retrieved",
943            excinfo.exception.strerror,
944        )
945
946
947@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
948class GetManagedObjectName(TestCase):
949    """
950    Tests for salt.utils.get_managed_object_name
951    """
952
953    def setUp(self):
954        patches = (
955            (
956                "salt.utils.vmware.get_properties_of_managed_object",
957                MagicMock(return_value={"key": "value"}),
958            ),
959        )
960        for mod, mock in patches:
961            patcher = patch(mod, mock)
962            patcher.start()
963            self.addCleanup(patcher.stop)
964        self.mock_mo_ref = MagicMock()
965
966    def test_get_properties_of_managed_object_call(self):
967        mock_get_properties_of_managed_object = MagicMock()
968        with patch(
969            "salt.utils.vmware.get_properties_of_managed_object",
970            mock_get_properties_of_managed_object,
971        ):
972            salt.utils.vmware.get_managed_object_name(self.mock_mo_ref)
973        mock_get_properties_of_managed_object.assert_called_once_with(
974            self.mock_mo_ref, ["name"]
975        )
976
977    def test_no_name_in_property_dict(self):
978        ret = salt.utils.vmware.get_managed_object_name(self.mock_mo_ref)
979        self.assertIsNone(ret)
980
981    def test_return_managed_object_name(self):
982        mock_get_properties_of_managed_object = MagicMock()
983        with patch(
984            "salt.utils.vmware.get_properties_of_managed_object",
985            MagicMock(return_value={"name": "fake_name"}),
986        ):
987            ret = salt.utils.vmware.get_managed_object_name(self.mock_mo_ref)
988        self.assertEqual(ret, "fake_name")
989
990
991@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
992class GetContentTestCase(TestCase):
993    """
994    Tests for salt.utils.get_content
995    """
996
997    # Method names to be patched
998    traversal_spec_method_name = (
999        "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec"
1000    )
1001    property_spec_method_name = (
1002        "salt.utils.vmware.vmodl.query.PropertyCollector.PropertySpec"
1003    )
1004    obj_spec_method_name = "salt.utils.vmware.vmodl.query.PropertyCollector.ObjectSpec"
1005    filter_spec_method_name = (
1006        "salt.utils.vmware.vmodl.query.PropertyCollector.FilterSpec"
1007    )
1008
1009    # Class variables
1010    si_mock = None
1011    root_folder_mock = None
1012    root_folder_prop = None
1013    container_view_mock = None
1014    create_container_view_mock = None
1015    result_mock = None
1016    retrieve_contents_mock = None
1017    destroy_mock = None
1018    obj_type_mock = None
1019    traversal_spec_ret_mock = None
1020    traversal_spec_mock = None
1021    property_spec_ret_mock = None
1022    property_spec_mock = None
1023    obj_spec_ret_mock = None
1024    obj_spec_mock = None
1025    filter_spec_ret_mock = None
1026    filter_spec_mock = None
1027
1028    def setUp(self):
1029        patches = (
1030            ("salt.utils.vmware.get_root_folder", MagicMock()),
1031            (
1032                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
1033                MagicMock(return_value=MagicMock()),
1034            ),
1035            (
1036                "salt.utils.vmware.vmodl.query.PropertyCollector.PropertySpec",
1037                MagicMock(return_value=MagicMock()),
1038            ),
1039            (
1040                "salt.utils.vmware.vmodl.query.PropertyCollector.ObjectSpec",
1041                MagicMock(return_value=MagicMock()),
1042            ),
1043            (
1044                "salt.utils.vmware.vmodl.query.PropertyCollector.FilterSpec",
1045                MagicMock(return_value=MagicMock()),
1046            ),
1047        )
1048        for mod, mock in patches:
1049            patcher = patch(mod, mock)
1050            patcher.start()
1051            self.addCleanup(patcher.stop)
1052        # setup the service instance
1053        self.si_mock = MagicMock()
1054        # RootFolder
1055        self.root_folder_mock = MagicMock()
1056        self.get_root_folder_mock = MagicMock(return_value=self.root_folder_mock)
1057        # CreateContainerView()
1058        self.container_view_mock = MagicMock()
1059        self.create_container_view_mock = MagicMock(
1060            return_value=self.container_view_mock
1061        )
1062        self.si_mock.content.viewManager.CreateContainerView = (
1063            self.create_container_view_mock
1064        )
1065        # RetrieveContents()
1066        self.result_mock = MagicMock()
1067        self.retrieve_contents_mock = MagicMock(return_value=self.result_mock)
1068        self.si_mock.content.propertyCollector.RetrieveContents = (
1069            self.retrieve_contents_mock
1070        )
1071        # Destroy()
1072        self.destroy_mock = MagicMock()
1073        self.container_view_mock.Destroy = self.destroy_mock
1074
1075        # override mocks
1076        self.obj_type_mock = MagicMock()
1077        self.traversal_spec_ret_mock = MagicMock()
1078        self.traversal_spec_mock = MagicMock(return_value=self.traversal_spec_ret_mock)
1079        self.property_spec_ret_mock = MagicMock()
1080        self.property_spec_mock = MagicMock(return_value=self.property_spec_ret_mock)
1081        self.obj_spec_ret_mock = MagicMock()
1082        self.obj_spec_mock = MagicMock(return_value=self.obj_spec_ret_mock)
1083        self.filter_spec_ret_mock = MagicMock()
1084        self.filter_spec_mock = MagicMock(return_value=self.filter_spec_ret_mock)
1085
1086    def test_empty_container_ref(self):
1087        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1088            salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1089        self.get_root_folder_mock.assert_called_once_with(self.si_mock)
1090        self.create_container_view_mock.assert_called_once_with(
1091            self.root_folder_mock, [self.obj_type_mock], True
1092        )
1093
1094    def test_defined_container_ref(self):
1095        container_ref_mock = MagicMock()
1096        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1097            with patch(self.obj_spec_method_name, self.obj_type_mock):
1098                salt.utils.vmware.get_content(
1099                    self.si_mock, self.obj_type_mock, container_ref=container_ref_mock
1100                )
1101        self.assertEqual(self.get_root_folder_mock.call_count, 0)
1102        self.create_container_view_mock.assert_called_once_with(
1103            container_ref_mock, [self.obj_type_mock], True
1104        )
1105
1106    # Also checks destroy is called
1107    def test_local_traversal_spec(self):
1108        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1109            with patch(self.traversal_spec_method_name, self.traversal_spec_mock):
1110                with patch(self.obj_spec_method_name, self.obj_spec_mock):
1111                    ret = salt.utils.vmware.get_content(
1112                        self.si_mock, self.obj_type_mock
1113                    )
1114        self.create_container_view_mock.assert_called_once_with(
1115            self.root_folder_mock, [self.obj_type_mock], True
1116        )
1117        self.traversal_spec_mock.assert_called_once_with(
1118            name="traverseEntities",
1119            path="view",
1120            skip=False,
1121            type=vim.view.ContainerView,
1122        )
1123        self.obj_spec_mock.assert_called_once_with(
1124            obj=self.container_view_mock,
1125            skip=True,
1126            selectSet=[self.traversal_spec_ret_mock],
1127        )
1128        # check destroy is called
1129        self.assertEqual(self.destroy_mock.call_count, 1)
1130
1131    def test_create_container_view_raise_no_permission(self):
1132        exc = vim.fault.NoPermission()
1133        exc.privilegeId = "Fake privilege"
1134        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1135            side_effect=exc
1136        )
1137        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1138            with self.assertRaises(VMwareApiError) as excinfo:
1139                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1140        self.assertEqual(
1141            excinfo.exception.strerror,
1142            "Not enough permissions. Required privilege: Fake privilege",
1143        )
1144
1145    def test_create_container_view_raise_vim_fault(self):
1146        exc = vim.fault.VimFault()
1147        exc.msg = "VimFault msg"
1148        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1149            side_effect=exc
1150        )
1151        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1152            with self.assertRaises(VMwareApiError) as excinfo:
1153                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1154        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
1155
1156    def test_create_container_view_raise_runtime_fault(self):
1157        exc = vmodl.RuntimeFault()
1158        exc.msg = "RuntimeFault msg"
1159        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1160            side_effect=exc
1161        )
1162        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1163            with self.assertRaises(VMwareRuntimeError) as excinfo:
1164                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1165        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
1166
1167    def test_destroy_raise_no_permission(self):
1168        exc = vim.fault.NoPermission()
1169        exc.privilegeId = "Fake privilege"
1170        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1171            return_value=MagicMock(Destroy=MagicMock(side_effect=exc))
1172        )
1173        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1174            with self.assertRaises(VMwareApiError) as excinfo:
1175                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1176        self.assertEqual(
1177            excinfo.exception.strerror,
1178            "Not enough permissions. Required privilege: Fake privilege",
1179        )
1180
1181    def test_destroy_raise_vim_fault(self):
1182        exc = vim.fault.VimFault()
1183        exc.msg = "VimFault msg"
1184        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1185            return_value=MagicMock(Destroy=MagicMock(side_effect=exc))
1186        )
1187        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1188            with self.assertRaises(VMwareApiError) as excinfo:
1189                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1190        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
1191
1192    def test_destroy_raise_runtime_fault(self):
1193        exc = vmodl.RuntimeFault()
1194        exc.msg = "RuntimeFault msg"
1195        self.si_mock.content.viewManager.CreateContainerView = MagicMock(
1196            return_value=MagicMock(Destroy=MagicMock(side_effect=exc))
1197        )
1198        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1199            with self.assertRaises(VMwareRuntimeError) as excinfo:
1200                salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1201        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
1202
1203    # Also checks destroy is not called
1204    def test_external_traversal_spec(self):
1205        traversal_spec_obj_mock = MagicMock()
1206        with patch("salt.utils.vmware.get_root_folder", self.get_root_folder_mock):
1207            with patch(self.traversal_spec_method_name, self.traversal_spec_mock):
1208                with patch(self.obj_spec_method_name, self.obj_spec_mock):
1209                    salt.utils.vmware.get_content(
1210                        self.si_mock,
1211                        self.obj_type_mock,
1212                        traversal_spec=traversal_spec_obj_mock,
1213                    )
1214        self.obj_spec_mock.assert_called_once_with(
1215            obj=self.root_folder_mock, skip=True, selectSet=[traversal_spec_obj_mock]
1216        )
1217        # Check local traversal methods are not called
1218        self.assertEqual(self.create_container_view_mock.call_count, 0)
1219        self.assertEqual(self.traversal_spec_mock.call_count, 0)
1220        # check destroy is not called
1221        self.assertEqual(self.destroy_mock.call_count, 0)
1222
1223    def test_property_obj_filter_specs_and_contents(self):
1224        with patch(self.traversal_spec_method_name, self.traversal_spec_mock):
1225            with patch(self.property_spec_method_name, self.property_spec_mock):
1226                with patch(self.obj_spec_method_name, self.obj_spec_mock):
1227                    with patch(self.filter_spec_method_name, self.filter_spec_mock):
1228                        ret = salt.utils.vmware.get_content(
1229                            self.si_mock, self.obj_type_mock
1230                        )
1231        self.traversal_spec_mock.assert_called_once_with(
1232            name="traverseEntities",
1233            path="view",
1234            skip=False,
1235            type=vim.view.ContainerView,
1236        )
1237        self.property_spec_mock.assert_called_once_with(
1238            type=self.obj_type_mock, all=True, pathSet=None
1239        )
1240        self.obj_spec_mock.assert_called_once_with(
1241            obj=self.container_view_mock,
1242            skip=True,
1243            selectSet=[self.traversal_spec_ret_mock],
1244        )
1245        self.retrieve_contents_mock.assert_called_once_with([self.filter_spec_ret_mock])
1246        self.assertEqual(ret, self.result_mock)
1247
1248    def test_retrieve_contents_raise_no_permission(self):
1249        exc = vim.fault.NoPermission()
1250        exc.privilegeId = "Fake privilege"
1251        self.si_mock.content.propertyCollector.RetrieveContents = MagicMock(
1252            side_effect=exc
1253        )
1254        with self.assertRaises(VMwareApiError) as excinfo:
1255            salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1256        self.assertEqual(
1257            excinfo.exception.strerror,
1258            "Not enough permissions. Required privilege: Fake privilege",
1259        )
1260
1261    def test_retrieve_contents_raise_vim_fault(self):
1262        exc = vim.fault.VimFault()
1263        exc.msg = "VimFault msg"
1264        self.si_mock.content.propertyCollector.RetrieveContents = MagicMock(
1265            side_effect=exc
1266        )
1267        with self.assertRaises(VMwareApiError) as excinfo:
1268            salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1269        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
1270
1271    def test_retrieve_contents_raise_runtime_fault(self):
1272        exc = vmodl.RuntimeFault()
1273        exc.msg = "RuntimeFault msg"
1274        self.si_mock.content.propertyCollector.RetrieveContents = MagicMock(
1275            side_effect=exc
1276        )
1277        with self.assertRaises(VMwareRuntimeError) as excinfo:
1278            salt.utils.vmware.get_content(self.si_mock, self.obj_type_mock)
1279        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
1280
1281    def test_local_properties_set(self):
1282        container_ref_mock = MagicMock()
1283        with patch(self.traversal_spec_method_name, self.traversal_spec_mock):
1284            with patch(self.property_spec_method_name, self.property_spec_mock):
1285                with patch(self.obj_spec_method_name, self.obj_spec_mock):
1286                    salt.utils.vmware.get_content(
1287                        self.si_mock,
1288                        self.obj_type_mock,
1289                        container_ref=container_ref_mock,
1290                        local_properties=True,
1291                    )
1292        self.assertEqual(self.traversal_spec_mock.call_count, 0)
1293        self.obj_spec_mock.assert_called_once_with(
1294            obj=container_ref_mock, skip=False, selectSet=None
1295        )
1296
1297
1298@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
1299class GetRootFolderTestCase(TestCase):
1300    """
1301    Tests for salt.utils.get_root_folder
1302    """
1303
1304    def setUp(self):
1305        self.mock_root_folder = MagicMock()
1306        self.mock_content = MagicMock(rootFolder=self.mock_root_folder)
1307        self.mock_si = MagicMock(
1308            RetrieveContent=MagicMock(return_value=self.mock_content)
1309        )
1310
1311    def test_raise_no_permission(self):
1312        exc = vim.fault.NoPermission()
1313        exc.privilegeId = "Fake privilege"
1314        type(self.mock_content).rootFolder = PropertyMock(side_effect=exc)
1315        with self.assertRaises(VMwareApiError) as excinfo:
1316            salt.utils.vmware.get_root_folder(self.mock_si)
1317        self.assertEqual(
1318            excinfo.exception.strerror,
1319            "Not enough permissions. Required privilege: Fake privilege",
1320        )
1321
1322    def test_raise_vim_fault(self):
1323        exc = vim.fault.VimFault()
1324        exc.msg = "VimFault msg"
1325        type(self.mock_content).rootFolder = PropertyMock(side_effect=exc)
1326        with self.assertRaises(VMwareApiError) as excinfo:
1327            salt.utils.vmware.get_root_folder(self.mock_si)
1328        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
1329
1330    def test_raise_runtime_fault(self):
1331        exc = vmodl.RuntimeFault()
1332        exc.msg = "RuntimeFault msg"
1333        type(self.mock_content).rootFolder = PropertyMock(side_effect=exc)
1334        with self.assertRaises(VMwareRuntimeError) as excinfo:
1335            salt.utils.vmware.get_root_folder(self.mock_si)
1336        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
1337
1338    def test_return(self):
1339        ret = salt.utils.vmware.get_root_folder(self.mock_si)
1340        self.assertEqual(ret, self.mock_root_folder)
1341
1342
1343@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
1344class GetServiceInfoTestCase(TestCase):
1345    """
1346    Tests for salt.utils.vmware.get_service_info
1347    """
1348
1349    def setUp(self):
1350        self.mock_about = MagicMock()
1351        self.mock_si = MagicMock(content=MagicMock())
1352        type(self.mock_si.content).about = PropertyMock(return_value=self.mock_about)
1353
1354    def tearDown(self):
1355        for attr in ("mock_si", "mock_about"):
1356            delattr(self, attr)
1357
1358    def test_about_ret(self):
1359        ret = salt.utils.vmware.get_service_info(self.mock_si)
1360        self.assertEqual(ret, self.mock_about)
1361
1362    def test_about_raises_no_permission(self):
1363        exc = vim.fault.NoPermission()
1364        exc.privilegeId = "Fake privilege"
1365        type(self.mock_si.content).about = PropertyMock(side_effect=exc)
1366        with self.assertRaises(VMwareApiError) as excinfo:
1367            salt.utils.vmware.get_service_info(self.mock_si)
1368        self.assertEqual(
1369            excinfo.exception.strerror,
1370            "Not enough permissions. Required privilege: Fake privilege",
1371        )
1372
1373    def test_about_raises_vim_fault(self):
1374        exc = vim.fault.VimFault()
1375        exc.msg = "VimFault msg"
1376        type(self.mock_si.content).about = PropertyMock(side_effect=exc)
1377        with self.assertRaises(VMwareApiError) as excinfo:
1378            salt.utils.vmware.get_service_info(self.mock_si)
1379        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
1380
1381    def test_about_raises_runtime_fault(self):
1382        exc = vmodl.RuntimeFault()
1383        exc.msg = "RuntimeFault msg"
1384        type(self.mock_si.content).about = PropertyMock(side_effect=exc)
1385        with self.assertRaises(VMwareRuntimeError) as excinfo:
1386            salt.utils.vmware.get_service_info(self.mock_si)
1387        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
1388
1389
1390@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
1391@skipIf(not HAS_GSSAPI, "The 'gssapi' library is missing")
1392class GssapiTokenTest(TestCase):
1393    """
1394    Test cases for salt.utils.vmware.get_gssapi_token
1395    """
1396
1397    def setUp(self):
1398        patches = (
1399            ("gssapi.Name", MagicMock(return_value="service")),
1400            ("gssapi.InitContext", MagicMock()),
1401        )
1402        for mod, mock in patches:
1403            patcher = patch(mod, mock)
1404            patcher.start()
1405            self.addCleanup(patcher.stop)
1406
1407    def test_no_gssapi(self):
1408        with patch("salt.utils.vmware.HAS_GSSAPI", False):
1409            with self.assertRaises(ImportError) as excinfo:
1410                salt.utils.vmware.get_gssapi_token("principal", "host", "domain")
1411                self.assertIn(
1412                    "The gssapi library is not imported.", excinfo.exception.message
1413                )
1414
1415    @skipIf(not HAS_GSSAPI, "The 'gssapi' library is missing")
1416    def test_service_name(self):
1417        mock_name = MagicMock()
1418        with patch.object(salt.utils.vmware.gssapi, "Name", mock_name):
1419
1420            with self.assertRaises(CommandExecutionError):
1421                salt.utils.vmware.get_gssapi_token("principal", "host", "domain")
1422            mock_name.assert_called_once_with(
1423                "principal/host@domain", gssapi.C_NT_USER_NAME
1424            )
1425
1426    @skipIf(not HAS_GSSAPI, "The 'gssapi' library is missing")
1427    def test_out_token_defined(self):
1428        mock_context = MagicMock(return_value=MagicMock())
1429        mock_context.return_value.established = False
1430        mock_context.return_value.step = MagicMock(return_value="out_token")
1431        with patch.object(salt.utils.vmware.gssapi, "InitContext", mock_context):
1432            ret = salt.utils.vmware.get_gssapi_token("principal", "host", "domain")
1433            self.assertEqual(mock_context.return_value.step.called, 1)
1434            self.assertEqual(ret, base64.b64encode(b"out_token"))
1435
1436    @skipIf(not HAS_GSSAPI, "The 'gssapi' library is missing")
1437    def test_out_token_undefined(self):
1438        mock_context = MagicMock(return_value=MagicMock())
1439        mock_context.return_value.established = False
1440        mock_context.return_value.step = MagicMock(return_value=None)
1441        with patch.object(salt.utils.vmware.gssapi, "InitContext", mock_context):
1442            with self.assertRaises(CommandExecutionError) as excinfo:
1443                salt.utils.vmware.get_gssapi_token("principal", "host", "domain")
1444            self.assertEqual(mock_context.return_value.step.called, 1)
1445            self.assertIn("Can't receive token", excinfo.exception.strerror)
1446
1447    @skipIf(not HAS_GSSAPI, "The 'gssapi' library is missing")
1448    def test_context_extablished(self):
1449        mock_context = MagicMock(return_value=MagicMock())
1450        mock_context.return_value.established = True
1451        mock_context.return_value.step = MagicMock(return_value="out_token")
1452        with patch.object(salt.utils.vmware.gssapi, "InitContext", mock_context):
1453            mock_context.established = True
1454            mock_context.step = MagicMock(return_value=None)
1455            with self.assertRaises(CommandExecutionError) as excinfo:
1456                salt.utils.vmware.get_gssapi_token("principal", "host", "domain")
1457            self.assertEqual(mock_context.step.called, 0)
1458            self.assertIn(
1459                "Context established, but didn't receive token",
1460                excinfo.exception.strerror,
1461            )
1462
1463
1464@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
1465class PrivateGetServiceInstanceTestCase(TestCase):
1466    """
1467    Tests for salt.utils.vmware._get_service_instance
1468    """
1469
1470    def setUp(self):
1471        patches = (
1472            ("salt.utils.vmware.SmartConnect", MagicMock()),
1473            ("salt.utils.vmware.Disconnect", MagicMock()),
1474            (
1475                "salt.utils.vmware.get_gssapi_token",
1476                MagicMock(return_value="fake_token"),
1477            ),
1478        )
1479        for mod, mock in patches:
1480            patcher = patch(mod, mock)
1481            patcher.start()
1482            self.addCleanup(patcher.stop)
1483
1484    def test_invalid_mechianism(self):
1485        with self.assertRaises(CommandExecutionError) as excinfo:
1486            salt.utils.vmware._get_service_instance(
1487                host="fake_host.fqdn",
1488                username="fake_username",
1489                password="fake_password",
1490                protocol="fake_protocol",
1491                port=1,
1492                mechanism="invalid_mechanism",
1493                principal="fake principal",
1494                domain="fake_domain",
1495            )
1496        self.assertIn("Unsupported mechanism", excinfo.exception.strerror)
1497
1498    def test_userpass_mechanism_empty_username(self):
1499        with self.assertRaises(CommandExecutionError) as excinfo:
1500            salt.utils.vmware._get_service_instance(
1501                host="fake_host.fqdn",
1502                username=None,
1503                password="fake_password",
1504                protocol="fake_protocol",
1505                port=1,
1506                mechanism="userpass",
1507                principal="fake principal",
1508                domain="fake_domain",
1509            )
1510        self.assertIn("mandatory parameter 'username'", excinfo.exception.strerror)
1511
1512    def test_userpass_mechanism_empty_password(self):
1513        with self.assertRaises(CommandExecutionError) as excinfo:
1514            salt.utils.vmware._get_service_instance(
1515                host="fake_host.fqdn",
1516                username="fake_username",
1517                password=None,
1518                protocol="fake_protocol",
1519                port=1,
1520                mechanism="userpass",
1521                principal="fake principal",
1522                domain="fake_domain",
1523            )
1524        self.assertIn("mandatory parameter 'password'", excinfo.exception.strerror)
1525
1526    def test_userpass_mechanism_no_domain(self):
1527        mock_sc = MagicMock()
1528        with patch("salt.utils.vmware.SmartConnect", mock_sc):
1529            salt.utils.vmware._get_service_instance(
1530                host="fake_host.fqdn",
1531                username="fake_username",
1532                password="fake_password",
1533                protocol="fake_protocol",
1534                port=1,
1535                mechanism="userpass",
1536                principal="fake principal",
1537                domain=None,
1538            )
1539            mock_sc.assert_called_once_with(
1540                host="fake_host.fqdn",
1541                user="fake_username",
1542                pwd="fake_password",
1543                protocol="fake_protocol",
1544                port=1,
1545                b64token=None,
1546                mechanism="userpass",
1547            )
1548
1549    def test_userpass_mech_domain_unused(self):
1550        mock_sc = MagicMock()
1551        with patch("salt.utils.vmware.SmartConnect", mock_sc):
1552            salt.utils.vmware._get_service_instance(
1553                host="fake_host.fqdn",
1554                username="fake_username@domain",
1555                password="fake_password",
1556                protocol="fake_protocol",
1557                port=1,
1558                mechanism="userpass",
1559                principal="fake principal",
1560                domain="fake_domain",
1561            )
1562            mock_sc.assert_called_once_with(
1563                host="fake_host.fqdn",
1564                user="fake_username@domain",
1565                pwd="fake_password",
1566                protocol="fake_protocol",
1567                port=1,
1568                b64token=None,
1569                mechanism="userpass",
1570            )
1571            mock_sc.reset_mock()
1572            salt.utils.vmware._get_service_instance(
1573                host="fake_host.fqdn",
1574                username="domain\\fake_username",
1575                password="fake_password",
1576                protocol="fake_protocol",
1577                port=1,
1578                mechanism="userpass",
1579                principal="fake principal",
1580                domain="fake_domain",
1581            )
1582            mock_sc.assert_called_once_with(
1583                host="fake_host.fqdn",
1584                user="domain\\fake_username",
1585                pwd="fake_password",
1586                protocol="fake_protocol",
1587                port=1,
1588                b64token=None,
1589                mechanism="userpass",
1590            )
1591
1592    def test_sspi_empty_principal(self):
1593        with self.assertRaises(CommandExecutionError) as excinfo:
1594            salt.utils.vmware._get_service_instance(
1595                host="fake_host.fqdn",
1596                username="fake_username",
1597                password="fake_password",
1598                protocol="fake_protocol",
1599                port=1,
1600                mechanism="sspi",
1601                principal=None,
1602                domain="fake_domain",
1603            )
1604        self.assertIn("mandatory parameters are missing", excinfo.exception.strerror)
1605
1606    def test_sspi_empty_domain(self):
1607        with self.assertRaises(CommandExecutionError) as excinfo:
1608            salt.utils.vmware._get_service_instance(
1609                host="fake_host.fqdn",
1610                username="fake_username",
1611                password="fake_password",
1612                protocol="fake_protocol",
1613                port=1,
1614                mechanism="sspi",
1615                principal="fake_principal",
1616                domain=None,
1617            )
1618        self.assertIn("mandatory parameters are missing", excinfo.exception.strerror)
1619
1620    def test_sspi_get_token_error(self):
1621        mock_token = MagicMock(side_effect=Exception("Exception"))
1622
1623        with patch("salt.utils.vmware.get_gssapi_token", mock_token):
1624            with self.assertRaises(VMwareConnectionError) as excinfo:
1625                salt.utils.vmware._get_service_instance(
1626                    host="fake_host.fqdn",
1627                    username="fake_username",
1628                    password="fake_password",
1629                    protocol="fake_protocol",
1630                    port=1,
1631                    mechanism="sspi",
1632                    principal="fake_principal",
1633                    domain="fake_domain",
1634                )
1635            mock_token.assert_called_once_with(
1636                "fake_principal", "fake_host.fqdn", "fake_domain"
1637            )
1638            self.assertEqual("Exception", excinfo.exception.strerror)
1639
1640    def test_sspi_get_token_success_(self):
1641        mock_token = MagicMock(return_value="fake_token")
1642        mock_sc = MagicMock()
1643
1644        with patch("salt.utils.vmware.get_gssapi_token", mock_token):
1645            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1646                salt.utils.vmware._get_service_instance(
1647                    host="fake_host.fqdn",
1648                    username="fake_username",
1649                    password="fake_password",
1650                    protocol="fake_protocol",
1651                    port=1,
1652                    mechanism="sspi",
1653                    principal="fake_principal",
1654                    domain="fake_domain",
1655                )
1656            mock_token.assert_called_once_with(
1657                "fake_principal", "fake_host.fqdn", "fake_domain"
1658            )
1659            mock_sc.assert_called_once_with(
1660                host="fake_host.fqdn",
1661                user="fake_username",
1662                pwd="fake_password",
1663                protocol="fake_protocol",
1664                port=1,
1665                b64token="fake_token",
1666                mechanism="sspi",
1667            )
1668
1669    def test_first_attempt_successful_connection(self):
1670        mock_sc = MagicMock()
1671        with patch("salt.utils.vmware.SmartConnect", mock_sc):
1672            salt.utils.vmware._get_service_instance(
1673                host="fake_host.fqdn",
1674                username="fake_username",
1675                password="fake_password",
1676                protocol="fake_protocol",
1677                port=1,
1678                mechanism="sspi",
1679                principal="fake_principal",
1680                domain="fake_domain",
1681            )
1682            mock_sc.assert_called_once_with(
1683                host="fake_host.fqdn",
1684                user="fake_username",
1685                pwd="fake_password",
1686                protocol="fake_protocol",
1687                port=1,
1688                b64token="fake_token",
1689                mechanism="sspi",
1690            )
1691
1692    def test_first_attempt_successful_connection_verify_ssl_false(self):
1693        with patch("ssl.SSLContext", MagicMock()), patch(
1694            "ssl._create_unverified_context", MagicMock()
1695        ):
1696            exc = vim.fault.HostConnectFault()
1697            exc.msg = "[SSL: CERTIFICATE_VERIFY_FAILED]"
1698            mock_sc = MagicMock(side_effect=[None])
1699            mock_ssl = MagicMock()
1700
1701            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1702                with patch("ssl._create_unverified_context", mock_ssl):
1703
1704                    salt.utils.vmware._get_service_instance(
1705                        host="fake_host.fqdn",
1706                        username="fake_username",
1707                        password="fake_password",
1708                        protocol="fake_protocol",
1709                        port=1,
1710                        mechanism="sspi",
1711                        principal="fake_principal",
1712                        domain="fake_domain",
1713                        verify_ssl=False,
1714                    )
1715
1716                    mock_ssl.assert_called_once_with()
1717                    calls = [
1718                        call(
1719                            host="fake_host.fqdn",
1720                            user="fake_username",
1721                            pwd="fake_password",
1722                            protocol="fake_protocol",
1723                            port=1,
1724                            sslContext=mock_ssl.return_value,
1725                            b64token="fake_token",
1726                            mechanism="sspi",
1727                        ),
1728                    ]
1729                    mock_sc.assert_has_calls(calls)
1730
1731    def test_second_attempt_successful_connection_verify_ssl_false(self):
1732        with patch("ssl.SSLContext", MagicMock()), patch(
1733            "ssl._create_unverified_context", MagicMock()
1734        ):
1735            exc = Exception("certificate verify failed")
1736            mock_sc = MagicMock(side_effect=[exc, None])
1737            mock_ssl_unverif = MagicMock()
1738            mock_ssl_context = MagicMock()
1739
1740            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1741                with patch("ssl._create_unverified_context", mock_ssl_unverif):
1742                    with patch("ssl.SSLContext", mock_ssl_context):
1743                        salt.utils.vmware._get_service_instance(
1744                            host="fake_host.fqdn",
1745                            username="fake_username",
1746                            password="fake_password",
1747                            protocol="fake_protocol",
1748                            port=1,
1749                            mechanism="sspi",
1750                            principal="fake_principal",
1751                            domain="fake_domain",
1752                            verify_ssl=False,
1753                        )
1754
1755                        mock_ssl_context.assert_called_once_with(ssl.PROTOCOL_TLSv1)
1756                        mock_ssl_unverif.assert_called_once_with()
1757                        calls = [
1758                            call(
1759                                host="fake_host.fqdn",
1760                                user="fake_username",
1761                                pwd="fake_password",
1762                                protocol="fake_protocol",
1763                                port=1,
1764                                sslContext=mock_ssl_unverif.return_value,
1765                                b64token="fake_token",
1766                                mechanism="sspi",
1767                            ),
1768                            call(
1769                                host="fake_host.fqdn",
1770                                user="fake_username",
1771                                pwd="fake_password",
1772                                protocol="fake_protocol",
1773                                port=1,
1774                                sslContext=mock_ssl_context.return_value,
1775                                b64token="fake_token",
1776                                mechanism="sspi",
1777                            ),
1778                        ]
1779                        mock_sc.assert_has_calls(calls)
1780
1781    def test_attempt_unsuccessful_connection_default_error(self):
1782        exc = Exception("Exception")
1783        mock_sc = MagicMock(side_effect=exc)
1784
1785        with patch("salt.utils.vmware.SmartConnect", mock_sc):
1786            with self.assertRaises(VMwareConnectionError) as excinfo:
1787                salt.utils.vmware._get_service_instance(
1788                    host="fake_host.fqdn",
1789                    username="fake_username",
1790                    password="fake_password",
1791                    protocol="fake_protocol",
1792                    port=1,
1793                    mechanism="sspi",
1794                    principal="fake_principal",
1795                    domain="fake_domain",
1796                )
1797
1798        self.assertEqual(mock_sc.call_count, 1)
1799        self.assertIn(
1800            "Could not connect to host 'fake_host.fqdn'",
1801            excinfo.exception.message,
1802        )
1803
1804    def test_attempt_unsuccessful_connection_vim_fault(self):
1805        exc = vim.fault.VimFault()
1806        exc.msg = "VimFault"
1807        mock_sc = MagicMock(side_effect=exc)
1808
1809        with patch("salt.utils.vmware.SmartConnect", mock_sc):
1810            with self.assertRaises(VMwareConnectionError) as excinfo:
1811                salt.utils.vmware._get_service_instance(
1812                    host="fake_host.fqdn",
1813                    username="fake_username",
1814                    password="fake_password",
1815                    protocol="fake_protocol",
1816                    port=1,
1817                    mechanism="sspi",
1818                    principal="fake_principal",
1819                    domain="fake_domain",
1820                )
1821
1822        self.assertEqual(mock_sc.call_count, 1)
1823        self.assertEqual("VimFault", excinfo.exception.message)
1824
1825    def test_first_attempt_unsuccsessful_connection_default_error(self):
1826        with patch("ssl.SSLContext", MagicMock()), patch(
1827            "ssl._create_unverified_context", MagicMock()
1828        ):
1829            exc = vim.fault.HostConnectFault()
1830            exc.msg = "certificate verify failed"
1831            exc2 = Exception("Exception")
1832            mock_sc = MagicMock(side_effect=[exc, exc2])
1833
1834            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1835                with self.assertRaises(VMwareConnectionError) as excinfo:
1836                    salt.utils.vmware._get_service_instance(
1837                        host="fake_host.fqdn",
1838                        username="fake_username",
1839                        password="fake_password",
1840                        protocol="fake_protocol",
1841                        port=1,
1842                        mechanism="sspi",
1843                        principal="fake_principal",
1844                        domain="fake_domain",
1845                        verify_ssl=False,
1846                    )
1847
1848            self.assertEqual(mock_sc.call_count, 2)
1849            self.assertIn(
1850                "Could not connect to host 'fake_host.fqdn'", excinfo.exception.message
1851            )
1852
1853    def test_first_attempt_unsuccsessful_cannot_vim_fault_verify_ssl(self):
1854        with patch("ssl.SSLContext", MagicMock()), patch(
1855            "ssl._create_unverified_context", MagicMock()
1856        ):
1857            exc = vim.fault.VimFault()
1858            exc.msg = "VimFault"
1859
1860            mock_sc = MagicMock(side_effect=[exc])
1861
1862            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1863                with self.assertRaises(VMwareConnectionError) as excinfo:
1864                    salt.utils.vmware._get_service_instance(
1865                        host="fake_host.fqdn",
1866                        username="fake_username",
1867                        password="fake_password",
1868                        protocol="fake_protocol",
1869                        port=1,
1870                        mechanism="sspi",
1871                        principal="fake_principal",
1872                        domain="fake_domain",
1873                        verify_ssl=False,
1874                    )
1875
1876            self.assertEqual(mock_sc.call_count, 1)
1877            self.assertIn("VimFault", excinfo.exception.message)
1878
1879    def test_third_attempt_unsuccessful_connection_detault_error(self):
1880        with patch("ssl.SSLContext", MagicMock()), patch(
1881            "ssl._create_unverified_context", MagicMock()
1882        ):
1883            exc = vim.fault.HostConnectFault()
1884            exc.msg = "certificate verify failed"
1885            exc2 = Exception("Exception")
1886            mock_sc = MagicMock(side_effect=[exc, exc2])
1887
1888            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1889                with self.assertRaises(VMwareConnectionError) as excinfo:
1890                    salt.utils.vmware._get_service_instance(
1891                        host="fake_host.fqdn",
1892                        username="fake_username",
1893                        password="fake_password",
1894                        protocol="fake_protocol",
1895                        port=1,
1896                        mechanism="sspi",
1897                        principal="fake_principal",
1898                        domain="fake_domain",
1899                        verify_ssl=False,
1900                    )
1901
1902            self.assertEqual(mock_sc.call_count, 2)
1903            self.assertIn(
1904                "Could not connect to host 'fake_host.fqdn", excinfo.exception.message
1905            )
1906
1907    def test_second_attempt_unsuccessful_connection_vim_fault(self):
1908        with patch("ssl.SSLContext", MagicMock()), patch(
1909            "ssl._create_unverified_context", MagicMock()
1910        ):
1911            exc = vim.fault.VimFault()
1912            exc.msg = "VimFault"
1913            mock_sc = MagicMock(side_effect=[exc])
1914
1915            with patch("salt.utils.vmware.SmartConnect", mock_sc):
1916                with self.assertRaises(VMwareConnectionError) as excinfo:
1917                    salt.utils.vmware._get_service_instance(
1918                        host="fake_host.fqdn",
1919                        username="fake_username",
1920                        password="fake_password",
1921                        protocol="fake_protocol",
1922                        port=1,
1923                        mechanism="sspi",
1924                        principal="fake_principal",
1925                        domain="fake_domain",
1926                        verify_ssl=False,
1927                    )
1928
1929            self.assertEqual(mock_sc.call_count, 1)
1930            self.assertIn("VimFault", excinfo.exception.message)
1931
1932
1933@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
1934class GetServiceInstanceTestCase(TestCase):
1935    """
1936    Tests for salt.utils.vmware.get_service_instance
1937    """
1938
1939    def setUp(self):
1940        patches = (
1941            ("salt.utils.vmware.GetSi", MagicMock(return_value=None)),
1942            (
1943                "salt.utils.vmware._get_service_instance",
1944                MagicMock(return_value=MagicMock()),
1945            ),
1946        )
1947        for mod, mock in patches:
1948            patcher = patch(mod, mock)
1949            patcher.start()
1950            self.addCleanup(patcher.stop)
1951
1952    def test_default_params(self):
1953        mock_get_si = MagicMock()
1954        with patch("salt.utils.vmware._get_service_instance", mock_get_si):
1955            salt.utils.vmware.get_service_instance(host="fake_host")
1956            mock_get_si.assert_called_once_with(
1957                "fake_host",
1958                None,
1959                None,
1960                "https",
1961                443,
1962                "userpass",
1963                None,
1964                None,
1965                verify_ssl=True,
1966            )
1967
1968    def test_no_cached_service_instance_same_host_on_proxy(self):
1969        with patch("salt.utils.platform.is_proxy", MagicMock(return_value=True)):
1970            # Service instance is uncached when using class default mock objs
1971            mock_get_si = MagicMock()
1972            with patch("salt.utils.vmware._get_service_instance", mock_get_si):
1973                salt.utils.vmware.get_service_instance(
1974                    host="fake_host",
1975                    username="fake_username",
1976                    password="fake_password",
1977                    protocol="fake_protocol",
1978                    port=1,
1979                    mechanism="fake_mechanism",
1980                    principal="fake_principal",
1981                    domain="fake_domain",
1982                )
1983                mock_get_si.assert_called_once_with(
1984                    "fake_host",
1985                    "fake_username",
1986                    "fake_password",
1987                    "fake_protocol",
1988                    1,
1989                    "fake_mechanism",
1990                    "fake_principal",
1991                    "fake_domain",
1992                    verify_ssl=True,
1993                )
1994
1995    def test_cached_service_instance_different_host(self):
1996        mock_si = MagicMock()
1997        mock_disconnect = MagicMock()
1998        mock_get_si = MagicMock(return_value=mock_si)
1999        mock_getstub = MagicMock()
2000        with patch("salt.utils.vmware.GetSi", mock_get_si):
2001            with patch("salt.utils.vmware.GetStub", mock_getstub):
2002                with patch("salt.utils.vmware.Disconnect", mock_disconnect):
2003                    salt.utils.vmware.get_service_instance(
2004                        host="fake_host",
2005                        username="fake_username",
2006                        password="fake_password",
2007                        protocol="fake_protocol",
2008                        port=1,
2009                        mechanism="fake_mechanism",
2010                        principal="fake_principal",
2011                        domain="fake_domain",
2012                    )
2013            self.assertEqual(mock_get_si.call_count, 1)
2014            self.assertEqual(mock_getstub.call_count, 1)
2015            self.assertEqual(mock_disconnect.call_count, 1)
2016
2017    def test_uncached_service_instance(self):
2018        # Service instance is uncached when using class default mock objs
2019        mock_get_si = MagicMock()
2020        with patch("salt.utils.vmware._get_service_instance", mock_get_si):
2021            salt.utils.vmware.get_service_instance(
2022                host="fake_host",
2023                username="fake_username",
2024                password="fake_password",
2025                protocol="fake_protocol",
2026                port=1,
2027                mechanism="fake_mechanism",
2028                principal="fake_principal",
2029                domain="fake_domain",
2030                verify_ssl=True,
2031            )
2032            mock_get_si.assert_called_once_with(
2033                "fake_host",
2034                "fake_username",
2035                "fake_password",
2036                "fake_protocol",
2037                1,
2038                "fake_mechanism",
2039                "fake_principal",
2040                "fake_domain",
2041                verify_ssl=True,
2042            )
2043
2044    def test_unauthenticated_service_instance(self):
2045        mock_si_current_time = MagicMock(side_effect=vim.fault.NotAuthenticated)
2046        mock_si = MagicMock()
2047        mock_get_si = MagicMock(return_value=mock_si)
2048        mock_si.CurrentTime = mock_si_current_time
2049        mock_disconnect = MagicMock()
2050        with patch("salt.utils.vmware._get_service_instance", mock_get_si):
2051            with patch("salt.utils.vmware.Disconnect", mock_disconnect):
2052                salt.utils.vmware.get_service_instance(
2053                    host="fake_host",
2054                    username="fake_username",
2055                    password="fake_password",
2056                    protocol="fake_protocol",
2057                    port=1,
2058                    mechanism="fake_mechanism",
2059                    principal="fake_principal",
2060                    domain="fake_domain",
2061                )
2062                self.assertEqual(mock_si_current_time.call_count, 1)
2063                self.assertEqual(mock_disconnect.call_count, 1)
2064                self.assertEqual(mock_get_si.call_count, 2)
2065
2066    def test_cached_unauthenticated_service_instance(self):
2067        mock_si_current_time = MagicMock(side_effect=vim.fault.NotAuthenticated)
2068        mock_si = MagicMock()
2069        mock_get_si = MagicMock(return_value=mock_si)
2070        mock_getsi = MagicMock(return_value=mock_si)
2071        mock_si.CurrentTime = mock_si_current_time
2072        mock_disconnect = MagicMock()
2073        with patch("salt.utils.vmware.GetSi", mock_getsi):
2074            with patch("salt.utils.vmware._get_service_instance", mock_get_si):
2075                with patch("salt.utils.vmware.Disconnect", mock_disconnect):
2076                    salt.utils.vmware.get_service_instance(
2077                        host="fake_host",
2078                        username="fake_username",
2079                        password="fake_password",
2080                        protocol="fake_protocol",
2081                        port=1,
2082                        mechanism="fake_mechanism",
2083                        principal="fake_principal",
2084                        domain="fake_domain",
2085                    )
2086                    self.assertEqual(mock_si_current_time.call_count, 1)
2087                    self.assertEqual(mock_disconnect.call_count, 1)
2088                    self.assertEqual(mock_get_si.call_count, 1)
2089
2090    def test_current_time_raise_no_permission(self):
2091        exc = vim.fault.NoPermission()
2092        exc.privilegeId = "Fake privilege"
2093        with patch(
2094            "salt.utils.vmware._get_service_instance",
2095            MagicMock(return_value=MagicMock(CurrentTime=MagicMock(side_effect=exc))),
2096        ):
2097            with self.assertRaises(VMwareApiError) as excinfo:
2098                salt.utils.vmware.get_service_instance(
2099                    host="fake_host",
2100                    username="fake_username",
2101                    password="fake_password",
2102                    protocol="fake_protocol",
2103                    port=1,
2104                    mechanism="fake_mechanism",
2105                    principal="fake_principal",
2106                    domain="fake_domain",
2107                )
2108        self.assertEqual(
2109            excinfo.exception.strerror,
2110            "Not enough permissions. Required privilege: Fake privilege",
2111        )
2112
2113    def test_current_time_raise_vim_fault(self):
2114        exc = vim.fault.VimFault()
2115        exc.msg = "VimFault msg"
2116        with patch(
2117            "salt.utils.vmware._get_service_instance",
2118            MagicMock(return_value=MagicMock(CurrentTime=MagicMock(side_effect=exc))),
2119        ):
2120            with self.assertRaises(VMwareApiError) as excinfo:
2121                salt.utils.vmware.get_service_instance(
2122                    host="fake_host",
2123                    username="fake_username",
2124                    password="fake_password",
2125                    protocol="fake_protocol",
2126                    port=1,
2127                    mechanism="fake_mechanism",
2128                    principal="fake_principal",
2129                    domain="fake_domain",
2130                )
2131        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2132
2133    def test_current_time_raise_runtime_fault(self):
2134        exc = vmodl.RuntimeFault()
2135        exc.msg = "RuntimeFault msg"
2136        with patch(
2137            "salt.utils.vmware._get_service_instance",
2138            MagicMock(return_value=MagicMock(CurrentTime=MagicMock(side_effect=exc))),
2139        ):
2140            with self.assertRaises(VMwareRuntimeError) as excinfo:
2141                salt.utils.vmware.get_service_instance(
2142                    host="fake_host",
2143                    username="fake_username",
2144                    password="fake_password",
2145                    protocol="fake_protocol",
2146                    port=1,
2147                    mechanism="fake_mechanism",
2148                    principal="fake_principal",
2149                    domain="fake_domain",
2150                )
2151        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2152
2153
2154@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2155class DisconnectTestCase(TestCase):
2156    """
2157    Tests for salt.utils.vmware.disconnect
2158    """
2159
2160    def setUp(self):
2161        self.mock_si = MagicMock()
2162        self.addCleanup(delattr, self, "mock_si")
2163
2164    def test_disconnect(self):
2165        mock_disconnect = MagicMock()
2166        with patch("salt.utils.vmware.Disconnect", mock_disconnect):
2167            salt.utils.vmware.disconnect(service_instance=self.mock_si)
2168            mock_disconnect.assert_called_once_with(self.mock_si)
2169
2170    def test_disconnect_raise_no_permission(self):
2171        exc = vim.fault.NoPermission()
2172        exc.privilegeId = "Fake privilege"
2173        with patch("salt.utils.vmware.Disconnect", MagicMock(side_effect=exc)):
2174            with self.assertRaises(VMwareApiError) as excinfo:
2175                salt.utils.vmware.disconnect(service_instance=self.mock_si)
2176        self.assertEqual(
2177            excinfo.exception.strerror,
2178            "Not enough permissions. Required privilege: Fake privilege",
2179        )
2180
2181    def test_disconnect_raise_vim_fault(self):
2182        exc = vim.fault.VimFault()
2183        exc.msg = "VimFault msg"
2184        with patch("salt.utils.vmware.Disconnect", MagicMock(side_effect=exc)):
2185            with self.assertRaises(VMwareApiError) as excinfo:
2186                salt.utils.vmware.disconnect(service_instance=self.mock_si)
2187        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2188
2189    def test_disconnect_raise_runtime_fault(self):
2190        exc = vmodl.RuntimeFault()
2191        exc.msg = "RuntimeFault msg"
2192        with patch("salt.utils.vmware.Disconnect", MagicMock(side_effect=exc)):
2193            with self.assertRaises(VMwareRuntimeError) as excinfo:
2194                salt.utils.vmware.disconnect(service_instance=self.mock_si)
2195        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2196
2197
2198@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2199class IsConnectionToAVCenterTestCase(TestCase):
2200    """
2201    Tests for salt.utils.vmware.is_connection_to_a_vcenter
2202    """
2203
2204    def test_api_type_raise_no_permission(self):
2205        exc = vim.fault.NoPermission()
2206        exc.privilegeId = "Fake privilege"
2207        mock_si = MagicMock()
2208        type(mock_si.content.about).apiType = PropertyMock(side_effect=exc)
2209        with self.assertRaises(VMwareApiError) as excinfo:
2210            salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2211        self.assertEqual(
2212            excinfo.exception.strerror,
2213            "Not enough permissions. Required privilege: Fake privilege",
2214        )
2215
2216    def test_api_type_raise_vim_fault(self):
2217        exc = vim.fault.VimFault()
2218        exc.msg = "VimFault msg"
2219        mock_si = MagicMock()
2220        type(mock_si.content.about).apiType = PropertyMock(side_effect=exc)
2221        with self.assertRaises(VMwareApiError) as excinfo:
2222            salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2223        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2224
2225    def test_api_type_raise_runtime_fault(self):
2226        exc = vmodl.RuntimeFault()
2227        exc.msg = "RuntimeFault msg"
2228        mock_si = MagicMock()
2229        type(mock_si.content.about).apiType = PropertyMock(side_effect=exc)
2230        with self.assertRaises(VMwareRuntimeError) as excinfo:
2231            salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2232        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2233
2234    def test_connected_to_a_vcenter(self):
2235        mock_si = MagicMock()
2236        mock_si.content.about.apiType = "VirtualCenter"
2237
2238        ret = salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2239        self.assertTrue(ret)
2240
2241    def test_connected_to_a_host(self):
2242        mock_si = MagicMock()
2243        mock_si.content.about.apiType = "HostAgent"
2244
2245        ret = salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2246        self.assertFalse(ret)
2247
2248    def test_connected_to_invalid_entity(self):
2249        mock_si = MagicMock()
2250        mock_si.content.about.apiType = "UnsupportedType"
2251
2252        with self.assertRaises(VMwareApiError) as excinfo:
2253            salt.utils.vmware.is_connection_to_a_vcenter(mock_si)
2254        self.assertIn(
2255            "Unexpected api type 'UnsupportedType'", excinfo.exception.strerror
2256        )
2257
2258
2259@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2260class GetNewServiceInstanceStub(TestCase, LoaderModuleMockMixin):
2261    """
2262    Tests for salt.utils.vmware.get_new_service_instance_stub
2263    """
2264
2265    def setup_loader_modules(self):
2266        return {salt.utils.vmware: {"sys": MagicMock(), "ssl": MagicMock()}}
2267
2268    def setUp(self):
2269        self.mock_stub = MagicMock(host="fake_host:1000", cookie='ignore"fake_cookie')
2270        self.mock_si = MagicMock(_stub=self.mock_stub)
2271        self.mock_ret = MagicMock()
2272        self.mock_new_stub = MagicMock()
2273        self.context_dict = {}
2274        patches = (
2275            (
2276                "salt.utils.vmware.VmomiSupport.GetRequestContext",
2277                MagicMock(return_value=self.context_dict),
2278            ),
2279            (
2280                "salt.utils.vmware.SoapStubAdapter",
2281                MagicMock(return_value=self.mock_new_stub),
2282            ),
2283        )
2284        for mod, mock in patches:
2285            patcher = patch(mod, mock)
2286            patcher.start()
2287            self.addCleanup(patcher.stop)
2288
2289        self.mock_context = MagicMock()
2290        self.mock_create_default_context = MagicMock(return_value=self.mock_context)
2291        salt.utils.vmware.ssl.create_default_context = self.mock_create_default_context
2292
2293    def tearDown(self):
2294        for attr in (
2295            "mock_stub",
2296            "mock_si",
2297            "mock_ret",
2298            "mock_new_stub",
2299            "context_dict",
2300            "mock_context",
2301            "mock_create_default_context",
2302        ):
2303            delattr(self, attr)
2304
2305    def test_ssl_default_context_loaded(self):
2306        salt.utils.vmware.get_new_service_instance_stub(self.mock_si, "fake_path")
2307        self.mock_create_default_context.assert_called_once_with()
2308        self.assertFalse(self.mock_context.check_hostname)
2309        self.assertEqual(self.mock_context.verify_mode, salt.utils.vmware.ssl.CERT_NONE)
2310
2311    def test_session_cookie_in_context(self):
2312        salt.utils.vmware.get_new_service_instance_stub(self.mock_si, "fake_path")
2313        self.assertEqual(self.context_dict["vcSessionCookie"], "fake_cookie")
2314
2315    def test_get_new_stub(self):
2316        mock_get_new_stub = MagicMock()
2317        with patch("salt.utils.vmware.SoapStubAdapter", mock_get_new_stub):
2318            salt.utils.vmware.get_new_service_instance_stub(
2319                self.mock_si, "fake_path", "fake_ns", "fake_version"
2320            )
2321        mock_get_new_stub.assert_called_once_with(
2322            host="fake_host",
2323            ns="fake_ns",
2324            path="fake_path",
2325            version="fake_version",
2326            poolSize=0,
2327            sslContext=self.mock_context,
2328        )
2329
2330    def test_new_stub_returned(self):
2331        ret = salt.utils.vmware.get_new_service_instance_stub(self.mock_si, "fake_path")
2332        self.assertEqual(self.mock_new_stub.cookie, 'ignore"fake_cookie')
2333        self.assertEqual(ret, self.mock_new_stub)
2334
2335
2336@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2337class GetServiceInstanceFromManagedObjectTestCase(TestCase):
2338    """
2339    Tests for salt.utils.vmware.get_managed_instance_from_managed_object
2340    """
2341
2342    def setUp(self):
2343        patches = (("salt.utils.vmware.vim.ServiceInstance", MagicMock()),)
2344        for mod, mock in patches:
2345            patcher = patch(mod, mock)
2346            patcher.start()
2347            self.addCleanup(patcher.stop)
2348        self.mock_si = MagicMock()
2349        self.mock_stub = PropertyMock()
2350        self.mock_mo_ref = MagicMock(_stub=self.mock_stub)
2351        for attr in ("mock_si", "mock_stub", "mock_mo_ref"):
2352            self.addCleanup(delattr, self, attr)
2353
2354    def test_default_name_parameter(self):
2355        mock_trace = MagicMock()
2356        type(salt.utils.vmware.log).trace = mock_trace
2357        salt.utils.vmware.get_service_instance_from_managed_object(self.mock_mo_ref)
2358        mock_trace.assert_called_once_with(
2359            "[%s] Retrieving service instance from managed object", "<unnamed>"
2360        )
2361
2362    def test_name_parameter_passed_in(self):
2363        mock_trace = MagicMock()
2364        type(salt.utils.vmware.log).trace = mock_trace
2365        salt.utils.vmware.get_service_instance_from_managed_object(
2366            self.mock_mo_ref, "fake_mo_name"
2367        )
2368        mock_trace.assert_called_once_with(
2369            "[%s] Retrieving service instance from managed object", "fake_mo_name"
2370        )
2371
2372    def test_service_instance_instantiation(self):
2373        mock_service_instance_ini = MagicMock()
2374        with patch("salt.utils.vmware.vim.ServiceInstance", mock_service_instance_ini):
2375            salt.utils.vmware.get_service_instance_from_managed_object(self.mock_mo_ref)
2376        mock_service_instance_ini.assert_called_once_with("ServiceInstance")
2377
2378    def test_si_return_and_stub_assignment(self):
2379        with patch(
2380            "salt.utils.vmware.vim.ServiceInstance",
2381            MagicMock(return_value=self.mock_si),
2382        ):
2383            ret = salt.utils.vmware.get_service_instance_from_managed_object(
2384                self.mock_mo_ref
2385            )
2386        self.assertEqual(ret, self.mock_si)
2387        self.assertEqual(ret._stub, self.mock_stub)
2388
2389
2390@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2391class GetDatacentersTestCase(TestCase):
2392    """
2393    Tests for salt.utils.vmware.get_datacenters
2394    """
2395
2396    def setUp(self):
2397        patches = (
2398            (
2399                "salt.utils.vmware.get_mors_with_properties",
2400                MagicMock(return_value=[{"name": "fake_dc", "object": MagicMock()}]),
2401            ),
2402        )
2403        for mod, mock in patches:
2404            patcher = patch(mod, mock)
2405            patcher.start()
2406            self.addCleanup(patcher.stop)
2407        self.mock_si = MagicMock()
2408        self.mock_dc1 = MagicMock()
2409        self.mock_dc2 = MagicMock()
2410        self.mock_entries = [
2411            {"name": "fake_dc1", "object": self.mock_dc1},
2412            {"name": "fake_dc2", "object": self.mock_dc2},
2413        ]
2414
2415    def test_get_mors_with_properties_call(self):
2416        mock_get_mors_with_properties = MagicMock(
2417            return_value=[{"name": "fake_dc", "object": MagicMock()}]
2418        )
2419        with patch(
2420            "salt.utils.vmware.get_mors_with_properties", mock_get_mors_with_properties
2421        ):
2422            salt.utils.vmware.get_datacenters(
2423                self.mock_si, datacenter_names=["fake_dc1"]
2424            )
2425        mock_get_mors_with_properties.assert_called_once_with(
2426            self.mock_si, vim.Datacenter, property_list=["name"]
2427        )
2428
2429    def test_get_mors_with_properties_returns_empty_array(self):
2430        with patch(
2431            "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
2432        ):
2433            res = salt.utils.vmware.get_datacenters(
2434                self.mock_si, datacenter_names=["fake_dc1"]
2435            )
2436        self.assertEqual(res, [])
2437
2438    def test_no_parameters(self):
2439        with patch(
2440            "salt.utils.vmware.get_mors_with_properties",
2441            MagicMock(return_value=self.mock_entries),
2442        ):
2443            res = salt.utils.vmware.get_datacenters(self.mock_si)
2444        self.assertEqual(res, [])
2445
2446    def test_datastore_not_found(self):
2447        with patch(
2448            "salt.utils.vmware.get_mors_with_properties",
2449            MagicMock(return_value=self.mock_entries),
2450        ):
2451            res = salt.utils.vmware.get_datacenters(
2452                self.mock_si, datacenter_names=["fake_dc"]
2453            )
2454        self.assertEqual(res, [])
2455
2456    def test_datastore_found(self):
2457        with patch(
2458            "salt.utils.vmware.get_mors_with_properties",
2459            MagicMock(return_value=self.mock_entries),
2460        ):
2461            res = salt.utils.vmware.get_datacenters(
2462                self.mock_si, datacenter_names=["fake_dc2"]
2463            )
2464        self.assertEqual(res, [self.mock_dc2])
2465
2466    def test_get_all_datastores(self):
2467        with patch(
2468            "salt.utils.vmware.get_mors_with_properties",
2469            MagicMock(return_value=self.mock_entries),
2470        ):
2471            res = salt.utils.vmware.get_datacenters(
2472                self.mock_si, get_all_datacenters=True
2473            )
2474        self.assertEqual(res, [self.mock_dc1, self.mock_dc2])
2475
2476
2477@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2478class GetDatacenterTestCase(TestCase):
2479    """
2480    Tests for salt.utils.vmware.get_datacenter
2481    """
2482
2483    def setUp(self):
2484        patches = (
2485            (
2486                "salt.utils.vmware.get_datacenters",
2487                MagicMock(return_value=[MagicMock()]),
2488            ),
2489        )
2490        for mod, mock in patches:
2491            patcher = patch(mod, mock)
2492            patcher.start()
2493            self.addCleanup(patcher.stop)
2494        self.mock_si = MagicMock()
2495        self.mock_dc = MagicMock()
2496
2497    def test_get_datacenters_call(self):
2498        mock_get_datacenters = MagicMock(return_value=[MagicMock()])
2499        with patch("salt.utils.vmware.get_datacenters", mock_get_datacenters):
2500            salt.utils.vmware.get_datacenter(self.mock_si, "fake_dc1")
2501        mock_get_datacenters.assert_called_once_with(
2502            self.mock_si, datacenter_names=["fake_dc1"]
2503        )
2504
2505    def test_no_datacenters_returned(self):
2506        with patch("salt.utils.vmware.get_datacenters", MagicMock(return_value=[])):
2507            with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
2508                salt.utils.vmware.get_datacenter(self.mock_si, "fake_dc1")
2509        self.assertEqual(
2510            "Datacenter 'fake_dc1' was not found", excinfo.exception.strerror
2511        )
2512
2513    def test_get_datacenter_return(self):
2514        with patch(
2515            "salt.utils.vmware.get_datacenters", MagicMock(return_value=[self.mock_dc])
2516        ):
2517            res = salt.utils.vmware.get_datacenter(self.mock_si, "fake_dc1")
2518        self.assertEqual(res, self.mock_dc)
2519
2520
2521@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2522class CreateDatacenterTestCase(TestCase):
2523    """
2524    Tests for salt.utils.vmware.create_datacenter
2525    """
2526
2527    def setUp(self):
2528        patches = (("salt.utils.vmware.get_root_folder", MagicMock()),)
2529        for mod, mock in patches:
2530            patcher = patch(mod, mock)
2531            patcher.start()
2532            self.addCleanup(patcher.stop)
2533        self.mock_si = MagicMock()
2534        self.mock_dc = MagicMock()
2535        self.mock_create_datacenter = MagicMock(return_value=self.mock_dc)
2536        self.mock_root_folder = MagicMock(CreateDatacenter=self.mock_create_datacenter)
2537
2538    def test_get_root_folder(self):
2539        mock_get_root_folder = MagicMock()
2540        with patch("salt.utils.vmware.get_root_folder", mock_get_root_folder):
2541            salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2542        mock_get_root_folder.assert_called_once_with(self.mock_si)
2543
2544    def test_create_datacenter_call(self):
2545        with patch(
2546            "salt.utils.vmware.get_root_folder",
2547            MagicMock(return_value=self.mock_root_folder),
2548        ):
2549            salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2550        self.mock_create_datacenter.assert_called_once_with("fake_dc")
2551
2552    def test_create_datacenter_raise_no_permission(self):
2553        exc = vim.fault.NoPermission()
2554        exc.privilegeId = "Fake privilege"
2555        self.mock_root_folder = MagicMock(CreateDatacenter=MagicMock(side_effect=exc))
2556        with patch(
2557            "salt.utils.vmware.get_root_folder",
2558            MagicMock(return_value=self.mock_root_folder),
2559        ):
2560            with self.assertRaises(VMwareApiError) as excinfo:
2561                salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2562        self.assertEqual(
2563            excinfo.exception.strerror,
2564            "Not enough permissions. Required privilege: Fake privilege",
2565        )
2566
2567    def test_create_datacenter_raise_vim_fault(self):
2568        exc = vim.VimFault()
2569        exc.msg = "VimFault msg"
2570        self.mock_root_folder = MagicMock(CreateDatacenter=MagicMock(side_effect=exc))
2571        with patch(
2572            "salt.utils.vmware.get_root_folder",
2573            MagicMock(return_value=self.mock_root_folder),
2574        ):
2575            with self.assertRaises(VMwareApiError) as excinfo:
2576                salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2577        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2578
2579    def test_create_datacenter_runtime_fault(self):
2580        exc = vmodl.RuntimeFault()
2581        exc.msg = "RuntimeFault msg"
2582        self.mock_root_folder = MagicMock(CreateDatacenter=MagicMock(side_effect=exc))
2583        with patch(
2584            "salt.utils.vmware.get_root_folder",
2585            MagicMock(return_value=self.mock_root_folder),
2586        ):
2587            with self.assertRaises(VMwareRuntimeError) as excinfo:
2588                salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2589        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2590
2591    def test_datastore_successfully_created(self):
2592        with patch(
2593            "salt.utils.vmware.get_root_folder",
2594            MagicMock(return_value=self.mock_root_folder),
2595        ):
2596            res = salt.utils.vmware.create_datacenter(self.mock_si, "fake_dc")
2597        self.assertEqual(res, self.mock_dc)
2598
2599
2600class FakeTaskClass:
2601    pass
2602
2603
2604@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2605class GetDvssTestCase(TestCase):
2606    def setUp(self):
2607        self.mock_si = MagicMock()
2608        self.mock_dc_ref = MagicMock()
2609        self.mock_traversal_spec = MagicMock()
2610        self.mock_items = [
2611            {"object": MagicMock(), "name": "fake_dvs1"},
2612            {"object": MagicMock(), "name": "fake_dvs2"},
2613            {"object": MagicMock(), "name": "fake_dvs3"},
2614        ]
2615        self.mock_get_mors = MagicMock(return_value=self.mock_items)
2616
2617        patches = (
2618            ("salt.utils.vmware.get_managed_object_name", MagicMock()),
2619            ("salt.utils.vmware.get_mors_with_properties", self.mock_get_mors),
2620            (
2621                "salt.utils.vmware.get_service_instance_from_managed_object",
2622                MagicMock(return_value=self.mock_si),
2623            ),
2624            (
2625                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
2626                MagicMock(return_value=self.mock_traversal_spec),
2627            ),
2628        )
2629        for mod, mock in patches:
2630            patcher = patch(mod, mock)
2631            patcher.start()
2632            self.addCleanup(patcher.stop)
2633
2634    def tearDown(self):
2635        for attr in (
2636            "mock_si",
2637            "mock_dc_ref",
2638            "mock_traversal_spec",
2639            "mock_items",
2640            "mock_get_mors",
2641        ):
2642            delattr(self, attr)
2643
2644    def test_get_managed_object_name_call(self):
2645        mock_get_managed_object_name = MagicMock()
2646        with patch(
2647            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
2648        ):
2649            salt.utils.vmware.get_dvss(self.mock_dc_ref)
2650        mock_get_managed_object_name.assert_called_once_with(self.mock_dc_ref)
2651
2652    def test_traversal_spec(self):
2653        mock_traversal_spec = MagicMock(return_value="traversal_spec")
2654        with patch(
2655            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
2656            mock_traversal_spec,
2657        ):
2658
2659            salt.utils.vmware.get_dvss(self.mock_dc_ref)
2660        mock_traversal_spec.assert_has_calls(
2661            [
2662                call(path="childEntity", skip=False, type=vim.Folder),
2663                call(
2664                    path="networkFolder",
2665                    skip=True,
2666                    type=vim.Datacenter,
2667                    selectSet=["traversal_spec"],
2668                ),
2669            ]
2670        )
2671
2672    def test_get_mors_with_properties(self):
2673        salt.utils.vmware.get_dvss(self.mock_dc_ref)
2674        self.mock_get_mors.assert_called_once_with(
2675            self.mock_si,
2676            vim.DistributedVirtualSwitch,
2677            container_ref=self.mock_dc_ref,
2678            property_list=["name"],
2679            traversal_spec=self.mock_traversal_spec,
2680        )
2681
2682    def test_get_no_dvss(self):
2683        ret = salt.utils.vmware.get_dvss(self.mock_dc_ref)
2684        self.assertEqual(ret, [])
2685
2686    def test_get_all_dvss(self):
2687        ret = salt.utils.vmware.get_dvss(self.mock_dc_ref, get_all_dvss=True)
2688        self.assertEqual(ret, [i["object"] for i in self.mock_items])
2689
2690    def test_filtered_all_dvss(self):
2691        ret = salt.utils.vmware.get_dvss(
2692            self.mock_dc_ref, dvs_names=["fake_dvs1", "fake_dvs3", "no_dvs"]
2693        )
2694        self.assertEqual(
2695            ret, [self.mock_items[0]["object"], self.mock_items[2]["object"]]
2696        )
2697
2698
2699@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2700class GetNetworkFolderTestCase(TestCase):
2701    def setUp(self):
2702        self.mock_si = MagicMock()
2703        self.mock_dc_ref = MagicMock()
2704        self.mock_traversal_spec = MagicMock()
2705        self.mock_entries = [{"object": MagicMock(), "name": "fake_netw_folder"}]
2706        self.mock_get_mors = MagicMock(return_value=self.mock_entries)
2707
2708        patches = (
2709            (
2710                "salt.utils.vmware.get_managed_object_name",
2711                MagicMock(return_value="fake_dc"),
2712            ),
2713            (
2714                "salt.utils.vmware.get_service_instance_from_managed_object",
2715                MagicMock(return_value=self.mock_si),
2716            ),
2717            (
2718                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
2719                MagicMock(return_value=self.mock_traversal_spec),
2720            ),
2721            ("salt.utils.vmware.get_mors_with_properties", self.mock_get_mors),
2722        )
2723        for mod, mock in patches:
2724            patcher = patch(mod, mock)
2725            patcher.start()
2726            self.addCleanup(patcher.stop)
2727
2728    def tearDown(self):
2729        for attr in (
2730            "mock_si",
2731            "mock_dc_ref",
2732            "mock_traversal_spec",
2733            "mock_entries",
2734            "mock_get_mors",
2735        ):
2736            delattr(self, attr)
2737
2738    def test_get_managed_object_name_call(self):
2739        mock_get_managed_object_name = MagicMock()
2740        with patch(
2741            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
2742        ):
2743            salt.utils.vmware.get_network_folder(self.mock_dc_ref)
2744        mock_get_managed_object_name.assert_called_once_with(self.mock_dc_ref)
2745
2746    def test_traversal_spec(self):
2747        mock_traversal_spec = MagicMock(return_value="traversal_spec")
2748        with patch(
2749            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
2750            mock_traversal_spec,
2751        ):
2752
2753            salt.utils.vmware.get_network_folder(self.mock_dc_ref)
2754        mock_traversal_spec.assert_called_once_with(
2755            path="networkFolder", skip=False, type=vim.Datacenter
2756        )
2757
2758    def test_get_mors_with_properties(self):
2759        salt.utils.vmware.get_network_folder(self.mock_dc_ref)
2760        self.mock_get_mors.assert_called_once_with(
2761            self.mock_si,
2762            vim.Folder,
2763            container_ref=self.mock_dc_ref,
2764            property_list=["name"],
2765            traversal_spec=self.mock_traversal_spec,
2766        )
2767
2768    def test_get_no_network_folder(self):
2769        with patch(
2770            "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
2771        ):
2772            with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
2773                salt.utils.vmware.get_network_folder(self.mock_dc_ref)
2774        self.assertEqual(
2775            excinfo.exception.strerror,
2776            "Network folder in datacenter 'fake_dc' wasn't retrieved",
2777        )
2778
2779    def test_get_network_folder(self):
2780        ret = salt.utils.vmware.get_network_folder(self.mock_dc_ref)
2781        self.assertEqual(ret, self.mock_entries[0]["object"])
2782
2783
2784@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2785class CreateDvsTestCase(TestCase):
2786    def setUp(self):
2787        self.mock_dc_ref = MagicMock()
2788        self.mock_dvs_create_spec = MagicMock()
2789        self.mock_task = MagicMock(spec=FakeTaskClass)
2790        self.mock_netw_folder = MagicMock(
2791            CreateDVS_Task=MagicMock(return_value=self.mock_task)
2792        )
2793        self.mock_wait_for_task = MagicMock()
2794
2795        patches = (
2796            (
2797                "salt.utils.vmware.get_managed_object_name",
2798                MagicMock(return_value="fake_dc"),
2799            ),
2800            (
2801                "salt.utils.vmware.get_network_folder",
2802                MagicMock(return_value=self.mock_netw_folder),
2803            ),
2804            ("salt.utils.vmware.wait_for_task", self.mock_wait_for_task),
2805        )
2806        for mod, mock in patches:
2807            patcher = patch(mod, mock)
2808            patcher.start()
2809            self.addCleanup(patcher.stop)
2810
2811    def tearDown(self):
2812        for attr in (
2813            "mock_dc_ref",
2814            "mock_dvs_create_spec",
2815            "mock_task",
2816            "mock_netw_folder",
2817            "mock_wait_for_task",
2818        ):
2819            delattr(self, attr)
2820
2821    def test_get_managed_object_name_call(self):
2822        mock_get_managed_object_name = MagicMock()
2823        with patch(
2824            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
2825        ):
2826            salt.utils.vmware.create_dvs(self.mock_dc_ref, "fake_dvs")
2827        mock_get_managed_object_name.assert_called_once_with(self.mock_dc_ref)
2828
2829    def test_no_dvs_create_spec(self):
2830        mock_spec = MagicMock(configSpec=None)
2831        mock_config_spec = MagicMock()
2832        mock_dvs_create_spec = MagicMock(return_value=mock_spec)
2833        mock_vmware_dvs_config_spec = MagicMock(return_value=mock_config_spec)
2834        with patch("salt.utils.vmware.vim.DVSCreateSpec", mock_dvs_create_spec):
2835            with patch(
2836                "salt.utils.vmware.vim.VMwareDVSConfigSpec", mock_vmware_dvs_config_spec
2837            ):
2838                salt.utils.vmware.create_dvs(self.mock_dc_ref, "fake_dvs")
2839        mock_dvs_create_spec.assert_called_once_with()
2840        mock_vmware_dvs_config_spec.assert_called_once_with()
2841        self.assertEqual(mock_spec.configSpec, mock_config_spec)
2842        self.assertEqual(mock_config_spec.name, "fake_dvs")
2843        self.mock_netw_folder.CreateDVS_Task.assert_called_once_with(mock_spec)
2844
2845    def test_get_network_folder(self):
2846        mock_get_network_folder = MagicMock()
2847        with patch("salt.utils.vmware.get_network_folder", mock_get_network_folder):
2848            salt.utils.vmware.create_dvs(self.mock_dc_ref, "fake_dvs")
2849        mock_get_network_folder.assert_called_once_with(self.mock_dc_ref)
2850
2851    def test_create_dvs_task_passed_in_spec(self):
2852        salt.utils.vmware.create_dvs(
2853            self.mock_dc_ref, "fake_dvs", dvs_create_spec=self.mock_dvs_create_spec
2854        )
2855        self.mock_netw_folder.CreateDVS_Task.assert_called_once_with(
2856            self.mock_dvs_create_spec
2857        )
2858
2859    def test_create_dvs_task_raises_no_permission(self):
2860        exc = vim.fault.NoPermission()
2861        exc.privilegeId = "Fake privilege"
2862        self.mock_netw_folder.CreateDVS_Task = MagicMock(side_effect=exc)
2863        with self.assertRaises(VMwareApiError) as excinfo:
2864            salt.utils.vmware.create_dvs(
2865                self.mock_dc_ref, "fake_dvs", dvs_create_spec=self.mock_dvs_create_spec
2866            )
2867        self.assertEqual(
2868            excinfo.exception.strerror,
2869            "Not enough permissions. Required privilege: Fake privilege",
2870        )
2871
2872    def test_create_dvs_task_raises_vim_fault(self):
2873        exc = vim.fault.VimFault()
2874        exc.msg = "VimFault msg"
2875        self.mock_netw_folder.CreateDVS_Task = MagicMock(side_effect=exc)
2876        with self.assertRaises(VMwareApiError) as excinfo:
2877            salt.utils.vmware.create_dvs(
2878                self.mock_dc_ref, "fake_dvs", dvs_create_spec=self.mock_dvs_create_spec
2879            )
2880        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2881
2882    def test_create_dvs_task_raises_runtime_fault(self):
2883        exc = vmodl.RuntimeFault()
2884        exc.msg = "RuntimeFault msg"
2885        self.mock_netw_folder.CreateDVS_Task = MagicMock(side_effect=exc)
2886        with self.assertRaises(VMwareRuntimeError) as excinfo:
2887            salt.utils.vmware.create_dvs(
2888                self.mock_dc_ref, "fake_dvs", dvs_create_spec=self.mock_dvs_create_spec
2889            )
2890        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2891
2892    def test_wait_for_tasks(self):
2893        salt.utils.vmware.create_dvs(
2894            self.mock_dc_ref, "fake_dvs", dvs_create_spec=self.mock_dvs_create_spec
2895        )
2896        self.mock_wait_for_task.assert_called_once_with(
2897            self.mock_task,
2898            "fake_dvs",
2899            "<class 'tests.unit.utils.test_vmware.FakeTaskClass'>",
2900        )
2901
2902
2903@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2904class UpdateDvsTestCase(TestCase):
2905    def setUp(self):
2906        self.mock_task = MagicMock(spec=FakeTaskClass)
2907        self.mock_dvs_ref = MagicMock(
2908            ReconfigureDvs_Task=MagicMock(return_value=self.mock_task)
2909        )
2910        self.mock_dvs_spec = MagicMock()
2911        self.mock_wait_for_task = MagicMock()
2912
2913        patches = (
2914            (
2915                "salt.utils.vmware.get_managed_object_name",
2916                MagicMock(return_value="fake_dvs"),
2917            ),
2918            ("salt.utils.vmware.wait_for_task", self.mock_wait_for_task),
2919        )
2920        for mod, mock in patches:
2921            patcher = patch(mod, mock)
2922            patcher.start()
2923            self.addCleanup(patcher.stop)
2924
2925    def tearDown(self):
2926        for attr in (
2927            "mock_dvs_ref",
2928            "mock_task",
2929            "mock_dvs_spec",
2930            "mock_wait_for_task",
2931        ):
2932            delattr(self, attr)
2933
2934    def test_get_managed_object_name_call(self):
2935        mock_get_managed_object_name = MagicMock()
2936        with patch(
2937            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
2938        ):
2939            salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2940        mock_get_managed_object_name.assert_called_once_with(self.mock_dvs_ref)
2941
2942    def test_reconfigure_dvs_task(self):
2943        salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2944        self.mock_dvs_ref.ReconfigureDvs_Task.assert_called_once_with(
2945            self.mock_dvs_spec
2946        )
2947
2948    def test_reconfigure_dvs_task_raises_no_permission(self):
2949        exc = vim.fault.NoPermission()
2950        exc.privilegeId = "Fake privilege"
2951        self.mock_dvs_ref.ReconfigureDvs_Task = MagicMock(side_effect=exc)
2952        with self.assertRaises(VMwareApiError) as excinfo:
2953            salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2954        self.assertEqual(
2955            excinfo.exception.strerror,
2956            "Not enough permissions. Required privilege: Fake privilege",
2957        )
2958
2959    def test_reconfigure_dvs_task_raises_vim_fault(self):
2960        exc = vim.fault.VimFault()
2961        exc.msg = "VimFault msg"
2962        self.mock_dvs_ref.ReconfigureDvs_Task = MagicMock(side_effect=exc)
2963        with self.assertRaises(VMwareApiError) as excinfo:
2964            salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2965        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
2966
2967    def test_reconfigure_dvs_task_raises_runtime_fault(self):
2968        exc = vmodl.RuntimeFault()
2969        exc.msg = "RuntimeFault msg"
2970        self.mock_dvs_ref.ReconfigureDvs_Task = MagicMock(side_effect=exc)
2971        with self.assertRaises(VMwareRuntimeError) as excinfo:
2972            salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2973        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
2974
2975    def test_wait_for_tasks(self):
2976        salt.utils.vmware.update_dvs(self.mock_dvs_ref, self.mock_dvs_spec)
2977        self.mock_wait_for_task.assert_called_once_with(
2978            self.mock_task,
2979            "fake_dvs",
2980            "<class 'tests.unit.utils.test_vmware.FakeTaskClass'>",
2981        )
2982
2983
2984@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
2985class SetDvsNetworkResourceManagementEnabledTestCase(TestCase):
2986    def setUp(self):
2987        self.mock_enabled = MagicMock()
2988        self.mock_dvs_ref = MagicMock(EnableNetworkResourceManagement=MagicMock())
2989
2990        patches = (
2991            (
2992                "salt.utils.vmware.get_managed_object_name",
2993                MagicMock(return_value="fake_dvs"),
2994            ),
2995        )
2996        for mod, mock in patches:
2997            patcher = patch(mod, mock)
2998            patcher.start()
2999            self.addCleanup(patcher.stop)
3000
3001    def tearDown(self):
3002        for attr in ("mock_dvs_ref", "mock_enabled"):
3003            delattr(self, attr)
3004
3005    def test_get_managed_object_name_call(self):
3006        mock_get_managed_object_name = MagicMock()
3007        with patch(
3008            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3009        ):
3010            salt.utils.vmware.set_dvs_network_resource_management_enabled(
3011                self.mock_dvs_ref, self.mock_enabled
3012            )
3013        mock_get_managed_object_name.assert_called_once_with(self.mock_dvs_ref)
3014
3015    def test_enable_network_resource_management(self):
3016        salt.utils.vmware.set_dvs_network_resource_management_enabled(
3017            self.mock_dvs_ref, self.mock_enabled
3018        )
3019        self.mock_dvs_ref.EnableNetworkResourceManagement.assert_called_once_with(
3020            enable=self.mock_enabled
3021        )
3022
3023    def test_enable_network_resource_management_raises_no_permission(self):
3024        exc = vim.fault.NoPermission()
3025        exc.privilegeId = "Fake privilege"
3026        self.mock_dvs_ref.EnableNetworkResourceManagement = MagicMock(side_effect=exc)
3027        with self.assertRaises(VMwareApiError) as excinfo:
3028            salt.utils.vmware.set_dvs_network_resource_management_enabled(
3029                self.mock_dvs_ref, self.mock_enabled
3030            )
3031        self.assertEqual(
3032            excinfo.exception.strerror,
3033            "Not enough permissions. Required privilege: Fake privilege",
3034        )
3035
3036    def test_enable_network_resource_management_raises_vim_fault(self):
3037        exc = vim.fault.VimFault()
3038        exc.msg = "VimFault msg"
3039        self.mock_dvs_ref.EnableNetworkResourceManagement = MagicMock(side_effect=exc)
3040        with self.assertRaises(VMwareApiError) as excinfo:
3041            salt.utils.vmware.set_dvs_network_resource_management_enabled(
3042                self.mock_dvs_ref, self.mock_enabled
3043            )
3044
3045    def test_enable_network_resource_management_raises_runtime_fault(self):
3046        exc = vmodl.RuntimeFault()
3047        exc.msg = "RuntimeFault msg"
3048        self.mock_dvs_ref.EnableNetworkResourceManagement = MagicMock(side_effect=exc)
3049        with self.assertRaises(VMwareRuntimeError) as excinfo:
3050            salt.utils.vmware.set_dvs_network_resource_management_enabled(
3051                self.mock_dvs_ref, self.mock_enabled
3052            )
3053        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3054
3055
3056@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3057class GetDvportgroupsTestCase(TestCase):
3058    def setUp(self):
3059        self.mock_si = MagicMock()
3060        self.mock_dc_ref = MagicMock(spec=vim.Datacenter)
3061        self.mock_dvs_ref = MagicMock(spec=vim.DistributedVirtualSwitch)
3062        self.mock_traversal_spec = MagicMock()
3063        self.mock_items = [
3064            {"object": MagicMock(), "name": "fake_pg1"},
3065            {"object": MagicMock(), "name": "fake_pg2"},
3066            {"object": MagicMock(), "name": "fake_pg3"},
3067        ]
3068        self.mock_get_mors = MagicMock(return_value=self.mock_items)
3069
3070        patches = (
3071            ("salt.utils.vmware.get_managed_object_name", MagicMock()),
3072            ("salt.utils.vmware.get_mors_with_properties", self.mock_get_mors),
3073            (
3074                "salt.utils.vmware.get_service_instance_from_managed_object",
3075                MagicMock(return_value=self.mock_si),
3076            ),
3077            (
3078                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
3079                MagicMock(return_value=self.mock_traversal_spec),
3080            ),
3081        )
3082        for mod, mock in patches:
3083            patcher = patch(mod, mock)
3084            patcher.start()
3085            self.addCleanup(patcher.stop)
3086
3087    def tearDown(self):
3088        for attr in (
3089            "mock_si",
3090            "mock_dc_ref",
3091            "mock_dvs_ref",
3092            "mock_traversal_spec",
3093            "mock_items",
3094            "mock_get_mors",
3095        ):
3096            delattr(self, attr)
3097
3098    def test_unsupported_parrent(self):
3099        with self.assertRaises(ArgumentValueError) as excinfo:
3100            salt.utils.vmware.get_dvportgroups(MagicMock())
3101        self.assertEqual(
3102            excinfo.exception.strerror,
3103            "Parent has to be either a datacenter, or a distributed virtual switch",
3104        )
3105
3106    def test_get_managed_object_name_call(self):
3107        mock_get_managed_object_name = MagicMock()
3108        with patch(
3109            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3110        ):
3111            salt.utils.vmware.get_dvportgroups(self.mock_dc_ref)
3112        mock_get_managed_object_name.assert_called_once_with(self.mock_dc_ref)
3113
3114    def test_traversal_spec_datacenter_parent(self):
3115        mock_traversal_spec = MagicMock(return_value="traversal_spec")
3116        with patch(
3117            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
3118            mock_traversal_spec,
3119        ):
3120
3121            salt.utils.vmware.get_dvportgroups(self.mock_dc_ref)
3122        mock_traversal_spec.assert_has_calls(
3123            [
3124                call(path="childEntity", skip=False, type=vim.Folder),
3125                call(
3126                    path="networkFolder",
3127                    skip=True,
3128                    type=vim.Datacenter,
3129                    selectSet=["traversal_spec"],
3130                ),
3131            ]
3132        )
3133
3134    def test_traversal_spec_dvs_parent(self):
3135        mock_traversal_spec = MagicMock(return_value="traversal_spec")
3136        with patch(
3137            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
3138            mock_traversal_spec,
3139        ):
3140
3141            salt.utils.vmware.get_dvportgroups(self.mock_dvs_ref)
3142        mock_traversal_spec.assert_called_once_with(
3143            path="portgroup", skip=False, type=vim.DistributedVirtualSwitch
3144        )
3145
3146    def test_get_mors_with_properties(self):
3147        salt.utils.vmware.get_dvportgroups(self.mock_dvs_ref)
3148        self.mock_get_mors.assert_called_once_with(
3149            self.mock_si,
3150            vim.DistributedVirtualPortgroup,
3151            container_ref=self.mock_dvs_ref,
3152            property_list=["name"],
3153            traversal_spec=self.mock_traversal_spec,
3154        )
3155
3156    def test_get_no_pgs(self):
3157        ret = salt.utils.vmware.get_dvportgroups(self.mock_dvs_ref)
3158        self.assertEqual(ret, [])
3159
3160    def test_get_all_pgs(self):
3161        ret = salt.utils.vmware.get_dvportgroups(
3162            self.mock_dvs_ref, get_all_portgroups=True
3163        )
3164        self.assertEqual(ret, [i["object"] for i in self.mock_items])
3165
3166    def test_filtered_pgs(self):
3167        ret = salt.utils.vmware.get_dvss(
3168            self.mock_dc_ref, dvs_names=["fake_pg1", "fake_pg3", "no_pg"]
3169        )
3170        self.assertEqual(
3171            ret, [self.mock_items[0]["object"], self.mock_items[2]["object"]]
3172        )
3173
3174
3175@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3176class GetUplinkDvportgroupTestCase(TestCase):
3177    def setUp(self):
3178        self.mock_si = MagicMock()
3179        self.mock_dvs_ref = MagicMock(spec=vim.DistributedVirtualSwitch)
3180        self.mock_traversal_spec = MagicMock()
3181        self.mock_items = [
3182            {"object": MagicMock(), "tag": [MagicMock(key="fake_tag")]},
3183            {"object": MagicMock(), "tag": [MagicMock(key="SYSTEM/DVS.UPLINKPG")]},
3184        ]
3185        self.mock_get_mors = MagicMock(return_value=self.mock_items)
3186
3187        patches = (
3188            (
3189                "salt.utils.vmware.get_managed_object_name",
3190                MagicMock(return_value="fake_dvs"),
3191            ),
3192            ("salt.utils.vmware.get_mors_with_properties", self.mock_get_mors),
3193            (
3194                "salt.utils.vmware.get_service_instance_from_managed_object",
3195                MagicMock(return_value=self.mock_si),
3196            ),
3197            (
3198                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
3199                MagicMock(return_value=self.mock_traversal_spec),
3200            ),
3201        )
3202        for mod, mock in patches:
3203            patcher = patch(mod, mock)
3204            patcher.start()
3205            self.addCleanup(patcher.stop)
3206
3207    def tearDown(self):
3208        for attr in (
3209            "mock_si",
3210            "mock_dvs_ref",
3211            "mock_traversal_spec",
3212            "mock_items",
3213            "mock_get_mors",
3214        ):
3215            delattr(self, attr)
3216
3217    def test_get_managed_object_name_call(self):
3218        mock_get_managed_object_name = MagicMock()
3219        with patch(
3220            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3221        ):
3222            salt.utils.vmware.get_uplink_dvportgroup(self.mock_dvs_ref)
3223        mock_get_managed_object_name.assert_called_once_with(self.mock_dvs_ref)
3224
3225    def test_traversal_spec(self):
3226        mock_traversal_spec = MagicMock(return_value="traversal_spec")
3227        with patch(
3228            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
3229            mock_traversal_spec,
3230        ):
3231
3232            salt.utils.vmware.get_uplink_dvportgroup(self.mock_dvs_ref)
3233        mock_traversal_spec.assert_called_once_with(
3234            path="portgroup", skip=False, type=vim.DistributedVirtualSwitch
3235        )
3236
3237    def test_get_mors_with_properties(self):
3238        salt.utils.vmware.get_uplink_dvportgroup(self.mock_dvs_ref)
3239        self.mock_get_mors.assert_called_once_with(
3240            self.mock_si,
3241            vim.DistributedVirtualPortgroup,
3242            container_ref=self.mock_dvs_ref,
3243            property_list=["tag"],
3244            traversal_spec=self.mock_traversal_spec,
3245        )
3246
3247    def test_get_no_uplink_pg(self):
3248        with patch(
3249            "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
3250        ):
3251            with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
3252                salt.utils.vmware.get_uplink_dvportgroup(self.mock_dvs_ref)
3253        self.assertEqual(
3254            excinfo.exception.strerror,
3255            "Uplink portgroup of DVS 'fake_dvs' wasn't found",
3256        )
3257
3258    def test_get_uplink_pg(self):
3259        ret = salt.utils.vmware.get_uplink_dvportgroup(self.mock_dvs_ref)
3260        self.assertEqual(ret, self.mock_items[1]["object"])
3261
3262
3263@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3264class CreateDvportgroupTestCase(TestCase):
3265    def setUp(self):
3266        self.mock_pg_spec = MagicMock()
3267        self.mock_task = MagicMock(spec=FakeTaskClass)
3268        self.mock_dvs_ref = MagicMock(
3269            CreateDVPortgroup_Task=MagicMock(return_value=self.mock_task)
3270        )
3271        self.mock_wait_for_task = MagicMock()
3272
3273        patches = (
3274            (
3275                "salt.utils.vmware.get_managed_object_name",
3276                MagicMock(return_value="fake_dvs"),
3277            ),
3278            ("salt.utils.vmware.wait_for_task", self.mock_wait_for_task),
3279        )
3280        for mod, mock in patches:
3281            patcher = patch(mod, mock)
3282            patcher.start()
3283            self.addCleanup(patcher.stop)
3284
3285    def tearDown(self):
3286        for attr in ("mock_pg_spec", "mock_dvs_ref", "mock_task", "mock_wait_for_task"):
3287            delattr(self, attr)
3288
3289    def test_get_managed_object_name_call(self):
3290        mock_get_managed_object_name = MagicMock()
3291        with patch(
3292            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3293        ):
3294            salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3295        mock_get_managed_object_name.assert_called_once_with(self.mock_dvs_ref)
3296
3297    def test_create_dvporgroup_task(self):
3298        salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3299        self.mock_dvs_ref.CreateDVPortgroup_Task.assert_called_once_with(
3300            self.mock_pg_spec
3301        )
3302
3303    def test_create_dvporgroup_task_raises_no_permission(self):
3304        exc = vim.fault.NoPermission()
3305        exc.privilegeId = "Fake privilege"
3306        self.mock_dvs_ref.CreateDVPortgroup_Task = MagicMock(side_effect=exc)
3307        with self.assertRaises(VMwareApiError) as excinfo:
3308            salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3309        self.assertEqual(
3310            excinfo.exception.strerror,
3311            "Not enough permissions. Required privilege: Fake privilege",
3312        )
3313
3314    def test_create_dvporgroup_task_raises_vim_fault(self):
3315        exc = vim.fault.VimFault()
3316        exc.msg = "VimFault msg"
3317        self.mock_dvs_ref.CreateDVPortgroup_Task = MagicMock(side_effect=exc)
3318        with self.assertRaises(VMwareApiError) as excinfo:
3319            salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3320        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3321
3322    def test_create_dvporgroup_task_raises_runtime_fault(self):
3323        exc = vmodl.RuntimeFault()
3324        exc.msg = "RuntimeFault msg"
3325        self.mock_dvs_ref.CreateDVPortgroup_Task = MagicMock(side_effect=exc)
3326        with self.assertRaises(VMwareRuntimeError) as excinfo:
3327            salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3328        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3329
3330    def test_wait_for_tasks(self):
3331        salt.utils.vmware.create_dvportgroup(self.mock_dvs_ref, self.mock_pg_spec)
3332        self.mock_wait_for_task.assert_called_once_with(
3333            self.mock_task,
3334            "fake_dvs",
3335            "<class 'tests.unit.utils.test_vmware.FakeTaskClass'>",
3336        )
3337
3338
3339@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3340class UpdateDvportgroupTestCase(TestCase):
3341    def setUp(self):
3342        self.mock_pg_spec = MagicMock()
3343        self.mock_task = MagicMock(spec=FakeTaskClass)
3344        self.mock_pg_ref = MagicMock(
3345            ReconfigureDVPortgroup_Task=MagicMock(return_value=self.mock_task)
3346        )
3347        self.mock_wait_for_task = MagicMock()
3348
3349        patches = (
3350            (
3351                "salt.utils.vmware.get_managed_object_name",
3352                MagicMock(return_value="fake_pg"),
3353            ),
3354            ("salt.utils.vmware.wait_for_task", self.mock_wait_for_task),
3355        )
3356        for mod, mock in patches:
3357            patcher = patch(mod, mock)
3358            patcher.start()
3359            self.addCleanup(patcher.stop)
3360
3361    def tearDown(self):
3362        for attr in ("mock_pg_spec", "mock_pg_ref", "mock_task", "mock_wait_for_task"):
3363            delattr(self, attr)
3364
3365    def test_get_managed_object_name_call(self):
3366        mock_get_managed_object_name = MagicMock()
3367        with patch(
3368            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3369        ):
3370            salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3371        mock_get_managed_object_name.assert_called_once_with(self.mock_pg_ref)
3372
3373    def test_reconfigure_dvporgroup_task(self):
3374        salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3375        self.mock_pg_ref.ReconfigureDVPortgroup_Task.assert_called_once_with(
3376            self.mock_pg_spec
3377        )
3378
3379    def test_reconfigure_dvporgroup_task_raises_no_permission(self):
3380        exc = vim.fault.NoPermission()
3381        exc.privilegeId = "Fake privilege"
3382        self.mock_pg_ref.ReconfigureDVPortgroup_Task = MagicMock(side_effect=exc)
3383        with self.assertRaises(VMwareApiError) as excinfo:
3384            salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3385        self.assertEqual(
3386            excinfo.exception.strerror,
3387            "Not enough permissions. Required privilege: Fake privilege",
3388        )
3389
3390    def test_reconfigure_dvporgroup_task_raises_vim_fault(self):
3391        exc = vim.fault.VimFault()
3392        exc.msg = "VimFault msg"
3393        self.mock_pg_ref.ReconfigureDVPortgroup_Task = MagicMock(side_effect=exc)
3394        with self.assertRaises(VMwareApiError) as excinfo:
3395            salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3396        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3397
3398    def test_reconfigure_dvporgroup_task_raises_runtime_fault(self):
3399        exc = vmodl.RuntimeFault()
3400        exc.msg = "RuntimeFault msg"
3401        self.mock_pg_ref.ReconfigureDVPortgroup_Task = MagicMock(side_effect=exc)
3402        with self.assertRaises(VMwareRuntimeError) as excinfo:
3403            salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3404        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3405
3406    def test_wait_for_tasks(self):
3407        salt.utils.vmware.update_dvportgroup(self.mock_pg_ref, self.mock_pg_spec)
3408        self.mock_wait_for_task.assert_called_once_with(
3409            self.mock_task,
3410            "fake_pg",
3411            "<class 'tests.unit.utils.test_vmware.FakeTaskClass'>",
3412        )
3413
3414
3415@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3416class RemoveDvportgroupTestCase(TestCase):
3417    def setUp(self):
3418        self.mock_task = MagicMock(spec=FakeTaskClass)
3419        self.mock_pg_ref = MagicMock(
3420            Destroy_Task=MagicMock(return_value=self.mock_task)
3421        )
3422        self.mock_wait_for_task = MagicMock()
3423
3424        patches = (
3425            (
3426                "salt.utils.vmware.get_managed_object_name",
3427                MagicMock(return_value="fake_pg"),
3428            ),
3429            ("salt.utils.vmware.wait_for_task", self.mock_wait_for_task),
3430        )
3431        for mod, mock in patches:
3432            patcher = patch(mod, mock)
3433            patcher.start()
3434            self.addCleanup(patcher.stop)
3435
3436    def tearDown(self):
3437        for attr in ("mock_pg_ref", "mock_task", "mock_wait_for_task"):
3438            delattr(self, attr)
3439
3440    def test_get_managed_object_name_call(self):
3441        mock_get_managed_object_name = MagicMock()
3442        with patch(
3443            "salt.utils.vmware.get_managed_object_name", mock_get_managed_object_name
3444        ):
3445            salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3446        mock_get_managed_object_name.assert_called_once_with(self.mock_pg_ref)
3447
3448    def test_destroy_task(self):
3449        salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3450        self.mock_pg_ref.Destroy_Task.assert_called_once_with()
3451
3452    def test_destroy_task_raises_no_permission(self):
3453        exc = vim.fault.NoPermission()
3454        exc.privilegeId = "Fake privilege"
3455        self.mock_pg_ref.Destroy_Task = MagicMock(side_effect=exc)
3456        with self.assertRaises(VMwareApiError) as excinfo:
3457            salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3458        self.assertEqual(
3459            excinfo.exception.strerror,
3460            "Not enough permissions. Required privilege: Fake privilege",
3461        )
3462
3463    def test_destroy_treconfigure_dvporgroup_task_raises_vim_fault(self):
3464        exc = vim.fault.VimFault()
3465        exc.msg = "VimFault msg"
3466        self.mock_pg_ref.Destroy_Task = MagicMock(side_effect=exc)
3467        with self.assertRaises(VMwareApiError) as excinfo:
3468            salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3469        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3470
3471    def test_destroy_treconfigure_dvporgroup_task_raises_runtime_fault(self):
3472        exc = vmodl.RuntimeFault()
3473        exc.msg = "RuntimeFault msg"
3474        self.mock_pg_ref.Destroy_Task = MagicMock(side_effect=exc)
3475        with self.assertRaises(VMwareRuntimeError) as excinfo:
3476            salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3477        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3478
3479    def test_wait_for_tasks(self):
3480        salt.utils.vmware.remove_dvportgroup(self.mock_pg_ref)
3481        self.mock_wait_for_task.assert_called_once_with(
3482            self.mock_task,
3483            "fake_pg",
3484            "<class 'tests.unit.utils.test_vmware.FakeTaskClass'>",
3485        )
3486
3487
3488@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3489class GetHostsTestCase(TestCase):
3490    """
3491    Tests for salt.utils.vmware.get_hosts
3492    """
3493
3494    def setUp(self):
3495        patches = (
3496            ("salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])),
3497            ("salt.utils.vmware.get_datacenter", MagicMock(return_value=None)),
3498            ("salt.utils.vmware.get_cluster", MagicMock(return_value=None)),
3499        )
3500        for mod, mock in patches:
3501            patcher = patch(mod, mock)
3502            patcher.start()
3503            self.addCleanup(patcher.stop)
3504        self.mock_root_folder = MagicMock()
3505        self.mock_si = MagicMock()
3506        self.mock_host1, self.mock_host2, self.mock_host3 = (
3507            MagicMock(),
3508            MagicMock(),
3509            MagicMock(),
3510        )
3511        self.mock_prop_host1 = {"name": "fake_hostname1", "object": self.mock_host1}
3512        self.mock_prop_host2 = {"name": "fake_hostname2", "object": self.mock_host2}
3513        self.mock_prop_host3 = {"name": "fake_hostname3", "object": self.mock_host3}
3514        self.mock_prop_hosts = [
3515            self.mock_prop_host1,
3516            self.mock_prop_host2,
3517            self.mock_prop_host3,
3518        ]
3519
3520    def test_cluster_no_datacenter(self):
3521        with self.assertRaises(ArgumentValueError) as excinfo:
3522            salt.utils.vmware.get_hosts(self.mock_si, cluster_name="fake_cluster")
3523        self.assertEqual(
3524            excinfo.exception.strerror,
3525            "Must specify the datacenter when specifying the cluster",
3526        )
3527
3528    def test_get_si_no_datacenter_no_cluster(self):
3529        mock_get_mors = MagicMock()
3530        mock_get_root_folder = MagicMock(return_value=self.mock_root_folder)
3531        with patch("salt.utils.vmware.get_root_folder", mock_get_root_folder):
3532            with patch("salt.utils.vmware.get_mors_with_properties", mock_get_mors):
3533                salt.utils.vmware.get_hosts(self.mock_si)
3534        mock_get_root_folder.assert_called_once_with(self.mock_si)
3535        mock_get_mors.assert_called_once_with(
3536            self.mock_si,
3537            vim.HostSystem,
3538            container_ref=self.mock_root_folder,
3539            property_list=["name"],
3540        )
3541
3542    def test_get_si_datacenter_name_no_cluster_name(self):
3543        mock_dc = MagicMock()
3544        mock_get_dc = MagicMock(return_value=mock_dc)
3545        mock_get_mors = MagicMock()
3546        with patch("salt.utils.vmware.get_datacenter", mock_get_dc):
3547            with patch("salt.utils.vmware.get_mors_with_properties", mock_get_mors):
3548                salt.utils.vmware.get_hosts(
3549                    self.mock_si, datacenter_name="fake_datacenter"
3550                )
3551        mock_get_dc.assert_called_once_with(self.mock_si, "fake_datacenter")
3552        mock_get_mors.assert_called_once_with(
3553            self.mock_si, vim.HostSystem, container_ref=mock_dc, property_list=["name"]
3554        )
3555
3556    def test_get_si_datacenter_name_and_cluster_name(self):
3557        mock_dc = MagicMock()
3558        mock_get_dc = MagicMock(return_value=mock_dc)
3559        mock_get_cl = MagicMock()
3560        mock_get_mors = MagicMock()
3561        with patch("salt.utils.vmware.get_datacenter", mock_get_dc):
3562            with patch("salt.utils.vmware.get_cluster", mock_get_cl):
3563                with patch("salt.utils.vmware.get_mors_with_properties", mock_get_mors):
3564                    salt.utils.vmware.get_hosts(
3565                        self.mock_si,
3566                        datacenter_name="fake_datacenter",
3567                        cluster_name="fake_cluster",
3568                    )
3569        mock_get_dc.assert_called_once_with(self.mock_si, "fake_datacenter")
3570        mock_get_mors.assert_called_once_with(
3571            self.mock_si,
3572            vim.HostSystem,
3573            container_ref=mock_dc,
3574            property_list=["name", "parent"],
3575        )
3576
3577    def test_host_get_all_hosts(self):
3578        with patch(
3579            "salt.utils.vmware.get_root_folder",
3580            MagicMock(return_value=self.mock_root_folder),
3581        ):
3582            with patch(
3583                "salt.utils.vmware.get_mors_with_properties",
3584                MagicMock(return_value=self.mock_prop_hosts),
3585            ):
3586                res = salt.utils.vmware.get_hosts(self.mock_si, get_all_hosts=True)
3587        self.assertEqual(res, [self.mock_host1, self.mock_host2, self.mock_host3])
3588
3589    def test_filter_hostname(self):
3590        with patch(
3591            "salt.utils.vmware.get_mors_with_properties",
3592            MagicMock(return_value=self.mock_prop_hosts),
3593        ):
3594            res = salt.utils.vmware.get_hosts(
3595                self.mock_si, host_names=["fake_hostname1", "fake_hostname2"]
3596            )
3597        self.assertEqual(res, [self.mock_host1, self.mock_host2])
3598
3599    def test_get_all_host_flag_not_set_and_no_host_names(self):
3600        with patch(
3601            "salt.utils.vmware.get_mors_with_properties",
3602            MagicMock(return_value=self.mock_prop_hosts),
3603        ):
3604            res = salt.utils.vmware.get_hosts(self.mock_si)
3605        self.assertEqual(res, [])
3606
3607    def test_filter_cluster(self):
3608        self.mock_prop_host1["parent"] = vim.ClusterComputeResource("cluster")
3609        self.mock_prop_host2["parent"] = vim.ClusterComputeResource("cluster")
3610        self.mock_prop_host3["parent"] = vim.Datacenter("dc")
3611        mock_get_cl_name = MagicMock(
3612            side_effect=["fake_bad_cluster", "fake_good_cluster"]
3613        )
3614        with patch(
3615            "salt.utils.vmware.get_mors_with_properties",
3616            MagicMock(return_value=self.mock_prop_hosts),
3617        ):
3618            with patch("salt.utils.vmware.get_managed_object_name", mock_get_cl_name):
3619                res = salt.utils.vmware.get_hosts(
3620                    self.mock_si,
3621                    datacenter_name="fake_datacenter",
3622                    cluster_name="fake_good_cluster",
3623                    get_all_hosts=True,
3624                )
3625        self.assertEqual(mock_get_cl_name.call_count, 2)
3626        self.assertEqual(res, [self.mock_host2])
3627
3628    def test_no_hosts(self):
3629        with patch(
3630            "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
3631        ):
3632            res = salt.utils.vmware.get_hosts(self.mock_si, get_all_hosts=True)
3633        self.assertEqual(res, [])
3634
3635    def test_one_host_returned(self):
3636        with patch(
3637            "salt.utils.vmware.get_mors_with_properties",
3638            MagicMock(return_value=[self.mock_prop_host1]),
3639        ):
3640            res = salt.utils.vmware.get_hosts(self.mock_si, get_all_hosts=True)
3641        self.assertEqual(res, [self.mock_host1])
3642
3643
3644@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3645class GetLicenseManagerTestCase(TestCase):
3646    """
3647    Tests for salt.utils.vmware.get_license_manager
3648    """
3649
3650    def setUp(self):
3651        self.mock_si = MagicMock()
3652        self.mock_lic_mgr = MagicMock()
3653        type(self.mock_si.content).licenseManager = PropertyMock(
3654            return_value=self.mock_lic_mgr
3655        )
3656
3657    def tearDown(self):
3658        for attr in ("mock_si", "mock_lic_mgr"):
3659            delattr(self, attr)
3660
3661    def test_raise_no_permission(self):
3662        exc = vim.fault.NoPermission()
3663        exc.privilegeId = "Fake privilege"
3664        type(self.mock_si.content).licenseManager = PropertyMock(side_effect=exc)
3665        with self.assertRaises(VMwareApiError) as excinfo:
3666            salt.utils.vmware.get_license_manager(self.mock_si)
3667        self.assertEqual(
3668            excinfo.exception.strerror,
3669            "Not enough permissions. Required privilege: Fake privilege",
3670        )
3671
3672    def test_raise_vim_fault(self):
3673        exc = vim.fault.VimFault()
3674        exc.msg = "VimFault msg"
3675        type(self.mock_si.content).licenseManager = PropertyMock(side_effect=exc)
3676        with self.assertRaises(VMwareApiError) as excinfo:
3677            salt.utils.vmware.get_license_manager(self.mock_si)
3678        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3679
3680    def test_raise_runtime_fault(self):
3681        exc = vmodl.RuntimeFault()
3682        exc.msg = "RuntimeFault msg"
3683        type(self.mock_si.content).licenseManager = PropertyMock(side_effect=exc)
3684        with self.assertRaises(VMwareRuntimeError) as excinfo:
3685            salt.utils.vmware.get_license_manager(self.mock_si)
3686        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3687
3688    def test_valid_assignment_manager(self):
3689        ret = salt.utils.vmware.get_license_manager(self.mock_si)
3690        self.assertEqual(ret, self.mock_lic_mgr)
3691
3692
3693@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3694class GetLicenseAssignmentManagerTestCase(TestCase):
3695    """
3696    Tests for salt.utils.vmware.get_license_assignment_manager
3697    """
3698
3699    def setUp(self):
3700        self.mock_si = MagicMock()
3701        self.mock_lic_assign_mgr = MagicMock()
3702        type(
3703            self.mock_si.content.licenseManager
3704        ).licenseAssignmentManager = PropertyMock(return_value=self.mock_lic_assign_mgr)
3705
3706    def tearDown(self):
3707        for attr in ("mock_si", "mock_lic_assign_mgr"):
3708            delattr(self, attr)
3709
3710    def test_raise_no_permission(self):
3711        exc = vim.fault.NoPermission()
3712        exc.privilegeId = "Fake privilege"
3713        type(
3714            self.mock_si.content.licenseManager
3715        ).licenseAssignmentManager = PropertyMock(side_effect=exc)
3716        with self.assertRaises(VMwareApiError) as excinfo:
3717            salt.utils.vmware.get_license_assignment_manager(self.mock_si)
3718        self.assertEqual(
3719            excinfo.exception.strerror,
3720            "Not enough permissions. Required privilege: Fake privilege",
3721        )
3722
3723    def test_raise_vim_fault(self):
3724        exc = vim.fault.VimFault()
3725        exc.msg = "VimFault msg"
3726        type(
3727            self.mock_si.content.licenseManager
3728        ).licenseAssignmentManager = PropertyMock(side_effect=exc)
3729        with self.assertRaises(VMwareApiError) as excinfo:
3730            salt.utils.vmware.get_license_assignment_manager(self.mock_si)
3731        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3732
3733    def test_raise_runtime_fault(self):
3734        exc = vmodl.RuntimeFault()
3735        exc.msg = "RuntimeFault msg"
3736        type(
3737            self.mock_si.content.licenseManager
3738        ).licenseAssignmentManager = PropertyMock(side_effect=exc)
3739        with self.assertRaises(VMwareRuntimeError) as excinfo:
3740            salt.utils.vmware.get_license_assignment_manager(self.mock_si)
3741        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3742
3743    def test_empty_license_assignment_manager(self):
3744        type(
3745            self.mock_si.content.licenseManager
3746        ).licenseAssignmentManager = PropertyMock(return_value=None)
3747        with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
3748            salt.utils.vmware.get_license_assignment_manager(self.mock_si)
3749        self.assertEqual(
3750            excinfo.exception.strerror, "License assignment manager was not retrieved"
3751        )
3752
3753    def test_valid_assignment_manager(self):
3754        ret = salt.utils.vmware.get_license_assignment_manager(self.mock_si)
3755        self.assertEqual(ret, self.mock_lic_assign_mgr)
3756
3757
3758@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3759class GetLicensesTestCase(TestCase):
3760    """
3761    Tests for salt.utils.vmware.get_licenses
3762    """
3763
3764    def setUp(self):
3765        self.mock_si = MagicMock()
3766        self.mock_licenses = [MagicMock(), MagicMock()]
3767        self.mock_lic_mgr = MagicMock()
3768        type(self.mock_lic_mgr).licenses = PropertyMock(return_value=self.mock_licenses)
3769        patches = (
3770            (
3771                "salt.utils.vmware.get_license_manager",
3772                MagicMock(return_value=self.mock_lic_mgr),
3773            ),
3774        )
3775        for mod, mock in patches:
3776            patcher = patch(mod, mock)
3777            patcher.start()
3778            self.addCleanup(patcher.stop)
3779
3780    def tearDown(self):
3781        for attr in ("mock_si", "mock_lic_mgr", "mock_licenses"):
3782            delattr(self, attr)
3783
3784    def test_no_license_manager_passed_in(self):
3785        mock_get_license_manager = MagicMock()
3786        with patch("salt.utils.vmware.get_license_manager", mock_get_license_manager):
3787            salt.utils.vmware.get_licenses(self.mock_si)
3788        mock_get_license_manager.assert_called_once_with(self.mock_si)
3789
3790    def test_license_manager_passed_in(self):
3791        mock_licenses = PropertyMock()
3792        mock_lic_mgr = MagicMock()
3793        type(mock_lic_mgr).licenses = mock_licenses
3794        mock_get_license_manager = MagicMock()
3795        with patch("salt.utils.vmware.get_license_manager", mock_get_license_manager):
3796            salt.utils.vmware.get_licenses(self.mock_si, license_manager=mock_lic_mgr)
3797        self.assertEqual(mock_get_license_manager.call_count, 0)
3798        self.assertEqual(mock_licenses.call_count, 1)
3799
3800    def test_raise_no_permission(self):
3801        exc = vim.fault.NoPermission()
3802        exc.privilegeId = "Fake privilege"
3803        type(self.mock_lic_mgr).licenses = PropertyMock(side_effect=exc)
3804        with self.assertRaises(VMwareApiError) as excinfo:
3805            salt.utils.vmware.get_licenses(self.mock_si)
3806        self.assertEqual(
3807            excinfo.exception.strerror,
3808            "Not enough permissions. Required privilege: Fake privilege",
3809        )
3810
3811    def test_raise_vim_fault(self):
3812        exc = vim.fault.VimFault()
3813        exc.msg = "VimFault msg"
3814        type(self.mock_lic_mgr).licenses = PropertyMock(side_effect=exc)
3815        with self.assertRaises(VMwareApiError) as excinfo:
3816            salt.utils.vmware.get_licenses(self.mock_si)
3817        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3818
3819    def test_raise_runtime_fault(self):
3820        exc = vmodl.RuntimeFault()
3821        exc.msg = "RuntimeFault msg"
3822        type(self.mock_lic_mgr).licenses = PropertyMock(side_effect=exc)
3823        with self.assertRaises(VMwareRuntimeError) as excinfo:
3824            salt.utils.vmware.get_licenses(self.mock_si)
3825        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3826
3827    def test_valid_licenses(self):
3828        ret = salt.utils.vmware.get_licenses(self.mock_si)
3829        self.assertEqual(ret, self.mock_licenses)
3830
3831
3832@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3833class AddLicenseTestCase(TestCase):
3834    """
3835    Tests for salt.utils.vmware.add_license
3836    """
3837
3838    def setUp(self):
3839        self.mock_si = MagicMock()
3840        self.mock_license = MagicMock()
3841        self.mock_add_license = MagicMock(return_value=self.mock_license)
3842        self.mock_lic_mgr = MagicMock(AddLicense=self.mock_add_license)
3843        self.mock_label = MagicMock()
3844        patches = (
3845            (
3846                "salt.utils.vmware.get_license_manager",
3847                MagicMock(return_value=self.mock_lic_mgr),
3848            ),
3849            ("salt.utils.vmware.vim.KeyValue", MagicMock(return_value=self.mock_label)),
3850        )
3851        for mod, mock in patches:
3852            patcher = patch(mod, mock)
3853            patcher.start()
3854            self.addCleanup(patcher.stop)
3855
3856    def tearDown(self):
3857        for attr in (
3858            "mock_si",
3859            "mock_lic_mgr",
3860            "mock_license",
3861            "mock_add_license",
3862            "mock_label",
3863        ):
3864            delattr(self, attr)
3865
3866    def test_no_license_manager_passed_in(self):
3867        mock_get_license_manager = MagicMock()
3868        with patch("salt.utils.vmware.get_license_manager", mock_get_license_manager):
3869            salt.utils.vmware.add_license(
3870                self.mock_si, "fake_license_key", "fake_license_description"
3871            )
3872        mock_get_license_manager.assert_called_once_with(self.mock_si)
3873
3874    def test_license_manager_passed_in(self):
3875        mock_get_license_manager = MagicMock()
3876        with patch("salt.utils.vmware.get_license_manager", mock_get_license_manager):
3877            salt.utils.vmware.add_license(
3878                self.mock_si,
3879                "fake_license_key",
3880                "fake_license_description",
3881                license_manager=self.mock_lic_mgr,
3882            )
3883        self.assertEqual(mock_get_license_manager.call_count, 0)
3884        self.assertEqual(self.mock_add_license.call_count, 1)
3885
3886    def test_label_settings(self):
3887        salt.utils.vmware.add_license(
3888            self.mock_si, "fake_license_key", "fake_license_description"
3889        )
3890        self.assertEqual(self.mock_label.key, "VpxClientLicenseLabel")
3891        self.assertEqual(self.mock_label.value, "fake_license_description")
3892
3893    def test_add_license_arguments(self):
3894        salt.utils.vmware.add_license(
3895            self.mock_si, "fake_license_key", "fake_license_description"
3896        )
3897        self.mock_add_license.assert_called_once_with(
3898            "fake_license_key", [self.mock_label]
3899        )
3900
3901    def test_add_license_raises_no_permission(self):
3902        exc = vim.fault.NoPermission()
3903        exc.privilegeId = "Fake privilege"
3904        self.mock_lic_mgr.AddLicense = MagicMock(side_effect=exc)
3905        with self.assertRaises(VMwareApiError) as excinfo:
3906            salt.utils.vmware.add_license(
3907                self.mock_si, "fake_license_key", "fake_license_description"
3908            )
3909        self.assertEqual(
3910            excinfo.exception.strerror,
3911            "Not enough permissions. Required privilege: Fake privilege",
3912        )
3913
3914    def test_add_license_raises_vim_fault(self):
3915        exc = vim.fault.VimFault()
3916        exc.msg = "VimFault msg"
3917        self.mock_lic_mgr.AddLicense = MagicMock(side_effect=exc)
3918        with self.assertRaises(VMwareApiError) as excinfo:
3919            salt.utils.vmware.add_license(
3920                self.mock_si, "fake_license_key", "fake_license_description"
3921            )
3922        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
3923
3924    def test_add_license_raises_runtime_fault(self):
3925        exc = vmodl.RuntimeFault()
3926        exc.msg = "RuntimeFault msg"
3927        self.mock_lic_mgr.AddLicense = MagicMock(side_effect=exc)
3928        with self.assertRaises(VMwareRuntimeError) as excinfo:
3929            salt.utils.vmware.add_license(
3930                self.mock_si, "fake_license_key", "fake_license_description"
3931            )
3932        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
3933
3934    def test_valid_license_added(self):
3935        ret = salt.utils.vmware.add_license(
3936            self.mock_si, "fake_license_key", "fake_license_description"
3937        )
3938        self.assertEqual(ret, self.mock_license)
3939
3940
3941@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
3942class GetAssignedLicensesTestCase(TestCase):
3943    """
3944    Tests for salt.utils.vmware.get_assigned_licenses
3945    """
3946
3947    def setUp(self):
3948        self.mock_ent_id = MagicMock()
3949        self.mock_si = MagicMock()
3950        type(self.mock_si.content.about).instanceUuid = PropertyMock(
3951            return_value=self.mock_ent_id
3952        )
3953        self.mock_moid = MagicMock()
3954        self.prop_mock_moid = PropertyMock(return_value=self.mock_moid)
3955        self.mock_entity_ref = MagicMock()
3956        type(self.mock_entity_ref)._moId = self.prop_mock_moid
3957        self.mock_assignments = [
3958            MagicMock(entityDisplayName="fake_ent1"),
3959            MagicMock(entityDisplayName="fake_ent2"),
3960        ]
3961        self.mock_query_assigned_licenses = MagicMock(
3962            return_value=[
3963                MagicMock(assignedLicense=self.mock_assignments[0]),
3964                MagicMock(assignedLicense=self.mock_assignments[1]),
3965            ]
3966        )
3967        self.mock_lic_assign_mgr = MagicMock(
3968            QueryAssignedLicenses=self.mock_query_assigned_licenses
3969        )
3970        patches = (
3971            (
3972                "salt.utils.vmware.get_license_assignment_manager",
3973                MagicMock(return_value=self.mock_lic_assign_mgr),
3974            ),
3975        )
3976        for mod, mock in patches:
3977            patcher = patch(mod, mock)
3978            patcher.start()
3979            self.addCleanup(patcher.stop)
3980
3981    def tearDown(self):
3982        for attr in (
3983            "mock_ent_id",
3984            "mock_si",
3985            "mock_moid",
3986            "prop_mock_moid",
3987            "mock_entity_ref",
3988            "mock_assignments",
3989            "mock_query_assigned_licenses",
3990            "mock_lic_assign_mgr",
3991        ):
3992            delattr(self, attr)
3993
3994    def test_no_license_assignment_manager_passed_in(self):
3995        mock_get_license_assign_manager = MagicMock()
3996        with patch(
3997            "salt.utils.vmware.get_license_assignment_manager",
3998            mock_get_license_assign_manager,
3999        ):
4000            salt.utils.vmware.get_assigned_licenses(
4001                self.mock_si, self.mock_entity_ref, "fake_entity_name"
4002            )
4003        mock_get_license_assign_manager.assert_called_once_with(self.mock_si)
4004
4005    def test_license_assignment_manager_passed_in(self):
4006        mock_get_license_assign_manager = MagicMock()
4007        with patch(
4008            "salt.utils.vmware.get_license_assignment_manager",
4009            mock_get_license_assign_manager,
4010        ):
4011            salt.utils.vmware.get_assigned_licenses(
4012                self.mock_si,
4013                self.mock_entity_ref,
4014                "fake_entity_name",
4015                license_assignment_manager=self.mock_lic_assign_mgr,
4016            )
4017        self.assertEqual(mock_get_license_assign_manager.call_count, 0)
4018
4019    def test_entity_name(self):
4020        mock_trace = MagicMock()
4021        with patch("salt._logging.impl.SaltLoggingClass.trace", mock_trace):
4022            salt.utils.vmware.get_assigned_licenses(
4023                self.mock_si, self.mock_entity_ref, "fake_entity_name"
4024            )
4025        mock_trace.assert_called_once_with(
4026            "Retrieving licenses assigned to '%s'", "fake_entity_name"
4027        )
4028
4029    def test_instance_uuid(self):
4030        mock_instance_uuid_prop = PropertyMock()
4031        type(self.mock_si.content.about).instanceUuid = mock_instance_uuid_prop
4032        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(
4033            return_value=[MagicMock(entityDisplayName="fake_vcenter")]
4034        )
4035        salt.utils.vmware.get_assigned_licenses(
4036            self.mock_si, entity_name="fake_vcenter"
4037        )
4038        self.assertEqual(mock_instance_uuid_prop.call_count, 1)
4039
4040    def test_instance_uuid_raises_no_permission(self):
4041        exc = vim.fault.NoPermission()
4042        exc.privilegeId = "Fake privilege"
4043        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4044        with self.assertRaises(VMwareApiError) as excinfo:
4045            salt.utils.vmware.get_assigned_licenses(
4046                self.mock_si, entity_name="fake_vcenter"
4047            )
4048        self.assertEqual(
4049            excinfo.exception.strerror,
4050            "Not enough permissions. Required privilege: Fake privilege",
4051        )
4052
4053    def test_instance_uuid_raises_vim_fault(self):
4054        exc = vim.fault.VimFault()
4055        exc.msg = "VimFault msg"
4056        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4057        with self.assertRaises(VMwareApiError) as excinfo:
4058            salt.utils.vmware.get_assigned_licenses(
4059                self.mock_si, entity_name="fake_vcenter"
4060            )
4061        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
4062
4063    def test_instance_uuid_raises_runtime_fault(self):
4064        exc = vmodl.RuntimeFault()
4065        exc.msg = "RuntimeFault msg"
4066        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4067        with self.assertRaises(VMwareRuntimeError) as excinfo:
4068            salt.utils.vmware.get_assigned_licenses(
4069                self.mock_si, entity_name="fake_vcenter"
4070            )
4071        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
4072
4073    def test_vcenter_entity_too_many_assignements(self):
4074        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(
4075            return_value=[MagicMock(), MagicMock()]
4076        )
4077        with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
4078            salt.utils.vmware.get_assigned_licenses(
4079                self.mock_si, entity_name="fake_vcenter"
4080            )
4081        self.assertEqual(
4082            excinfo.exception.strerror,
4083            "Unexpected return. Expect only a single assignment",
4084        )
4085
4086    def test_wrong_vcenter_name(self):
4087        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(
4088            return_value=[MagicMock(entityDisplayName="bad_vcenter")]
4089        )
4090        with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
4091            salt.utils.vmware.get_assigned_licenses(
4092                self.mock_si, entity_name="fake_vcenter"
4093            )
4094        self.assertEqual(
4095            excinfo.exception.strerror,
4096            "Got license assignment info for a different vcenter",
4097        )
4098
4099    def test_query_assigned_licenses_vcenter(self):
4100        with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
4101            salt.utils.vmware.get_assigned_licenses(
4102                self.mock_si, entity_name="fake_vcenter"
4103            )
4104        self.mock_query_assigned_licenses.assert_called_once_with(self.mock_ent_id)
4105
4106    def test_query_assigned_licenses_with_entity(self):
4107        salt.utils.vmware.get_assigned_licenses(
4108            self.mock_si, self.mock_entity_ref, "fake_entity_name"
4109        )
4110        self.mock_query_assigned_licenses.assert_called_once_with(self.mock_moid)
4111
4112    def test_query_assigned_licenses_raises_no_permission(self):
4113        exc = vim.fault.NoPermission()
4114        exc.privilegeId = "Fake privilege"
4115        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(side_effect=exc)
4116        with self.assertRaises(VMwareApiError) as excinfo:
4117            salt.utils.vmware.get_assigned_licenses(
4118                self.mock_si, self.mock_entity_ref, "fake_entity_name"
4119            )
4120        self.assertEqual(
4121            excinfo.exception.strerror,
4122            "Not enough permissions. Required privilege: Fake privilege",
4123        )
4124
4125    def test_query_assigned_licenses_raises_vim_fault(self):
4126        exc = vim.fault.VimFault()
4127        exc.msg = "VimFault msg"
4128        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(side_effect=exc)
4129        with self.assertRaises(VMwareApiError) as excinfo:
4130            salt.utils.vmware.get_assigned_licenses(
4131                self.mock_si, self.mock_entity_ref, "fake_entity_name"
4132            )
4133        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
4134
4135    def test_query_assigned_licenses_raises_runtime_fault(self):
4136        exc = vmodl.RuntimeFault()
4137        exc.msg = "RuntimeFault msg"
4138        self.mock_lic_assign_mgr.QueryAssignedLicenses = MagicMock(side_effect=exc)
4139        with self.assertRaises(VMwareRuntimeError) as excinfo:
4140            salt.utils.vmware.get_assigned_licenses(
4141                self.mock_si, self.mock_entity_ref, "fake_entity_name"
4142            )
4143        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
4144
4145    def test_valid_assignments(self):
4146        ret = salt.utils.vmware.get_assigned_licenses(
4147            self.mock_si, self.mock_entity_ref, "fake_entity_name"
4148        )
4149        self.assertEqual(ret, self.mock_assignments)
4150
4151
4152@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4153class AssignLicenseTestCase(TestCase):
4154    """
4155    Tests for salt.utils.vmware.assign_license
4156    """
4157
4158    def setUp(self):
4159        self.mock_ent_id = MagicMock()
4160        self.mock_si = MagicMock()
4161        type(self.mock_si.content.about).instanceUuid = PropertyMock(
4162            return_value=self.mock_ent_id
4163        )
4164        self.mock_lic_key = MagicMock()
4165        self.mock_moid = MagicMock()
4166        self.prop_mock_moid = PropertyMock(return_value=self.mock_moid)
4167        self.mock_entity_ref = MagicMock()
4168        type(self.mock_entity_ref)._moId = self.prop_mock_moid
4169        self.mock_license = MagicMock()
4170        self.mock_update_assigned_license = MagicMock(return_value=self.mock_license)
4171        self.mock_lic_assign_mgr = MagicMock(
4172            UpdateAssignedLicense=self.mock_update_assigned_license
4173        )
4174        patches = (
4175            (
4176                "salt.utils.vmware.get_license_assignment_manager",
4177                MagicMock(return_value=self.mock_lic_assign_mgr),
4178            ),
4179        )
4180        for mod, mock in patches:
4181            patcher = patch(mod, mock)
4182            patcher.start()
4183            self.addCleanup(patcher.stop)
4184
4185    def test_no_license_assignment_manager_passed_in(self):
4186        mock_get_license_assign_manager = MagicMock()
4187        with patch(
4188            "salt.utils.vmware.get_license_assignment_manager",
4189            mock_get_license_assign_manager,
4190        ):
4191            salt.utils.vmware.assign_license(
4192                self.mock_si,
4193                self.mock_lic_key,
4194                "fake_license_name",
4195                self.mock_entity_ref,
4196                "fake_entity_name",
4197            )
4198        mock_get_license_assign_manager.assert_called_once_with(self.mock_si)
4199
4200    def test_license_assignment_manager_passed_in(self):
4201        mock_get_license_assign_manager = MagicMock()
4202        with patch(
4203            "salt.utils.vmware.get_license_assignment_manager",
4204            mock_get_license_assign_manager,
4205        ):
4206            salt.utils.vmware.assign_license(
4207                self.mock_si,
4208                self.mock_lic_key,
4209                "fake_license_name",
4210                self.mock_entity_ref,
4211                "fake_entity_name",
4212                license_assignment_manager=self.mock_lic_assign_mgr,
4213            )
4214        self.assertEqual(mock_get_license_assign_manager.call_count, 0)
4215        self.assertEqual(self.mock_update_assigned_license.call_count, 1)
4216
4217    def test_entity_name(self):
4218        mock_trace = MagicMock()
4219        with patch("salt._logging.impl.SaltLoggingClass.trace", mock_trace):
4220            salt.utils.vmware.assign_license(
4221                self.mock_si,
4222                self.mock_lic_key,
4223                "fake_license_name",
4224                self.mock_entity_ref,
4225                "fake_entity_name",
4226            )
4227        mock_trace.assert_called_once_with(
4228            "Assigning license to '%s'", "fake_entity_name"
4229        )
4230
4231    def test_instance_uuid(self):
4232        mock_instance_uuid_prop = PropertyMock()
4233        type(self.mock_si.content.about).instanceUuid = mock_instance_uuid_prop
4234        self.mock_lic_assign_mgr.UpdateAssignedLicense = MagicMock(
4235            return_value=[MagicMock(entityDisplayName="fake_vcenter")]
4236        )
4237        salt.utils.vmware.assign_license(
4238            self.mock_si,
4239            self.mock_lic_key,
4240            "fake_license_name",
4241            entity_name="fake_entity_name",
4242        )
4243        self.assertEqual(mock_instance_uuid_prop.call_count, 1)
4244
4245    def test_instance_uuid_raises_no_permission(self):
4246        exc = vim.fault.NoPermission()
4247        exc.privilegeId = "Fake privilege"
4248        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4249        with self.assertRaises(VMwareApiError) as excinfo:
4250            salt.utils.vmware.assign_license(
4251                self.mock_si,
4252                self.mock_lic_key,
4253                "fake_license_name",
4254                entity_name="fake_entity_name",
4255            )
4256        self.assertEqual(
4257            excinfo.exception.strerror,
4258            "Not enough permissions. Required privilege: Fake privilege",
4259        )
4260
4261    def test_instance_uuid_raises_vim_fault(self):
4262        exc = vim.fault.VimFault()
4263        exc.msg = "VimFault msg"
4264        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4265        with self.assertRaises(VMwareApiError) as excinfo:
4266            salt.utils.vmware.assign_license(
4267                self.mock_si,
4268                self.mock_lic_key,
4269                "fake_license_name",
4270                entity_name="fake_entity_name",
4271            )
4272        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
4273
4274    def test_instance_uuid_raises_runtime_fault(self):
4275        exc = vmodl.RuntimeFault()
4276        exc.msg = "RuntimeFault msg"
4277        type(self.mock_si.content.about).instanceUuid = PropertyMock(side_effect=exc)
4278        with self.assertRaises(VMwareRuntimeError) as excinfo:
4279            salt.utils.vmware.assign_license(
4280                self.mock_si,
4281                self.mock_lic_key,
4282                "fake_license_name",
4283                entity_name="fake_entity_name",
4284            )
4285        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
4286
4287    def test_update_assigned_licenses_vcenter(self):
4288        salt.utils.vmware.assign_license(
4289            self.mock_si,
4290            self.mock_lic_key,
4291            "fake_license_name",
4292            entity_name="fake_entity_name",
4293        )
4294        self.mock_update_assigned_license.assert_called_once_with(
4295            self.mock_ent_id, self.mock_lic_key, "fake_license_name"
4296        )
4297
4298    def test_update_assigned_licenses_call_with_entity(self):
4299        salt.utils.vmware.assign_license(
4300            self.mock_si,
4301            self.mock_lic_key,
4302            "fake_license_name",
4303            self.mock_entity_ref,
4304            "fake_entity_name",
4305        )
4306        self.mock_update_assigned_license.assert_called_once_with(
4307            self.mock_moid, self.mock_lic_key, "fake_license_name"
4308        )
4309
4310    def test_update_assigned_licenses_raises_no_permission(self):
4311        exc = vim.fault.NoPermission()
4312        exc.privilegeId = "Fake privilege"
4313        self.mock_lic_assign_mgr.UpdateAssignedLicense = MagicMock(side_effect=exc)
4314        with self.assertRaises(VMwareApiError) as excinfo:
4315            salt.utils.vmware.assign_license(
4316                self.mock_si,
4317                self.mock_lic_key,
4318                "fake_license_name",
4319                self.mock_entity_ref,
4320                "fake_entity_name",
4321            )
4322        self.assertEqual(
4323            excinfo.exception.strerror,
4324            "Not enough permissions. Required privilege: Fake privilege",
4325        )
4326
4327    def test_update_assigned_licenses_raises_vim_fault(self):
4328        exc = vim.fault.VimFault()
4329        exc.msg = "VimFault msg"
4330        self.mock_lic_assign_mgr.UpdateAssignedLicense = MagicMock(side_effect=exc)
4331        with self.assertRaises(VMwareApiError) as excinfo:
4332            salt.utils.vmware.assign_license(
4333                self.mock_si,
4334                self.mock_lic_key,
4335                "fake_license_name",
4336                self.mock_entity_ref,
4337                "fake_entity_name",
4338            )
4339        self.assertEqual(excinfo.exception.strerror, "VimFault msg")
4340
4341    def test_update_assigned_licenses_raises_runtime_fault(self):
4342        exc = vmodl.RuntimeFault()
4343        exc.msg = "RuntimeFault msg"
4344        self.mock_lic_assign_mgr.UpdateAssignedLicense = MagicMock(side_effect=exc)
4345        with self.assertRaises(VMwareRuntimeError) as excinfo:
4346            salt.utils.vmware.assign_license(
4347                self.mock_si,
4348                self.mock_lic_key,
4349                "fake_license_name",
4350                self.mock_entity_ref,
4351                "fake_entity_name",
4352            )
4353        self.assertEqual(excinfo.exception.strerror, "RuntimeFault msg")
4354
4355    def test_valid_assignments(self):
4356        ret = salt.utils.vmware.assign_license(
4357            self.mock_si,
4358            self.mock_lic_key,
4359            "fake_license_name",
4360            self.mock_entity_ref,
4361            "fake_entity_name",
4362        )
4363        self.assertEqual(ret, self.mock_license)
4364
4365
4366@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4367class GetStorageSystemTestCase(TestCase):
4368    """
4369    Tests for salt.utils.vmware.get_storage_system
4370    """
4371
4372    def setUp(self):
4373        self.mock_si = MagicMock(content=MagicMock())
4374        self.mock_host_ref = MagicMock()
4375        self.mock_get_managed_object_name = MagicMock(return_value="fake_host")
4376        self.mock_traversal_spec = MagicMock()
4377        self.mock_obj = MagicMock()
4378        self.mock_get_mors = MagicMock(return_value=[{"object": self.mock_obj}])
4379
4380        patches = (
4381            (
4382                "salt.utils.vmware.get_managed_object_name",
4383                self.mock_get_managed_object_name,
4384            ),
4385            ("salt.utils.vmware.get_mors_with_properties", self.mock_get_mors),
4386            (
4387                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4388                MagicMock(return_value=self.mock_traversal_spec),
4389            ),
4390        )
4391        for mod, mock in patches:
4392            patcher = patch(mod, mock)
4393            patcher.start()
4394            self.addCleanup(patcher.stop)
4395
4396    def tearDown(self):
4397        for attr in (
4398            "mock_si",
4399            "mock_host_ref",
4400            "mock_get_managed_object_name",
4401            "mock_traversal_spec",
4402            "mock_obj",
4403        ):
4404            delattr(self, attr)
4405
4406    def test_no_hostname_argument(self):
4407        salt.utils.vmware.get_storage_system(self.mock_si, self.mock_host_ref)
4408        self.mock_get_managed_object_name.assert_called_once_with(self.mock_host_ref)
4409
4410    def test_hostname_argument(self):
4411        salt.utils.vmware.get_storage_system(
4412            self.mock_si, self.mock_host_ref, hostname="fake_host"
4413        )
4414        self.assertEqual(self.mock_get_managed_object_name.call_count, 0)
4415
4416    def test_traversal_spec(self):
4417        mock_traversal_spec = MagicMock(return_value=[{"object": self.mock_obj}])
4418        with patch(
4419            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4420            mock_traversal_spec,
4421        ):
4422
4423            salt.utils.vmware.get_storage_system(self.mock_si, self.mock_host_ref)
4424        mock_traversal_spec.assert_called_once_with(
4425            path="configManager.storageSystem", type=vim.HostSystem, skip=False
4426        )
4427
4428    def test_get_mors_with_properties(self):
4429        salt.utils.vmware.get_storage_system(self.mock_si, self.mock_host_ref)
4430        self.mock_get_mors.assert_called_once_with(
4431            self.mock_si,
4432            vim.HostStorageSystem,
4433            property_list=["systemFile"],
4434            container_ref=self.mock_host_ref,
4435            traversal_spec=self.mock_traversal_spec,
4436        )
4437
4438    def test_empty_mors_result(self):
4439        with patch(
4440            "salt.utils.vmware.get_mors_with_properties", MagicMock(return_value=[])
4441        ):
4442            with self.assertRaises(VMwareObjectRetrievalError) as excinfo:
4443                salt.utils.vmware.get_storage_system(self.mock_si, self.mock_host_ref)
4444        self.assertEqual(
4445            excinfo.exception.strerror,
4446            "Host's 'fake_host' storage system was not retrieved",
4447        )
4448
4449    def test_valid_mors_result(self):
4450        res = salt.utils.vmware.get_storage_system(self.mock_si, self.mock_host_ref)
4451        self.assertEqual(res, self.mock_obj)
4452
4453
4454@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4455class GetDatastoresTestCase(TestCase):
4456    """
4457    Tests for salt.utils.vmware.get_datastores
4458    """
4459
4460    def setUp(self):
4461        self.mock_si = MagicMock()
4462        self.mock_reference = MagicMock(spec=vim.HostSystem)
4463        self.mock_mount_infos = [
4464            MagicMock(
4465                volume=MagicMock(
4466                    spec=vim.HostVmfsVolume, extent=[MagicMock(diskName="fake_disk2")]
4467                )
4468            ),
4469            MagicMock(
4470                volume=MagicMock(
4471                    spec=vim.HostVmfsVolume, extent=[MagicMock(diskName="fake_disk3")]
4472                )
4473            ),
4474        ]
4475        self.mock_mount_infos[0].volume.name = "fake_ds2"
4476        self.mock_mount_infos[1].volume.name = "fake_ds3"
4477        self.mock_entries = [
4478            {"name": "fake_ds1", "object": MagicMock()},
4479            {"name": "fake_ds2", "object": MagicMock()},
4480            {"name": "fake_ds3", "object": MagicMock()},
4481        ]
4482        self.mock_storage_system = MagicMock()
4483        self.mock_get_storage_system = MagicMock(return_value=self.mock_storage_system)
4484        self.mock_get_managed_object_name = MagicMock(return_value="fake_host")
4485        self.mock_traversal_spec = MagicMock()
4486
4487        patches = (
4488            (
4489                "salt.utils.vmware.get_managed_object_name",
4490                self.mock_get_managed_object_name,
4491            ),
4492            ("salt.utils.vmware.get_storage_system", self.mock_get_storage_system),
4493            (
4494                "salt.utils.vmware.get_properties_of_managed_object",
4495                MagicMock(
4496                    return_value={
4497                        "fileSystemVolumeInfo.mountInfo": self.mock_mount_infos
4498                    }
4499                ),
4500            ),
4501            (
4502                "salt.utils.vmware.get_mors_with_properties",
4503                MagicMock(return_value=self.mock_entries),
4504            ),
4505            (
4506                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4507                MagicMock(return_value=self.mock_traversal_spec),
4508            ),
4509        )
4510        for mod, mock in patches:
4511            patcher = patch(mod, mock)
4512            patcher.start()
4513            self.addCleanup(patcher.stop)
4514
4515    def tearDown(self):
4516        for attr in (
4517            "mock_si",
4518            "mock_reference",
4519            "mock_storage_system",
4520            "mock_get_storage_system",
4521            "mock_mount_infos",
4522            "mock_entries",
4523            "mock_get_managed_object_name",
4524            "mock_traversal_spec",
4525        ):
4526            delattr(self, attr)
4527
4528    def test_get_reference_name_call(self):
4529        salt.utils.vmware.get_datastores(self.mock_si, self.mock_reference)
4530        self.mock_get_managed_object_name.assert_called_once_with(self.mock_reference)
4531
4532    def test_get_no_datastores(self):
4533        res = salt.utils.vmware.get_datastores(self.mock_si, self.mock_reference)
4534        self.assertEqual(res, [])
4535
4536    def test_get_storage_system_call(self):
4537        salt.utils.vmware.get_datastores(
4538            self.mock_si, self.mock_reference, backing_disk_ids=["fake_disk1"]
4539        )
4540        self.mock_get_storage_system.assert_called_once_with(
4541            self.mock_si, self.mock_reference, "fake_host"
4542        )
4543
4544    def test_get_mount_info_call(self):
4545        mock_get_properties_of_managed_object = MagicMock()
4546        with patch(
4547            "salt.utils.vmware.get_properties_of_managed_object",
4548            mock_get_properties_of_managed_object,
4549        ):
4550            salt.utils.vmware.get_datastores(
4551                self.mock_si, self.mock_reference, backing_disk_ids=["fake_disk1"]
4552            )
4553        mock_get_properties_of_managed_object.assert_called_once_with(
4554            self.mock_storage_system, ["fileSystemVolumeInfo.mountInfo"]
4555        )
4556
4557    def test_backing_disks_no_mount_info(self):
4558        with patch(
4559            "salt.utils.vmware.get_properties_of_managed_object",
4560            MagicMock(return_value={}),
4561        ):
4562            res = salt.utils.vmware.get_datastores(
4563                self.mock_si, self.mock_reference, backing_disk_ids=["fake_disk_id"]
4564            )
4565        self.assertEqual(res, [])
4566
4567    def test_host_traversal_spec(self):
4568        # Reference is of type vim.HostSystem
4569        mock_traversal_spec_init = MagicMock()
4570        with patch(
4571            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4572            mock_traversal_spec_init,
4573        ):
4574
4575            salt.utils.vmware.get_datastores(
4576                self.mock_si, self.mock_reference, get_all_datastores=True
4577            )
4578        mock_traversal_spec_init.assert_called_once_with(
4579            name="host_datastore_traversal",
4580            path="datastore",
4581            skip=False,
4582            type=vim.HostSystem,
4583        )
4584
4585    def test_cluster_traversal_spec(self):
4586        mock_traversal_spec_init = MagicMock()
4587        # Reference is of type vim.ClusterComputeResource
4588        mock_reference = MagicMock(spec=vim.ClusterComputeResource)
4589        with patch(
4590            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4591            mock_traversal_spec_init,
4592        ):
4593
4594            salt.utils.vmware.get_datastores(
4595                self.mock_si, mock_reference, get_all_datastores=True
4596            )
4597        mock_traversal_spec_init.assert_called_once_with(
4598            name="cluster_datastore_traversal",
4599            path="datastore",
4600            skip=False,
4601            type=vim.ClusterComputeResource,
4602        )
4603
4604    def test_datacenter_traversal_spec(self):
4605        mock_traversal_spec_init = MagicMock()
4606        # Reference is of type vim.ClusterComputeResource
4607        mock_reference = MagicMock(spec=vim.Datacenter)
4608        with patch(
4609            "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4610            mock_traversal_spec_init,
4611        ):
4612
4613            salt.utils.vmware.get_datastores(
4614                self.mock_si, mock_reference, get_all_datastores=True
4615            )
4616        mock_traversal_spec_init.assert_called_once_with(
4617            name="datacenter_datastore_traversal",
4618            path="datastore",
4619            skip=False,
4620            type=vim.Datacenter,
4621        )
4622
4623    def test_root_folder_traversal_spec(self):
4624        mock_traversal_spec_init = MagicMock(return_value="traversal")
4625        mock_reference = MagicMock(spec=vim.Folder)
4626        with patch(
4627            "salt.utils.vmware.get_managed_object_name",
4628            MagicMock(side_effect=["fake_host", "Datacenters"]),
4629        ):
4630            with patch(
4631                "salt.utils.vmware.vmodl.query.PropertyCollector.TraversalSpec",
4632                mock_traversal_spec_init,
4633            ):
4634
4635                salt.utils.vmware.get_datastores(
4636                    self.mock_si, mock_reference, get_all_datastores=True
4637                )
4638
4639        mock_traversal_spec_init.assert_has_calls(
4640            [
4641                call(path="datastore", skip=False, type=vim.Datacenter),
4642                call(
4643                    path="childEntity",
4644                    selectSet=["traversal"],
4645                    skip=False,
4646                    type=vim.Folder,
4647                ),
4648            ]
4649        )
4650
4651    def test_unsupported_reference_type(self):
4652        class FakeClass:
4653            pass
4654
4655        mock_reference = MagicMock(spec=FakeClass)
4656        with self.assertRaises(ArgumentValueError) as excinfo:
4657            salt.utils.vmware.get_datastores(
4658                self.mock_si, mock_reference, get_all_datastores=True
4659            )
4660        self.assertEqual(
4661            excinfo.exception.strerror, "Unsupported reference type 'FakeClass'"
4662        )
4663
4664    def test_get_mors_with_properties(self):
4665        mock_get_mors_with_properties = MagicMock()
4666        with patch(
4667            "salt.utils.vmware.get_mors_with_properties", mock_get_mors_with_properties
4668        ):
4669            salt.utils.vmware.get_datastores(
4670                self.mock_si, self.mock_reference, get_all_datastores=True
4671            )
4672        mock_get_mors_with_properties.assert_called_once_with(
4673            self.mock_si,
4674            object_type=vim.Datastore,
4675            property_list=["name"],
4676            container_ref=self.mock_reference,
4677            traversal_spec=self.mock_traversal_spec,
4678        )
4679
4680    def test_get_all_datastores(self):
4681        res = salt.utils.vmware.get_datastores(
4682            self.mock_si, self.mock_reference, get_all_datastores=True
4683        )
4684        self.assertEqual(
4685            res,
4686            [
4687                self.mock_entries[0]["object"],
4688                self.mock_entries[1]["object"],
4689                self.mock_entries[2]["object"],
4690            ],
4691        )
4692
4693    def test_get_datastores_filtered_by_name(self):
4694        res = salt.utils.vmware.get_datastores(
4695            self.mock_si, self.mock_reference, datastore_names=["fake_ds1", "fake_ds2"]
4696        )
4697        self.assertEqual(
4698            res, [self.mock_entries[0]["object"], self.mock_entries[1]["object"]]
4699        )
4700
4701    def test_get_datastores_filtered_by_backing_disk(self):
4702        res = salt.utils.vmware.get_datastores(
4703            self.mock_si,
4704            self.mock_reference,
4705            backing_disk_ids=["fake_disk2", "fake_disk3"],
4706        )
4707        self.assertEqual(
4708            res, [self.mock_entries[1]["object"], self.mock_entries[2]["object"]]
4709        )
4710
4711    def test_get_datastores_filtered_by_both_name_and_backing_disk(self):
4712        # Simulate VMware data model for volumes fake_ds2, fake_ds3
4713        res = salt.utils.vmware.get_datastores(
4714            self.mock_si,
4715            self.mock_reference,
4716            datastore_names=["fake_ds1"],
4717            backing_disk_ids=["fake_disk3"],
4718        )
4719        self.assertEqual(
4720            res, [self.mock_entries[0]["object"], self.mock_entries[2]["object"]]
4721        )
4722
4723
4724@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4725class RenameDatastoreTestCase(TestCase):
4726    """
4727    Tests for salt.utils.vmware.rename_datastore
4728    """
4729
4730    def setUp(self):
4731        self.mock_ds_ref = MagicMock()
4732        self.mock_get_managed_object_name = MagicMock(return_value="fake_ds")
4733
4734        patches = (
4735            (
4736                "salt.utils.vmware.get_managed_object_name",
4737                self.mock_get_managed_object_name,
4738            ),
4739        )
4740        for mod, mock in patches:
4741            patcher = patch(mod, mock)
4742            patcher.start()
4743            self.addCleanup(patcher.stop)
4744
4745    def tearDown(self):
4746        for attr in ("mock_ds_ref", "mock_get_managed_object_name"):
4747            delattr(self, attr)
4748
4749    def test_datastore_name_call(self):
4750        salt.utils.vmware.rename_datastore(self.mock_ds_ref, "fake_new_name")
4751        self.mock_get_managed_object_name.assert_called_once_with(self.mock_ds_ref)
4752
4753    def test_rename_datastore_raise_no_permission(self):
4754        exc = vim.fault.NoPermission()
4755        exc.privilegeId = "Fake privilege"
4756        type(self.mock_ds_ref).RenameDatastore = MagicMock(side_effect=exc)
4757        with self.assertRaises(VMwareApiError) as excinfo:
4758            salt.utils.vmware.rename_datastore(self.mock_ds_ref, "fake_new_name")
4759        self.assertEqual(
4760            excinfo.exception.strerror,
4761            "Not enough permissions. Required privilege: Fake privilege",
4762        )
4763
4764    def test_rename_datastore_raise_vim_fault(self):
4765        exc = vim.VimFault()
4766        exc.msg = "vim_fault"
4767        type(self.mock_ds_ref).RenameDatastore = MagicMock(side_effect=exc)
4768        with self.assertRaises(VMwareApiError) as excinfo:
4769            salt.utils.vmware.rename_datastore(self.mock_ds_ref, "fake_new_name")
4770        self.assertEqual(excinfo.exception.strerror, "vim_fault")
4771
4772    def test_rename_datastore_raise_runtime_fault(self):
4773        exc = vmodl.RuntimeFault()
4774        exc.msg = "runtime_fault"
4775        type(self.mock_ds_ref).RenameDatastore = MagicMock(side_effect=exc)
4776        with self.assertRaises(VMwareRuntimeError) as excinfo:
4777            salt.utils.vmware.rename_datastore(self.mock_ds_ref, "fake_new_name")
4778        self.assertEqual(excinfo.exception.strerror, "runtime_fault")
4779
4780    def test_rename_datastore(self):
4781        salt.utils.vmware.rename_datastore(self.mock_ds_ref, "fake_new_name")
4782        self.mock_ds_ref.RenameDatastore.assert_called_once_with("fake_new_name")
4783
4784
4785class ConvertToKbTestCase(TestCase):
4786    """
4787    Tests for converting units
4788    """
4789
4790    def setUp(self):
4791        pass
4792
4793    def test_gb_conversion_call(self):
4794        self.assertEqual(
4795            salt.utils.vmware.convert_to_kb("Gb", 10),
4796            {"size": int(10485760), "unit": "KB"},
4797        )
4798
4799    def test_mb_conversion_call(self):
4800        self.assertEqual(
4801            salt.utils.vmware.convert_to_kb("Mb", 10),
4802            {"size": int(10240), "unit": "KB"},
4803        )
4804
4805    def test_kb_conversion_call(self):
4806        self.assertEqual(
4807            salt.utils.vmware.convert_to_kb("Kb", 10), {"size": int(10), "unit": "KB"}
4808        )
4809
4810    def test_conversion_bad_input_argument_fault(self):
4811        self.assertRaises(
4812            ArgumentValueError, salt.utils.vmware.convert_to_kb, "test", 10
4813        )
4814
4815
4816@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4817@patch("salt.utils.vmware.get_managed_object_name", MagicMock())
4818@patch("salt.utils.vmware.wait_for_task", MagicMock())
4819class CreateVirtualMachineTestCase(TestCase):
4820    """
4821    Tests for salt.utils.vmware.create_vm
4822    """
4823
4824    def setUp(self):
4825        self.vm_name = "fake_vm"
4826        self.mock_task = MagicMock()
4827        self.mock_config_spec = MagicMock()
4828        self.mock_resourcepool_object = MagicMock()
4829        self.mock_host_object = MagicMock()
4830        self.mock_vm_create_task = MagicMock(return_value=self.mock_task)
4831        self.mock_folder_object = MagicMock(CreateVM_Task=self.mock_vm_create_task)
4832
4833    def test_create_vm_pool_task_call(self):
4834        salt.utils.vmware.create_vm(
4835            self.vm_name,
4836            self.mock_config_spec,
4837            self.mock_folder_object,
4838            self.mock_resourcepool_object,
4839        )
4840        self.mock_vm_create_task.assert_called_once()
4841
4842    def test_create_vm_host_task_call(self):
4843        salt.utils.vmware.create_vm(
4844            self.vm_name,
4845            self.mock_config_spec,
4846            self.mock_folder_object,
4847            self.mock_resourcepool_object,
4848            host_object=self.mock_host_object,
4849        )
4850        self.mock_vm_create_task.assert_called_once()
4851
4852    def test_create_vm_raise_no_permission(self):
4853        exception = vim.fault.NoPermission()
4854        exception.msg = "vim.fault.NoPermission msg"
4855        self.mock_folder_object.CreateVM_Task = MagicMock(side_effect=exception)
4856        with self.assertRaises(VMwareApiError) as exc:
4857            salt.utils.vmware.create_vm(
4858                self.vm_name,
4859                self.mock_config_spec,
4860                self.mock_folder_object,
4861                self.mock_resourcepool_object,
4862            )
4863        self.assertEqual(
4864            exc.exception.strerror, "Not enough permissions. Required privilege: "
4865        )
4866
4867    def test_create_vm_raise_vim_fault(self):
4868        exception = vim.fault.VimFault()
4869        exception.msg = "vim.fault.VimFault msg"
4870        self.mock_folder_object.CreateVM_Task = MagicMock(side_effect=exception)
4871        with self.assertRaises(VMwareApiError) as exc:
4872            salt.utils.vmware.create_vm(
4873                self.vm_name,
4874                self.mock_config_spec,
4875                self.mock_folder_object,
4876                self.mock_resourcepool_object,
4877            )
4878        self.assertEqual(exc.exception.strerror, "vim.fault.VimFault msg")
4879
4880    def test_create_vm_raise_runtime_fault(self):
4881        exception = vmodl.RuntimeFault()
4882        exception.msg = "vmodl.RuntimeFault msg"
4883        self.mock_folder_object.CreateVM_Task = MagicMock(side_effect=exception)
4884        with self.assertRaises(VMwareRuntimeError) as exc:
4885            salt.utils.vmware.create_vm(
4886                self.vm_name,
4887                self.mock_config_spec,
4888                self.mock_folder_object,
4889                self.mock_resourcepool_object,
4890            )
4891        self.assertEqual(exc.exception.strerror, "vmodl.RuntimeFault msg")
4892
4893    def test_create_vm_wait_for_task(self):
4894        mock_wait_for_task = MagicMock()
4895        with patch("salt.utils.vmware.wait_for_task", mock_wait_for_task):
4896            salt.utils.vmware.create_vm(
4897                self.vm_name,
4898                self.mock_config_spec,
4899                self.mock_folder_object,
4900                self.mock_resourcepool_object,
4901            )
4902        mock_wait_for_task.assert_called_once_with(
4903            self.mock_task, self.vm_name, "CreateVM Task", 10, "info"
4904        )
4905
4906
4907@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4908@patch("salt.utils.vmware.get_managed_object_name", MagicMock())
4909@patch("salt.utils.vmware.wait_for_task", MagicMock())
4910class RegisterVirtualMachineTestCase(TestCase):
4911    """
4912    Tests for salt.utils.vmware.register_vm
4913    """
4914
4915    def setUp(self):
4916        self.vm_name = "fake_vm"
4917        self.mock_task = MagicMock()
4918        self.mock_vmx_path = MagicMock()
4919        self.mock_resourcepool_object = MagicMock()
4920        self.mock_host_object = MagicMock()
4921        self.mock_vm_register_task = MagicMock(return_value=self.mock_task)
4922        self.vm_folder_object = MagicMock(RegisterVM_Task=self.mock_vm_register_task)
4923        self.datacenter = MagicMock(vmFolder=self.vm_folder_object)
4924
4925    def test_register_vm_pool_task_call(self):
4926        salt.utils.vmware.register_vm(
4927            self.datacenter,
4928            self.vm_name,
4929            self.mock_vmx_path,
4930            self.mock_resourcepool_object,
4931        )
4932        self.mock_vm_register_task.assert_called_once()
4933
4934    def test_register_vm_host_task_call(self):
4935        salt.utils.vmware.register_vm(
4936            self.datacenter,
4937            self.vm_name,
4938            self.mock_vmx_path,
4939            self.mock_resourcepool_object,
4940            host_object=self.mock_host_object,
4941        )
4942        self.mock_vm_register_task.assert_called_once()
4943
4944    def test_register_vm_raise_no_permission(self):
4945        exception = vim.fault.NoPermission()
4946        self.vm_folder_object.RegisterVM_Task = MagicMock(side_effect=exception)
4947        with self.assertRaises(VMwareApiError) as exc:
4948            salt.utils.vmware.register_vm(
4949                self.datacenter,
4950                self.vm_name,
4951                self.mock_vmx_path,
4952                self.mock_resourcepool_object,
4953            )
4954        self.assertEqual(
4955            exc.exception.strerror, "Not enough permissions. Required privilege: "
4956        )
4957
4958    def test_register_vm_raise_vim_fault(self):
4959        exception = vim.fault.VimFault()
4960        exception.msg = "vim.fault.VimFault msg"
4961        self.vm_folder_object.RegisterVM_Task = MagicMock(side_effect=exception)
4962        with self.assertRaises(VMwareApiError) as exc:
4963            salt.utils.vmware.register_vm(
4964                self.datacenter,
4965                self.vm_name,
4966                self.mock_vmx_path,
4967                self.mock_resourcepool_object,
4968            )
4969        self.assertEqual(exc.exception.strerror, "vim.fault.VimFault msg")
4970
4971    def test_register_vm_raise_runtime_fault(self):
4972        exception = vmodl.RuntimeFault()
4973        exception.msg = "vmodl.RuntimeFault msg"
4974        self.vm_folder_object.RegisterVM_Task = MagicMock(side_effect=exception)
4975        with self.assertRaises(VMwareRuntimeError) as exc:
4976            salt.utils.vmware.register_vm(
4977                self.datacenter,
4978                self.vm_name,
4979                self.mock_vmx_path,
4980                self.mock_resourcepool_object,
4981            )
4982        self.assertEqual(exc.exception.strerror, "vmodl.RuntimeFault msg")
4983
4984    def test_register_vm_wait_for_task(self):
4985        mock_wait_for_task = MagicMock()
4986        with patch("salt.utils.vmware.wait_for_task", mock_wait_for_task):
4987            salt.utils.vmware.register_vm(
4988                self.datacenter,
4989                self.vm_name,
4990                self.mock_vmx_path,
4991                self.mock_resourcepool_object,
4992            )
4993        mock_wait_for_task.assert_called_once_with(
4994            self.mock_task, self.vm_name, "RegisterVM Task"
4995        )
4996
4997
4998@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
4999@patch("salt.utils.vmware.get_managed_object_name", MagicMock())
5000@patch("salt.utils.vmware.wait_for_task", MagicMock())
5001class UpdateVirtualMachineTestCase(TestCase):
5002    """
5003    Tests for salt.utils.vmware.update_vm
5004    """
5005
5006    def setUp(self):
5007        self.mock_task = MagicMock()
5008        self.mock_config_spec = MagicMock()
5009        self.mock_vm_update_task = MagicMock(return_value=self.mock_task)
5010        self.mock_vm_ref = MagicMock(ReconfigVM_Task=self.mock_vm_update_task)
5011
5012    def test_update_vm_task_call(self):
5013        salt.utils.vmware.update_vm(self.mock_vm_ref, self.mock_config_spec)
5014        self.mock_vm_update_task.assert_called_once()
5015
5016    def test_update_vm_raise_vim_fault(self):
5017        exception = vim.fault.VimFault()
5018        exception.msg = "vim.fault.VimFault"
5019        self.mock_vm_ref.ReconfigVM_Task = MagicMock(side_effect=exception)
5020        with self.assertRaises(VMwareApiError) as exc:
5021            salt.utils.vmware.update_vm(self.mock_vm_ref, self.mock_config_spec)
5022        self.assertEqual(exc.exception.strerror, "vim.fault.VimFault")
5023
5024    def test_update_vm_raise_runtime_fault(self):
5025        exception = vmodl.RuntimeFault()
5026        exception.msg = "vmodl.RuntimeFault"
5027        self.mock_vm_ref.ReconfigVM_Task = MagicMock(side_effect=exception)
5028        with self.assertRaises(VMwareRuntimeError) as exc:
5029            salt.utils.vmware.update_vm(self.mock_vm_ref, self.mock_config_spec)
5030        self.assertEqual(exc.exception.strerror, "vmodl.RuntimeFault")
5031
5032    def test_update_vm_wait_for_task(self):
5033        mock_wait_for_task = MagicMock()
5034        with patch(
5035            "salt.utils.vmware.get_managed_object_name", MagicMock(return_value="my_vm")
5036        ):
5037            with patch("salt.utils.vmware.wait_for_task", mock_wait_for_task):
5038                salt.utils.vmware.update_vm(self.mock_vm_ref, self.mock_config_spec)
5039        mock_wait_for_task.assert_called_once_with(
5040            self.mock_task, "my_vm", "ReconfigureVM Task"
5041        )
5042
5043
5044@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
5045@patch("salt.utils.vmware.get_managed_object_name", MagicMock())
5046@patch("salt.utils.vmware.wait_for_task", MagicMock())
5047class DeleteVirtualMachineTestCase(TestCase):
5048    """
5049    Tests for salt.utils.vmware.delete_vm
5050    """
5051
5052    def setUp(self):
5053        self.mock_task = MagicMock()
5054        self.mock_vm_destroy_task = MagicMock(return_value=self.mock_task)
5055        self.mock_vm_ref = MagicMock(Destroy_Task=self.mock_vm_destroy_task)
5056
5057    def test_destroy_vm_task_call(self):
5058        salt.utils.vmware.delete_vm(self.mock_vm_ref)
5059        self.mock_vm_destroy_task.assert_called_once()
5060
5061    def test_destroy_vm_raise_vim_fault(self):
5062        exception = vim.fault.VimFault()
5063        exception.msg = "vim.fault.VimFault"
5064        self.mock_vm_ref.Destroy_Task = MagicMock(side_effect=exception)
5065        with self.assertRaises(VMwareApiError) as exc:
5066            salt.utils.vmware.delete_vm(self.mock_vm_ref)
5067        self.assertEqual(exc.exception.strerror, "vim.fault.VimFault")
5068
5069    def test_destroy_vm_raise_runtime_fault(self):
5070        exception = vmodl.RuntimeFault()
5071        exception.msg = "vmodl.RuntimeFault"
5072        self.mock_vm_ref.Destroy_Task = MagicMock(side_effect=exception)
5073        with self.assertRaises(VMwareRuntimeError) as exc:
5074            salt.utils.vmware.delete_vm(self.mock_vm_ref)
5075        self.assertEqual(exc.exception.strerror, "vmodl.RuntimeFault")
5076
5077    def test_destroy_vm_wait_for_task(self):
5078        mock_wait_for_task = MagicMock()
5079        with patch(
5080            "salt.utils.vmware.get_managed_object_name", MagicMock(return_value="my_vm")
5081        ):
5082            with patch("salt.utils.vmware.wait_for_task", mock_wait_for_task):
5083                salt.utils.vmware.delete_vm(self.mock_vm_ref)
5084        mock_wait_for_task.assert_called_once_with(
5085            self.mock_task, "my_vm", "Destroy Task"
5086        )
5087
5088
5089@skipIf(not HAS_PYVMOMI, "The 'pyvmomi' library is missing")
5090@patch("salt.utils.vmware.get_managed_object_name", MagicMock())
5091class UnregisterVirtualMachineTestCase(TestCase):
5092    """
5093    Tests for salt.utils.vmware.unregister_vm
5094    """
5095
5096    def setUp(self):
5097        self.mock_vm_unregister = MagicMock()
5098        self.mock_vm_ref = MagicMock(UnregisterVM=self.mock_vm_unregister)
5099
5100    def test_unregister_vm_task_call(self):
5101        salt.utils.vmware.unregister_vm(self.mock_vm_ref)
5102        self.mock_vm_unregister.assert_called_once()
5103
5104    def test_unregister_vm_raise_vim_fault(self):
5105        exception = vim.fault.VimFault()
5106        exception.msg = "vim.fault.VimFault"
5107        self.mock_vm_ref.UnregisterVM = MagicMock(side_effect=exception)
5108        with self.assertRaises(VMwareApiError) as exc:
5109            salt.utils.vmware.unregister_vm(self.mock_vm_ref)
5110        self.assertEqual(exc.exception.strerror, "vim.fault.VimFault")
5111
5112    def test_unregister_vm_raise_runtime_fault(self):
5113        exception = vmodl.RuntimeFault()
5114        exception.msg = "vmodl.RuntimeFault"
5115        self.mock_vm_ref.UnregisterVM = MagicMock(side_effect=exception)
5116        with self.assertRaises(VMwareRuntimeError) as exc:
5117            salt.utils.vmware.unregister_vm(self.mock_vm_ref)
5118        self.assertEqual(exc.exception.strerror, "vmodl.RuntimeFault")
5119