fb-vmware 1.7.1__py3-none-any.whl → 1.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. fb_vmware/__init__.py +1 -1
  2. fb_vmware/app/__init__.py +285 -6
  3. fb_vmware/app/get_host_list.py +115 -100
  4. fb_vmware/app/get_network_list.py +176 -218
  5. fb_vmware/app/get_rpool_list.py +386 -0
  6. fb_vmware/app/get_storage_cluster_info.py +303 -0
  7. fb_vmware/app/get_storage_cluster_list.py +100 -107
  8. fb_vmware/app/get_storage_list.py +145 -112
  9. fb_vmware/app/get_vm_info.py +79 -17
  10. fb_vmware/app/get_vm_list.py +169 -95
  11. fb_vmware/app/search_storage.py +470 -0
  12. fb_vmware/argparse_actions.py +78 -0
  13. fb_vmware/base.py +28 -1
  14. fb_vmware/cluster.py +99 -7
  15. fb_vmware/connect.py +450 -20
  16. fb_vmware/datastore.py +195 -6
  17. fb_vmware/dc.py +19 -1
  18. fb_vmware/ds_cluster.py +215 -2
  19. fb_vmware/dvs.py +37 -1
  20. fb_vmware/errors.py +31 -10
  21. fb_vmware/host.py +40 -2
  22. fb_vmware/host_port_group.py +1 -2
  23. fb_vmware/network.py +17 -1
  24. fb_vmware/obj.py +30 -1
  25. fb_vmware/vm.py +19 -1
  26. fb_vmware/xlate.py +8 -13
  27. fb_vmware-1.8.1.data/data/share/locale/de/LC_MESSAGES/fb_vmware.mo +0 -0
  28. fb_vmware-1.8.1.data/data/share/locale/en/LC_MESSAGES/fb_vmware.mo +0 -0
  29. {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/METADATA +2 -1
  30. fb_vmware-1.8.1.dist-info/RECORD +40 -0
  31. {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/entry_points.txt +3 -0
  32. fb_vmware-1.7.1.data/data/share/locale/de_DE/LC_MESSAGES/fb_vmware.mo +0 -0
  33. fb_vmware-1.7.1.data/data/share/locale/en_US/LC_MESSAGES/fb_vmware.mo +0 -0
  34. fb_vmware-1.7.1.dist-info/RECORD +0 -36
  35. {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/WHEEL +0 -0
  36. {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/licenses/LICENSE +0 -0
fb_vmware/datastore.py CHANGED
@@ -27,12 +27,14 @@ from fb_tools.xlate import format_list
27
27
  from pyVmomi import vim
28
28
 
29
29
  # Own modules
30
+ from .errors import FbVMWareRuntimeError
30
31
  from .errors import VSphereHandlerError
31
32
  from .errors import VSphereNameError
33
+ from .errors import VSphereNoDatastoreFoundError
32
34
  from .obj import VsphereObject
33
35
  from .xlate import XLATOR
34
36
 
35
- __version__ = "1.5.0"
37
+ __version__ = "1.8.2"
36
38
  LOG = logging.getLogger(__name__)
37
39
 
38
40
  _ = XLATOR.gettext
@@ -63,6 +65,15 @@ class VsphereDatastore(VsphereObject):
63
65
  "version",
64
66
  )
65
67
 
68
+ valid_storage_types = (
69
+ "NFS",
70
+ "SSD",
71
+ "HDD",
72
+ "LOCAL",
73
+ )
74
+
75
+ default_storage_type = "HDD"
76
+
66
77
  # -------------------------------------------------------------------------
67
78
  def __init__(
68
79
  self,
@@ -109,10 +120,13 @@ class VsphereDatastore(VsphereObject):
109
120
  self._url = str(url)
110
121
  self._for_k8s = False
111
122
 
112
- self._storage_type = "unknown"
123
+ self._storage_type = self.default_storage_type
113
124
 
114
125
  self._calculated_usage = 0.0
115
126
 
127
+ self.hosts = None
128
+ self.compute_clusters = None
129
+
116
130
  super(VsphereDatastore, self).__init__(
117
131
  name=name,
118
132
  obj_type="vsphere_datastore",
@@ -285,7 +299,7 @@ class VsphereDatastore(VsphereObject):
285
299
  # -----------------------------------------------------------
286
300
  @property
287
301
  def storage_type(self):
288
- """Return the type of storage volume, such as SAS or SATA or SSD."""
302
+ """Return the type of storage volume, such as HDD or SSD."""
289
303
  return self._storage_type
290
304
 
291
305
  # -----------------------------------------------------------
@@ -321,6 +335,8 @@ class VsphereDatastore(VsphereObject):
321
335
  verbose=0,
322
336
  base_dir=None,
323
337
  test_mode=False,
338
+ detailled=False,
339
+ hostlist=None,
324
340
  ):
325
341
  """Create a new VsphereDatastore object based on the data given from pyvmomi module."""
326
342
  if test_mode:
@@ -388,8 +404,50 @@ class VsphereDatastore(VsphereObject):
388
404
  LOG.debug(_("Creating {} object from:").format(cls.__name__) + "\n" + pp(params))
389
405
 
390
406
  ds = cls(**params)
407
+
408
+ if detailled:
409
+ ds.get_hosts(data, hostlist=hostlist)
410
+
391
411
  return ds
392
412
 
413
+ # -------------------------------------------------------------------------
414
+ def get_hosts(self, data, hostlist=None):
415
+ """Get a list of all connected ESX hosts."""
416
+ if not hasattr(data, "host"):
417
+ return
418
+
419
+ if hostlist is None:
420
+ hostlist = {}
421
+
422
+ self.hosts = set()
423
+ self.compute_clusters = set()
424
+
425
+ for host_data in data.host:
426
+ host_name = host_data.key.name
427
+ self.hosts.add(host_name)
428
+ if host_name not in hostlist:
429
+ parents = self.get_parents(host_data.key)
430
+ if self.verbose > 2:
431
+ LOG.debug(f"Parents of host {host_name!r}:\n" + pp(parents))
432
+ dc = None
433
+ cr = None
434
+ for i in range(len(parents), 0, -1):
435
+ (parent_type, parent_name) = parents[i - 1]
436
+ if parent_type == "vim.Datacenter":
437
+ dc = parent_name
438
+ if parent_type in ("vim.ComputeResource", "vim.ClusterComputeResource"):
439
+ cr = parent_name
440
+
441
+ # hostlist[host_name] = (parents[1][1], parents[3][1])
442
+ hostlist[host_name] = {
443
+ "dc": dc,
444
+ "cr": cr,
445
+ }
446
+
447
+ for host in hostlist:
448
+ compute_cluster = hostlist[host]["cr"]
449
+ self.compute_clusters.add(compute_cluster)
450
+
393
451
  # -------------------------------------------------------------------------
394
452
  @classmethod
395
453
  def storage_type_by_name(cls, name):
@@ -398,16 +456,19 @@ class VsphereDatastore(VsphereObject):
398
456
  return "NFS"
399
457
 
400
458
  if "-sas-" in name.lower():
401
- return "SAS"
459
+ return "HDD"
402
460
 
403
461
  if "-ssd-" in name.lower():
404
462
  return "SSD"
405
463
 
406
464
  if "-sata-" in name.lower():
407
- return "SATA"
465
+ return "HDD"
466
+
467
+ if "-hdd-" in name.lower():
468
+ return "HDD"
408
469
 
409
470
  if cls.re_vmcb_fs.search(name):
410
- return "SATA"
471
+ return "HDD"
411
472
 
412
473
  if cls.re_local_ds.search(name):
413
474
  return "LOCAL"
@@ -426,6 +487,24 @@ class VsphereDatastore(VsphereObject):
426
487
  return True
427
488
  return False
428
489
 
490
+ # -----------------------------------------------------------
491
+ def get_pyvmomi_obj(self, service_instance):
492
+ """Return the appropriate PyVMomi object for the current object."""
493
+ obj = None
494
+ if not self.name:
495
+ return None
496
+
497
+ content = service_instance.RetrieveContent()
498
+ container = content.viewManager.CreateContainerView(
499
+ content.rootFolder, vim.Datastore, True
500
+ )
501
+ for c in container.view:
502
+ if c.name == self.name:
503
+ obj = c
504
+ break
505
+
506
+ return obj
507
+
429
508
  # -------------------------------------------------------------------------
430
509
  def as_dict(self, short=True):
431
510
  """
@@ -803,6 +882,116 @@ class VsphereDatastoreDict(MutableMapping, FbGenericBaseObject):
803
882
 
804
883
  return ds_name
805
884
 
885
+ # -------------------------------------------------------------------------
886
+ def search_space(
887
+ self,
888
+ needed_gb,
889
+ storage_type="any",
890
+ reserve_space=True,
891
+ compute_cluster=None,
892
+ use_local=False,
893
+ use_random_select=False,
894
+ ):
895
+ """Find a datastore in dict with the given minimum free space and the given type."""
896
+ st_type = storage_type.lower()
897
+ search_chains = {
898
+ "any": ("hdd", "ssd"),
899
+ "hdd": ("hdd",),
900
+ "ssd": ("ssd",),
901
+ }
902
+ if use_local:
903
+ search_chains["any"] = ("hdd", "ssd", "local")
904
+ search_chains["local"] = ("local",)
905
+
906
+ if st_type not in search_chains:
907
+ raise ValueError(
908
+ _("Could not handle storage type {}.").format(self.colored(storage_type, "RED"))
909
+ )
910
+
911
+ for st_tp in search_chains[st_type]:
912
+ ds_name = self._search_space(
913
+ needed_gb,
914
+ storage_type=st_tp,
915
+ reserve_space=reserve_space,
916
+ compute_cluster=compute_cluster,
917
+ use_random_select=use_random_select,
918
+ )
919
+ if ds_name:
920
+ return ds_name
921
+
922
+ raise VSphereNoDatastoreFoundError(needed_gb)
923
+
924
+ # -------------------------------------------------------------------------
925
+ def _search_space(
926
+ self,
927
+ needed_gb,
928
+ storage_type,
929
+ reserve_space=True,
930
+ compute_cluster=None,
931
+ use_random_select=False,
932
+ ):
933
+
934
+ LOG.debug(
935
+ _("Searching datastore for {c:d} GiB of type {t!r}.").format(
936
+ c=needed_gb, t=storage_type
937
+ )
938
+ )
939
+ LOG.debug(_("Given compute cluster: {!r}.").format(compute_cluster))
940
+
941
+ avail_ds_names = []
942
+ spaces = {}
943
+ for ds_name, ds in self.items():
944
+ usable = True
945
+ if ds.storage_type.lower() != storage_type.lower():
946
+ # LOG.debug(f"Datastore {ds_name} has wrong storage type {ds.storage_type}.")
947
+ continue
948
+ if ds.avail_space_gb < needed_gb:
949
+ # LOG.debug(f"Datastore {ds_name} is too small with {ds.avail_space_gb:0f} GB.")
950
+ usable = False
951
+
952
+ if usable and compute_cluster:
953
+ if ds.compute_clusters is None:
954
+ msg = _(
955
+ "Cannot detect connection with compute cluster {cl!r}, datastore "
956
+ "was not detailled discovered."
957
+ ).format(ds_name)
958
+ raise FbVMWareRuntimeError(msg)
959
+ found = False
960
+ for cc_name in ds.compute_clusters:
961
+ # LOG.debug(f"Checking for CC {cc_name!r} == {compute_cluster!r}.")
962
+ if cc_name == compute_cluster:
963
+ found = True
964
+ break
965
+ if not found:
966
+ # LOG.debug(
967
+ # f"Datastore {ds_name} is connected with wrong computing clusters: "
968
+ # + pp(ds_cluster.compute_clusters)
969
+ # )
970
+ usable = False
971
+
972
+ if usable:
973
+ avail_ds_names.append(ds_name)
974
+ spaces[ds_name] = ds.avail_space_gb
975
+
976
+ if not avail_ds_names:
977
+ return None
978
+
979
+ if use_random_select:
980
+ ds_name = random.choice(avail_ds_names)
981
+ else:
982
+ ds_name = None
983
+ last_val = 0.0
984
+ for n in spaces.keys():
985
+ if spaces[n] > last_val:
986
+ ds_name = n
987
+ last_val = spaces[n]
988
+
989
+ if reserve_space:
990
+ ds = self[ds_name]
991
+ ds.calculated_usage += needed_gb
992
+
993
+ return ds_name
994
+
806
995
 
807
996
  # =============================================================================
808
997
  if __name__ == "__main__":
fb_vmware/dc.py CHANGED
@@ -23,7 +23,7 @@ from .obj import DEFAULT_OBJ_STATUS
23
23
  from .obj import VsphereObject
24
24
  from .xlate import XLATOR
25
25
 
26
- __version__ = "1.0.0"
26
+ __version__ = "1.1.1"
27
27
  LOG = logging.getLogger(__name__)
28
28
 
29
29
  DEFAULT_HOST_FOLDER = "host"
@@ -133,6 +133,24 @@ class VsphereDatacenter(VsphereObject):
133
133
  """Key for Maximum Hardware Version used on this datacenter."""
134
134
  return self._max_hw_version_key
135
135
 
136
+ # -----------------------------------------------------------
137
+ def get_pyvmomi_obj(self, service_instance):
138
+ """Return the appropriate PyVMomi object for the current object."""
139
+ obj = None
140
+ if not self.name:
141
+ return None
142
+
143
+ content = service_instance.RetrieveContent()
144
+ container = content.viewManager.CreateContainerView(
145
+ content.rootFolder, vim.Datacenter, True
146
+ )
147
+ for c in container.view:
148
+ if c.name == self.name:
149
+ obj = c
150
+ break
151
+
152
+ return obj
153
+
136
154
  # -------------------------------------------------------------------------
137
155
  def as_dict(self, short=True):
138
156
  """
fb_vmware/ds_cluster.py CHANGED
@@ -11,6 +11,7 @@ from __future__ import absolute_import
11
11
 
12
12
  # Standard modules
13
13
  import logging
14
+ import random
14
15
 
15
16
  try:
16
17
  from collections.abc import MutableMapping
@@ -25,12 +26,16 @@ from fb_tools.xlate import format_list
25
26
  from pyVmomi import vim
26
27
 
27
28
  # Own modules
29
+ from .datastore import VsphereDatastore
30
+ from .datastore import VsphereDatastoreDict
31
+ from .errors import FbVMWareRuntimeError
28
32
  from .errors import VSphereHandlerError
29
33
  from .errors import VSphereNameError
34
+ from .errors import VSphereNoDsClusterFoundError
30
35
  from .obj import VsphereObject
31
36
  from .xlate import XLATOR
32
37
 
33
- __version__ = "1.4.0"
38
+ __version__ = "1.8.2"
34
39
  LOG = logging.getLogger(__name__)
35
40
 
36
41
  _ = XLATOR.gettext
@@ -53,6 +58,13 @@ class VsphereDsCluster(VsphereObject):
53
58
  "version",
54
59
  )
55
60
 
61
+ valid_storage_types = (
62
+ "SSD",
63
+ "HDD",
64
+ )
65
+
66
+ default_storage_type = "HDD"
67
+
56
68
  # -------------------------------------------------------------------------
57
69
  def __init__(
58
70
  self,
@@ -74,8 +86,12 @@ class VsphereDsCluster(VsphereObject):
74
86
  self._dc_name = None
75
87
  self._capacity = int(capacity)
76
88
  self._free_space = int(free_space)
89
+ self.datastores = None
90
+ self.hosts = None
91
+ self.compute_clusters = None
77
92
 
78
93
  self._calculated_usage = 0.0
94
+ self._storage_type = self.default_storage_type
79
95
 
80
96
  super(VsphereDsCluster, self).__init__(
81
97
  name=name,
@@ -92,6 +108,10 @@ class VsphereDsCluster(VsphereObject):
92
108
  self.vsphere = vsphere
93
109
  self.dc_name = dc_name
94
110
 
111
+ st_type = self.storage_type_by_name(self.name)
112
+ if st_type:
113
+ self._storage_type = st_type
114
+
95
115
  if initialized is not None:
96
116
  self.initialized = initialized
97
117
 
@@ -178,6 +198,30 @@ class VsphereDsCluster(VsphereObject):
178
198
 
179
199
  self._vsphere = val
180
200
 
201
+ # -----------------------------------------------------------
202
+ @property
203
+ def storage_type(self):
204
+ """Return the type of storage volume, such as HDD or SSD."""
205
+ return self._storage_type
206
+
207
+ # -------------------------------------------------------------------------
208
+ @classmethod
209
+ def storage_type_by_name(cls, name):
210
+ """Guess the storage type by its name. May be overridden in descentant classes."""
211
+ if "-sas-" in name.lower():
212
+ return "HDD"
213
+
214
+ if "-ssd-" in name.lower():
215
+ return "SSD"
216
+
217
+ if "-sata-" in name.lower():
218
+ return "HDD"
219
+
220
+ if "-hdd-" in name.lower():
221
+ return "HDD"
222
+
223
+ return None
224
+
181
225
  # -------------------------------------------------------------------------
182
226
  @classmethod
183
227
  def from_summary(
@@ -189,6 +233,7 @@ class VsphereDsCluster(VsphereObject):
189
233
  verbose=0,
190
234
  base_dir=None,
191
235
  test_mode=False,
236
+ detailled=False,
192
237
  ):
193
238
  """Create a new VsphereDsCluster object based on the data given from pyvmomi."""
194
239
  if test_mode:
@@ -239,10 +284,71 @@ class VsphereDsCluster(VsphereObject):
239
284
 
240
285
  if verbose > 2:
241
286
  LOG.debug(_("Creating {} object from:").format(cls.__name__) + "\n" + pp(params))
242
-
243
287
  cluster = cls(**params)
288
+
289
+ if detailled:
290
+ cluster.get_detailled_info(data)
291
+
244
292
  return cluster
245
293
 
294
+ # -----------------------------------------------------------
295
+ def get_detailled_info(self, data):
296
+ """Get detailled infos about owning datastores and connected hosts."""
297
+ if not hasattr(data, "childEntity"):
298
+ return
299
+
300
+ self.datastores = VsphereDatastoreDict()
301
+ self.hosts = set()
302
+ self.compute_clusters = set()
303
+
304
+ hostlist = {}
305
+
306
+ for child in data.childEntity:
307
+ if isinstance(child, vim.Datastore):
308
+ if self.verbose > 1:
309
+ LOG.debug(
310
+ _("Datastore {ds!r} is assigned to datastore_cluster {dsc!r}.").format(
311
+ ds=child.name, dsc=self.name
312
+ )
313
+ )
314
+ ds = VsphereDatastore.from_summary(
315
+ child,
316
+ vsphere=self.vsphere,
317
+ dc_name=self.dc_name,
318
+ cluster=self.name,
319
+ appname=self.appname,
320
+ verbose=self.verbose,
321
+ base_dir=self.base_dir,
322
+ detailled=True,
323
+ hostlist=hostlist,
324
+ )
325
+ self.datastores.append(ds)
326
+
327
+ for host in ds.hosts:
328
+ self.hosts.add(host)
329
+
330
+ if ds.compute_clusters:
331
+ for compute_cluster in ds.compute_clusters:
332
+ self.compute_clusters.add(compute_cluster)
333
+
334
+ # -----------------------------------------------------------
335
+ def get_pyvmomi_obj(self, service_instance):
336
+ """Return the appropriate PyVMomi object for the current object."""
337
+ obj = None
338
+ if not self.name:
339
+ return None
340
+
341
+ content = service_instance.RetrieveContent()
342
+ container = content.viewManager.CreateContainerView(
343
+ content.rootFolder, vim.StoragePod, True
344
+ )
345
+ for c in container.view:
346
+ if c.name == self.name:
347
+ obj = c
348
+ break
349
+
350
+ return obj
351
+
246
352
  # -------------------------------------------------------------------------
247
353
  def as_dict(self, short=True):
248
354
  """
@@ -262,6 +368,7 @@ class VsphereDsCluster(VsphereObject):
262
368
  res["dc_name"] = self.dc_name
263
369
  res["free_space"] = self.free_space
264
370
  res["free_space_gb"] = self.free_space_gb
371
+ res["storage_type"] = self.storage_type
265
372
  res["vsphere"] = self.vsphere
266
373
 
267
374
  return res
@@ -550,6 +657,112 @@ class VsphereDsClusterDict(MutableMapping, FbGenericBaseObject):
550
657
  res.append(self._map[cluster_name].as_dict(short))
551
658
  return res
552
659
 
660
+ # -------------------------------------------------------------------------
661
+ def search_space(
662
+ self,
663
+ needed_gb,
664
+ storage_type="any",
665
+ reserve_space=True,
666
+ compute_cluster=None,
667
+ use_random_select=False,
668
+ ):
669
+ """Find a datastore cluster with the given minimum free space and the given type."""
670
+ st_type = storage_type.lower()
671
+ search_chains = {
672
+ "any": ("hdd", "ssd"),
673
+ "hdd": ("hdd",),
674
+ "ssd": ("ssd",),
675
+ }
676
+
677
+ if st_type not in search_chains:
678
+ raise ValueError(
679
+ _("Could not handle storage type {}.").format(self.colored(storage_type, "RED"))
680
+ )
681
+
682
+ for st_tp in search_chains[st_type]:
683
+ ds_cluster_name = self._search_space(
684
+ needed_gb,
685
+ storage_type=st_tp,
686
+ reserve_space=reserve_space,
687
+ compute_cluster=compute_cluster,
688
+ use_random_select=use_random_select,
689
+ )
690
+ if ds_cluster_name:
691
+ return ds_cluster_name
692
+
693
+ raise VSphereNoDsClusterFoundError(needed_gb)
694
+
695
+ # -------------------------------------------------------------------------
696
+ def _search_space(
697
+ self,
698
+ needed_gb,
699
+ storage_type,
700
+ reserve_space=True,
701
+ compute_cluster=None,
702
+ use_random_select=False,
703
+ ):
704
+
705
+ LOG.debug(
706
+ _("Searching datastore cluster for {c:d} GiB of type {t!r}.").format(
707
+ c=needed_gb, t=storage_type
708
+ )
709
+ )
710
+ LOG.debug(_("Given compute cluster: {!r}.").format(compute_cluster))
711
+
712
+ avail_dsc_names = []
713
+ spaces = {}
714
+ for dsc_name, dsc in self.items():
715
+ usable = True
716
+ if dsc.storage_type.lower() != storage_type.lower():
717
+ # LOG.debug(f"DS cluster {dsc_name} has wrong storage type {ds.storage_type}.")
718
+ continue
719
+ if dsc.avail_space_gb < needed_gb:
720
+ # LOG.debug(f"DS cluster {dsc_name} is too small with {ds.avail_space_gb:0f} GB.")
721
+ usable = False
722
+
723
+ if usable and compute_cluster:
724
+ if dsc.compute_clusters is None:
725
+ msg = _(
726
+ "Cannot detect connection with compute cluster {cl!r}, datastore cluster "
727
+ "was not detailled discovered."
728
+ ).format(dsc_name)
729
+ raise FbVMWareRuntimeError(msg)
730
+ found = False
731
+ for cc_name in dsc.compute_clusters:
732
+ # LOG.debug(f"Checking for CC {cc_name!r} == {compute_cluster!r}.")
733
+ if cc_name == compute_cluster:
734
+ found = True
735
+ break
736
+ if not found:
737
+ # LOG.debug(
738
+ # f"DS cluster {dsc_name} is connected with wrong computing clusters: "
739
+ # + pp(dsc.compute_clusters)
740
+ # )
741
+ usable = False
742
+
743
+ if usable:
744
+ avail_dsc_names.append(dsc_name)
745
+ spaces[dsc_name] = dsc.avail_space_gb
746
+
747
+ if not avail_dsc_names:
748
+ return None
749
+
750
+ if use_random_select:
751
+ dsc_name = random.choice(avail_dsc_names)
752
+ else:
753
+ dsc_name = None
754
+ last_val = 0.0
755
+ for n in spaces.keys():
756
+ if spaces[n] > last_val:
757
+ dsc_name = n
758
+ last_val = spaces[n]
759
+
760
+ if reserve_space:
761
+ dsc = self[dsc_name]
762
+ dsc.calculated_usage += needed_gb
763
+
764
+ return dsc_name
765
+
553
766
 
554
767
  # =============================================================================
555
768
 
fb_vmware/dvs.py CHANGED
@@ -29,7 +29,7 @@ from .obj import DEFAULT_OBJ_STATUS
29
29
  from .obj import VsphereObject
30
30
  from .xlate import XLATOR
31
31
 
32
- __version__ = "0.5.0"
32
+ __version__ = "1.1.0"
33
33
  LOG = logging.getLogger(__name__)
34
34
 
35
35
  _ = XLATOR.gettext
@@ -299,6 +299,24 @@ class VsphereDVS(VsphereObject):
299
299
 
300
300
  self._vsphere = val
301
301
 
302
+ # -----------------------------------------------------------
303
+ def get_pyvmomi_obj(self, service_instance):
304
+ """Return the appropriate PyVMomi object for the current object."""
305
+ obj = None
306
+ if not self.name:
307
+ return None
308
+
309
+ content = service_instance.RetrieveContent()
310
+ container = content.viewManager.CreateContainerView(
311
+ content.rootFolder, vim.DistributedVirtualSwitch, True
312
+ )
313
+ for c in container.view:
314
+ if c.name == self.name:
315
+ obj = c
316
+ break
317
+
318
+ return obj
319
+
302
320
  # -------------------------------------------------------------------------
303
321
  def as_dict(self, short=True):
304
322
  """
@@ -707,6 +725,24 @@ class VsphereDvPortGroup(VsphereNetwork):
707
725
  return
708
726
  self._uplink = to_bool(value)
709
727
 
728
+ # -----------------------------------------------------------
729
+ def get_pyvmomi_obj(self, service_instance):
730
+ """Return the appropriate PyVMomi object for the current object."""
731
+ obj = None
732
+ if not self.name:
733
+ return None
734
+
735
+ content = service_instance.RetrieveContent()
736
+ container = content.viewManager.CreateContainerView(
737
+ content.rootFolder, vim.dvs.DistributedVirtualPortgroup, True
738
+ )
739
+ for c in container.view:
740
+ if c.name == self.name:
741
+ obj = c
742
+ break
743
+
744
+ return obj
745
+
710
746
  # -------------------------------------------------------------------------
711
747
  def as_dict(self, short=True):
712
748
  """