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.
- fb_vmware/__init__.py +1 -1
- fb_vmware/app/__init__.py +285 -6
- fb_vmware/app/get_host_list.py +115 -100
- fb_vmware/app/get_network_list.py +176 -218
- fb_vmware/app/get_rpool_list.py +386 -0
- fb_vmware/app/get_storage_cluster_info.py +303 -0
- fb_vmware/app/get_storage_cluster_list.py +100 -107
- fb_vmware/app/get_storage_list.py +145 -112
- fb_vmware/app/get_vm_info.py +79 -17
- fb_vmware/app/get_vm_list.py +169 -95
- fb_vmware/app/search_storage.py +470 -0
- fb_vmware/argparse_actions.py +78 -0
- fb_vmware/base.py +28 -1
- fb_vmware/cluster.py +99 -7
- fb_vmware/connect.py +450 -20
- fb_vmware/datastore.py +195 -6
- fb_vmware/dc.py +19 -1
- fb_vmware/ds_cluster.py +215 -2
- fb_vmware/dvs.py +37 -1
- fb_vmware/errors.py +31 -10
- fb_vmware/host.py +40 -2
- fb_vmware/host_port_group.py +1 -2
- fb_vmware/network.py +17 -1
- fb_vmware/obj.py +30 -1
- fb_vmware/vm.py +19 -1
- fb_vmware/xlate.py +8 -13
- fb_vmware-1.8.1.data/data/share/locale/de/LC_MESSAGES/fb_vmware.mo +0 -0
- fb_vmware-1.8.1.data/data/share/locale/en/LC_MESSAGES/fb_vmware.mo +0 -0
- {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/METADATA +2 -1
- fb_vmware-1.8.1.dist-info/RECORD +40 -0
- {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/entry_points.txt +3 -0
- fb_vmware-1.7.1.data/data/share/locale/de_DE/LC_MESSAGES/fb_vmware.mo +0 -0
- fb_vmware-1.7.1.data/data/share/locale/en_US/LC_MESSAGES/fb_vmware.mo +0 -0
- fb_vmware-1.7.1.dist-info/RECORD +0 -36
- {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/WHEEL +0 -0
- {fb_vmware-1.7.1.dist-info → fb_vmware-1.8.1.dist-info}/licenses/LICENSE +0 -0
fb_vmware/connect.py
CHANGED
|
@@ -55,7 +55,7 @@ from .network import VsphereNetwork, VsphereNetworkDict
|
|
|
55
55
|
from .vm import VsphereVm, VsphereVmList
|
|
56
56
|
from .xlate import XLATOR
|
|
57
57
|
|
|
58
|
-
__version__ = "2.
|
|
58
|
+
__version__ = "2.11.3"
|
|
59
59
|
LOG = logging.getLogger(__name__)
|
|
60
60
|
|
|
61
61
|
DEFAULT_OS_VERSION = "rhel9_64Guest"
|
|
@@ -279,12 +279,15 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
279
279
|
return
|
|
280
280
|
|
|
281
281
|
# -------------------------------------------------------------------------
|
|
282
|
-
def get_clusters(self, disconnect=False):
|
|
283
|
-
"""Get all clusters from vSphere as VsphereCluster objects."""
|
|
282
|
+
def get_clusters(self, vsphere_name=None, search_in_dc=None, disconnect=False):
|
|
283
|
+
"""Get all computing clusters from vSphere as VsphereCluster objects."""
|
|
284
284
|
LOG.debug(_("Trying to get all clusters from vSphere ..."))
|
|
285
285
|
|
|
286
286
|
self.clusters = []
|
|
287
287
|
|
|
288
|
+
if vsphere_name is None:
|
|
289
|
+
vsphere_name = self.name
|
|
290
|
+
|
|
288
291
|
try:
|
|
289
292
|
|
|
290
293
|
if not self.service_instance:
|
|
@@ -292,11 +295,17 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
292
295
|
|
|
293
296
|
self.get_datacenters()
|
|
294
297
|
content = self.service_instance.RetrieveContent()
|
|
298
|
+
|
|
295
299
|
for dc_name in self.datacenters.keys():
|
|
300
|
+
if search_in_dc is not None:
|
|
301
|
+
if dc_name != search_in_dc:
|
|
302
|
+
continue
|
|
303
|
+
if self.verbose > 1:
|
|
304
|
+
LOG.debug(_("Get all computing clusters in DC {!r} ...").format(dc_name))
|
|
296
305
|
dc = self.get_obj(content, [vim.Datacenter], dc_name)
|
|
297
306
|
|
|
298
307
|
for child in dc.hostFolder.childEntity:
|
|
299
|
-
self._get_clusters(child, dc_name=dc_name)
|
|
308
|
+
self._get_clusters(child, vsphere_name=vsphere_name, dc_name=dc_name)
|
|
300
309
|
|
|
301
310
|
finally:
|
|
302
311
|
if disconnect:
|
|
@@ -314,13 +323,21 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
314
323
|
LOG.debug(_("Found clusters:") + "\n" + pp(out))
|
|
315
324
|
|
|
316
325
|
# -------------------------------------------------------------------------
|
|
317
|
-
def _get_clusters(self, child, dc_name=None, depth=1):
|
|
326
|
+
def _get_clusters(self, child, vsphere_name=None, dc_name=None, depth=1):
|
|
327
|
+
|
|
328
|
+
if vsphere_name is None:
|
|
329
|
+
vsphere_name = self.name
|
|
318
330
|
|
|
319
331
|
if hasattr(child, "childEntity"):
|
|
320
332
|
if depth > self.max_search_depth:
|
|
321
333
|
return
|
|
322
334
|
for sub_child in child.childEntity:
|
|
323
|
-
self._get_clusters(
|
|
335
|
+
self._get_clusters(
|
|
336
|
+
sub_child,
|
|
337
|
+
vsphere_name=vsphere_name,
|
|
338
|
+
dc_name=dc_name,
|
|
339
|
+
depth=(depth + 1),
|
|
340
|
+
)
|
|
324
341
|
return
|
|
325
342
|
|
|
326
343
|
if isinstance(child, (vim.ClusterComputeResource, vim.ComputeResource)):
|
|
@@ -329,6 +346,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
329
346
|
appname=self.appname,
|
|
330
347
|
verbose=self.verbose,
|
|
331
348
|
base_dir=self.base_dir,
|
|
349
|
+
vsphere=vsphere_name,
|
|
332
350
|
dc_name=dc_name,
|
|
333
351
|
)
|
|
334
352
|
if self.verbose > 1:
|
|
@@ -374,7 +392,15 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
374
392
|
return None
|
|
375
393
|
|
|
376
394
|
# -------------------------------------------------------------------------
|
|
377
|
-
def get_datastores(
|
|
395
|
+
def get_datastores(
|
|
396
|
+
self,
|
|
397
|
+
vsphere_name=None,
|
|
398
|
+
no_local_ds=True,
|
|
399
|
+
search_in_dc=None,
|
|
400
|
+
warn_if_empty=True,
|
|
401
|
+
disconnect=False,
|
|
402
|
+
detailled=False,
|
|
403
|
+
):
|
|
378
404
|
"""Get all datastores from vSphere as VsphereDatastore objects."""
|
|
379
405
|
LOG.debug(_("Trying to get all datastores from vSphere ..."))
|
|
380
406
|
self.datastores = VsphereDatastoreDict()
|
|
@@ -391,7 +417,10 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
391
417
|
self.get_datacenters()
|
|
392
418
|
content = self.service_instance.RetrieveContent()
|
|
393
419
|
for dc_name in self.datacenters.keys():
|
|
394
|
-
if
|
|
420
|
+
if search_in_dc is not None:
|
|
421
|
+
if dc_name != search_in_dc:
|
|
422
|
+
continue
|
|
423
|
+
if self.verbose > 1:
|
|
395
424
|
LOG.debug(_("Get all datastores in DC {!r} ...").format(dc_name))
|
|
396
425
|
dc = self.get_obj(content, [vim.Datacenter], dc_name)
|
|
397
426
|
for child in dc.datastoreFolder.childEntity:
|
|
@@ -400,6 +429,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
400
429
|
vsphere_name=vsphere_name,
|
|
401
430
|
dc_name=dc_name,
|
|
402
431
|
no_local_ds=no_local_ds,
|
|
432
|
+
detailled=detailled,
|
|
403
433
|
)
|
|
404
434
|
|
|
405
435
|
finally:
|
|
@@ -412,7 +442,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
412
442
|
LOG.debug(_("Found datastores:") + "\n" + pp(self.datastores.as_list()))
|
|
413
443
|
else:
|
|
414
444
|
LOG.debug(_("Found datastores:") + "\n" + pp(list(self.datastores.keys())))
|
|
415
|
-
|
|
445
|
+
elif warn_if_empty:
|
|
416
446
|
raise VSphereNoDatastoresFoundError()
|
|
417
447
|
|
|
418
448
|
for ds_name, ds in self.datastores.items():
|
|
@@ -430,6 +460,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
430
460
|
cluster=None,
|
|
431
461
|
no_local_ds=True,
|
|
432
462
|
depth=1,
|
|
463
|
+
detailled=False,
|
|
433
464
|
):
|
|
434
465
|
|
|
435
466
|
if self.verbose > 3:
|
|
@@ -454,6 +485,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
454
485
|
cluster=ds.name,
|
|
455
486
|
no_local_ds=no_local_ds,
|
|
456
487
|
depth=(depth + 1),
|
|
488
|
+
detailled=detailled,
|
|
457
489
|
)
|
|
458
490
|
return
|
|
459
491
|
|
|
@@ -468,6 +500,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
468
500
|
cluster=cluster,
|
|
469
501
|
no_local_ds=no_local_ds,
|
|
470
502
|
depth=(depth + 1),
|
|
503
|
+
detailled=detailled,
|
|
471
504
|
)
|
|
472
505
|
return
|
|
473
506
|
|
|
@@ -484,6 +517,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
484
517
|
appname=self.appname,
|
|
485
518
|
verbose=self.verbose,
|
|
486
519
|
base_dir=self.base_dir,
|
|
520
|
+
detailled=detailled,
|
|
487
521
|
)
|
|
488
522
|
if self.verbose > 2:
|
|
489
523
|
LOG.debug(
|
|
@@ -496,7 +530,14 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
496
530
|
return
|
|
497
531
|
|
|
498
532
|
# -------------------------------------------------------------------------
|
|
499
|
-
def get_ds_clusters(
|
|
533
|
+
def get_ds_clusters(
|
|
534
|
+
self,
|
|
535
|
+
vsphere_name=None,
|
|
536
|
+
search_in_dc=None,
|
|
537
|
+
warn_if_empty=True,
|
|
538
|
+
disconnect=False,
|
|
539
|
+
detailled=False,
|
|
540
|
+
):
|
|
500
541
|
"""Get all datastores clusters from vSphere as VsphereDsCluster objects."""
|
|
501
542
|
LOG.debug(_("Trying to get all datastore clusters from vSphere ..."))
|
|
502
543
|
self.ds_clusters = VsphereDsClusterDict()
|
|
@@ -512,12 +553,21 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
512
553
|
|
|
513
554
|
self.get_datacenters()
|
|
514
555
|
content = self.service_instance.RetrieveContent()
|
|
556
|
+
|
|
515
557
|
for dc_name in self.datacenters.keys():
|
|
516
|
-
if
|
|
558
|
+
if search_in_dc is not None:
|
|
559
|
+
if dc_name != search_in_dc:
|
|
560
|
+
continue
|
|
561
|
+
if self.verbose > 1:
|
|
517
562
|
LOG.debug(_("Get all datastore clusters in DC {!r} ...").format(dc_name))
|
|
518
563
|
dc = self.get_obj(content, [vim.Datacenter], dc_name)
|
|
519
564
|
for child in dc.datastoreFolder.childEntity:
|
|
520
|
-
self._get_ds_clusters(
|
|
565
|
+
self._get_ds_clusters(
|
|
566
|
+
child,
|
|
567
|
+
vsphere_name=vsphere_name,
|
|
568
|
+
dc_name=dc_name,
|
|
569
|
+
detailled=detailled,
|
|
570
|
+
)
|
|
521
571
|
|
|
522
572
|
finally:
|
|
523
573
|
if disconnect:
|
|
@@ -533,7 +583,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
533
583
|
LOG.debug(
|
|
534
584
|
_("Found datastore clusters:") + "\n" + pp(list(self.ds_clusters.keys()))
|
|
535
585
|
)
|
|
536
|
-
|
|
586
|
+
elif warn_if_empty:
|
|
537
587
|
LOG.warning(_("No vSphere datastore clusters found."))
|
|
538
588
|
|
|
539
589
|
for dsc_name, dsc in self.ds_clusters.items():
|
|
@@ -543,7 +593,14 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
543
593
|
LOG.debug(_("Datastore cluster mappings:") + "\n" + pp(self.ds_cluster_mapping))
|
|
544
594
|
|
|
545
595
|
# -------------------------------------------------------------------------
|
|
546
|
-
def _get_ds_clusters(
|
|
596
|
+
def _get_ds_clusters(
|
|
597
|
+
self,
|
|
598
|
+
child,
|
|
599
|
+
vsphere_name=None,
|
|
600
|
+
dc_name=None,
|
|
601
|
+
depth=1,
|
|
602
|
+
detailled=False,
|
|
603
|
+
):
|
|
547
604
|
|
|
548
605
|
if self.verbose > 3:
|
|
549
606
|
LOG.debug(_("Found a {} child.").format(child.__class__.__name__))
|
|
@@ -557,6 +614,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
557
614
|
vsphere_name=vsphere_name,
|
|
558
615
|
dc_name=dc_name,
|
|
559
616
|
depth=depth + 1,
|
|
617
|
+
detailled=detailled,
|
|
560
618
|
)
|
|
561
619
|
|
|
562
620
|
if isinstance(child, vim.StoragePod):
|
|
@@ -567,11 +625,80 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
567
625
|
appname=self.appname,
|
|
568
626
|
verbose=self.verbose,
|
|
569
627
|
base_dir=self.base_dir,
|
|
628
|
+
detailled=detailled,
|
|
570
629
|
)
|
|
571
630
|
self.ds_clusters.append(ds)
|
|
572
631
|
|
|
573
632
|
return
|
|
574
633
|
|
|
634
|
+
# -------------------------------------------------------------------------
|
|
635
|
+
def get_ds_cluster(
|
|
636
|
+
self, cluster_name, vsphere_name=None, no_error=False, disconnect=False, detailled=False
|
|
637
|
+
):
|
|
638
|
+
"""Get the first datastore cluster from vSphere with the given name."""
|
|
639
|
+
if vsphere_name is None:
|
|
640
|
+
vsphere_name = self.name
|
|
641
|
+
|
|
642
|
+
if not cluster_name:
|
|
643
|
+
msg = _("No valid cluster name given on calling {}.").format("get_ds_cluster()")
|
|
644
|
+
raise ValueError(msg)
|
|
645
|
+
|
|
646
|
+
msg = _("Searching for datastore cluster {cl} in vSphere {vs} ...").format(
|
|
647
|
+
cl=self.colored(cluster_name, "CYAN"), vs=self.colored(vsphere_name, "CYAN")
|
|
648
|
+
)
|
|
649
|
+
LOG.debug(msg)
|
|
650
|
+
|
|
651
|
+
try:
|
|
652
|
+
if not self.service_instance:
|
|
653
|
+
self.connect()
|
|
654
|
+
|
|
655
|
+
if not self.datacenters.keys():
|
|
656
|
+
self.get_datacenters()
|
|
657
|
+
content = self.service_instance.RetrieveContent()
|
|
658
|
+
container = content.viewManager.CreateContainerView(
|
|
659
|
+
content.rootFolder, [vim.StoragePod], True
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
obj = None
|
|
663
|
+
|
|
664
|
+
for entry in container.view:
|
|
665
|
+
if entry.name == cluster_name:
|
|
666
|
+
obj = entry
|
|
667
|
+
break
|
|
668
|
+
if not obj:
|
|
669
|
+
msg = _("Datastore cluster {} not found.").format(
|
|
670
|
+
self.colored(cluster_name, "CYAN")
|
|
671
|
+
)
|
|
672
|
+
if no_error:
|
|
673
|
+
LOG.debug(msg)
|
|
674
|
+
else:
|
|
675
|
+
LOG.error(msg)
|
|
676
|
+
return None
|
|
677
|
+
|
|
678
|
+
parents = self.get_parents(obj)
|
|
679
|
+
|
|
680
|
+
# Highest parent is the vSphere root - we don't need it
|
|
681
|
+
parents.pop(0)
|
|
682
|
+
# Next parent is the datacenter
|
|
683
|
+
dc_tuple = parents.pop(0)
|
|
684
|
+
dc_name = dc_tuple[1]
|
|
685
|
+
|
|
686
|
+
ds_cluster = VsphereDsCluster.from_summary(
|
|
687
|
+
obj,
|
|
688
|
+
vsphere=vsphere_name,
|
|
689
|
+
dc_name=dc_name,
|
|
690
|
+
appname=self.appname,
|
|
691
|
+
verbose=self.verbose,
|
|
692
|
+
base_dir=self.base_dir,
|
|
693
|
+
detailled=detailled,
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
return ds_cluster
|
|
697
|
+
|
|
698
|
+
finally:
|
|
699
|
+
if disconnect:
|
|
700
|
+
self.disconnect()
|
|
701
|
+
|
|
575
702
|
# -------------------------------------------------------------------------
|
|
576
703
|
def get_networks(self, vsphere_name=None, disconnect=False):
|
|
577
704
|
"""Get all networks from vSphere as VsphereNetwork objects."""
|
|
@@ -776,6 +903,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
776
903
|
if isinstance(child, (vim.ClusterComputeResource, vim.ComputeResource)):
|
|
777
904
|
cluster = VsphereCluster.from_summary(
|
|
778
905
|
child,
|
|
906
|
+
vsphere=vsphere_name,
|
|
779
907
|
dc_name=dc_name,
|
|
780
908
|
appname=self.appname,
|
|
781
909
|
verbose=self.verbose,
|
|
@@ -846,8 +974,6 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
846
974
|
vsphere_name=None,
|
|
847
975
|
no_error=False,
|
|
848
976
|
disconnect=False,
|
|
849
|
-
as_vmw_obj=False,
|
|
850
|
-
as_obj=False,
|
|
851
977
|
name_only=False,
|
|
852
978
|
):
|
|
853
979
|
"""Get a virtual machine from vSphere as VsphereVm object by its name."""
|
|
@@ -861,12 +987,10 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
861
987
|
)
|
|
862
988
|
)
|
|
863
989
|
re_name = re.compile(pattern_name, re.IGNORECASE)
|
|
864
|
-
vmlist = self.
|
|
990
|
+
vmlist = self.get_vm_list(
|
|
865
991
|
re_name,
|
|
866
992
|
vsphere_name=vsphere_name,
|
|
867
993
|
disconnect=disconnect,
|
|
868
|
-
as_vmw_obj=as_vmw_obj,
|
|
869
|
-
as_obj=as_obj,
|
|
870
994
|
name_only=name_only,
|
|
871
995
|
stop_at_found=True,
|
|
872
996
|
)
|
|
@@ -881,6 +1005,86 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
881
1005
|
|
|
882
1006
|
return vmlist[0]
|
|
883
1007
|
|
|
1008
|
+
# -------------------------------------------------------------------------
|
|
1009
|
+
def get_vm_direct(
|
|
1010
|
+
self,
|
|
1011
|
+
vm_name,
|
|
1012
|
+
vsphere_name=None,
|
|
1013
|
+
no_error=False,
|
|
1014
|
+
disconnect=False,
|
|
1015
|
+
name_only=False,
|
|
1016
|
+
):
|
|
1017
|
+
"""Get a virtual machine from vSphere as VsphereVm object straight by its name."""
|
|
1018
|
+
if vsphere_name is None:
|
|
1019
|
+
vsphere_name = self.name
|
|
1020
|
+
|
|
1021
|
+
LOG.debug(
|
|
1022
|
+
_("Searching for VM {n!r} in vSphere {v!r} ...").format(n=vm_name, v=vsphere_name)
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
try:
|
|
1026
|
+
if not self.service_instance:
|
|
1027
|
+
self.connect()
|
|
1028
|
+
|
|
1029
|
+
if not self.datacenters.keys():
|
|
1030
|
+
self.get_datacenters()
|
|
1031
|
+
content = self.service_instance.RetrieveContent()
|
|
1032
|
+
|
|
1033
|
+
vm_obj = self.get_obj(content, [vim.VirtualMachine], vm_name)
|
|
1034
|
+
|
|
1035
|
+
if vm_obj:
|
|
1036
|
+
if self.verbose > 1:
|
|
1037
|
+
LOG.debug(
|
|
1038
|
+
_("Got VM {vm} in vSphere {vs}.").format(
|
|
1039
|
+
vm=self.colored(vm_name, "CYAN"), vs=self.colored(vsphere_name, "CYAN")
|
|
1040
|
+
)
|
|
1041
|
+
)
|
|
1042
|
+
parents = self.get_parents(vm_obj)
|
|
1043
|
+
if self.verbose > 3:
|
|
1044
|
+
LOG.debug("Parents of VM {vm!r}:\n{p}".format(vm=vm_obj.name, p=pp(parents)))
|
|
1045
|
+
|
|
1046
|
+
# Highest parent is the vSphere root - we don't need it
|
|
1047
|
+
parents.pop(0)
|
|
1048
|
+
# Next parent is the datacenter
|
|
1049
|
+
dc_tuple = parents.pop(0)
|
|
1050
|
+
dc_name = dc_tuple[1]
|
|
1051
|
+
# Next parent is the VM folder of the datacenter - we also don't need it
|
|
1052
|
+
parents.pop(0)
|
|
1053
|
+
# Rest are now the parent folders from top to bottom
|
|
1054
|
+
parent_path = "/" + "/".join(x[1] for x in parents)
|
|
1055
|
+
if self.verbose > 1:
|
|
1056
|
+
LOG.debug(
|
|
1057
|
+
_("VM {vm} is located in DC {dc} path {p}.").format(
|
|
1058
|
+
vm=self.colored(vm_name, "CYAN"),
|
|
1059
|
+
dc=self.colored(dc_name, "CYAN"),
|
|
1060
|
+
p=self.colored(parent_path, "CYAN"),
|
|
1061
|
+
)
|
|
1062
|
+
)
|
|
1063
|
+
|
|
1064
|
+
vm = VsphereVm.from_summary(
|
|
1065
|
+
vm_obj,
|
|
1066
|
+
parent_path,
|
|
1067
|
+
vsphere=vsphere_name,
|
|
1068
|
+
dc_name=dc_name,
|
|
1069
|
+
appname=self.appname,
|
|
1070
|
+
verbose=self.verbose,
|
|
1071
|
+
base_dir=self.base_dir,
|
|
1072
|
+
)
|
|
1073
|
+
|
|
1074
|
+
return vm
|
|
1075
|
+
|
|
1076
|
+
else:
|
|
1077
|
+
msg = _("vSphere VM {!r} not found.").format(vm_name)
|
|
1078
|
+
if no_error:
|
|
1079
|
+
LOG.debug(msg)
|
|
1080
|
+
else:
|
|
1081
|
+
LOG.error(msg)
|
|
1082
|
+
return None
|
|
1083
|
+
|
|
1084
|
+
finally:
|
|
1085
|
+
if disconnect:
|
|
1086
|
+
self.disconnect()
|
|
1087
|
+
|
|
884
1088
|
# -------------------------------------------------------------------------
|
|
885
1089
|
def _dict_from_vim_obj(self, vm, cur_path):
|
|
886
1090
|
|
|
@@ -969,11 +1173,237 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
969
1173
|
vm_info["interfaces"][unit_nr] = iface
|
|
970
1174
|
return vm_info
|
|
971
1175
|
|
|
1176
|
+
# -------------------------------------------------------------------------
|
|
1177
|
+
def get_vm_list(
|
|
1178
|
+
self,
|
|
1179
|
+
re_name,
|
|
1180
|
+
vsphere_name=None,
|
|
1181
|
+
is_template=None,
|
|
1182
|
+
disconnect=False,
|
|
1183
|
+
name_only=False,
|
|
1184
|
+
stop_at_found=False,
|
|
1185
|
+
):
|
|
1186
|
+
"""Get all virtual machines from vSphere.
|
|
1187
|
+
|
|
1188
|
+
The result may be fltered by a regular expression, or whether it is a regular
|
|
1189
|
+
VM or a template.
|
|
1190
|
+
|
|
1191
|
+
Result is (depending of parameter 'name_only') either as a list of tuples with
|
|
1192
|
+
three members (VM name, DC name and path), or as a VsphereVmList (list of VMs
|
|
1193
|
+
as VsphereVm objects).
|
|
1194
|
+
|
|
1195
|
+
@param re_name: a regular expression for filtering the result list by the name.
|
|
1196
|
+
Maybe None, then all VMs are returned
|
|
1197
|
+
|
|
1198
|
+
"""
|
|
1199
|
+
if vsphere_name is None:
|
|
1200
|
+
vsphere_name = self.name
|
|
1201
|
+
|
|
1202
|
+
if not hasattr(re_name, "match"):
|
|
1203
|
+
msg = _("Parameter {p!r} => {r!r} seems not to be a regex object.").format(
|
|
1204
|
+
p="re_name", r=re_name
|
|
1205
|
+
)
|
|
1206
|
+
raise TypeError(msg)
|
|
1207
|
+
# if as_vmw_obj and as_obj:
|
|
1208
|
+
# msg = _("Parameter {p1!r} and {p2!r} may not be {w!r} at the same time.").format(
|
|
1209
|
+
# p1="as_vmw_obj", p2="as_obj", w=True
|
|
1210
|
+
# )
|
|
1211
|
+
# raise ValueError(msg)
|
|
1212
|
+
|
|
1213
|
+
LOG.debug(
|
|
1214
|
+
_("Trying to get list of VMs with name pattern {} ...").format(
|
|
1215
|
+
self.colored(re_name.pattern, "CYAN")
|
|
1216
|
+
)
|
|
1217
|
+
)
|
|
1218
|
+
vm_list = []
|
|
1219
|
+
if not name_only:
|
|
1220
|
+
vm_list = VsphereVmList(
|
|
1221
|
+
appname=self.appname,
|
|
1222
|
+
verbose=self.verbose,
|
|
1223
|
+
base_dir=self.base_dir,
|
|
1224
|
+
initialized=True,
|
|
1225
|
+
)
|
|
1226
|
+
|
|
1227
|
+
try:
|
|
1228
|
+
if not self.service_instance:
|
|
1229
|
+
self.connect()
|
|
1230
|
+
|
|
1231
|
+
if not self.datacenters.keys():
|
|
1232
|
+
self.get_datacenters()
|
|
1233
|
+
content = self.service_instance.RetrieveContent()
|
|
1234
|
+
|
|
1235
|
+
for dc_name in self.datacenters.keys():
|
|
1236
|
+
if self.verbose > 0:
|
|
1237
|
+
LOG.debug(
|
|
1238
|
+
_("Searching for virtual machines in DC {} ...").format(
|
|
1239
|
+
self.colored(dc_name, "CYAN")
|
|
1240
|
+
)
|
|
1241
|
+
)
|
|
1242
|
+
dc = self.get_obj(content, [vim.Datacenter], dc_name)
|
|
1243
|
+
|
|
1244
|
+
for child in dc.vmFolder.childEntity:
|
|
1245
|
+
path = "/" + child.name
|
|
1246
|
+
if self.verbose == 1:
|
|
1247
|
+
LOG.debug(
|
|
1248
|
+
_("Searching in top path {} ...").format(self.colored(path, "CYAN"))
|
|
1249
|
+
)
|
|
1250
|
+
vms = self._get_vm_list(
|
|
1251
|
+
child,
|
|
1252
|
+
re_name,
|
|
1253
|
+
parent_path="/",
|
|
1254
|
+
vsphere_name=vsphere_name,
|
|
1255
|
+
dc_name=dc_name,
|
|
1256
|
+
is_template=is_template,
|
|
1257
|
+
name_only=name_only,
|
|
1258
|
+
stop_at_found=stop_at_found,
|
|
1259
|
+
)
|
|
1260
|
+
if vms:
|
|
1261
|
+
vm_list += vms
|
|
1262
|
+
if stop_at_found:
|
|
1263
|
+
break
|
|
1264
|
+
if len(vm_list) and stop_at_found:
|
|
1265
|
+
break
|
|
1266
|
+
finally:
|
|
1267
|
+
if disconnect:
|
|
1268
|
+
self.disconnect()
|
|
1269
|
+
|
|
1270
|
+
if len(vm_list):
|
|
1271
|
+
msg = ngettext(
|
|
1272
|
+
"Found one VM with name pattern {p}.",
|
|
1273
|
+
"Found {no} VMs with name pattern {p}.",
|
|
1274
|
+
len(vm_list),
|
|
1275
|
+
)
|
|
1276
|
+
else:
|
|
1277
|
+
msg = _("Did not found a VM with name pattern {p}.")
|
|
1278
|
+
LOG.debug(
|
|
1279
|
+
msg.format(
|
|
1280
|
+
no=self.colored(str(len(vm_list)), "CYAN"), p=self.colored(re_name.pattern, "CYAN")
|
|
1281
|
+
)
|
|
1282
|
+
)
|
|
1283
|
+
|
|
1284
|
+
return vm_list
|
|
1285
|
+
|
|
1286
|
+
# -------------------------------------------------------------------------
|
|
1287
|
+
def _get_vm_list( # noqa: C901
|
|
1288
|
+
self,
|
|
1289
|
+
entry,
|
|
1290
|
+
re_name,
|
|
1291
|
+
parent_path,
|
|
1292
|
+
vsphere_name=None,
|
|
1293
|
+
dc_name=None,
|
|
1294
|
+
is_template=None,
|
|
1295
|
+
depth=1,
|
|
1296
|
+
name_only=False,
|
|
1297
|
+
stop_at_found=False,
|
|
1298
|
+
):
|
|
1299
|
+
|
|
1300
|
+
vm_list = []
|
|
1301
|
+
if not name_only:
|
|
1302
|
+
vm_list = VsphereVmList(
|
|
1303
|
+
appname=self.appname,
|
|
1304
|
+
verbose=self.verbose,
|
|
1305
|
+
base_dir=self.base_dir,
|
|
1306
|
+
initialized=True,
|
|
1307
|
+
)
|
|
1308
|
+
|
|
1309
|
+
if isinstance(entry, vim.VirtualMachine):
|
|
1310
|
+
|
|
1311
|
+
summary = entry.summary
|
|
1312
|
+
vm_config = summary.config
|
|
1313
|
+
vm_name = vm_config.name
|
|
1314
|
+
|
|
1315
|
+
add_to_list = True
|
|
1316
|
+
|
|
1317
|
+
if self.verbose > 2:
|
|
1318
|
+
LOG.debug(_("Checking VM {} ...").format(self.colored(vm_name, "CYAN")))
|
|
1319
|
+
if is_template is not None:
|
|
1320
|
+
if self.verbose > 3:
|
|
1321
|
+
msg = _("Checking VM {!r} for being a template ...")
|
|
1322
|
+
if not is_template:
|
|
1323
|
+
msg = _("Checking VM {!r} for being not a template ...")
|
|
1324
|
+
LOG.debug(msg.format(vm_name))
|
|
1325
|
+
if is_template and not vm_config.template:
|
|
1326
|
+
add_to_list = False
|
|
1327
|
+
if not is_template and vm_config.template:
|
|
1328
|
+
add_to_list = False
|
|
1329
|
+
|
|
1330
|
+
if add_to_list:
|
|
1331
|
+
if self.verbose > 3:
|
|
1332
|
+
LOG.debug(_("Checking VM {!r} for pattern.").format(vm_name))
|
|
1333
|
+
if not re_name.search(vm_name):
|
|
1334
|
+
add_to_list = False
|
|
1335
|
+
|
|
1336
|
+
if add_to_list:
|
|
1337
|
+
if self.verbose > 1:
|
|
1338
|
+
vsn = "~"
|
|
1339
|
+
if vsphere_name:
|
|
1340
|
+
vsn = vsphere_name
|
|
1341
|
+
dcn = "~"
|
|
1342
|
+
if dc_name:
|
|
1343
|
+
dcn = dc_name
|
|
1344
|
+
LOG.debug(
|
|
1345
|
+
_("Found VM {vm} in vSphere {vs}, DC {dc}, path {p}.").format(
|
|
1346
|
+
vm=self.colored(vm_name, "CYAN"),
|
|
1347
|
+
vs=self.colored(vsn, "CYAN"),
|
|
1348
|
+
dc=self.colored(dcn, "CYAN"),
|
|
1349
|
+
p=self.colored(parent_path, "CYAN"),
|
|
1350
|
+
)
|
|
1351
|
+
)
|
|
1352
|
+
|
|
1353
|
+
if name_only:
|
|
1354
|
+
vm_list.append((vm_name, dc_name, parent_path))
|
|
1355
|
+
else:
|
|
1356
|
+
if self.verbose > 1:
|
|
1357
|
+
LOG.debug(f"Get VM {vm_name!r} as an object.")
|
|
1358
|
+
|
|
1359
|
+
vm = VsphereVm.from_summary(
|
|
1360
|
+
entry,
|
|
1361
|
+
parent_path,
|
|
1362
|
+
vsphere=vsphere_name,
|
|
1363
|
+
dc_name=dc_name,
|
|
1364
|
+
appname=self.appname,
|
|
1365
|
+
verbose=self.verbose,
|
|
1366
|
+
base_dir=self.base_dir,
|
|
1367
|
+
)
|
|
1368
|
+
vm_list.append(vm)
|
|
1369
|
+
|
|
1370
|
+
if stop_at_found:
|
|
1371
|
+
return vm_list
|
|
1372
|
+
|
|
1373
|
+
if hasattr(entry, "childEntity"):
|
|
1374
|
+
if depth > self.max_search_depth:
|
|
1375
|
+
return vm_list
|
|
1376
|
+
|
|
1377
|
+
if parent_path != "/":
|
|
1378
|
+
cur_path = parent_path + "/" + entry.name
|
|
1379
|
+
else:
|
|
1380
|
+
cur_path = "/" + entry.name
|
|
1381
|
+
if self.verbose > 1:
|
|
1382
|
+
LOG.debug(_("Searching in path {} ...").format(self.colored(cur_path, "CYAN")))
|
|
1383
|
+
for child in entry.childEntity:
|
|
1384
|
+
vms = self._get_vm_list(
|
|
1385
|
+
child,
|
|
1386
|
+
re_name,
|
|
1387
|
+
parent_path=cur_path,
|
|
1388
|
+
vsphere_name=vsphere_name,
|
|
1389
|
+
dc_name=dc_name,
|
|
1390
|
+
is_template=is_template,
|
|
1391
|
+
depth=depth + 1,
|
|
1392
|
+
name_only=name_only,
|
|
1393
|
+
stop_at_found=stop_at_found,
|
|
1394
|
+
)
|
|
1395
|
+
|
|
1396
|
+
if len(vms):
|
|
1397
|
+
vm_list += vms
|
|
1398
|
+
|
|
1399
|
+
return vm_list
|
|
1400
|
+
|
|
972
1401
|
# -------------------------------------------------------------------------
|
|
973
1402
|
def get_vms(
|
|
974
1403
|
self,
|
|
975
1404
|
re_name,
|
|
976
1405
|
vsphere_name=None,
|
|
1406
|
+
late=None,
|
|
977
1407
|
is_template=None,
|
|
978
1408
|
disconnect=False,
|
|
979
1409
|
as_vmw_obj=False,
|
|
@@ -1027,7 +1457,7 @@ class VsphereConnection(BaseVsphereHandler):
|
|
|
1027
1457
|
for child in dc.vmFolder.childEntity:
|
|
1028
1458
|
path = child.name
|
|
1029
1459
|
if self.verbose > 0:
|
|
1030
|
-
LOG.debug(_("Searching in path {} ...").format(self.colored(path,
|
|
1460
|
+
LOG.debug(_("Searching in path {} ...").format(self.colored(path, "CYAN")))
|
|
1031
1461
|
vms = self._get_vms(
|
|
1032
1462
|
child,
|
|
1033
1463
|
re_name,
|