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

VMUpdateNic._get_vnic_device()   B

Complexity

Conditions 7

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 7
dl 0
loc 16
rs 7.3333
1
from pyVmomi import vim
2
3
from vmwarelib import inventory
4
from vmwarelib.actions import BaseAction
5
6
7
class VMUpdateNic(BaseAction):
8
9
    def run(self, vm_id, network_id, vnic_key, ip, subnet, gateway=None, domain=None):
10
        # convert ids to stubs
11
        virtualmachine = inventory.get_virtualmachine(self.si_content, vm_id)
12
        network = inventory.get_network(self.si_content, network_id)
13
        vnic = self._get_vnic_device(virtualmachine, vnic_key)
14
15
        # add new vnic
16
        configspec = vim.vm.ConfigSpec()
17
        nic = vim.vm.device.VirtualDeviceSpec()
18
        nic.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
19
        nic.device = vim.vm.device.VirtualVmxnet3()
20
        nic.device.wakeOnLanEnabled = True
21
        nic.device.addressType = 'assigned'
22
        nic.device.key = vnic.key
23
        nic.device.deviceInfo = vim.Description()
24
        nic.device.deviceInfo.label = 'Network Adapter-%s' % (ip)
25
        nic.device.deviceInfo.summary = 'summary'
26
        nic.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
27
        nic.device.backing.port = vim.dvs.PortConnection()
28
        nic.device.backing.port.switchUuid = network.config.distributedVirtualSwitch.uuid
29
        nic.device.backing.port.portgroupKey = network.config.key
30
        nic.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
31
        nic.device.connectable.startConnected = True
32
        nic.device.connectable.allowGuestControl = True
33
        configspec.deviceChange = [nic]
34
        add_vnic_task = virtualmachine.ReconfigVM_Task(configspec)
35
        successfully_added_vnic = self._wait_for_task(add_vnic_task)
36
37
        if not successfully_added_vnic:
38
            return self._format_result(successfully_added_vnic, 'Failed to update nic.')
39
40
        adaptermap = vim.vm.customization.AdapterMapping()
41
        adaptermap.adapter = vim.vm.customization.IPSettings()
42
        adaptermap.adapter.ip = vim.vm.customization.FixedIp()
43
        adaptermap.adapter.ip.ipAddress = ip
44
        adaptermap.adapter.subnetMask = subnet
45
        adaptermap.adapter.gateway = gateway
46
        adaptermap.adapter.dnsDomain = domain
47
48
        globalip = vim.vm.customization.GlobalIPSettings()
49
50
        ident = vim.vm.customization.LinuxPrep()
51
        ident.domain = domain
52
        ident.hostName = vim.vm.customization.FixedName()
53
        ident.hostName.name = virtualmachine.name
54
55
        customspec = vim.vm.customization.Specification()
56
        customspec.identity = ident
57
        customspec.nicSettingMap = [adaptermap]
58
        customspec.globalIPSettings = globalip
59
60
        try:
61
            customize_task = virtualmachine.Customize(spec=customspec)
62
            successfully_customized = self._wait_for_task(customize_task)
63
        except:
64
            self.logger.exception('Failed to create customization spec.')
65
            raise
66
        msg = 'Updated nic and assigned IP.' if successfully_customized else 'Failed to assign ip.'
67
        return self._format_result(successfully_customized, msg=msg)
68
69
    @staticmethod
70
    def _get_vnic_device(vm, vnic_key=-1):
71
        verify_vnic = vnic_key != -1
72
        for device in vm.config.hardware.device:
73
            # If a key is passed in verify that it is a vnic else look for the first vnic.
74
            if verify_vnic and device.key == vnic_key:
75
                is_vnic = isinstance(device, vim.vm.device.VirtualEthernetCard)
76
                if not is_vnic:
77
                    raise Exception('Invalid device key %s' % str(vnic_key))
78
                return device
79
            elif not verify_vnic:
80
                is_vnic = isinstance(device, vim.vm.device.VirtualEthernetCard)
81
                if is_vnic:
82
                    return device
83
        # ending up here mean a bad key or no vnic.
84
        raise Exception('vnic for device %s not found' % str(vnic_key))
85
86
    @staticmethod
87
    def _format_result(state, msg=None):
88
        return {'state': state, 'msg': msg}
89