Completed
Pull Request — master (#460)
by Manas
02:06
created

GetVMs.run()   F

Complexity

Conditions 33

Size

Total Lines 113

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 113
rs 2
cc 33

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

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