Completed
Pull Request — master (#462)
by
unknown
02:26
created

VMAddHDD   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 100
Duplicated Lines 0 %
Metric Value
dl 0
loc 100
rs 10
wmc 13

4 Methods

Rating   Name   Duplication   Size   Complexity  
A get_storage_placement_spec() 0 17 1
A get_controller_key() 0 7 3
A get_next_unit_number() 0 11 4
B run() 0 61 5
1
#!/usr/bin/env python
2
3
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
4
# contributor license agreements.  See the NOTICE file distributed with
5
# this work for additional information regarding copyright ownership.
6
# The ASF licenses this file to You under the Apache License, Version 2.0
7
# (the "License"); you may not use this file except in compliance with
8
# the License.  You may obtain a copy of the License at
9
#
10
#     http://www.apache.org/licenses/LICENSE-2.0
11
#
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS,
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
# See the License for the specific language governing permissions and
16
# limitations under the License.
17
18
from pyVmomi import vim
19
import sys
20
21
from vmwarelib import inventory
22
from vmwarelib import checkinputs
23
from vmwarelib.actions import BaseAction
24
25
26
class VMAddHDD(BaseAction):
27
    def run(self, vm_id, vm_name, datastore_cluster,
28
            datastore, disk_size, provision_type):
29
        # ensure that minimal inputs are provided
30
        #checkinputs.vm_identifier(vm_id, vm_name)
31
        checkinputs.one_of_two_strings(vm_id, vm_name, "ID or Name")
32
33
        vm = inventory.get_virtualmachine(self.si_content, vm_id, vm_name)
34
        spec = vim.vm.ConfigSpec()
35
        hdd_unit_number = self.get_next_unit_number(vm)
36
        ctrl_key = self.get_controller_key(vm)
37
38
        #Prepare new Disk configuration
39
        disk_changes = []
40
        disk_spec = vim.vm.device.VirtualDeviceSpec()
41
        disk_spec.fileOperation = "create"
42
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
43
        disk_spec.device = vim.vm.device.VirtualDisk()
44
        disk_spec.device.backing =\
45
            vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
46
        disk_spec.device.backing.diskMode = "persistent"
47
48
        if provision_type == 'thin':
49
            disk_spec.device.backing.thinProvisioned = True
50
51
        disk_spec.device.unitNumber = hdd_unit_number
52
        disk_spec.device.capacityInKB = int(disk_size) * 1024 * 1024
53
        disk_spec.device.controllerKey = ctrl_key
54
55
        #If Datastore Cluster is provided attach Disk via that
56
        if datastore_cluster:
57
            ds_clust_obj = inventory.get_datastore_cluster(
58
                self.si_content, name=datastore_cluster)
59
            disk_changes.append(disk_spec)
60
            spec.deviceChange = disk_changes
61
            srm = self.si_content.storageResourceManager
62
63
            storage_placement_spec = self.get_storage_placement_spec(
64
                ds_clust_obj, vm, spec)
65
            datastores = srm.RecommendDatastores(
66
                storageSpec=storage_placement_spec)
67
68
            if not datastores.recommendations:
69
                sys.stderr.write('Skipping as No datastore Recommendations')
70
71
            add_disk_task = srm.ApplyStorageDrsRecommendation_Task(
72
                datastores.recommendations[0].key)
73
74
        elif datastore:
75
            datastore_obj = inventory.get_datastore(self.si_content,
76
                                                    name=datastore)
77
            disk_spec.device.backing.datastore = datastore_obj
78
            disk_changes.append(disk_spec)
79
            spec.deviceChange = disk_changes
80
            add_disk_task = vm.ReconfigVM_Task(spec)
81
        else:
82
            disk_changes.append(disk_spec)
83
            spec.deviceChange = disk_changes
84
            add_disk_task = vm.ReconfigVM_Task(spec)
85
86
        successfully_added_disk = self._wait_for_task(add_disk_task)
87
        return {'state': successfully_added_disk}
88
89
    def get_storage_placement_spec(self, ds_clust_obj, vm, vm_reconfig_spec):
90
        storage_placement_spec = vim.storageDrs.StoragePlacementSpec()
91
        storage_placement_spec.type =\
92
            vim.storageDrs.StoragePlacementSpec.PlacementType.reconfigure
93
        storage_placement_spec.configSpec = vm_reconfig_spec
94
        storage_placement_spec.podSelectionSpec =\
95
            vim.storageDrs.PodSelectionSpec()
96
        storage_placement_spec.vm = vm
97
98
        vm_pod_cfg = vim.storageDrs.PodSelectionSpec.VmPodConfig()
99
        vm_pod_cfg.storagePod = ds_clust_obj
100
        disk_locator = vim.storageDrs.PodSelectionSpec.DiskLocator()
101
        disk_locator.diskBackingInfo =\
102
            vm_reconfig_spec.deviceChange[0].device.backing
103
        vm_pod_cfg.disk = [disk_locator]
104
        storage_placement_spec.podSelectionSpec.initialVmConfig = [vm_pod_cfg]
105
        return storage_placement_spec
106
107
    def get_next_unit_number(self, vm):
108
        unit_number = 0
109
        #Cycle though devices on VM and find
110
        #entries with attribute "fileName".
111
        for device in vm.config.hardware.device:
112
            if hasattr(device.backing, 'fileName'):
113
                unit_number = int(device.unitNumber) + 1
114
                #unit number 7 is reserved
115
                if unit_number == 7:
116
                    unit_number += 1
117
        return unit_number
118
119
    def get_controller_key(self, vm):
120
        #1000 is the default used for hdd controllers
121
        key = 1000
122
        for device in vm.config.hardware.device:
123
            if isinstance(device, vim.vm.device.VirtualSCSIController):
124
                key = device.key
125
        return key
126