diff --git a/CHANGELOG.md b/CHANGELOG.md
index a540acb..fe6e1bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
| Идентификатор
задачи | Описание |
| --- | --- |
-| BANS-462
BANS-472
BANS-475
BANS-476
BANS-477
BANS-478 | Добавлен новый модуль **decort_account_info**, который позволяет получить следующую информацию об аккаунте:
• основная информация
• используемые и зарезервированные ресурсы
• ресурсные группы
• виртуальные машины
• внутренние сети
• диски |
+| BANS-462
BANS-472
BANS-475
BANS-476
BANS-477
BANS-478
BANS-479 | Добавлен новый модуль **decort_account_info**, который позволяет получить следующую информацию об аккаунте:
• основная информация
• используемые и зарезервированные ресурсы
• ресурсные группы
• виртуальные машины
• внутренние сети
• диски
• образы |
## Исправления
diff --git a/library/decort_account_info.py b/library/decort_account_info.py
index 27713b2..4514347 100644
--- a/library/decort_account_info.py
+++ b/library/decort_account_info.py
@@ -33,6 +33,7 @@ class DecortAccountInfo(DecortController):
account_id=amodule.params['id'],
computes_args=self.mapped_computes_args,
disks_args=self.mapped_disks_args,
+ images_args=self.mapped_images_args,
resource_consumption=amodule.params['resource_consumption'],
resource_groups_args=self.mapped_rg_args,
vinses_args=self.mapped_vinses_args,
@@ -178,6 +179,58 @@ class DecortAccountInfo(DecortController):
id=dict(
type='int',
),
+ images=dict(
+ type='dict',
+ options=dict(
+ deleted=dict(
+ type='bool',
+ default=False,
+ ),
+ filter=dict(
+ type='dict',
+ options=dict(
+ id=dict(
+ type='int',
+ ),
+ name=dict(
+ type='str',
+ ),
+ type=dict(
+ type='str',
+ choices=self.IMAGE_TYPES,
+ ),
+ ),
+ ),
+ 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_IMAGE_LIST,
+ required=True,
+ ),
+ ),
+ ),
+ ),
+ ),
jwt=dict(
type='str',
fallback=(env_fallback, ['DECORT_JWT']),
@@ -387,6 +440,38 @@ class DecortAccountInfo(DecortController):
return mapped_args
+ @property
+ def mapped_images_args(self) -> None | dict:
+ """
+ Map the module argument `images` to
+ arguments dictionary for the method
+ `DecortController.account_images`
+ (excluding for `account_id`).
+ """
+
+ input_args = self.amodule.params['images']
+ if not input_args:
+ return input_args
+
+ mapped_args = {}
+ mapped_args['deleted'] = input_args['deleted']
+ if input_args['filter']:
+ mapped_args['image_id'] = input_args['filter']['id']
+ mapped_args['image_name'] = input_args['filter']['name']
+ mapped_args['image_type'] = input_args['filter']['type']
+ if input_args['pagination']:
+ mapped_args['page_number'] =\
+ input_args['pagination']['number']
+ mapped_args['page_size'] =\
+ input_args['pagination']['size']
+ if input_args['sorting']:
+ mapped_args['sort_by_asc'] =\
+ input_args['sorting']['asc']
+ mapped_args['sort_by_field'] =\
+ input_args['sorting']['field']
+
+ return mapped_args
+
@property
def mapped_rg_args(self) -> None | dict:
"""
diff --git a/module_utils/decort_utils.py b/module_utils/decort_utils.py
index f03709a..22c2f91 100644
--- a/module_utils/decort_utils.py
+++ b/module_utils/decort_utils.py
@@ -73,6 +73,18 @@ class DecortController(object):
'type',
]
+ FIELDS_FOR_SORTING_ACCOUNT_IMAGE_LIST = [
+ 'UNCPath',
+ 'desc',
+ 'id',
+ 'name',
+ 'public',
+ 'size',
+ 'status',
+ 'type',
+ 'username',
+ ]
+
FIELDS_FOR_SORTING_ACCOUNT_RG_LIST = [
'createdBy',
'createdTime',
@@ -123,6 +135,14 @@ class DecortController(object):
DISK_TYPES = ['B', 'D']
+ IMAGE_TYPES = [
+ 'cdrom',
+ 'linux',
+ 'other',
+ 'virtual',
+ 'windows',
+ ]
+
RESOURCE_GROUP_STATUSES = [
'CREATED',
'DELETED',
@@ -2059,6 +2079,7 @@ class DecortController(object):
computes_args: None | dict = None,
disks_args: None | dict = None,
fail_if_not_found=False,
+ images_args: None | dict = None,
resource_consumption=False,
resource_groups_args: None | dict = None,
vinses_args: None | dict = None,
@@ -2087,6 +2108,12 @@ class DecortController(object):
the method `self.amodule.fail_json(**self.result)` will be
called if account is not found.
+ @param (None | dict) images_args: If dict is
+ specified, then the method `self.account_images`
+ will be called passing founded account ID
+ and `**images_args`. Result of the call will
+ be added to account info dict (key `images`).
+
@param (bool) resource_consumption: If `True` is specified,
then the method `self.account_resource_consumption`
will be called passing founded account ID and result of
@@ -2208,6 +2235,13 @@ class DecortController(object):
**disks_args
)
+ if images_args is not None:
+ account_details['images'] =\
+ self.account_images(
+ account_id=account_details['id'],
+ **images_args
+ )
+
return account_details['id'], account_details
@waypoint
@@ -2492,6 +2526,66 @@ class DecortController(object):
return disks
+ @waypoint
+ def account_images(
+ self,
+ account_id: int,
+ deleted: bool = False,
+ image_id: None | int = None,
+ image_name: None | str = None,
+ image_type: None | str = None,
+ page_number: int = 1,
+ page_size: None | int = None,
+ sort_by_asc=True,
+ sort_by_field: None | str = None,
+ ) -> list[dict]:
+ """
+ Implementation of functionality of the API method
+ `/cloudapi/account/listTemplates`.
+ """
+
+ if image_type and (
+ not image_type in self.IMAGE_TYPES
+ ):
+ self.result['msg'] = (
+ f'{image_type} is not valid image type'
+ f' for filtering account image 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_IMAGE_LIST:
+ self.result['msg'] = (
+ f'{sort_by_field} is not valid field for sorting'
+ f' account image 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,
+ 'imageId': image_id,
+ 'includedeleted': deleted,
+ 'name': image_name,
+ 'page': page_number if page_size else None,
+ 'size': page_size,
+ 'sortBy': sort_by,
+ 'type': image_type,
+ }
+
+ api_resp = self.decort_api_call(
+ arg_req_function=requests.post,
+ arg_api_name='/restmachine/cloudapi/account/listTemplates',
+ arg_params=api_params,
+ )
+
+ images = api_resp.json()['data']
+
+ return images
+
###################################
# GPU resource manipulation methods
###################################