Completed
Push — master ( ca2760...4c7c7c )
by Manas
15s
created

NewNetworkAdapter.get_vm_reconfig_spec()   D

Complexity

Conditions 10

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 59
rs 4.8648
cc 10

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 NewNetworkAdapter.get_vm_reconfig_spec() 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 import inventory
19
from vmwarelib.actions import BaseAction
20
21
22
class NewNetworkAdapter(BaseAction):
23
24
    @staticmethod
25
    def get_vm_reconfig_spec(distributed_switch_obj, mac_address, network_obj, port_key,
26
                             stay_connected, network_type, wake_on_lan):
27
        # creating virtual device
28
        if network_type == 'e1000':
29
            virtual_network = vim.vm.device.VirtualE1000()
30
        elif network_type == 'flexible':
31
            virtual_network = vim.vm.device.VirtualPCNet32()
32
            lance_option = vim.vm.device.VirtualPCNet32Option()
33
            lance_option.supportsMorphing = True
34
        # TODO and question for Manas: We need to plug in that lance_option on something.
35
        # I could not find any class that uses VirtualPCNet32Option or any of its upstream classes.
36
        elif network_type == 'vmxnet':
37
            virtual_network = vim.vm.device.VirtualVmxnet()
38
        elif network_type == 'enhancedvmxnet':
39
            virtual_network = vim.vm.device.VirtualVmxnet2()
40
        elif network_type == 'vmxnet3':
41
            virtual_network = vim.vm.device.VirtualVmxnet3()
42
        else:
43
            virtual_network = vim.vm.device.VirtualEthernetCard()
44
45
        virtual_network.wakeOnLanEnabled = wake_on_lan
46
        connect_info = vim.vm.device.VirtualDevice.ConnectInfo()
47
        connect_info.startConnected = stay_connected
48
        virtual_network.connectable = connect_info
49
        if mac_address:
50
            virtual_network.macAddress = mac_address
51
            virtual_network.addressType = vim.vm.device.VirtualEthernetCardOption.MacTypes.manual
52
53
        # creating backing info
54
        backing_info = None
55
        if distributed_switch_obj:
56
            dvs_port_connection = vim.dvs.PortConnection()
57
            dvs_port_connection.switchUuid = distributed_switch_obj.uuid
58
            if port_key:
59
                dvs_port_connection.portKey = port_key
60
                port_criteria = vim.dvs.PortCriteria()
61
                port_criteria.portKey = port_key
62
                ports = distributed_switch_obj.FetchDVPorts(port_criteria)
63
                dvs_port_connection.portgroupKey = ports[0].portgroupKey
64
            backing_info = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
65
            backing_info.port = dvs_port_connection
66
67
        if network_obj:
68
            backing_info = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
69
            backing_info.network = network_obj
70
            backing_info.deviceName = network_obj.name
71
72
        virtual_network.backing = backing_info
73
74
        # creating network device spec
75
        network_spec = vim.vm.device.VirtualDeviceSpec()
76
        network_spec.device = virtual_network
77
        network_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
78
79
        # creating reconfig spec
80
        vm_reconfig_spec = vim.vm.ConfigSpec()
81
        vm_reconfig_spec.deviceChange = [network_spec]
82
        return vm_reconfig_spec
83
84
    def run(self, vms, distributed_switch=None, mac_address=None, network_name=None, port_key=None,
85
            stay_connected=False, network_type='Flexible', wake_on_lan=False):
86
        network_type = network_type.lower() if network_type else None
87
        si = self.si
88
        si_content = si.RetrieveContent()
89
90
        vm_objs = [vim.VirtualMachine(moid, stub=si._stub) for moid in vms]
91
        # by checking the name property, the vms' existance is checked.
92
        [vm_obj.name for vm_obj in vm_objs]
93
94
        distributed_switch_obj = None
95
        if distributed_switch:
96
            distributed_switch_obj = vim.DistributedVirtualSwitch(distributed_switch, stub=si._stub)
97
            # by checking the name property, the distributed switch existence is checked.
98
            distributed_switch_obj.name
99
100
        network_obj = None
101
        if network_name:
102
            network_obj = inventory.get_network(si_content, name=network_name)
103
            # by checking the name property, the network existence is checked.
104
            network_obj.name
105
106
        result = []
107
        for vm in vm_objs:
108
            vm_reconfig_spec = NewNetworkAdapter.get_vm_reconfig_spec(distributed_switch_obj,
109
                mac_address, network_obj, port_key, stay_connected, network_type, wake_on_lan)
110
            add_disk_task = vm.ReconfigVM_Task(spec=vm_reconfig_spec)
111
            successfully_added_network = self._wait_for_task(add_disk_task)
112
            result.append({
113
                "vm_moid": vm._GetMoId(),
114
                "success": successfully_added_network
115
            })
116
117
        return result
118