Completed
Pull Request — master (#405)
by Edward
01:59
created

GetVMs   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 143
Duplicated Lines 0 %
Metric Value
dl 0
loc 143
rs 8.439
wmc 47

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __add_vm_properties_to_map_from_vm_array() 0 8 3
F run() 0 132 44

How to fix   Complexity   

Complex Class

Complex classes like GetVMs often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from sets import Set
2
3
from pyVmomi import vim
4
from vmwarelib.actions import BaseAction
5
6
7
class GetVMs(BaseAction):
8
9
    def run(self, ids=None, names=None, datastores=None, datastore_clusters=None,
10
            resource_pools=None, vapps=None, hosts=None, folders=None, clusters=None,
11
            datacenters=None, virtual_switches=None, no_recursion=False):
12
        # TODO: food for thought. PowerCli contains additional parameters that
13
        # are not present here for the folliwing reason:
14
        # <server> - we may need to bring it in if we decide to have connections
15
        # to more than 1 VC.
16
        # <tag>    - Tags in VC are not the same as tags you see in Web Client
17
        # for the reason, that those tags are stored in Inventory Service only.
18
        # PowerCli somehow can access it, from vSphere SDK there is no way.
19
20
        si = self.si
21
        si_content = si.RetrieveContent()
22
        props = ['name', 'runtime.powerState']
23
        moid_to_vm = {}
24
25
        # Getting vms by their ids
26
        vms_from_vmids = []
27
        if ids:
28
            vm_moids = [moid.strip() for moid in ids.split(',')]
29
            vms_from_vmids = [vim.VirtualMachine(moid, stub=si._stub) for moid in vm_moids]
30
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_vmids)
31
32
        # Getting vms by their names
33
        vms_from_names = []
34
        if names:
35
            vm_names_set = Set([name.strip() for name in names.split(',')])
36
            container = si_content.viewManager.CreateContainerView(si_content.rootFolder,
37
                                                                   [vim.VirtualMachine], True)
38
            for vm in container.view:
39
                if vm.name in vm_names_set:
40
                    vms_from_names.append(vm)
41
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_names)
42
43
        # Getting vms from datastore objects
44
        vms_from_datastores = []
45
        if datastores:
46
            datastore_moids = [moid.strip() for moid in datastores.split(',')]
47
            vim_datastores = [vim.Datastore(moid, stub=si._stub) for moid in datastore_moids]
48
            for ds in vim_datastores:
49
                vms_from_datastores.extend(ds.vm)
50
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_datastores)
51
52
        # Getting vms from datastore cluster objects
53
        vms_from_datastore_clusters = []
54
        if datastore_clusters:
55
            datastore_cluster_moids = [moid.strip() for moid in datastore_clusters.split(',')]
56
            vim_datastore_clusters = [vim.StoragePod(moid, stub=si._stub)
57
                                      for moid in datastore_cluster_moids]
58
            for ds_cl in vim_datastore_clusters:
59
                for ds in ds_cl.childEntity:
60
                    vms_from_datastore_clusters.extend(ds.vm)
61
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_datastore_clusters)
62
63
        # Getting vms from virtual switch objects
64
        vms_from_virtual_switches = []
65
        if virtual_switches:
66
            virtual_switch_moids = [moid.strip() for moid in virtual_switches.split(',')]
67
            vim_virtual_switches = [vim.DistributedVirtualSwitch(moid, stub=si._stub)
68
                                    for moid in virtual_switch_moids]
69
            for vswitch in vim_virtual_switches:
70
                for pg in vswitch.portgroup:
71
                    vms_from_virtual_switches.extend(pg.vm)
72
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_virtual_switches)
73
74
        # Getting vms from containers (location param)
75
        vms_from_containers = []
76
        containers = []
77
78
        if resource_pools:
79
            container_moids = [moid.strip() for moid in resource_pools.split(',')]
80
            containers += [vim.ResourcePool(moid, stub=si._stub) for moid in container_moids]
81
82
        if vapps:
83
            container_moids = [moid.strip() for moid in vapps.split(',')]
84
            containers += [vim.VirtualApp(moid, stub=si._stub) for moid in container_moids]
85
86
        if hosts:
87
            container_moids = [moid.strip() for moid in hosts.split(',')]
88
            containers += [vim.HostSystem(moid, stub=si._stub) for moid in container_moids]
89
90
        if folders:
91
            container_moids = [moid.strip() for moid in folders.split(',')]
92
            containers += [vim.Folder(moid, stub=si._stub) for moid in container_moids]
93
94
        if clusters:
95
            container_moids = [moid.strip() for moid in clusters.split(',')]
96
            containers += [vim.ComputeResource(moid, stub=si._stub) for moid in container_moids]
97
98
        if datacenters:
99
            container_moids = [moid.strip() for moid in datacenters.split(',')]
100
            containers += [vim.Datacenter(moid, stub=si._stub) for moid in container_moids]
101
102
        for cont in containers:
103
104
            objView = si_content.viewManager.CreateContainerView(cont,
105
                                                                 [vim.VirtualMachine],
106
                                                                 not no_recursion)
107
108
            tSpec = vim.PropertyCollector.TraversalSpec(name='tSpecName', path='view',
109
                                                        skip=False, type=vim.view.ContainerView)
110
111
            pSpec = vim.PropertyCollector.PropertySpec(all=False, pathSet=props, type=vim.VirtualMachine)
112
113
            oSpec = vim.PropertyCollector.ObjectSpec(obj=objView, selectSet=[tSpec], skip=False)
114
115
            pfSpec = vim.PropertyCollector.FilterSpec(objectSet=[oSpec], propSet=[pSpec],
116
                                                      reportMissingObjectsInResults=False)
117
118
            retOptions = vim.PropertyCollector.RetrieveOptions()
119
120
            retProps = si_content.propertyCollector.RetrievePropertiesEx(specSet=[pfSpec],
121
                                                                         options=retOptions)
122
123
            vms_from_containers += retProps.objects
124
125
            while retProps.token:
126
                retProps = si_content.propertyCollector.ContinueRetrievePropertiesEx(
127
                    token=retProps.token
128
                )
129
                vms_from_containers += retProps.objects
130
            objView.Destroy()
131
132
        for vm in vms_from_containers:
133
            if vm.obj._GetMoId() not in moid_to_vm:
134
                moid_to_vm[vm.obj._GetMoId()] = {
135
                    "moid": vm.obj._GetMoId(),
136
                    "name": vm.propSet[0].val,
137
                    "runtime.powerState": vm.propSet[1].val
138
                }
139
140
        return moid_to_vm.values()
141
142
    @staticmethod
143
    def __add_vm_properties_to_map_from_vm_array(vm_map, vm_array):
144
        for vm in vm_array:
145
            if vm._GetMoId() not in vm_map:
146
                vm_map[vm._GetMoId()] = {
147
                      "moid": vm._GetMoId(),
148
                      "name": vm.name,
149
                      "runtime.powerState": vm.runtime.powerState
150
                      }
151