Completed
Pull Request — master (#460)
by Manas
02:13
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
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from pyVmomi import vim
17
18
from vmwarelib.actions import BaseAction
19
20
21
class GetVMs(BaseAction):
22
23
    def run(self, ids=None, names=None, datastores=None, datastore_clusters=None,
24
            resource_pools=None, vapps=None, hosts=None, folders=None, clusters=None,
25
            datacenters=None, virtual_switches=None, no_recursion=False):
26
        # TODO: food for thought. PowerCli contains additional parameters that are not present
27
        # here for the folliwing reason:
28
        # <server> - we may need to bring it in if we decide to have connections to more than 1 VC.
29
        # <tag>    - Tags in VC are not the same as tags you see in Web Client for the reason, that
30
        #            those tags are stored in Inventory Service only. PowerCli somehow can access
31
        #            it, from vSphere SDK there is no way.
32
33
        si = self.si
34
        si_content = si.RetrieveContent()
35
        props = ['name', 'runtime.powerState']
36
        moid_to_vm = {}
37
38
        # getting vms by their ids
39
        vms_from_vmids = []
40
        if ids:
41
            vms_from_vmids = [vim.VirtualMachine(moid, stub=si._stub) for moid in ids]
42
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_vmids)
43
44
        # getting vms by their names
45
        vms_from_names = []
46
        if names:
47
            container = si_content.viewManager.CreateContainerView(si_content.rootFolder,
48
                                                                   [vim.VirtualMachine], True)
49
            for vm in container.view:
50
                if vm.name in names:
51
                    vms_from_names.append(vm)
52
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_names)
53
54
        # getting vms from datastore objects
55
        vms_from_datastores = []
56
        if datastores:
57
            vim_datastores = [vim.Datastore(moid, stub=si._stub) for moid in datastores]
58
            for ds in vim_datastores:
59
                vms_from_datastores.extend(ds.vm)
60
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_datastores)
61
62
        # getting vms from datastore cluster objects
63
        vms_from_datastore_clusters = []
64
        if datastore_clusters:
65
            vim_datastore_clusters = [
66
                vim.StoragePod(moid, stub=si._stub) for moid in datastore_clusters
67
            ]
68
            for ds_cl in vim_datastore_clusters:
69
                for ds in ds_cl.childEntity:
70
                    vms_from_datastore_clusters.extend(ds.vm)
71
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm,
72
                vms_from_datastore_clusters)
73
74
        # getting vms from virtual switch objects
75
        vms_from_virtual_switches = []
76
        if virtual_switches:
77
            vim_virtual_switches = [
78
                vim.DistributedVirtualSwitch(moid, stub=si._stub) for moid in virtual_switches
79
            ]
80
            for vswitch in vim_virtual_switches:
81
                for pg in vswitch.portgroup:
82
                    vms_from_virtual_switches.extend(pg.vm)
83
            GetVMs.__add_vm_properties_to_map_from_vm_array(moid_to_vm, vms_from_virtual_switches)
84
85
        # getting vms from containers (location param)
86
        vms_from_containers = []
87
        containers = []
88
89
        if resource_pools:
90
            containers += [vim.ResourcePool(moid, stub=si._stub) for moid in resource_pools]
91
92
        if vapps:
93
            containers += [vim.VirtualApp(moid, stub=si._stub) for moid in vapps]
94
95
        if hosts:
96
            containers += [vim.HostSystem(moid, stub=si._stub) for moid in hosts]
97
98
        if folders:
99
            containers += [vim.Folder(moid, stub=si._stub) for moid in folders]
100
101
        if clusters:
102
            containers += [vim.ComputeResource(moid, stub=si._stub) for moid in clusters]
103
104
        if datacenters:
105
            containers += [vim.Datacenter(moid, stub=si._stub) for moid in datacenters]
106
107
        for cont in containers:
108
            objView = si_content.viewManager.CreateContainerView(cont, [vim.VirtualMachine],
109
                not no_recursion)
110
            tSpec = vim.PropertyCollector.TraversalSpec(name='tSpecName', path='view', skip=False,
111
                type=vim.view.ContainerView)
112
            pSpec = vim.PropertyCollector.PropertySpec(all=False, pathSet=props,
113
                type=vim.VirtualMachine)
114
            oSpec = vim.PropertyCollector.ObjectSpec(obj=objView, selectSet=[tSpec], skip=False)
115
            pfSpec = vim.PropertyCollector.FilterSpec(objectSet=[oSpec], propSet=[pSpec],
116
                reportMissingObjectsInResults=False)
117
            retOptions = vim.PropertyCollector.RetrieveOptions()
118
            retProps = si_content.propertyCollector.RetrievePropertiesEx(specSet=[pfSpec],
119
                options=retOptions)
120
            vms_from_containers += retProps.objects
121
            while retProps.token:
122
                retProps = si_content.propertyCollector.ContinueRetrievePropertiesEx(
123
                    token=retProps.token)
124
                vms_from_containers += retProps.objects
125
            objView.Destroy()
126
127
        for vm in vms_from_containers:
128
            if vm.obj._GetMoId() not in moid_to_vm:
129
                moid_to_vm[vm.obj._GetMoId()] = {
130
                    "moid": vm.obj._GetMoId(),
131
                    "name": vm.propSet[0].val,
132
                    "runtime.powerState": vm.propSet[1].val
133
                }
134
135
        return moid_to_vm.values()
136
137
    @staticmethod
138
    def __add_vm_properties_to_map_from_vm_array(vm_map, vm_array):
139
        for vm in vm_array:
140
            if vm._GetMoId() not in vm_map:
141
                vm_map[vm._GetMoId()] = {
142
                    "moid": vm._GetMoId(),
143
                    "name": vm.name,
144
                    "runtime.powerState": vm.runtime.powerState
145
                }
146