Merge branch 'rc-5.2.6' into 'dev_5.3.0'

Update dev_5.3.0 branch

See merge request rudecs/dev/decort-ansible!87
rc-5.3.0^2
commit f12e6fc941

@ -43,8 +43,11 @@ class decort_bservice(DecortController):
self.fail_json(**self.result)
# fail the module -> exit
# now validate RG
validated_rg_id, validated_rg_facts = self.rg_find(validated_acc_id,
arg_amodule.params['rg_id'],)
validated_rg_id, validated_rg_facts = self.rg_find(
arg_account_id=validated_acc_id,
arg_rg_id=arg_amodule.params['rg_id'],
arg_rg_name=arg_amodule.params['rg_name']
)
if not validated_rg_id:
self.result['failed'] = True
self.result['changed'] = False
@ -76,7 +79,7 @@ class decort_bservice(DecortController):
"""
self.result['failed'] = False
self.result['changed'] = False
if self.k8s_id:
if self.bservice_id:
self.result['msg'] = ("No state change required for B-service ID {} because of its "
"current status '{}'.").format(self.bservice_id, self.bservice_info['status'])
else:
@ -148,8 +151,7 @@ class decort_bservice(DecortController):
ret_dict['state'] = self.bservice_info['status']
ret_dict['rg_id'] = self.bservice_info['rgId']
ret_dict['account_id'] = self.acc_id
ret_dict['groupsName'] = self.bservice_info['groupsName']
ret_dict['groupsIds'] = self.bservice_info['groups']
ret_dict['groups'] = self.bservice_info['groups']
return ret_dict
@staticmethod
def build_parameters():

@ -276,7 +276,7 @@ class decort_disk(DecortController):
self.result['msg'] = ("Current user does not have access to the account ID {} / "
"name '{}' or non-existent account specified.").format(arg_amodule.params['account_id'],
arg_amodule.params['account_name'])
self.fail_json(**self.result)
self.amodule.fail_json(**self.result)
else:
self.acc_id = validated_acc_id
self.acc_info = validated_acc_info
@ -289,7 +289,7 @@ class decort_disk(DecortController):
else:
self.result['failed'] = True
self.result['msg'] = ("Cannot manage Disk when its ID is 0 and name is empty")
self.fail_json(**self.result)
self.amodule.fail_json(**self.result)
if arg_amodule.params['place_with']:
image_id, image_facts = self.image_find(arg_amodule.params['place_with'], "", 0)
@ -311,10 +311,11 @@ class decort_disk(DecortController):
)
#IO tune
if self.amodule.params['limitIO']:
self.disk_limitIO(self.amodule.params['limitIO'],self.disk_id)
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":
self.dick_share(self.disk_id,self.amodule.params['shareable'])
self.disk_share(self.disk_id,self.amodule.params['shareable'])
return
def action(self,restore=False):
@ -324,7 +325,7 @@ class decort_disk(DecortController):
self.disk_restore(self.disk_id)
#rename if id present
if self.amodule.params['name'] != self.disk_info['name']:
self.disk_rename(diskId=self.disk_id,
self.disk_rename(disk_id=self.disk_id,
name=self.amodule.params['name'])
self.disk_info['name'] = self.amodule.params['name']
#resize
@ -519,6 +520,9 @@ def main():
elif decon.disk_info['status'] == "DELETED":
if amodule.params['state'] in ('present'):
decon.action(restore=True)
elif (amodule.params['state'] == 'absent' and
amodule.params['permanently']):
decon.delete()
else:
decon.nop()
else:

@ -132,6 +132,7 @@ class decort_group(DecortController):
self.bservice_id,
self.group_id
)
self.group_should_exist = False
return
@ -206,10 +207,23 @@ class decort_group(DecortController):
bservice_id=dict(type='int', required=True),
count=dict(type='int', required=True),
timeoutStart=dict(type='int', required=False),
role=dict(type='str', required=False),
role=dict(type='str', required=False, default=''),
cpu=dict(type='int', required=False),
ram=dict(type='int', required=False),
networks=dict(type='list', default=[], required=False),
networks=dict(
type='list', default=[], elements='dict',
options=dict(
type=dict(
type='str',
required=True,
choices=['VINS', 'EXTNET']
),
id=dict(
type='int',
required=True
)
)
),
description=dict(type='str', default="Created by decort ansible module"),
verify_ssl=dict(type='bool', required=False, default=True),
workflow_callback=dict(type='str', required=False),

@ -102,8 +102,11 @@ class decort_k8s(DecortController):
self.amodule.fail_json(**self.result)
# fail the module -> exit
# now validate RG
validated_rg_id, validated_rg_facts = self.rg_find(validated_acc_id,
arg_amodule.params['rg_id'],)
validated_rg_id, validated_rg_facts = self.rg_find(
arg_account_id=validated_acc_id,
arg_rg_id=arg_amodule.params['rg_id'],
arg_rg_name=arg_amodule.params['rg_name']
)
if not validated_rg_id:
self.result['failed'] = True
self.result['changed'] = False
@ -150,6 +153,9 @@ class decort_k8s(DecortController):
config=None,
)
if self.amodule.params['getConfig'] and self.k8s_info['techStatus'] == "STARTED":
ret_dict['config'] = self.k8s_getConfig()
if check_mode:
# in check mode return immediately with the default values
return ret_dict
@ -169,9 +175,6 @@ class decort_k8s(DecortController):
ret_dict['k8s_Masters'] = self.k8s_info['k8sGroups']['masters']
ret_dict['k8s_Workers'] = self.k8s_info['k8sGroups']['workers']
if self.amodule.params['getConfig'] and self.k8s_info['techStatus'] == "STARTED":
ret_dict['config'] = self.k8s_getConfig()
return ret_dict
def nop(self):
@ -234,6 +237,9 @@ class decort_k8s(DecortController):
)
if not k8s_id:
if k8s_id == 0:
return
else:
self.result['failed'] = True
self.amodule.fail_json(**self.result)
@ -254,8 +260,10 @@ class decort_k8s(DecortController):
self.k8s_should_exist = False
return
def action(self,disared_state,started=True):
def action(self, disared_state, started=True, preupdate: bool = False):
if preupdate:
# K8s info updating
self.k8s_info = self.k8s_get_by_id(k8s_id=self.k8s_id)
#k8s state
self.k8s_state(self.k8s_info, disared_state, started)
self.k8s_id,self.k8s_info = self.k8s_find(k8s_id=self.amodule.params['id'],
@ -333,10 +341,10 @@ class decort_k8s(DecortController):
extnet_only=dict(type='bool', default=False),
additionalSANs=dict(type='list',required=False, default=None),
init_conf=dict(type='dict', required=False, default=None),
cluster_conf=dict(type='str', required=False, default=None),
kublet_conf=dict(type='str', required=False, default=None),
kubeproxy_conf=dict(type='str', required=False, default=None),
join_conf=dict(type='str', required=False, default=None),
cluster_conf=dict(type='dict', required=False, default=None),
kublet_conf=dict(type='dict', required=False, default=None),
kubeproxy_conf=dict(type='dict', required=False, default=None),
join_conf=dict(type='dict', required=False, default=None),
oidc_cert=dict(type='raw',required=False,default=None),
verify_ssl=dict(type='bool', required=False, default=True),
workflow_callback=dict(type='str', required=False),
@ -386,8 +394,12 @@ def main():
elif subj.k8s_info['status'] == "DELETED":
if amodule.params['state'] in ('disabled', 'enabled', 'present'):
subj.k8s_restore(subj.k8s_id)
subj.action(amodule.params['state'])
subj.action(disared_state=amodule.params['state'],
preupdate=True)
if amodule.params['state'] == 'absent':
if amodule.params['permanent']:
subj.destroy()
else:
subj.nop()
elif subj.k8s_info['techStatus'] in ("STARTED","STOPPED"):
if amodule.params['state'] == 'disabled':

@ -624,7 +624,11 @@ class decort_kvmvm(DecortController):
Note that it does not modify power state of KVM VM.
"""
self.compute_networks(self.comp_info, self.amodule.params['networks'])
self.compute_bootdisk_size(self.comp_info, self.amodule.params['boot_disk'])
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)
self.compute_data_disks(self.comp_info, self.amodule.params['data_disks'])
self.compute_resize(self.comp_info,
self.amodule.params['cpu'], self.amodule.params['ram'],
@ -778,7 +782,7 @@ class decort_kvmvm(DecortController):
affinity_label=dict(type='str', required=False),
aff_rule=dict(type='list', required=False),
aaff_rule=dict(type='list', required=False),
ci_user_data=dict(type='list',elements='dict', required=False),
ci_user_data=dict(type='dict', required=False),
state=dict(type='str',
default='present',
choices=['absent', 'paused', 'poweredoff', 'halted', 'poweredon', 'present', 'check']),

@ -66,16 +66,9 @@ class decort_lb(DecortController):
self.result['msg'] = "Specified RG ID {} not found.".format(arg_amodule.params['vins_id'])
self.amodule.fail_json(**self.result)
if arg_amodule.params['vins_id']:
self.vins_id, self.vins_facts = self.vins_find(arg_amodule.params['vins_id'])
if not self.vins_id:
self.result['failed'] = True
self.result['msg'] = "Specified ViNS ID {} not found.".format(arg_amodule.params['vins_id'])
self.amodule.fail_json(**self.result)
elif arg_amodule.params['account_id'] or arg_amodule.params['account_name'] != "":
if arg_amodule.params['rg_name']:
if not arg_amodule.params['rg_name']:
self.result['failed'] = True
self.result['msg'] = ("RG name must be specified with account present")
self.amodule.fail_json(**self.result)
@ -86,7 +79,31 @@ class decort_lb(DecortController):
self.result['msg'] = ("Current user does not have access to the requested account "
"or non-existent account specified.")
self.amodule.fail_json(**self.result)
self.rg_id, self.rg_facts = self.rg_find(self._acc_id,0, arg_rg_name=arg_amodule.params['rg_name'])
self.rg_id, self.rg_facts = self.rg_find(self.acc_id,0, arg_rg_name=arg_amodule.params['rg_name'])
if arg_amodule.params['vins_id']:
self.vins_id, self.vins_facts = self.vins_find(
vins_id=arg_amodule.params['vins_id']
)
if not self.vins_id:
self.result['failed'] = True
self.result['msg'] = (
f'Specified ViNS ID {arg_amodule.params["vins_id"]}'
f' not found'
)
self.amodule.fail_json(**self.result)
elif arg_amodule.params['vins_name']:
self.vins_id, self.vins_facts = self.vins_find(
vins_id=arg_amodule.params['vins_id'],
vins_name=arg_amodule.params['vins_name'],
rg_id=self.rg_id)
if not self.vins_id:
self.result['failed'] = True
self.result['msg'] = (
f'Specified ViNS name {arg_amodule.params["vins_name"]}'
f' not found in RG ID {self.rg_id}'
)
self.amodule.fail_json(**self.result)
if self.rg_id and self.vins_id:
self.lb_id, self.lb_facts = self.lb_find(0,arg_amodule.params['lb_name'],self.rg_id)
@ -98,7 +115,8 @@ class decort_lb(DecortController):
self.amodule.params['ext_net_id'],
self.amodule.params['ha_lb'],
self.amodule.params['annotation'])
if self.amodule.params['backends'] or self.amodule.params['frontends']:
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'],
@ -114,10 +132,10 @@ class decort_lb(DecortController):
def action(self,d_state='',restore=False):
if restore == True:
self.lb_restore(arg_vins_id=self.lb_id)
self.lb_state(self.vins_facts, 'enabled')
self.lb_facts['status'] = "ENABLED"
self.lb_facts['techStatus'] = "STARTED"
self.lb_restore(lb_id=self.lb_id)
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
self.lb_state(self.lb_facts, 'enabled')
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
self.lb_update(
self.lb_facts['primaryNode'],
@ -132,6 +150,14 @@ class decort_lb(DecortController):
if d_state != '':
self.lb_state(self.lb_facts, d_state)
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
if (d_state == 'enabled' and
self.lb_facts.get('status') == 'ENABLED' and
self.lb_facts.get('techStatus') == 'STOPPED'):
self.lb_state(self.lb_facts, 'started')
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
return
def delete(self):
@ -148,7 +174,7 @@ class decort_lb(DecortController):
self.result['changed'] = False
if self.lb_id:
self.result['msg'] = ("No state change required for LB ID {} because of its "
"current status '{}'.").format(self.lb_id, self.vins_facts['status'])
"current status '{}'.").format(self.lb_id, self.lb_facts['status'])
else:
self.result['msg'] = ("No state change to '{}' can be done for "
"non-existent LB instance.").format(self.amodule.params['state'])
@ -187,7 +213,7 @@ class decort_lb(DecortController):
# in check mode return immediately with the default values
return ret_dict
if self.vins_facts is None:
if self.lb_facts is None:
# if void facts provided - change state value to ABSENT and return
ret_dict['state'] = "ABSENT"
return ret_dict
@ -288,23 +314,24 @@ def main():
elif decon.lb_facts['status'] == "DISABLED":
if amodule.params['state'] == 'absent':
decon.delete()
elif amodule.params['state'] in ('present', 'disabled'):
elif amodule.params['state'] == 'disabled':
decon.action()
elif amodule.params['state'] == 'enabled':
elif amodule.params['state'] in ('enabled', 'present'):
decon.action('enabled')
elif decon.lb_facts['status'] in ["CREATED", "ENABLED"]:
if amodule.params['state'] == 'absent':
decon.delete()
elif amodule.params['state'] in ('present', 'enabled'):
decon.action()
decon.action(d_state='enabled')
elif amodule.params['state'] == 'disabled':
decon.action('disabled')
elif amodule.params['state'] in ('stopped', 'started','restart'):
decon.action(amodule.params['state'])
elif decon.lb_facts['status'] == "DELETED":
if amodule.params['state'] in ['present', 'enabled']:
decon.action(restore=True)
elif amodule.params['state'] == 'absent':
decon.action(d_state='enabled', restore=True)
elif (amodule.params['state'] == 'absent' and
amodule.params['permanently']):
decon.delete()
elif amodule.params['state'] == 'disabled':
decon.error()

@ -313,9 +313,17 @@ class decort_osimage(DecortController):
amodule.fail_json(**self.result)
if amodule.params['image_id'] != 0 and amodule.params['image_name']:
self.validated_image_id = amodule.params['image_id']
if amodule.params['image_name']:
if amodule.params['virt_id'] != 0 and amodule.params['virt_name']:
self.validated_virt_image_id, image_facts =\
self.decort_virt_image_find(amodule)
if (self.validated_virt_image_id and
amodule.params['virt_name'] != image_facts['name']):
self.decort_virt_image_rename(amodule)
self.result['msg'] = 'Virtual image renamed successfully'
elif amodule.params['image_id'] != 0 and amodule.params['image_name']:
self.validated_image_id, image_facts = self.decort_image_find(amodule)
if (self.validated_image_id and
amodule.params['image_name'] != image_facts['name']):
decort_osimage.decort_image_rename(self,amodule)
self.result['msg'] = ("Image renamed successfully")
@ -350,7 +358,7 @@ class decort_osimage(DecortController):
hotresize=amodule.params['hotresize'],
username=amodule.params['image_username'],
password=amodule.params['image_password'],
account_Id=amodule.params['account_Id'],
account_Id=self.validated_account_id,
usernameDL=amodule.params['usernameDL'],
passwordDL=amodule.params['passwordDL'],
sepId=amodule.params['sepId'],
@ -389,6 +397,12 @@ class decort_osimage(DecortController):
image_id, image_facts = decort_osimage.decort_image_find(self, amodule)
return image_id, image_facts
def decort_virt_image_rename(self, amodule):
image_facts = self.image_rename(imageId=self.validated_virt_image_id,
name=amodule.params['virt_name'])
self.result['msg'] = ("Virtual image renamed successfully")
image_id, image_facts = self.decort_virt_image_find(amodule)
return image_id, image_facts
def decort_osimage_package_facts(arg_osimage_facts, arg_check_mode=False):
"""Package a dictionary of OS image according to the decort_osimage module specification. This
@ -507,38 +521,15 @@ def main():
decon = decort_osimage(amodule)
if amodule.params['image_name'] or amodule.params['image_id']:
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
decon.validated_image_id = decort_osimage.decort_osimage_package_facts(image_facts)['id']
if decort_osimage.decort_osimage_package_facts(image_facts)['id'] > 0:
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
if amodule.params['state'] == "present" and decon.validated_image_id == 0 and amodule.params['image_name'] and amodule.params['url']:
decort_osimage.decort_image_create(decon,amodule)
decon.result['changed'] = True
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
decon.result['msg'] = ("OS image '{}' created").format(decort_osimage.decort_osimage_package_facts(image_facts)['id'])
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
decon.validated_image_id = decort_osimage.decort_osimage_package_facts(image_facts)['id']
elif amodule.params['state'] == "absent":
if amodule.params['image_name'] or amodule.params['image_id'] and\
decort_osimage.decort_osimage_package_facts(image_facts)['accountId'] == amodule.params['account_Id']:
amodule.image_id_delete = decon.validated_image_id
decort_osimage.decort_image_delete(decon,amodule)
if amodule.params['virt_name'] or amodule.params['virt_id']:
image_id, image_facts = decort_osimage.decort_virt_image_find(decon, amodule)
decon.validated_image_id, _ = decort_osimage.decort_image_find(decon, amodule)
if decort_osimage.decort_osimage_package_facts(image_facts)['id'] > 0:
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
decon.validated_virt_image_id = decort_osimage.decort_osimage_package_facts(image_facts)['id']
decon.validated_virt_image_name = decort_osimage.decort_osimage_package_facts(image_facts)['name']
if decort_osimage.decort_osimage_package_facts(image_facts)['id'] == 0 and amodule.params['state'] == "present" and decon.validated_image_id > 0:
image_id, image_facts = decort_osimage.decort_virt_image_create(decon,amodule)
decon.result['msg'] = ("Virtual image '{}' created").format(decort_osimage.decort_osimage_package_facts(image_facts)['id'])
@ -547,19 +538,36 @@ def main():
decon.result['msg'] = ("Cannot find OS image")
amodule.fail_json(**decon.result)
if decon.validated_image_id:
if decon.validated_virt_image_id:
if decort_osimage.decort_osimage_package_facts(image_facts)['linkto'] != decon.validated_image_id:
decort_osimage.decort_virt_image_link(decon,amodule)
decon.result['changed'] = True
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)
elif amodule.params['image_name'] or amodule.params['image_id']:
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
decon.validated_image_id = decort_osimage.decort_osimage_package_facts(image_facts)['id']
if decort_osimage.decort_osimage_package_facts(image_facts)['id'] > 0:
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
if amodule.params['state'] == "present" and decon.validated_image_id == 0 and amodule.params['image_name'] and amodule.params['url']:
decort_osimage.decort_image_create(decon,amodule)
decon.result['changed'] = True
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
decon.result['msg'] = ("OS image '{}' created").format(decort_osimage.decort_osimage_package_facts(image_facts)['id'])
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
decon.validated_image_id = decort_osimage.decort_osimage_package_facts(image_facts)['id']
elif amodule.params['state'] == "absent" and decon.validated_image_id:
if amodule.params['image_name'] or amodule.params['image_id'] and\
decort_osimage.decort_osimage_package_facts(image_facts)['accountId'] == amodule.params['account_Id']:
amodule.image_id_delete = decon.validated_image_id
decort_osimage.decort_image_delete(decon,amodule)
if decon.result['failed'] == True:
# we failed to find the specified image - fail the module

@ -324,10 +324,13 @@ class decort_rg(DecortController):
"", # this is location code. TODO: add module argument
)
self.validated_rg_id, self.rg_facts = self.rg_find(self.validated_acc_id,
self.validated_rg_id,
if self.validated_rg_id:
self.validated_rg_id, self.rg_facts = self.rg_find(
arg_account_id=self.validated_acc_id,
arg_rg_id=self.validated_rg_id,
arg_rg_name="",
arg_check_state=False)
arg_check_state=False
)
self.rg_should_exist = True
return
@ -493,8 +496,12 @@ def main():
elif decon.rg_facts['status'] == "DELETED":
if amodule.params['state'] == 'absent' and amodule.params['permanently'] == True:
decon.destroy()
elif amodule.params['state'] == 'present':
elif (amodule.params['state'] == 'present'
or amodule.params['state'] == 'disabled'):
decon.restore()
elif amodule.params['state'] == 'enabled':
decon.restore()
decon.enable()
elif decon.rg_facts['status'] in ("DISABLED"):
if amodule.params['state'] == 'absent':
decon.destroy()
@ -503,8 +510,15 @@ def main():
else:
if amodule.params['state'] in ('present', 'enabled'):
if not amodule.params['rg_name']:
decon.result['failed'] = True
decon.result['msg'] = (
'Resource group could not be created because'
' the "rg_name" parameter was not specified.'
)
else:
decon.create()
if amodule.params['access']:
if amodule.params['access'] and not amodule.check_mode:
decon.access()
elif amodule.params['state'] in ('disabled'):
decon.error()

@ -392,10 +392,12 @@ class DecortController(object):
retry_counter = retry_counter - 1
else:
self.result['failed'] = True
self.result['msg'] = ("Error when calling DECORT API '{}', HTTP status code '{}', "
"reason '{}', parameters '{}'.").format(api_resp.url,
api_resp.status_code,
api_resp.reason, arg_params)
self.result['msg'] = (
f'Error when calling DECORT API {api_resp.url}'
f', HTTP status code {api_resp.status_code}'
f', reason "{api_resp.reason}"'
f', parameters {arg_params}, text {api_resp.text}.'
)
self.amodule.fail_json(**self.result)
return None # actually, this directive will never be executed as fail_json aborts the script
@ -1102,10 +1104,6 @@ class DecortController(object):
elif not new_ram:
new_ram = comp_dict['ram']
# stupid hack?
if new_ram > 1 and new_ram < 512:
new_ram = new_ram * 1024
if comp_dict['cpus'] == new_cpu and comp_dict['ram'] == new_ram:
# no need to call API in this case, as requested size is not different from the current one
self.result['failed'] = False
@ -1247,7 +1245,7 @@ class DecortController(object):
if comp_dict['affinityRules']:
for rule in comp_dict['affinityRules']:
del rule['guid']
if rule not in aff:
if not aff or rule not in aff:
affrule_del.append(rule)
if aff:
@ -1259,7 +1257,7 @@ class DecortController(object):
if comp_dict['antiAffinityRules']:
for rule in comp_dict['antiAffinityRules']:
del rule['guid']
if rule not in aaff:
if not aaff or rule not in aaff:
aaffrule_del.append(rule)
if aaff:
@ -1388,7 +1386,6 @@ class DecortController(object):
return image_record['id'], image_record
self.result['failed'] = False
self.result['failed'] = True
self.result['msg'] = ("Failed to find OS image by name '{}', SEP ID {}, pool '{}' for "
"account ID '{}'.").format(image_name,
sepid, pool,
@ -1441,7 +1438,7 @@ class DecortController(object):
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/image/list", api_params)
# On success the above call will return here. On error it will abort execution by calling fail_json.
images_list = json.loads(api_resp.content.decode('utf8'))
for image_record in images_list:
for image_record in images_list['data']:
if image_record['name'] == virt_name and image_record['status'] == "CREATED" and image_record['type'] == "virtual":
if sepid == 0 and pool == "":
# if no filtering by SEP ID or pool name is requested, return the first match
@ -1450,7 +1447,6 @@ class DecortController(object):
if full_match:
return image_record['id'], image_record
self.result['failed'] = True
self.result['msg'] = ("Failed to find virtual OS image by name '{}', SEP ID {}, pool '{}' for "
"account ID '{}'.").format(virt_name,
sepid, pool,
@ -1563,9 +1559,10 @@ class DecortController(object):
@param (int) )rg_id: ID of the RG to find and return facts for.
@return: RG ID and a dictionary of RG facts as provided by rg/get API call. Note that if it fails
to find the RG with the specified ID, it may return 0 for ID and empty dictionary for the facts. So
it is suggested to check the return values accordingly.
@return: RG ID and a dictionary of RG facts as provided by rg/get
API call. Note that if it fails to find the RG with the specified ID,
it may return 0 for ID and empty dictionary for the facts. So it is
suggested to check the return values accordingly.
"""
ret_rg_id = 0
ret_rg_dict = dict()
@ -1575,14 +1572,41 @@ class DecortController(object):
self.result['msg'] = "rg_get_by_id(): zero RG ID specified."
self.amodule.fail_json(**self.result)
api_params = dict(rgId=rg_id, )
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/rg/get", api_params)
if api_resp.status_code == 200:
api_params = {'rgId': rg_id}
# Get RG base info
api_rg_resp = self.decort_api_call(
arg_req_function=requests.post,
arg_api_name='/restmachine/cloudapi/rg/get',
arg_params=api_params
)
if api_rg_resp.status_code != 200:
self.result['warning'] = (
f'rg_get_by_id(): failed to get RG by ID {rg_id}.'
f' HTTP code {api_rg_resp.status_code}'
f', response {api_rg_resp.reason}.'
)
return ret_rg_id, ret_rg_dict
ret_rg_id = rg_id
ret_rg_dict = json.loads(api_resp.content.decode('utf8'))
ret_rg_dict = api_rg_resp.json()
# Get RG resources info
rg_status = ret_rg_dict.get('status')
if not rg_status or rg_status in ('DELETED', 'DESTROYED'):
return ret_rg_id, ret_rg_dict
api_rg_res_resp = self.decort_api_call(
arg_req_function=requests.post,
arg_api_name='/restmachine/cloudapi/rg/getResourceConsumption',
arg_params=api_params
)
if api_rg_res_resp.status_code != 200:
self.result['warning'] = (
f'rg_get_by_id(): failed to get RG Resources by ID {rg_id}.'
f' HTTP code {api_rg_res_resp.status_code}'
f', response {api_rg_res_resp.reason}.'
)
else:
self.result['warning'] = ("rg_get_by_id(): failed to get RG by ID {}. HTTP code {}, "
"response {}.").format(rg_id, api_resp.status_code, api_resp.reason)
ret_rg_dict['Resources'] = api_rg_res_resp.json()
return ret_rg_id, ret_rg_dict
@ -1658,7 +1682,7 @@ class DecortController(object):
self.amodule.fail_json(**self.result)
# try to locate RG by name - start with getting all RGs IDs within the specified account
#api_params['accountId'] = arg_account_id
api_params['includedeleted'] = False
api_params['includedeleted'] = True
#api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/account/listRG", api_params)
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/rg/list",api_params)
if api_resp.status_code == 200:
@ -1841,7 +1865,7 @@ class DecortController(object):
# - when quering resource limits, the keys are in the form of cloud units (CU_*)
query_key_map = dict(cpu='CU_C',
ram='CU_M',
disk='CU_D',
disk='CU_DM',
ext_ips='CU_I',
net_transfer='CU_NP',)
set_key_map = dict(cpu='maxCPUCapacity',
@ -2250,9 +2274,9 @@ class DecortController(object):
# self.result['msg'] = "vins_find(): cannot find Account ID {}.".format(account_id)
# self.amodule.fail_json(**self.result)
# NOTE: account's 'vins' attribute does not list destroyed ViNSes!
for runner in rg_facts['vins']:
# api_params['vinsId'] = runner
ret_vins_id, ret_vins_facts = self._vins_get_by_id(runner)
account_vinses = self._get_all_account_vinses(account_id)
for vins in account_vinses:
ret_vins_id, ret_vins_facts = self._vins_get_by_id(vins['id'])
if ret_vins_id and ret_vins_facts['name'] == vins_name:
if not check_state or ret_vins_facts['status'] not in VINS_INVALID_STATES:
return ret_vins_id, ret_vins_facts
@ -2729,7 +2753,7 @@ class DecortController(object):
"write_iops_sec_max",
"size_iops_sec",
):
if val and val < self.MIN_IOPS:
if val and val < MIN_IOPS:
self.result['msg'] = (f"{arg} was set below the minimum iops {MIN_IOPS}: {val} provided")
return
@ -2812,12 +2836,6 @@ class DecortController(object):
DISK_INVALID_STATES = ["MODELED", "CREATING", "DELETING", "DESTROYING"]
if self.amodule.check_mode:
self.result['failed'] = False
self.result['msg'] = "disk_find() in check mode: find Disk ID {} / name '{}' was requested.".format(disk_id,
name)
return
ret_disk_id = 0
ret_disk_facts = None
@ -2833,10 +2851,18 @@ class DecortController(object):
return 0, None
elif name:
if account_id:
api_params = dict(accountId=account_id,name=name)
api_params = {
'accountId': account_id,
'name': name,
'show_all': True
}
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/disks/search", api_params)
disks_list = api_resp.json()
# Filtering disks by status
excluded_statuses = ('PURGED', 'DESTROYED')
filter_f = lambda x: x.get('status') not in excluded_statuses
disks_list = [d for d in disks_list if filter_f(d)]
# the above call may return more than one matching disk
disks_list = json.loads(api_resp.content.decode('utf8'))
if len(disks_list) == 0:
return 0, None
elif len(disks_list) > 1:
@ -3108,7 +3134,7 @@ class DecortController(object):
if runner['vmId'] == comp_facts['id']:
existing_rules.append(runner)
if not len(existing_rules) and not len(new_rules):
if not existing_rules and not new_rules:
self.result['failed'] = False
self.result['warning'] = ("pfw_configure(): both existing and new port forwarding rule lists "
"for Compute ID {} are empty - nothing to do.").format(comp_facts['id'])
@ -3116,9 +3142,15 @@ class DecortController(object):
if new_rules == None or len(new_rules) == 0:
# delete all existing rules for this Compute
api_params = dict(vinsId=vins_facts['id'],
ruleId=-1)
self.decort_api_call(requests.post, "/restmachine/cloudapi/vins/natRuleDel", api_params)
for rule in existing_rules:
self.decort_api_call(
arg_req_function=requests.post,
arg_api_name="/restmachine/cloudapi/vins/natRuleDel",
arg_params={
'vinsId': vins_facts['id'],
'ruleId': rule['id']
}
)
self.result['changed'] = True
return ret_rules
@ -3456,7 +3488,7 @@ class DecortController(object):
api_params = dict(name=k8s_name,
rgId=rg_id,
k8ciId=k8ci_id,
vins_Id=vins_id,
vinsId=vins_id,
workerGroupName=def_wg_name,
networkPlugin=plugin,
masterNum=master_count,
@ -3488,6 +3520,7 @@ class DecortController(object):
extnetOnly=extnet_only,
)
upload_files = None
if oidc_cert:
upload_files = {'oidcCertificate': ('cert.pem', str(oidc_cert),'application/x-x509-ca-cert')}
@ -3534,9 +3567,15 @@ class DecortController(object):
self.result['waypoints'] = "{} -> {}".format(self.result['waypoints'], "k8s_workers_modify")
if self.amodule.check_mode:
result_msg = 'k8s_workers_modify() in check mode: No changing.'
if self.result.get('msg'):
self.result['msg'] += f'\n{result_msg}'
else:
self.result['msg'] = result_msg
return
if self.k8s_info['techStatus'] != "STARTED":
self.result['changed'] = False
self.result['msg'] = ("k8s_workers_modify(): Can't modify with TechStatus other then STARTED")
return
@ -3698,6 +3737,14 @@ class DecortController(object):
self.result['waypoints'] = "{} -> {}".format(self.result['waypoints'], "bservice_provision")
if self.amodule.check_mode:
result_msg = 'bservice_provision() in check mode: No changing.'
if self.result.get('msg'):
self.result['msg'] += f'\n{result_msg}'
else:
self.result['msg'] = result_msg
return 0
api_url = "/restmachine/cloudapi/bservice/create"
api_params = dict(
name = bs_name,
@ -3827,11 +3874,12 @@ class DecortController(object):
self.result['waypoints'] = "{} -> {}".format(self.result['waypoints'], "group_find")
if group_id == 0:
try:
i = bs_info['groupsName'].index(group_name)
except:
return 0,None
group_id = int(bs_info['groups'][i])
for group in bs_info['groups']:
if group['name'] == group_name:
return self._group_get_by_id(bs_id=bs_id,
g_id=group['id'])
return 0, None
return self._group_get_by_id(bs_id,group_id)
def group_state(self,bs_id,gr_id,desired_state):
@ -3925,7 +3973,7 @@ class DecortController(object):
else:
list_extnet.append(net['id'])
if gr_dict['vinses'] != list_vins:
if sorted(gr_dict['vinses']) != sorted(list_vins):
api_url = "/restmachine/cloudapi/bservice/groupUpdateVins"
api_params = dict(
serviceId=bs_id,
@ -3947,10 +3995,6 @@ class DecortController(object):
self.result['waypoints'] = "{} -> {}".format(self.result['waypoints'], "group_provision")
list_vins= list()
for net in arg_network:
if net['type'] == 'VINS':
list_vins.append(net['id'])
api_url = "/restmachine/cloudapi/bservice/groupAdd"
api_params = dict(
serviceId = bs_id,
@ -3962,13 +4006,15 @@ class DecortController(object):
imageId = arg_image_id,
driver = arg_driver,
role = arg_role,
vinses = list_vins,
vinses = [n['id'] for n in arg_network if n['type'] == 'VINS'],
extnets = [n['id'] for n in arg_network if n['type'] == 'EXTNET'],
timeoutStart = arg_timeout
)
self.decort_api_call(requests.post, api_url, api_params)
api_resp = self.decort_api_call(requests.post, api_url, api_params)
new_bsgroup_id = int(api_resp.text)
self.result['failed'] = False
self.result['changed'] = True
return
return new_bsgroup_id
def group_delete(self,bs_id,gr_id):
@ -4023,8 +4069,8 @@ class DecortController(object):
self.result['msg'] = "_rg_listlb(): zero RG ID specified."
self.amodule.fail_json(**self.result)
api_params = dict(rgId=rg_id)
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/rg/listLb", api_params)
api_params = dict(rgId=rg_id, includedeleted=True)
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/lb/list", api_params)
if api_resp.status_code == 200:
ret_rg_vins_list = json.loads(api_resp.content.decode('utf8'))
else:
@ -4038,7 +4084,7 @@ class DecortController(object):
@returns: LB ID and dictionary with LB facts.
"""
LB_INVALID_STATES = ["ENABLING", "DISABLING", "DELETING", "DELETED", "DESTROYING", "DESTROYED"]
LB_INVALID_STATES = ["ENABLING", "DISABLING", "DELETING", "DESTROYING", "DESTROYED"]
ret_lb_id = 0
ret_lb_facts = None
@ -4105,7 +4151,7 @@ class DecortController(object):
vinsId=vins_id,
highlyAvailable=ha_status,
start=start,
decs=annotation
desc=annotation
)
api_resp = self.decort_api_call(requests.post, api_url, api_params)
# On success the above call will return here. On error it will abort execution by calling fail_json.
@ -4144,7 +4190,7 @@ class DecortController(object):
NOP_STATES_FOR_LB_CHANGE = ["MODELED", "DISABLING", "ENABLING", "DELETING", "DELETED", "DESTROYING",
"DESTROYED"]
VALID_TARGET_STATES = ["enabled", "disabled","restart"]
VALID_TARGET_STATES = ["enabled", "disabled","restart", 'started']
VALID_TARGET_TSTATES = ["STARTED","STOPPED"]
if lb_dict['status'] in NOP_STATES_FOR_LB_CHANGE:
@ -4435,6 +4481,15 @@ class DecortController(object):
def lb_update(self,prime,front_ha_ip,back_ha_ip,lb_backends=[],lb_frontends=[],mod_backends=[],mod_servers=[],mod_frontends=[]):
self.result['waypoints'] = "{} -> {}".format(self.result['waypoints'], "lb_update")
if self.amodule.check_mode:
result_msg = 'lb_update() in check mode: No changing.'
if self.result.get('msg'):
self.result['msg'] += f'\n{result_msg}'
else:
self.result['msg'] = result_msg
return
#lists from module and cloud
mod_backs_list = [back['name'] for back in mod_backends]
lb_backs_list = [back['name'] for back in lb_backends]
@ -4445,9 +4500,6 @@ class DecortController(object):
#FE
mod_front_list = [front['name'] for front in mod_frontends]
lb_front_list = [front['name'] for front in lb_frontends]
if del_list_backs:
self._lb_delete_backends(
@ -4470,6 +4522,9 @@ class DecortController(object):
mod_servers
)
mod_front_list = [front['name'] for front in mod_frontends]
lb_front_list = [front['name'] for front in lb_frontends]
del_list_fronts = set(lb_front_list).difference(mod_front_list)
add_list_fronts = set(mod_front_list).difference(lb_front_list)
upd_front_list = set(lb_front_list).intersection(mod_front_list)
@ -4524,7 +4579,7 @@ class DecortController(object):
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/lb/frontendDelete", api_params)
#del from cloud dict
if type(front)==dict:
del self.lb_facts['frontends'][front['name']]
self.lb_facts['frontends'].remove(front)
self.result['changed'] = True
return
@ -4547,6 +4602,7 @@ class DecortController(object):
bind['address']if "address" in bind else bind_ip,
bind['port'],
)
return
def _lb_create_backends(self,back_list,mod_backs,mod_serv):
'''
@ -4630,8 +4686,8 @@ class DecortController(object):
serverName = server['name'],
address = server['address'],
port = mod_back['port'],
check = server['check'] if "check" in server else None,
**server['server_settings'] if "server_settings" in server else {},
check = mod_back['check'] if "check" in mod_back else None,
**mod_back['server_settings'] if "server_settings" in mod_back else {},
)
api_resp = self.decort_api_call(requests.post, "/restmachine/cloudapi/lb/backendServerAdd", api_params)
self.result['changed'] = True
@ -4690,11 +4746,14 @@ class DecortController(object):
lb_bind, = list(filter(lambda i: i['name'] == bind['name'],lb_front['bindings']))
del lb_bind['guid']
if not bind.get('address'):
bind['address'] = bind_ip
if dict(sorted(bind.items())) != dict(sorted(lb_bind.items())):
self._lb_bind_frontend(
front,
bind['name'],
bind['address'] if "address" in bind else bind_ip,
bind['address'],
bind['port'],
update=True,
)

Loading…
Cancel
Save