diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87c1265..8307a8f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
| Идентификатор
задачи | Описание |
| --- | --- |
-| BANS-462
BANS-472 | Добавлен новый модуль **decort_account_info**, который позволяет получить следующую информацию об аккаунте:
• основная информация
• используемые и зарезервированные ресурсы |
+| BANS-462
BANS-472
BANS-475 | Добавлен новый модуль **decort_account_info**, который позволяет получить следующую информацию об аккаунте:
• основная информация
• используемые и зарезервированные ресурсы
• ресурсные группы |
## Исправления
diff --git a/library/decort_account_info.py b/library/decort_account_info.py
index 6d331a4..801f990 100644
--- a/library/decort_account_info.py
+++ b/library/decort_account_info.py
@@ -32,6 +32,7 @@ class DecortAccountInfo(DecortController):
account_name=amodule.params['name'],
account_id=amodule.params['id'],
resource_consumption=amodule.params['resource_consumption'],
+ resource_groups_params=self.mapped_rg_params,
fail_if_not_found=True
)
@@ -72,6 +73,60 @@ class DecortAccountInfo(DecortController):
type='str',
fallback=(env_fallback, ['DECORT_OAUTH2_URL'])
),
+ resource_groups=dict(
+ type='dict',
+ options=dict(
+ filter=dict(
+ type='dict',
+ options=dict(
+ id=dict(
+ type='int',
+ ),
+ name=dict(
+ type='str'
+ ),
+ status=dict(
+ type='str',
+ choices=self.RESOURCE_GROUP_STATUSES,
+ ),
+ vins_id=dict(
+ type='int'
+ ),
+ vm_id=dict(
+ type='int'
+ ),
+ ),
+ ),
+ pagination=dict(
+ type='dict',
+ options=dict(
+ number=dict(
+ type='int',
+ default=1,
+ ),
+ size=dict(
+ type='int',
+ required=True,
+ ),
+ ),
+ ),
+ sorting=dict(
+ type='dict',
+ options=dict(
+ asc=dict(
+ type='bool',
+ default=True,
+ ),
+ field=dict(
+ type='str',
+ choices=\
+ self.FIELDS_FOR_SORTING_ACCOUNT_RG_LIST,
+ required=True,
+ ),
+ ),
+ ),
+ ),
+ ),
resource_consumption=dict(
type='bool',
default=False
@@ -94,6 +149,37 @@ class DecortAccountInfo(DecortController):
]
)
+ @property
+ def mapped_rg_params(self) -> None | dict:
+ input_params = self.amodule.params['resource_groups']
+ if not input_params:
+ return input_params
+
+ mapped_params = {}
+ if input_params['filter']:
+ mapped_params['rg_id'] =\
+ input_params['filter']['id']
+ mapped_params['rg_name'] =\
+ input_params['filter']['name']
+ mapped_params['rg_status'] =\
+ input_params['filter']['status']
+ mapped_params['vins_id'] =\
+ input_params['filter']['vins_id']
+ mapped_params['vm_id'] =\
+ input_params['filter']['vm_id']
+ if input_params['pagination']:
+ mapped_params['page_number'] =\
+ input_params['pagination']['number']
+ mapped_params['page_size'] =\
+ input_params['pagination']['size']
+ if input_params['sorting']:
+ mapped_params['sort_by_asc'] =\
+ input_params['sorting']['asc']
+ mapped_params['sort_by_field'] =\
+ input_params['sorting']['field']
+
+ return mapped_params
+
def exit(self):
self.result['facts'] = self.facts
self.amodule.exit_json(**self.result)
diff --git a/module_utils/decort_utils.py b/module_utils/decort_utils.py
index b43adfe..f0453e7 100644
--- a/module_utils/decort_utils.py
+++ b/module_utils/decort_utils.py
@@ -41,6 +41,34 @@ class DecortController(object):
based on the requested authentication type.
"""
+ FIELDS_FOR_SORTING_ACCOUNT_RG_LIST = [
+ 'createdBy',
+ 'createdTime',
+ 'deletedBy',
+ 'deletedTime',
+ 'id',
+ 'milestones',
+ 'name',
+ 'status',
+ 'updatedBy',
+ 'updatedTime',
+ 'vinses',
+ ]
+
+ RESOURCE_GROUP_STATUSES = [
+ 'CREATED',
+ 'DELETED',
+ 'DELETING',
+ 'DESTROYED',
+ 'DESTROYING',
+ 'DISABLED',
+ 'DISABLING',
+ 'ENABLED',
+ 'ENABLING',
+ 'MODELED',
+ 'RESTORING',
+ ]
+
VM_RESIZE_NOT = 0
VM_RESIZE_DOWN = 1
VM_RESIZE_UP = 2
@@ -1930,7 +1958,9 @@ class DecortController(object):
return
def account_find(self, account_name, account_id=0,
- resource_consumption=False, fail_if_not_found=False):
+ resource_consumption=False,
+ resource_groups_params: None | dict = None,
+ fail_if_not_found=False):
"""Find cloud account specified by the name and return facts about the account. Knowing account is
required for certain cloud resource management tasks (e.g. creating new RG).
@@ -2012,6 +2042,13 @@ class DecortController(object):
account_details['resource_reserved'] =\
resource_consumption['Reserved']
+ if resource_groups_params is not None:
+ account_details['resource_groups'] =\
+ self.account_resource_groups(
+ account_id=account_details['id'],
+ **resource_groups_params
+ )
+
return account_details['id'], account_details
def account_resource_consumption(self, account_id: int,
@@ -2033,6 +2070,67 @@ class DecortController(object):
" account specified.")
self.amodule.fail_json(**self.result)
+ def account_resource_groups(
+ self,
+ account_id: int,
+ page_number: int = 1,
+ page_size: None | int = None,
+ rg_id: None | int = None,
+ rg_name: None | str = None,
+ rg_status: None | str = None,
+ sort_by_field: None | str = None,
+ sort_by_asc=True,
+ vins_id: None | int = None,
+ vm_id: None | int = None,
+ ) -> list[dict]:
+ self.result['waypoints'] += f' -> account_resource_groups'
+
+ if rg_status and not rg_status in self.RESOURCE_GROUP_STATUSES:
+ self.result['msg'] = (
+ f'{rg_status} is not valid RG status for filtering'
+ f' account resource groups list.'
+ )
+ self.amodule.fail_json(**self.result)
+
+ sort_by = None
+ if sort_by_field:
+ if not sort_by_field in self.FIELDS_FOR_SORTING_ACCOUNT_RG_LIST:
+ self.result['msg'] = (
+ f'{sort_by_field} is not valid field for sorting'
+ f' account resource groups list.'
+ )
+ self.amodule.fail_json(**self.result)
+
+ sort_by_prefix = '+' if sort_by_asc else '-'
+ sort_by = f'{sort_by_prefix}{sort_by_field}'
+
+ api_params = {
+ 'accountId': account_id,
+ 'name': rg_name,
+ 'page': page_number if page_size else None,
+ 'rgId': rg_id,
+ 'size': page_size,
+ 'sortBy': sort_by,
+ 'status': rg_status,
+ 'vinsId': vins_id,
+ 'vmId': vm_id,
+ }
+
+ api_resp = self.decort_api_call(
+ arg_req_function=requests.post,
+ arg_api_name='/restmachine/cloudapi/account/listRG',
+ arg_params=api_params,
+ )
+
+ resource_groups = api_resp.json()['data']
+
+ for rg in resource_groups:
+ rg['createdTime_readable'] = self.sec_to_dt_str(rg['createdTime'])
+ rg['deletedTime_readable'] = self.sec_to_dt_str(rg['deletedTime'])
+ rg['updatedTime_readable'] = self.sec_to_dt_str(rg['updatedTime'])
+
+ return resource_groups
+
###################################
# GPU resource manipulation methods
###################################