7.2.0
This commit is contained in:
@@ -73,7 +73,6 @@ class decort_disk(DecortController):
|
||||
name = self.amodule.params['name'],
|
||||
description=self.amodule.params['description'],
|
||||
size=self.amodule.params['size'],
|
||||
type=self.amodule.params['type'],
|
||||
iops=self.amodule.params['iops'],
|
||||
sep_id=self.amodule.params['sep_id'],
|
||||
pool=self.amodule.params['pool'],
|
||||
@@ -83,7 +82,7 @@ class decort_disk(DecortController):
|
||||
self.disk_limitIO(disk_id=self.disk_id,
|
||||
limits=self.amodule.params['limitIO'])
|
||||
#set share status
|
||||
if self.amodule.params['shareable'] and self.amodule.params['type'] == "D":
|
||||
if self.amodule.params['shareable']:
|
||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
||||
return
|
||||
|
||||
@@ -114,8 +113,7 @@ class decort_disk(DecortController):
|
||||
self.disk_limitIO(self.disk_id,self.amodule.params['limitIO'])
|
||||
#share check/update
|
||||
#raise Exception(self.amodule.params['shareable'])
|
||||
if self.amodule.params['shareable'] != self.disk_info['shareable'] and \
|
||||
self.amodule.params['type'] == "D":
|
||||
if self.amodule.params['shareable'] != self.disk_info['shareable']:
|
||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
||||
return
|
||||
|
||||
@@ -220,15 +218,6 @@ class decort_disk(DecortController):
|
||||
size=dict(
|
||||
type='int',
|
||||
),
|
||||
type=dict(
|
||||
type='str',
|
||||
default='D',
|
||||
choices=[
|
||||
'B',
|
||||
'D',
|
||||
'T',
|
||||
],
|
||||
),
|
||||
iops=dict(
|
||||
type='int',
|
||||
default=2000,
|
||||
|
||||
@@ -82,6 +82,20 @@ class decort_k8s(DecortController):
|
||||
self.acc_id = self.k8s_info['accountId']
|
||||
# check workers and groups for add or remove?
|
||||
|
||||
aparam_sysctl = arg_amodule.params['lb_sysctl']
|
||||
if aparam_sysctl is not None:
|
||||
_, lb_info = self._lb_get_by_id(lb_id=self.k8s_info['lbId'])
|
||||
sysctl_with_str_values = {
|
||||
k: str(v) for k, v in aparam_sysctl.items()
|
||||
}
|
||||
if sysctl_with_str_values != lb_info['sysctlParams']:
|
||||
self.message(
|
||||
'Check for parameter "lb_sysctl" failed: '
|
||||
'cannot change lb_sysctl for an existing cluster '
|
||||
'load balancer.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if not self.k8s_id:
|
||||
validated_k8ci_id = self.k8s_k8ci_find(arg_amodule.params['k8ci_id'])
|
||||
if not validated_k8ci_id:
|
||||
@@ -96,6 +110,17 @@ class decort_k8s(DecortController):
|
||||
self.result['msg'] = "At least one worker group must be present"
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
if (
|
||||
arg_amodule.params['lb_sysctl'] is not None
|
||||
and not arg_amodule.params['with_lb']
|
||||
):
|
||||
self.message(
|
||||
'Check for parameter "lb_sysctl" failed: '
|
||||
'"lb_sysctl" can only be set if the parameter "with_lb" '
|
||||
'is set to True.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
return
|
||||
|
||||
def package_facts(self,check_mode=False):
|
||||
@@ -129,6 +154,7 @@ class decort_k8s(DecortController):
|
||||
ret_dict['account_id'] = self.acc_id
|
||||
ret_dict['k8s_Masters'] = self.k8s_info['k8sGroups']['masters']
|
||||
ret_dict['k8s_Workers'] = self.k8s_info['k8sGroups']['workers']
|
||||
ret_dict['lb_id'] = self.k8s_info['lbId']
|
||||
|
||||
return ret_dict
|
||||
|
||||
@@ -200,6 +226,7 @@ class decort_k8s(DecortController):
|
||||
self.amodule.params['description'],
|
||||
self.amodule.params['extnet_only'],
|
||||
master_chipset,
|
||||
lb_sysctl=self.amodule.params['lb_sysctl'],
|
||||
)
|
||||
|
||||
if not k8s_id:
|
||||
@@ -216,10 +243,12 @@ class decort_k8s(DecortController):
|
||||
|
||||
if self.k8s_id:
|
||||
self.k8s_should_exist = True
|
||||
self.k8s_workers_modify(
|
||||
arg_k8swg=self.k8s_info,
|
||||
arg_modwg=target_wgs,
|
||||
)
|
||||
if len(target_wgs) > 1:
|
||||
self.k8s_workers_modify(
|
||||
arg_k8swg=self.k8s_info,
|
||||
arg_modwg=target_wgs,
|
||||
)
|
||||
self.k8s_info = self.k8s_get_by_id(k8s_id=self.k8s_id)
|
||||
return
|
||||
|
||||
def destroy(self):
|
||||
@@ -230,11 +259,21 @@ class decort_k8s(DecortController):
|
||||
|
||||
def action(self, disared_state, started=True, preupdate: bool = False):
|
||||
if self.amodule.params['master_chipset'] is not None:
|
||||
self.result['msg'] = (
|
||||
'"master_chipset" parameter must not be specified '
|
||||
'when modifying an existing K8s cluster.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
for master_node in self.k8s_info['k8sGroups']['masters'][
|
||||
'detailedInfo'
|
||||
]:
|
||||
_, master_node_info, _ = self._compute_get_by_id(
|
||||
comp_id=master_node['id']
|
||||
)
|
||||
if (
|
||||
master_node_info['chipset']
|
||||
!= self.amodule.params['master_chipset']
|
||||
):
|
||||
self.result['msg'] = (
|
||||
'"master_chipset" cannot be changed '
|
||||
'for existing K8s cluster.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if preupdate:
|
||||
# K8s info updating
|
||||
@@ -434,6 +473,9 @@ class decort_k8s(DecortController):
|
||||
type='str',
|
||||
choices=['Q35', 'i440fx'],
|
||||
),
|
||||
lb_sysctl=dict(
|
||||
type='dict',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
|
||||
@@ -37,15 +37,62 @@ class decort_kvmvm(DecortController):
|
||||
validated_rg_id = 0
|
||||
validated_rg_facts = None
|
||||
|
||||
self.vm_to_clone_id = 0
|
||||
self.vm_to_clone_info = None
|
||||
|
||||
if arg_amodule.params['clone_from'] is not None:
|
||||
self.vm_to_clone_id, self.vm_to_clone_info, _ = (
|
||||
self._compute_get_by_id(
|
||||
comp_id=self.aparams['clone_from']['id'],
|
||||
)
|
||||
)
|
||||
if not self.vm_to_clone_id:
|
||||
self.message(
|
||||
f'Check for parameter "clone_from.id" failed: '
|
||||
f'VM ID {self.aparams["clone_from"]["id"]} does not exist.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
elif self.vm_to_clone_info['status'] in ('DESTROYED', 'DELETED'):
|
||||
self.message(
|
||||
f'Check for parameter "clone_from.id" failed: '
|
||||
f'VM ID {self.aparams["clone_from"]["id"]} is in '
|
||||
f'{self.vm_to_clone_info["status"]} state and '
|
||||
f'cannot be cloned.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
clone_id, clone_dict, _ = self.compute_find(
|
||||
comp_name=self.aparams['name'],
|
||||
rg_id=self.vm_to_clone_info['rgId'],
|
||||
)
|
||||
self.check_amodule_args_for_clone(
|
||||
clone_id=clone_id,
|
||||
clone_dict=clone_dict,
|
||||
)
|
||||
self.check_amodule_args_for_change()
|
||||
|
||||
if not clone_id:
|
||||
clone_id = self.clone()
|
||||
|
||||
self.comp_id, self.comp_info, self.rg_id = self._compute_get_by_id(
|
||||
comp_id=clone_id,
|
||||
need_custom_fields=True,
|
||||
need_console_url=self.aparams['get_console_url'],
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
comp_id = arg_amodule.params['id']
|
||||
|
||||
# Analyze Compute name & ID, RG name & ID and build arguments to compute_find accordingly.
|
||||
if arg_amodule.params['name'] == "" and arg_amodule.params['id'] == 0:
|
||||
if arg_amodule.params['name'] == "" and comp_id == 0:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot manage Compute when its ID is 0 and name is empty."
|
||||
self.fail_json(**self.result)
|
||||
# fail the module - exit
|
||||
|
||||
if not arg_amodule.params['id']: # manage Compute by name -> need RG identity
|
||||
if not comp_id: # manage Compute by name -> need RG identity
|
||||
if not arg_amodule.params['rg_id']: # RG ID is not set -> locate RG by name -> need account ID
|
||||
validated_acc_id, _ = self.account_find(arg_amodule.params['account_name'],
|
||||
arg_amodule.params['account_id'])
|
||||
@@ -78,18 +125,21 @@ class decort_kvmvm(DecortController):
|
||||
# because this Compute does not exist or something goes wrong in the upstream API
|
||||
# We call compute_find with check_state=False as we also consider the case when a Compute
|
||||
# specified by account / RG / compute name never existed and will be created for the first time.
|
||||
self.comp_id, self.comp_info, self.rg_id = self.compute_find(comp_id=arg_amodule.params['id'],
|
||||
self.comp_id, self.comp_info, self.rg_id = self.compute_find(comp_id=comp_id,
|
||||
comp_name=arg_amodule.params['name'],
|
||||
rg_id=validated_rg_id,
|
||||
check_state=False,
|
||||
need_custom_fields=True)
|
||||
need_custom_fields=True,
|
||||
need_console_url=self.aparams['get_console_url'])
|
||||
|
||||
if self.comp_id:
|
||||
self.comp_should_exist = True
|
||||
self.acc_id = self.comp_info['accountId']
|
||||
self.check_amodule_args_for_change()
|
||||
else:
|
||||
if self.amodule.params['state'] != 'absent':
|
||||
self.check_amodule_args_for_create()
|
||||
|
||||
return
|
||||
|
||||
def check_amodule_args(self):
|
||||
@@ -215,7 +265,11 @@ class decort_kvmvm(DecortController):
|
||||
# each of the following calls will abort if argument is missing
|
||||
self.check_amodule_argument('cpu')
|
||||
self.check_amodule_argument('ram')
|
||||
validated_bdisk_size = self.amodule.params['boot_disk'] or 0
|
||||
validated_bdisk_size = 0
|
||||
if self.amodule.params['boot'] is not None:
|
||||
validated_bdisk_size = self.amodule.params['boot'].get(
|
||||
'disk_size', 0
|
||||
)
|
||||
|
||||
image_id, image_facts = None, None
|
||||
if self.aparam_image:
|
||||
@@ -295,7 +349,7 @@ class decort_kvmvm(DecortController):
|
||||
self.comp_id = self.kvmvm_provision(rg_id=self.rg_id,
|
||||
comp_name=self.amodule.params['name'],
|
||||
cpu=self.amodule.params['cpu'], ram=self.amodule.params['ram'],
|
||||
boot_disk=validated_bdisk_size,
|
||||
boot_disk_size=validated_bdisk_size,
|
||||
image_id=image_id,
|
||||
description=self.amodule.params['description'],
|
||||
userdata=cloud_init_params,
|
||||
@@ -340,10 +394,10 @@ class decort_kvmvm(DecortController):
|
||||
new_networks=self.amodule.params['networks'],
|
||||
)
|
||||
# Next manage data disks
|
||||
if self.amodule.params['data_disks'] is not None:
|
||||
self.compute_data_disks(
|
||||
if self.amodule.params['disks'] is not None:
|
||||
self.compute_disks(
|
||||
comp_dict=self.comp_info,
|
||||
new_data_disks=self.amodule.params['data_disks'],
|
||||
aparam_disks=self.amodule.params['disks'],
|
||||
)
|
||||
|
||||
self.compute_affinity(self.comp_info,
|
||||
@@ -372,6 +426,7 @@ class decort_kvmvm(DecortController):
|
||||
_, self.comp_info, _ = self.compute_find(
|
||||
comp_id=self.comp_id,
|
||||
need_custom_fields=True,
|
||||
need_console_url=self.amodule.params['get_console_url'],
|
||||
)
|
||||
|
||||
if self.compute_update_args:
|
||||
@@ -404,6 +459,7 @@ class decort_kvmvm(DecortController):
|
||||
_, self.comp_info, _ = self.compute_find(
|
||||
comp_id=self.comp_id,
|
||||
need_custom_fields=True,
|
||||
need_console_url=self.amodule.params['get_console_url'],
|
||||
)
|
||||
self.modify()
|
||||
self.comp_should_exist = True
|
||||
@@ -435,12 +491,27 @@ class decort_kvmvm(DecortController):
|
||||
order_changing=self.aparams['network_order_changing'],
|
||||
)
|
||||
|
||||
boot_disk_new_size = self.amodule.params['boot_disk']
|
||||
if boot_disk_new_size:
|
||||
self.compute_bootdisk_size(self.comp_info, boot_disk_new_size)
|
||||
if self.amodule.params['disks'] is not None:
|
||||
self.compute_disks(
|
||||
comp_dict=self.comp_info,
|
||||
aparam_disks=self.amodule.params['disks'],
|
||||
)
|
||||
|
||||
if self.amodule.params['data_disks'] is not None:
|
||||
self.compute_data_disks(self.comp_info, self.amodule.params['data_disks'])
|
||||
aparam_boot = self.amodule.params['boot']
|
||||
if aparam_boot is not None:
|
||||
aparam_disk_id = aparam_boot['disk_id']
|
||||
if aparam_disk_id is not None:
|
||||
for disk in self.comp_info['disks']:
|
||||
if disk['id'] == aparam_disk_id and disk['type'] != 'B':
|
||||
self.compute_boot_disk(
|
||||
comp_id=self.comp_info['id'],
|
||||
boot_disk=aparam_disk_id,
|
||||
)
|
||||
break
|
||||
|
||||
boot_disk_new_size = aparam_boot['disk_size']
|
||||
if boot_disk_new_size:
|
||||
self.compute_bootdisk_size(self.comp_info, boot_disk_new_size)
|
||||
|
||||
self.compute_resize(self.comp_info,
|
||||
self.amodule.params['cpu'], self.amodule.params['ram'],
|
||||
@@ -530,6 +601,8 @@ class decort_kvmvm(DecortController):
|
||||
vnc_password="",
|
||||
snapshots=[],
|
||||
preferred_cpu_cores=[],
|
||||
clones=[],
|
||||
clone_reference=0,
|
||||
)
|
||||
|
||||
if check_mode or self.comp_info is None:
|
||||
@@ -600,6 +673,12 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
ret_dict['preferred_cpu_cores'] = self.comp_info['preferredCpu']
|
||||
|
||||
if self.amodule.params['get_console_url']:
|
||||
ret_dict['console_url'] = self.comp_info['console_url']
|
||||
|
||||
ret_dict['clones'] = self.comp_info['clones']
|
||||
ret_dict['clone_reference'] = self.comp_info['cloneReference']
|
||||
|
||||
return ret_dict
|
||||
|
||||
def check_amodule_args_for_create(self):
|
||||
@@ -641,11 +720,12 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
if (
|
||||
self.aparams['sep_id'] is not None
|
||||
and self.aparams['boot_disk'] is None
|
||||
and self.aparams['boot'] is None
|
||||
and self.aparams['boot']['disk_size'] is None
|
||||
):
|
||||
self.message(
|
||||
'Check for parameter "sep_id" failed: '
|
||||
'"image_id" or "image_name" or "boot_disk" '
|
||||
'"image_id" or "image_name" or "boot.disk_size" '
|
||||
'must be specified to set sep_id.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
@@ -680,8 +760,16 @@ class decort_kvmvm(DecortController):
|
||||
description=dict(
|
||||
type='str',
|
||||
),
|
||||
boot_disk=dict(
|
||||
type='int',
|
||||
boot=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
disk_id=dict(
|
||||
type='int',
|
||||
),
|
||||
disk_size=dict(
|
||||
type='int',
|
||||
),
|
||||
),
|
||||
),
|
||||
sep_id=dict(
|
||||
type='int',
|
||||
@@ -696,8 +784,24 @@ class decort_kvmvm(DecortController):
|
||||
cpu=dict(
|
||||
type='int',
|
||||
),
|
||||
data_disks=dict( # list of integer disk IDs
|
||||
type='list',
|
||||
disks=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
mode=dict(
|
||||
type='str',
|
||||
choices=[
|
||||
'update',
|
||||
'detach',
|
||||
'delete',
|
||||
'match',
|
||||
],
|
||||
default='update',
|
||||
),
|
||||
ids=dict(
|
||||
type='list',
|
||||
elements='int',
|
||||
),
|
||||
),
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
@@ -836,40 +940,135 @@ class decort_kvmvm(DecortController):
|
||||
type='list',
|
||||
elements='int',
|
||||
),
|
||||
get_console_url=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
clone_from=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
force=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
snapshot=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
name=dict(
|
||||
type='str',
|
||||
),
|
||||
timestamp=dict(
|
||||
type='int',
|
||||
),
|
||||
datetime=dict(
|
||||
type='str',
|
||||
),
|
||||
),
|
||||
mutually_exclusive=[
|
||||
('name', 'timestamp', 'datetime'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('id', 'name'),
|
||||
],
|
||||
required_by={
|
||||
'clone_from': 'name',
|
||||
},
|
||||
)
|
||||
|
||||
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']:
|
||||
if disk['type'] == 'B':
|
||||
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.'
|
||||
)
|
||||
comp_info = self.vm_to_clone_info or self.comp_info
|
||||
comp_id = comp_info['id']
|
||||
|
||||
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"]}'
|
||||
)
|
||||
aparam_boot = self.amodule.params['boot']
|
||||
if aparam_boot is not None:
|
||||
new_boot_disk_size = aparam_boot['disk_size']
|
||||
if new_boot_disk_size is not None:
|
||||
boot_disk_size = 0
|
||||
for disk in self.comp_info['disks']:
|
||||
if disk['type'] == 'B':
|
||||
boot_disk_size = disk['sizeMax']
|
||||
break
|
||||
else:
|
||||
if aparam_boot is None or aparam_boot['disk_id'] is None:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Can\'t set boot disk size for Compute '
|
||||
f'{comp_id}, because it doesn\'t '
|
||||
f'have a boot disk.'
|
||||
)
|
||||
|
||||
if new_boot_disk_size < boot_disk_size:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'New boot disk size {new_boot_disk_size} is less'
|
||||
f' than current {boot_disk_size} for Compute ID '
|
||||
f'{comp_id}'
|
||||
)
|
||||
|
||||
aparam_disks = self.amodule.params['disks']
|
||||
aparam_boot_disk_id = aparam_boot['disk_id']
|
||||
comp_disk_ids = [disk['id'] for disk in self.comp_info['disks']]
|
||||
if aparam_disks is None:
|
||||
if (
|
||||
aparam_boot_disk_id is not None
|
||||
and aparam_boot_disk_id not in comp_disk_ids
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "boot.disk_id" failed: '
|
||||
f'disk {aparam_boot_disk_id} is not attached to '
|
||||
f'Compute ID {self.comp_id}.'
|
||||
)
|
||||
else:
|
||||
match aparam_disks['mode']:
|
||||
case 'update':
|
||||
if (
|
||||
aparam_boot_disk_id not in comp_disk_ids
|
||||
and aparam_boot_disk_id not in aparam_disks['ids']
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "boot.disk_id" failed: '
|
||||
f'disk {aparam_boot_disk_id} is not attached '
|
||||
f'to Compute ID {self.comp_id}.'
|
||||
)
|
||||
case 'match':
|
||||
if aparam_boot_disk_id not in aparam_disks['ids']:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "boot.disk_id" failed: '
|
||||
f'disk {aparam_boot_disk_id} is not in '
|
||||
f'disks.ids'
|
||||
)
|
||||
case 'detach' | 'delete':
|
||||
if aparam_boot_disk_id in aparam_disks['ids']:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "boot.disk_id" failed: '
|
||||
f'disk {aparam_boot_disk_id} cannot be '
|
||||
f'detached or deleted to set as boot disk.'
|
||||
)
|
||||
elif aparam_boot_disk_id not in comp_disk_ids:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "boot.disk_id" failed: '
|
||||
f'disk {aparam_boot_disk_id} is not attached '
|
||||
f'to Compute ID {self.comp_id}.'
|
||||
)
|
||||
|
||||
if (
|
||||
not self.comp_info['imageId']
|
||||
not comp_info['imageId']
|
||||
and self.amodule.params['state'] in ('poweredon', 'paused')
|
||||
):
|
||||
check_errors = True
|
||||
@@ -880,7 +1079,7 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
is_vm_stopped_or_will_be_stopped = (
|
||||
(
|
||||
self.comp_info['techStatus'] == 'STOPPED'
|
||||
comp_info['techStatus'] == 'STOPPED'
|
||||
and (
|
||||
self.amodule.params['state'] is None
|
||||
or self.amodule.params['state'] in (
|
||||
@@ -889,7 +1088,7 @@ class decort_kvmvm(DecortController):
|
||||
)
|
||||
)
|
||||
or (
|
||||
self.comp_info['techStatus'] != 'STOPPED'
|
||||
comp_info['techStatus'] != 'STOPPED'
|
||||
and self.amodule.params['state'] in (
|
||||
'halted', 'poweredoff',
|
||||
)
|
||||
@@ -905,7 +1104,7 @@ class decort_kvmvm(DecortController):
|
||||
)
|
||||
|
||||
vm_snapshot_labels = [
|
||||
snapshot['label'] for snapshot in self.comp_info['snapSets']
|
||||
snapshot['label'] for snapshot in comp_info['snapSets']
|
||||
]
|
||||
if self.amodule.params['rollback_to'] not in vm_snapshot_labels:
|
||||
check_errors = True
|
||||
@@ -913,7 +1112,7 @@ class decort_kvmvm(DecortController):
|
||||
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"]}.'
|
||||
f'for VM ID {comp_id}.'
|
||||
)
|
||||
|
||||
params_to_check = {
|
||||
@@ -925,7 +1124,7 @@ class decort_kvmvm(DecortController):
|
||||
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 comp_info[comp_field_name] != self.aparams[param_name]
|
||||
and not is_vm_stopped_or_will_be_stopped
|
||||
):
|
||||
check_errors = True
|
||||
@@ -944,7 +1143,7 @@ class decort_kvmvm(DecortController):
|
||||
|
||||
if (
|
||||
self.aparam_networks_has_dpdk
|
||||
and not self.comp_info['hpBacked']
|
||||
and not comp_info['hpBacked']
|
||||
and not self.aparams['hp_backed']
|
||||
):
|
||||
check_errors = True
|
||||
@@ -954,9 +1153,149 @@ class decort_kvmvm(DecortController):
|
||||
'to a DPDK network.'
|
||||
)
|
||||
|
||||
is_vm_started_or_will_be_started = (
|
||||
(
|
||||
comp_info['techStatus'] == 'STARTED'
|
||||
and (
|
||||
self.amodule.params['state'] is None
|
||||
or self.amodule.params['state'] in (
|
||||
'poweredon', 'present',
|
||||
)
|
||||
)
|
||||
)
|
||||
or (
|
||||
comp_info['techStatus'] != 'STARTED'
|
||||
and self.amodule.params['state'] == 'poweredon'
|
||||
)
|
||||
)
|
||||
|
||||
if self.amodule.params['get_console_url']:
|
||||
if not is_vm_started_or_will_be_started:
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "get_console_url" failed: '
|
||||
'VM must be started to get console url.'
|
||||
)
|
||||
|
||||
aparam_disks = self.aparams['disks']
|
||||
if aparam_disks is not None:
|
||||
if self.comp_info['snapSets']:
|
||||
match aparam_disks['mode']:
|
||||
case 'detach' | 'delete':
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "disks" failed: '
|
||||
f'cannot {aparam_disks["mode"]} disks for '
|
||||
f'Compute ID {self.comp_id} while snapshots '
|
||||
f'exist in compute.'
|
||||
)
|
||||
case 'match':
|
||||
comp_disk_ids = {
|
||||
disk['id'] for disk in self.comp_info['disks']
|
||||
}
|
||||
disks = set(aparam_disks['ids'])
|
||||
disks_to_detach = comp_disk_ids - disks
|
||||
if disks_to_detach:
|
||||
check_errors = True
|
||||
self.message(
|
||||
f'Check for parameter "disks" failed: '
|
||||
f'disks {disks_to_detach} cannot be detached '
|
||||
f'from Compute ID {self.comp_id} while '
|
||||
f'snapshots exist in compute.'
|
||||
)
|
||||
|
||||
if check_errors:
|
||||
self.exit(fail=True)
|
||||
|
||||
def check_amodule_args_for_clone(self, clone_id: int, clone_dict: dict):
|
||||
check_errors = False
|
||||
aparam_clone_from = self.aparams['clone_from']
|
||||
|
||||
if (
|
||||
clone_id
|
||||
and clone_dict['cloneReference'] != self.vm_to_clone_id
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "name" failed: '
|
||||
f'VM with name {self.aparams["name"]} '
|
||||
f'already exists.'
|
||||
)
|
||||
if (
|
||||
self.vm_to_clone_info['techStatus'] == 'STARTED'
|
||||
and not aparam_clone_from['force']
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "clone_from.force" failed: '
|
||||
'VM must be stopped or parameter "force" must be True '
|
||||
'to clone it.'
|
||||
)
|
||||
|
||||
aparam_snapshot = aparam_clone_from['snapshot']
|
||||
snapshot_timestamps = [
|
||||
snapshot['timestamp']
|
||||
for snapshot in self.vm_to_clone_info['snapSets']
|
||||
]
|
||||
if aparam_snapshot is not None:
|
||||
if (
|
||||
aparam_snapshot['name'] is not None
|
||||
and aparam_snapshot['name'] not in (
|
||||
snapshot['label']
|
||||
for snapshot in self.vm_to_clone_info['snapSets']
|
||||
)
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "clone_from.snapshot.name" '
|
||||
'failed: snapshot with name '
|
||||
f'{aparam_snapshot["name"]} does not exist for VM ID '
|
||||
f'{self.vm_to_clone_id}.'
|
||||
)
|
||||
if (
|
||||
aparam_snapshot['timestamp'] is not None
|
||||
and aparam_snapshot['timestamp'] not in snapshot_timestamps
|
||||
):
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "clone_from.snapshot.timestamp" '
|
||||
'failed: snapshot with timestamp '
|
||||
f'{aparam_snapshot["timestamp"]} does not exist for '
|
||||
f'VM ID {self.vm_to_clone_id}.'
|
||||
)
|
||||
if aparam_snapshot['datetime'] is not None:
|
||||
timestamp_from_dt_str = self.dt_str_to_sec(
|
||||
dt_str=aparam_snapshot['datetime']
|
||||
)
|
||||
if timestamp_from_dt_str not in snapshot_timestamps:
|
||||
check_errors = True
|
||||
self.message(
|
||||
'Check for parameter "clone_from.snapshot.datetime" '
|
||||
'failed: snapshot with datetime '
|
||||
f'{aparam_snapshot["datetime"]} does not exist for '
|
||||
f'VM ID {self.vm_to_clone_id}.'
|
||||
)
|
||||
|
||||
if check_errors:
|
||||
self.exit(fail=True)
|
||||
|
||||
def clone(self):
|
||||
clone_from_snapshot = self.aparams['clone_from']['snapshot']
|
||||
snapshot_timestamp, snapshot_name, snapshot_datetime = None, None, None
|
||||
if clone_from_snapshot:
|
||||
snapshot_timestamp = clone_from_snapshot['timestamp']
|
||||
snapshot_name = clone_from_snapshot['name']
|
||||
snapshot_datetime = clone_from_snapshot['datetime']
|
||||
clone_id = self.compute_clone(
|
||||
compute_id=self.vm_to_clone_id,
|
||||
name=self.aparams['name'],
|
||||
force=self.aparams['clone_from']['force'],
|
||||
snapshot_timestamp=snapshot_timestamp,
|
||||
snapshot_name=snapshot_name,
|
||||
snapshot_datetime=snapshot_datetime,
|
||||
)
|
||||
return clone_id
|
||||
|
||||
# Workflow digest:
|
||||
# 1) authenticate to DECORT controller & validate authentication by issuing API call - done when creating DECSController
|
||||
# 2) check if the VM with the specified id or rg_name:name exists
|
||||
@@ -976,8 +1315,6 @@ def main():
|
||||
amodule = subj.amodule
|
||||
|
||||
if subj.comp_id:
|
||||
subj.check_amodule_args_for_change()
|
||||
|
||||
if subj.comp_info['status'] in ("DISABLED", "MIGRATING", "DELETING", "DESTROYING", "ERROR", "REDEPLOYING"):
|
||||
# cannot do anything on the existing Compute in the listed states
|
||||
subj.error() # was subj.nop()
|
||||
@@ -1001,6 +1338,7 @@ def main():
|
||||
_, subj.comp_info, _ = subj.compute_find(
|
||||
comp_id=subj.comp_id,
|
||||
need_custom_fields=True,
|
||||
need_console_url=amodule.params['get_console_url'],
|
||||
)
|
||||
subj.modify()
|
||||
elif amodule.params['state'] == 'absent':
|
||||
@@ -1041,6 +1379,7 @@ def main():
|
||||
_, subj.comp_info, _ = subj.compute_find(
|
||||
comp_id=subj.comp_id,
|
||||
need_custom_fields=True,
|
||||
need_console_url=amodule.params['get_console_url'],
|
||||
)
|
||||
#
|
||||
# We no longer need to re-read RG facts, as all network info is now available inside
|
||||
|
||||
@@ -103,20 +103,17 @@ class decort_lb(DecortController):
|
||||
self.rg_id,self.vins_id,
|
||||
self.amodule.params['ext_net_id'],
|
||||
self.amodule.params['ha_lb'],
|
||||
self.amodule.params['description'])
|
||||
self.amodule.params['description'],
|
||||
sysctl=self.amodule.params['sysctl'],)
|
||||
if self.lb_id and (self.amodule.params['backends'] or
|
||||
self.amodule.params['frontends']):
|
||||
self.lb_id, self.lb_facts = self.lb_find(0,self.amodule.params['lb_name'],self.rg_id)
|
||||
self.lb_update(
|
||||
self.lb_facts['primaryNode'],
|
||||
self.lb_facts['frontendHAIP'],
|
||||
self.lb_facts['backendHAIP'],
|
||||
self.lb_facts['backends'],
|
||||
self.lb_facts['frontends'],
|
||||
self.amodule.params['backends'],
|
||||
self.amodule.params['servers'],
|
||||
self.amodule.params['frontends']
|
||||
)
|
||||
lb_facts=self.lb_facts,
|
||||
aparam_backends=self.amodule.params['backends'],
|
||||
aparam_frontends=self.amodule.params['frontends'],
|
||||
aparam_servers=self.amodule.params['servers'],
|
||||
)
|
||||
return
|
||||
|
||||
def action(self,d_state='',restore=False):
|
||||
@@ -127,14 +124,11 @@ class decort_lb(DecortController):
|
||||
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
|
||||
|
||||
self.lb_update(
|
||||
self.lb_facts['primaryNode'],
|
||||
self.lb_facts['frontendHAIP'],
|
||||
self.lb_facts['backendHAIP'],
|
||||
self.lb_facts['backends'],
|
||||
self.lb_facts['frontends'],
|
||||
self.amodule.params['backends'],
|
||||
self.amodule.params['servers'],
|
||||
self.amodule.params['frontends'],
|
||||
lb_facts=self.lb_facts,
|
||||
aparam_backends=self.amodule.params['backends'],
|
||||
aparam_frontends=self.amodule.params['frontends'],
|
||||
aparam_servers=self.amodule.params['servers'],
|
||||
aparam_sysctl=self.aparams['sysctl'],
|
||||
)
|
||||
|
||||
if d_state != '':
|
||||
@@ -196,6 +190,7 @@ class decort_lb(DecortController):
|
||||
ret_dict = dict(id=0,
|
||||
name="none",
|
||||
state="CHECK_MODE",
|
||||
sysctl={},
|
||||
)
|
||||
|
||||
if arg_check_mode:
|
||||
@@ -216,6 +211,7 @@ class decort_lb(DecortController):
|
||||
if self.amodule.params['state']!="absent":
|
||||
ret_dict['backends'] = self.lb_facts['backends']
|
||||
ret_dict['frontends'] = self.lb_facts['frontends']
|
||||
ret_dict['sysctl'] = self.lb_facts['sysctlParams']
|
||||
return ret_dict
|
||||
|
||||
@property
|
||||
@@ -292,6 +288,9 @@ class decort_lb(DecortController):
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
sysctl=dict(
|
||||
type='dict',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
|
||||
@@ -279,9 +279,8 @@ def main():
|
||||
amodule.exit_json(**decon.result)
|
||||
|
||||
if decon.validated_virt_image_id > 0 and amodule.params['state'] == "absent":
|
||||
decon.result['msg'] = ("Osimage module cannot delete virtual images.")
|
||||
decon.result['failed'] = True
|
||||
amodule.exit_json(**decon.result)
|
||||
amodule.image_id_delete = decon.validated_virt_image_id
|
||||
decort_osimage.decort_image_delete(decon, amodule)
|
||||
|
||||
elif amodule.params['image_name'] or amodule.params['image_id']:
|
||||
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
|
||||
|
||||
@@ -121,6 +121,7 @@ class decort_rg(DecortController):
|
||||
arg_res_types=self.amodule.params['resType'],
|
||||
arg_newname=self.amodule.params['rename'],
|
||||
arg_sep_pools=self.amodule.params['sep_pools'],
|
||||
arg_desc=self.amodule.params['description'],
|
||||
)
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
@@ -235,6 +236,7 @@ class decort_rg(DecortController):
|
||||
ret_dict['ViNS'] = self.rg_facts['vins']
|
||||
ret_dict['computes'] = self.rg_facts['vms']
|
||||
ret_dict['uniqPools'] = self.rg_facts['uniqPools']
|
||||
ret_dict['description'] = self.rg_facts['desc']
|
||||
|
||||
return ret_dict
|
||||
|
||||
@@ -362,6 +364,7 @@ def main():
|
||||
or amodule.params['resType']
|
||||
or amodule.params['rename'] != ""
|
||||
or amodule.params['sep_pools'] is not None
|
||||
or amodule.params['description'] is not None
|
||||
):
|
||||
decon.update()
|
||||
if amodule.params['access']:
|
||||
|
||||
Reference in New Issue
Block a user