7.1.0
This commit is contained in:
@@ -18,6 +18,8 @@ class decort_kvmvm(DecortController):
|
||||
super(decort_kvmvm, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
self.aparam_networks_has_dpdk = None
|
||||
|
||||
self.check_amodule_args()
|
||||
|
||||
self.comp_should_exist = False
|
||||
@@ -30,6 +32,7 @@ class decort_kvmvm(DecortController):
|
||||
self.rg_id = 0
|
||||
self.aparam_image = None
|
||||
|
||||
|
||||
validated_acc_id =0
|
||||
validated_rg_id = 0
|
||||
validated_rg_facts = None
|
||||
@@ -84,38 +87,9 @@ class decort_kvmvm(DecortController):
|
||||
if self.comp_id:
|
||||
self.comp_should_exist = True
|
||||
self.acc_id = self.comp_info['accountId']
|
||||
|
||||
check_error = False
|
||||
params_to_check = {
|
||||
'chipset': 'chipset',
|
||||
'cpu_pin': 'cpupin',
|
||||
'hp_backed': 'hpBacked',
|
||||
'numa_affinity': 'numaAffinity',
|
||||
}
|
||||
for param_name, comp_field_name in params_to_check.items():
|
||||
if (
|
||||
self.aparams[param_name] is not None
|
||||
and self.comp_info[comp_field_name] != self.aparams[param_name]
|
||||
and self.aparams['state'] not in ('halted', 'poweredoff')
|
||||
):
|
||||
self.message(
|
||||
f'Cannot change "{param_name}" for compute '
|
||||
f'{self.comp_id} if parameter "state" is not '
|
||||
f'halted or poweredoff.'
|
||||
)
|
||||
check_error = True
|
||||
|
||||
if check_error:
|
||||
self.exit(fail=True)
|
||||
|
||||
else:
|
||||
if self.aparams['chipset'] is None:
|
||||
self.message(
|
||||
'Check for parameter "chipset" failed: '
|
||||
'chipset must be specified for a new compute.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if self.amodule.params['state'] != 'absent':
|
||||
self.check_amodule_args_for_create()
|
||||
return
|
||||
|
||||
def check_amodule_args(self):
|
||||
@@ -124,13 +98,16 @@ class decort_kvmvm(DecortController):
|
||||
cannot be implemented using Ansible Argument spec.
|
||||
"""
|
||||
|
||||
check_error = False
|
||||
|
||||
# Check parameter "networks"
|
||||
aparam_nets = self.aparams['networks']
|
||||
if aparam_nets:
|
||||
check_error = False
|
||||
net_types = {net['type'] for net in aparam_nets}
|
||||
# DPDK and other networks
|
||||
self.aparam_networks_has_dpdk = False
|
||||
if self.VMNetType.DPDK.value in net_types:
|
||||
self.aparam_networks_has_dpdk = True
|
||||
if not net_types.issubset(
|
||||
{self.VMNetType.DPDK.value, self.VMNetType.EMPTY.value}
|
||||
):
|
||||
@@ -140,6 +117,17 @@ class decort_kvmvm(DecortController):
|
||||
' a compute cannot be connected to a DPDK network and'
|
||||
' a network of another type at the same time.'
|
||||
)
|
||||
|
||||
if (
|
||||
self.aparams['hp_backed'] is not None
|
||||
and not self.aparams['hp_backed']
|
||||
):
|
||||
check_error = True
|
||||
self.message(
|
||||
'Check for parameter "networks" failed: '
|
||||
'hp_backed must be set to True to connect a compute '
|
||||
'to a DPDK network.'
|
||||
)
|
||||
# MTU for non-DPDK networks
|
||||
for net in aparam_nets:
|
||||
if (
|
||||
@@ -153,8 +141,6 @@ class decort_kvmvm(DecortController):
|
||||
' (remove parameter "mtu" for network'
|
||||
f' {net["type"]} with ID {net["id"]}).'
|
||||
)
|
||||
if check_error:
|
||||
self.exit(fail=True)
|
||||
|
||||
aparam_custom_fields = self.aparams['custom_fields']
|
||||
if aparam_custom_fields is not None:
|
||||
@@ -162,11 +148,25 @@ class decort_kvmvm(DecortController):
|
||||
aparam_custom_fields['disable']
|
||||
and aparam_custom_fields['fields'] is not None
|
||||
):
|
||||
check_error = True
|
||||
self.message(
|
||||
'Check for parameter "custom_fields" failed: '
|
||||
'"fields" cannot be set if "disable" is True.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
aparam_pref_cpu_cores = self.aparams['preferred_cpu_cores']
|
||||
if (
|
||||
aparam_pref_cpu_cores
|
||||
and len(set(aparam_pref_cpu_cores)) != len(aparam_pref_cpu_cores)
|
||||
):
|
||||
check_error = True
|
||||
self.message(
|
||||
'Check for parameter "preferred_cpu_cores" failed: '
|
||||
'the list must contain only unique elements.'
|
||||
)
|
||||
|
||||
if check_error:
|
||||
self.exit(fail=True)
|
||||
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for Compute management by decort_kvmvm module.
|
||||
@@ -280,6 +280,15 @@ class decort_kvmvm(DecortController):
|
||||
if numa_affinity is None:
|
||||
numa_affinity = 'none'
|
||||
|
||||
|
||||
chipset = self.amodule.params['chipset']
|
||||
if chipset is None:
|
||||
chipset = 'i440fx'
|
||||
self.message(
|
||||
msg=f'Chipset not specified, '
|
||||
f'default value "{chipset}" will be used.',
|
||||
warning=True,
|
||||
)
|
||||
# if we get through here, all parameters required to create new Compute instance should be at hand
|
||||
|
||||
# NOTE: KVM VM is created in HALTED state and must be explicitly started
|
||||
@@ -293,10 +302,11 @@ class decort_kvmvm(DecortController):
|
||||
sep_id=self.amodule.params['sep_id' ] if "sep_id" in self.amodule.params else None,
|
||||
pool_name=self.amodule.params['pool'] if "pool" in self.amodule.params else None,
|
||||
start_on_create=start_compute,
|
||||
chipset=self.amodule.params['chipset'],
|
||||
chipset=chipset,
|
||||
cpu_pin=cpu_pin,
|
||||
hp_backed=hp_backed,
|
||||
numa_affinity=numa_affinity)
|
||||
numa_affinity=numa_affinity,
|
||||
preferred_cpu_cores=self.amodule.params['preferred_cpu_cores'],)
|
||||
self.comp_should_exist = True
|
||||
|
||||
# Originally we would have had to re-read comp_info after VM was provisioned
|
||||
@@ -406,6 +416,18 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
Note that it does not modify power state of KVM VM.
|
||||
"""
|
||||
if self.compute_update_args:
|
||||
self.compute_update(
|
||||
compute_id=self.comp_info['id'],
|
||||
**self.compute_update_args,
|
||||
)
|
||||
|
||||
if self.amodule.params['rollback_to'] is not None:
|
||||
self.compute_rollback(
|
||||
compute_id=self.comp_info['id'],
|
||||
snapshot_label=self.amodule.params['rollback_to'],
|
||||
)
|
||||
|
||||
if self.amodule.params['networks'] is not None:
|
||||
self.compute_networks(
|
||||
comp_dict=self.comp_info,
|
||||
@@ -430,12 +452,6 @@ class decort_kvmvm(DecortController):
|
||||
self.amodule.params['aaff_rule'],
|
||||
label=self.amodule.params['affinity_label'])
|
||||
|
||||
if self.compute_update_args:
|
||||
self.compute_update(
|
||||
compute_id=self.comp_info['id'],
|
||||
**self.compute_update_args,
|
||||
)
|
||||
|
||||
aparam_custom_fields = self.amodule.params['custom_fields']
|
||||
if aparam_custom_fields is not None:
|
||||
compute_custom_fields = self.comp_info['custom_fields']
|
||||
@@ -465,14 +481,15 @@ class decort_kvmvm(DecortController):
|
||||
'numa_affinity': 'numaAffinity',
|
||||
'description': 'desc',
|
||||
'auto_start': 'autoStart',
|
||||
'preferred_cpu_cores': 'preferredCpu',
|
||||
}
|
||||
for param_name, comp_field_name in params_to_check.items():
|
||||
aparam_value = self.amodule.params[param_name]
|
||||
for aparam_name, comp_field_name in params_to_check.items():
|
||||
aparam_value = self.amodule.params[aparam_name]
|
||||
if (
|
||||
aparam_value is not None
|
||||
and aparam_value != self.comp_info[comp_field_name]
|
||||
):
|
||||
result_args[param_name] = aparam_value
|
||||
result_args[aparam_name] = aparam_value
|
||||
|
||||
return result_args
|
||||
|
||||
@@ -511,6 +528,8 @@ class decort_kvmvm(DecortController):
|
||||
numa_affinity="",
|
||||
custom_fields={},
|
||||
vnc_password="",
|
||||
snapshots=[],
|
||||
preferred_cpu_cores=[],
|
||||
)
|
||||
|
||||
if check_mode or self.comp_info is None:
|
||||
@@ -577,6 +596,10 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
ret_dict['auto_start'] = self.comp_info['autoStart']
|
||||
|
||||
ret_dict['snapshots'] = self.comp_info['snapSets']
|
||||
|
||||
ret_dict['preferred_cpu_cores'] = self.comp_info['preferredCpu']
|
||||
|
||||
return ret_dict
|
||||
|
||||
def check_amodule_args_for_create(self):
|
||||
@@ -627,6 +650,21 @@ class decort_kvmvm(DecortController):
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if self.aparams['rollback_to'] is not None:
|
||||
self.message(
|
||||
'Check for parameter "rollback_to" failed: '
|
||||
'rollback_to can be specified only for existing compute.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if self.aparam_networks_has_dpdk and not self.aparams['hp_backed']:
|
||||
self.message(
|
||||
'Check for parameter "networks" failed:'
|
||||
' hp_backed must be set to True to connect a compute'
|
||||
' to a DPDK network.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
@@ -790,7 +828,14 @@ class decort_kvmvm(DecortController):
|
||||
),
|
||||
auto_start=dict(
|
||||
type='bool',
|
||||
)
|
||||
),
|
||||
rollback_to=dict(
|
||||
type='str',
|
||||
),
|
||||
preferred_cpu_cores=dict(
|
||||
type='list',
|
||||
elements='int',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
@@ -799,6 +844,8 @@ class decort_kvmvm(DecortController):
|
||||
)
|
||||
|
||||
def check_amodule_args_for_change(self):
|
||||
check_errors = False
|
||||
|
||||
new_boot_disk_size = self.amodule.params['boot_disk']
|
||||
if new_boot_disk_size is not None:
|
||||
for disk in self.comp_info['disks']:
|
||||
@@ -806,30 +853,109 @@ class decort_kvmvm(DecortController):
|
||||
boot_disk_size = disk['sizeMax']
|
||||
break
|
||||
else:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Can\'t set boot disk size for Compute '
|
||||
f'{self.comp_info["id"]}, because it doesn\'t have a '
|
||||
f'boot disk.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if new_boot_disk_size < boot_disk_size:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'New boot disk size {new_boot_disk_size} is less than '
|
||||
f'current {boot_disk_size} for Compute ID '
|
||||
f'{self.comp_info["id"]}'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if (
|
||||
not self.comp_info['imageId']
|
||||
and self.amodule.params['state'] in ('poweredon', 'paused')
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "state" failed: '
|
||||
'state for a blank Compute can not be "poweredon" or "paused".'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
is_vm_stopped_or_will_be_stopped = (
|
||||
(
|
||||
self.comp_info['techStatus'] == 'STOPPED'
|
||||
and (
|
||||
self.amodule.params['state'] is None
|
||||
or self.amodule.params['state'] in (
|
||||
'halted', 'poweredoff', 'present',
|
||||
)
|
||||
)
|
||||
)
|
||||
or (
|
||||
self.comp_info['techStatus'] != 'STOPPED'
|
||||
and self.amodule.params['state'] in (
|
||||
'halted', 'poweredoff',
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if self.amodule.params['rollback_to'] is not None:
|
||||
if not is_vm_stopped_or_will_be_stopped:
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "rollback_to" failed: '
|
||||
'VM must be stopped to rollback.'
|
||||
)
|
||||
|
||||
vm_snapshot_labels = [
|
||||
snapshot['label'] for snapshot in self.comp_info['snapSets']
|
||||
]
|
||||
if self.amodule.params['rollback_to'] not in vm_snapshot_labels:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "rollback_to" failed: '
|
||||
f'snapshot with label '
|
||||
f'{self.amodule.params["rollback_to"]} does not exist '
|
||||
f'for VM ID{self.comp_info["id"]}.'
|
||||
)
|
||||
|
||||
params_to_check = {
|
||||
'chipset': 'chipset',
|
||||
'cpu_pin': 'cpupin',
|
||||
'hp_backed': 'hpBacked',
|
||||
'numa_affinity': 'numaAffinity',
|
||||
}
|
||||
for param_name, comp_field_name in params_to_check.items():
|
||||
if (
|
||||
self.aparams[param_name] is not None
|
||||
and self.comp_info[comp_field_name] != self.aparams[param_name]
|
||||
and not is_vm_stopped_or_will_be_stopped
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "{param_name}" failed: '
|
||||
f'VM must be stopped to change {param_name}.'
|
||||
)
|
||||
|
||||
if self.aparams['preferred_cpu_cores'] is not None:
|
||||
if not is_vm_stopped_or_will_be_stopped:
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "preferred_cpu_cores" failed: '
|
||||
'VM must be stopped to change preferred_cpu_cores.'
|
||||
)
|
||||
|
||||
if (
|
||||
self.aparam_networks_has_dpdk
|
||||
and not self.comp_info['hpBacked']
|
||||
and not self.aparams['hp_backed']
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "networks" failed: '
|
||||
'hp_backed must be set to True to connect a compute '
|
||||
'to a DPDK network.'
|
||||
)
|
||||
|
||||
if check_errors:
|
||||
self.exit(fail=True)
|
||||
|
||||
# Workflow digest:
|
||||
# 1) authenticate to DECORT controller & validate authentication by issuing API call - done when creating DECSController
|
||||
@@ -892,8 +1018,6 @@ def main():
|
||||
elif amodule.params['state'] == 'paused':
|
||||
subj.error()
|
||||
else:
|
||||
subj.check_amodule_args_for_create()
|
||||
|
||||
state = amodule.params['state']
|
||||
if state is None:
|
||||
state = 'present'
|
||||
|
||||
Reference in New Issue
Block a user