This commit is contained in:
2026-06-01 18:27:15 +03:00
parent ae986fa9e6
commit 1ab446e05d
34 changed files with 5135 additions and 2113 deletions

View File

@@ -19,8 +19,7 @@ class decort_rg(DecortController):
amodule = self.amodule
self.validated_acc_id = 0
self.validated_rg_id = 0
self.validated_rg_facts = None
self.rg_id: int = 0
if amodule.params['rg_id'] is None:
if self.amodule.params['account_id']:
@@ -42,13 +41,15 @@ class decort_rg(DecortController):
else:
self.rg_should_exist = False
if self.validated_rg_id and self.rg_facts['status'] != 'DESTROYED':
if self.rg_id and (
self.rg_info.status != sdk_types.ResourceGroupStatus.DESTROYED
):
self.check_amodule_args_for_change()
def get_info(self):
# If this is the first getting info
if not self.validated_rg_id:
self.validated_rg_id, self.rg_facts = self.rg_find(
if self._rg_info is None:
self.rg_id, self._rg_info = self.rg_find(
arg_account_id=self.validated_acc_id,
arg_rg_id=self.aparams['rg_id'],
arg_rg_name=self.aparams['rg_name'],
@@ -61,16 +62,16 @@ class decort_rg(DecortController):
if self.amodule.check_mode:
return
_, self.rg_facts = self.rg_find(arg_rg_id=self.validated_rg_id)
_, self._rg_info = self.rg_find(arg_rg_id=self.rg_id)
def access(self):
should_change_access = False
acc_granted = False
for rg_item in self.rg_facts['acl']:
if rg_item['userGroupId'] == self.amodule.params['access']['user']:
for rg_item in self.rg_info.acl:
if rg_item.user_name == self.amodule.params['access']['user']:
acc_granted = True
if self.amodule.params['access']['action'] == 'grant':
if rg_item['right'] != self.amodule.params['access']['right']:
if rg_item.access_type.value != self.amodule.params['access']['right']:
should_change_access = True
if self.amodule.params['access']['action'] == 'revoke':
should_change_access = True
@@ -78,19 +79,30 @@ class decort_rg(DecortController):
should_change_access = True
if should_change_access == True:
self.rg_access(self.validated_rg_id, self.amodule.params['access'])
self.rg_facts['access'] = self.amodule.params['access']
if self.amodule.params['access']['action'] == "grant":
self.sdk_checkmode(self.api.ca.rg.access_grant)(
access_type=sdk_types.AccessTypeForSet(
self.amodule.params['access']['right']
),
rg_id=self.rg_id,
user_name=self.amodule.params['access']['user'],
)
else:
self.sdk_checkmode(self.api.ca.rg.access_revoke)(
rg_id=self.rg_id,
user_name=self.amodule.params['access']['user'],
)
self.rg_should_exist = True
return
def error(self):
self.result['failed'] = True
self.result['changed'] = False
if self.validated_rg_id > 0:
if self.rg_id:
self.result['msg'] = ("Invalid target state '{}' requested for rg ID {} in the "
"current status '{}'.").format(self.validated_rg_id,
"current status '{}'.").format(self.rg_id,
self.amodule.params['state'],
self.rg_facts['status'])
self.rg_info.status.value)
else:
self.result['msg'] = ("Invalid target state '{}' requested for non-existent rg name '{}' "
"in account ID {} ").format(self.amodule.params['state'],
@@ -99,20 +111,31 @@ class decort_rg(DecortController):
return
def update(self):
resources = self.rg_facts['Resources']['Reserved']
try:
rg_res_model = (
self.api.cloudapi.rg.get_resource_consumption(rg_id=self.rg_id)
)
except sdk_exceptions.RequestException as e:
self.message(
msg=(
f'Failed to get RG Resources by ID {self.rg_id}: {e}'
)
)
self.exit(fail=True)
reserved_resources = rg_res_model.reserved
incorrect_quota = dict(Requested=dict(),
Reserved=dict(),)
query_key_map = dict(
cpu='cpu',
ram='ram',
disk='disksize',
ext_ips='extips',
storage_policies='policies',
cpu='cpu_count',
ram='ram_size_mb',
disk='storage_size_gb_by_real_usage',
ext_ips='ext_ip_count',
storage_policies='storage_policies',
)
if self.amodule.params['quotas']:
for quota_item in self.amodule.params['quotas']:
if quota_item == 'storage_policies':
rg_storage_policies = resources[query_key_map[quota_item]]
rg_storage_policies = reserved_resources.storage_policies
aparam_storage_policies = self.amodule.params['quotas'][
quota_item
]
@@ -124,32 +147,35 @@ class decort_rg(DecortController):
if (
rg_storage_policy
and aparam_storage_policy['storage_size_gb']
< rg_storage_policy['disksize']
< rg_storage_policy.storage_size_gb_by_real_usage
):
incorrect_quota['Requested'][quota_item] = (
self.amodule.params['quotas'][quota_item]
)
incorrect_quota['Reserved'][quota_item] = (
resources[query_key_map[quota_item]]
getattr(
reserved_resources,
query_key_map[quota_item]
)
)
elif (
self.amodule.params['quotas'][quota_item]
< resources[query_key_map[quota_item]]
< getattr(reserved_resources, query_key_map[quota_item])
):
incorrect_quota['Requested'][quota_item] = (
self.amodule.params['quotas'][quota_item]
)
incorrect_quota['Reserved'][quota_item] = (
resources[query_key_map[quota_item]]
getattr(reserved_resources, query_key_map[quota_item])
)
if incorrect_quota['Requested']:
if reserved_resources and incorrect_quota['Requested']:
self.result['msg'] = ("Cannot limit less than already reserved'{}'").format(incorrect_quota)
self.result['failed'] = True
if not self.result['failed']:
self.rg_update(
arg_rg_dict=self.rg_facts,
rg_model=self.rg_info,
arg_quotas=self.amodule.params['quotas'],
arg_res_types=self.amodule.params['resType'],
arg_newname=self.amodule.params['rename'],
@@ -160,13 +186,15 @@ class decort_rg(DecortController):
return
def setDefNet(self):
rg_def_net_type = self.rg_facts['def_net_type']
rg_def_net_id = self.rg_facts['def_net_id']
rg_def_net_type = self.rg_info.default_net_type.value
rg_def_net_id = self.rg_info.default_net_id
aparam_def_net_type = self.aparams['def_netType']
aparam_def_net_id = self.aparams['def_netId']
need_to_reset = (aparam_def_net_type == 'NONE'
and rg_def_net_type != aparam_def_net_type)
need_to_reset = (
aparam_def_net_type == sdk_types.RGDefaultNetType.NONE
and rg_def_net_type != aparam_def_net_type
)
need_to_change = False
if aparam_def_net_id is not None:
@@ -174,16 +202,26 @@ class decort_rg(DecortController):
or aparam_def_net_type != rg_def_net_type)
if need_to_reset or need_to_change:
self.rg_setDefNet(
arg_rg_id=self.validated_rg_id,
arg_net_type=aparam_def_net_type,
arg_net_id=aparam_def_net_id,
)
if aparam_def_net_type == sdk_types.RGDefaultNetType.NONE:
self.sdk_checkmode(self.api.ca.rg.remove_def_net)(
rg_id=self.rg_id,
)
else:
if aparam_def_net_type == sdk_types.RGDefaultNetType.PRIVATE:
net_type = sdk_types.RGDefaultNetTypeForSet.PRIVATE
elif aparam_def_net_type == sdk_types.RGDefaultNetType.PUBLIC:
net_type = sdk_types.RGDefaultNetTypeForSet.PUBLIC
self.sdk_checkmode(self.api.ca.rg.set_def_net)(
net_type=net_type,
rg_id=self.rg_id,
net_id=aparam_def_net_id,
)
self.rg_should_exist = True
return
def create(self):
self.validated_rg_id = self.rg_provision(
self.rg_id = self.rg_provision(
self.validated_acc_id,
self.amodule.params['rg_name'],
self.amodule.params['owner'],
@@ -198,10 +236,10 @@ class decort_rg(DecortController):
sdn_access_group_id=self.aparams['sdn_access_group_id'],
)
if self.validated_rg_id:
self.validated_rg_id, self.rg_facts = self.rg_find(
if self.rg_id:
self.rg_id, self._rg_info = self.rg_find(
arg_account_id=self.validated_acc_id,
arg_rg_id=self.validated_rg_id,
arg_rg_id=self.rg_id,
arg_rg_name="",
arg_check_state=False
)
@@ -209,31 +247,30 @@ class decort_rg(DecortController):
return
def enable(self):
self.rg_enable(self.validated_rg_id,
self.amodule.params['state'])
if self.amodule.params['state'] == "enabled":
self.rg_facts['status'] = 'CREATED'
else:
self.rg_facts['status'] = 'DISABLED'
self.sdk_checkmode(self.api.ca.rg.enable)(
rg_id=self.rg_id,
)
elif self.amodule.params['state'] == "disabled":
self.sdk_checkmode(self.api.ca.rg.disable)(
rg_id=self.rg_id,
)
self.rg_should_exist = True
return
def restore(self):
self.rg_restore(self.validated_rg_id)
self.rg_facts['status'] = 'DISABLED'
self.sdk_checkmode(self.api.ca.rg.restore)(
rg_id=self.rg_id,
)
self.rg_should_exist = True
return
def destroy(self):
self.rg_delete(
rg_id=self.validated_rg_id,
self.sdk_checkmode(self.api.ca.rg.delete)(
rg_id=self.rg_id,
permanently=self.amodule.params['permanently'],
recursively=self.aparams['recursive_deletion'],
)
if self.amodule.params['permanently'] == True:
self.rg_facts['status'] = 'DESTROYED'
else:
self.rg_facts['status'] = 'DELETED'
self.rg_should_exist = False
return
@@ -259,23 +296,7 @@ class decort_rg(DecortController):
# ret_dict['state'] = "ABSENT"
# return ret_dict
ret_dict['id'] = self.rg_facts['id']
ret_dict['name'] = self.rg_facts['name']
ret_dict['state'] = self.rg_facts['status']
ret_dict['account_id'] = self.rg_facts['accountId']
ret_dict['gid'] = self.rg_facts['gid']
ret_dict['quota'] = self.rg_facts['resourceLimits']
ret_dict['resTypes'] = self.rg_facts['resourceTypes']
ret_dict['defNetId'] = self.rg_facts['def_net_id']
ret_dict['defNetType'] = self.rg_facts['def_net_type']
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']
ret_dict['sdn_access_group_id'] = self.rg_facts['sdn_access_group_id']
ret_dict['storage_policy_ids'] = self.rg_facts['storage_policy_ids']
return ret_dict
return self.rg_info.model_dump()
@property
def amodule_init_args(self) -> dict:
@@ -290,6 +311,24 @@ class decort_rg(DecortController):
),
access=dict(
type='dict',
options=dict(
action=dict(
type='str',
required=True,
choices=[
'grant',
'revoke',
],
),
user=dict(
type='str',
required=True,
),
right=dict(
type='str',
choices=sdk_types.AccessTypeForSet._member_names_,
),
),
),
description=dict(
type='str',
@@ -297,12 +336,8 @@ class decort_rg(DecortController):
),
def_netType=dict(
type='str',
choices=[
'PRIVATE',
'PUBLIC',
'NONE',
],
default='PRIVATE',
choices=sdk_types.RGDefaultNetType._member_names_,
default=sdk_types.RGDefaultNetType.PRIVATE.name,
),
def_netId=dict(
type='int',
@@ -386,13 +421,13 @@ class decort_rg(DecortController):
self.aparams['sdn_access_group_id'] is not None
and (
self.aparams['sdn_access_group_id']
!= self.rg_facts['sdn_access_group_id']
!= self.rg_info.sdn_access_group_id
)
):
self.message(
'Check for parameter "sdn_access_group_id" failed: '
'cannot change sdn_access_group_id for an existing resource '
f'group ID {self.validated_rg_id}.'
f'group ID {self.rg_id}.'
)
check_errors = True
@@ -410,10 +445,15 @@ class decort_rg(DecortController):
def run(self):
amodule = self.amodule
#amodule.check_mode=True
if self.validated_rg_id > 0:
if self.rg_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING", "CONFIRMED"]:
if self.rg_id:
if self.rg_info.status in [
sdk_types.ResourceGroupStatus.MODELED,
sdk_types.ResourceGroupStatus.DISABLING,
sdk_types.ResourceGroupStatus.ENABLING,
sdk_types.ResourceGroupStatus.DESTROYING,
]:
self.error()
elif self.rg_facts['status'] in ("CREATED"):
elif self.rg_info.status == sdk_types.ResourceGroupStatus.CREATED:
if amodule.params['state'] == 'absent':
self.destroy()
elif amodule.params['state'] == "disabled":
@@ -432,7 +472,7 @@ class decort_rg(DecortController):
if amodule.params['def_netType'] is not None:
self.setDefNet()
elif self.rg_facts['status'] == "DELETED":
elif self.rg_info.status == sdk_types.ResourceGroupStatus.DELETED:
if amodule.params['state'] == 'absent' and amodule.params['permanently'] == True:
self.destroy()
elif (amodule.params['state'] == 'present'
@@ -441,7 +481,7 @@ class decort_rg(DecortController):
elif amodule.params['state'] == 'enabled':
self.restore()
self.enable()
elif self.rg_facts['status'] in ("DISABLED"):
elif self.rg_info.status == sdk_types.ResourceGroupStatus.DISABLED:
if amodule.params['state'] == 'absent':
self.destroy()
elif amodule.params['state'] == ("enabled"):