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

NewHardDisk.run()   C

Complexity

Conditions 8

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 56
rs 6.1256
cc 8

How to fix   Long Method   

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:

1
import sys
2
3
from pyVmomi import vim
4
5
from vmwarelib.actions import BaseAction
6
7
8
class NewHardDisk(BaseAction):
9
10
    @staticmethod
11
    def get_backinginfo_for_existing_disk(disk_path):
12
        backing_info = vim.vm.device.VirtualDevice.FileBackingInfo()
13
        backing_info.fileName = disk_path
14
        return backing_info
15
16
    @staticmethod
17
    def get_flatfile_backinginfo(storage_format, persistence):
18
        backing_info = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
19
        if storage_format == 'eagerzeroedthick':
20
            backing_info.thinProvisioned = False
21
            backing_info.eagerlyScrub = True
22
        elif storage_format == 'thin':
23
            backing_info.thinProvisioned = True
24
        elif storage_format == 'thin2gb':
25
            backing_info.thinProvisioned = True
26
            backing_info.split = True
27
        elif storage_format == 'thick':
28
            backing_info.thinProvisioned = False
29
        elif storage_format == 'thick2gb':
30
            backing_info.thinProvisioned = False
31
            backing_info.split = True
32
        backing_info.diskMode = persistence
33
        return backing_info
34
35
    @staticmethod
36
    def get_rawfile_backinginfo(device_name, persistence):
37
        backing_info = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
38
        backing_info.deviceName = device_name
39
        backing_info.diskMode = persistence
40
        return backing_info
41
42
    @staticmethod
43
    def get_next_unit_number(vm):
44
        unit_number = 0
45
        for dev in vm.config.hardware.device:
46
            if isinstance(dev, vim.VirtualDisk):
47
                unit_number = int(dev.unitNumber) + 1
48
                # unit_number 7 reserved for scsi controller
49
                if unit_number == 7:
50
                    unit_number += 1
51
        return unit_number
52
53
    @staticmethod
54
    def get_vm_reconfig_spec(vm, datastore, disk_type, storage_format, persistence, disk_path,
55
                             device_name, capacity_gb):
56
        if disk_path:
57
            backing_info = NewHardDisk.get_backinginfo_for_existing_disk(disk_path)
58
        elif disk_type == 'flat':
59
            backing_info = NewHardDisk.get_flatfile_backinginfo(storage_format, persistence)
60
        elif disk_type.startswith('raw'):
61
            backing_info = NewHardDisk.get_rawfile_backinginfo(device_name, persistence)
62
        else:
63
            raise Exception("Wrong disk_type and empty disk_path. Either one should be present.")
64
        backing_info.datastore = datastore
65
66
        # creating Virtual Disk Device
67
        virtual_disk = vim.vm.device.VirtualDisk()
68
        virtual_disk.backing = backing_info
69
        virtual_disk.capacityInKB = (int(capacity_gb * 1024 * 1024) if disk_path == '' else 0)
70
        virtual_disk.controllerKey = 1000
71
        virtual_disk.unitNumber = NewHardDisk.get_next_unit_number(vm)
72
73
        # creating Virtual Device Spec
74
        disk_spec = vim.vm.device.VirtualDeviceSpec()
75
        if not disk_path:
76
            disk_spec.fileOperation = "create"
77
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
78
        disk_spec.device = virtual_disk
79
80
        # creating reconfig spec
81
        vm_reconfig_spec = vim.vm.ConfigSpec()
82
        vm_reconfig_spec.deviceChange = [disk_spec]
83
        return vm_reconfig_spec
84
85
    @staticmethod
86
    def get_storage_placement_spec(ds_clust_obj, vm, vm_reconfig_spec):
87
        storage_placement_spec = vim.storageDrs.StoragePlacementSpec()
88
        storage_placement_spec.type = vim.storageDrs.StoragePlacementSpec.\
89
            PlacementType.reconfigure
90
        storage_placement_spec.configSpec = vm_reconfig_spec
91
        storage_placement_spec.podSelectionSpec = vim.storageDrs.PodSelectionSpec()
92
        storage_placement_spec.vm = vm
93
94
        vm_pod_cfg = vim.storageDrs.PodSelectionSpec.VmPodConfig()
95
        vm_pod_cfg.storagePod = ds_clust_obj
96
        disk_locator = vim.storageDrs.PodSelectionSpec.DiskLocator()
97
        disk_locator.diskBackingInfo = vm_reconfig_spec.deviceChange[0].device.backing
98
        vm_pod_cfg.disk = [disk_locator]
99
        storage_placement_spec.podSelectionSpec.initialVmConfig = [vm_pod_cfg]
100
101
        return storage_placement_spec
102
103
    def run(self, vms, persistence='Persistent', disk_type='flat', capacity_gb=1, datastore=None,
104
            datastore_cluster=None, device_name=None, disk_path='', storage_format='Thin'):
105
        # TODO: 'controller' parameter is missing here. The reason is because we do not support
106
        # passing real objects like PowerCli and there is no uuid to find and address the
107
        # controller in the system.
108
        persistence = persistence.lower()
109
        disk_type = disk_type.lower()
110
        storage_format = storage_format.lower()
111
112
        si = self.si
113
        si_content = si.RetrieveContent()
114
        vm_objs = [vim.VirtualMachine(moid, stub=si._stub) for moid in vms]
115
        # by checking the name property, the vms' existance is checked.
116
        [vm_obj.name for vm_obj in vm_objs]
117
        datastore_obj = None
118
        if datastore:
119
            datastore_obj = vim.Datastore(datastore, stub=si._stub)
120
            # by checking the name property, the vms' existance is checked.
121
            datastore_obj.name
122
123
        result = []
124
125
        if datastore_cluster:
126
            ds_clust_obj = vim.StoragePod(datastore_cluster, stub=si._stub)
127
            # by retrieving the name property, the existance is checked.
128
            ds_clust_obj.name
129
            srm = si_content.storageResourceManager
130
131
            for vm in vm_objs:
132
                vm_reconfig_spec = NewHardDisk.get_vm_reconfig_spec(vm, datastore_obj, disk_type,
133
                    storage_format, persistence, disk_path, device_name, capacity_gb)
134
                storage_placement_spec = NewHardDisk.get_storage_placement_spec(ds_clust_obj, vm,
135
                    vm_reconfig_spec)
136
                datastores = srm.RecommendDatastores(storageSpec=storage_placement_spec)
137
                if not datastores.recommendations:
138
                    sys.stderr.write('Skipping %s as there is no datastore recommendation' %
139
                        vm.obj._GetMoId())
140
                add_disk_task = srm.ApplyStorageDrsRecommendation_Task(
141
                    datastores.recommendations[0].key)
142
                successfully_added_disk = self._wait_for_task(add_disk_task)
143
                result.append({
144
                    "vm_moid": vm._GetMoId(),
145
                    "success": successfully_added_disk
146
                })
147
        else:
148
            for vm in vm_objs:
149
                vm_reconfig_spec = NewHardDisk.get_vm_reconfig_spec(vm, datastore_obj, disk_type,
150
                    storage_format, persistence, disk_path, device_name, capacity_gb)
151
                add_disk_task = vm.ReconfigVM_Task(spec=vm_reconfig_spec)
152
                successfully_added_disk = self._wait_for_task(add_disk_task)
153
                result.append({
154
                    "vm_moid": vm._GetMoId(),
155
                    "success": successfully_added_disk
156
                })
157
158
        return result
159