11.0.0
This commit is contained in:
167
CHANGELOG.md
167
CHANGELOG.md
@@ -1,11 +1,170 @@
|
|||||||
# Список изменений в версии 10.0.1
|
# Список изменений в версии 11.0.0
|
||||||
|
|
||||||
## Добавлено
|
## Добавлено
|
||||||
|
### Глобально
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-909 | В системные требования добавлена библиотека Python `dynamix_sdk`. |
|
||||||
|
| BANS-918 | Добавлен общий для всех модулей параметр `ignore_api_compatibility`. |
|
||||||
|
| BANS-913 | Добавлен общий для всех модулей параметр `ignore_sdk_version_check`. |
|
||||||
|
| BANS-954 | Добавлен модуль `decort_vm` в связи с переименованием из `decort_kvmvm`. |
|
||||||
|
| BANS-953 | Добавлен модуль `decort_image` в связи с переименованием из `decort_osimage`. |
|
||||||
|
| BANS-997 | Добавлен модуль `decort_security_group_list`, позволяющий получить список доступных групп безопасности. |
|
||||||
|
| BANS-884 | Добавлен модуль `decort_disk_list`, позволяющий получить список доступных дисков. |
|
||||||
|
| BANS-936 | Добавлен модуль `decort_rg_list`, позволяющий получить список доступных ресурсных групп. |
|
||||||
|
| BANS-949 | Добавлен модуль `decort_vins_list`, позволяющий получить список доступных внутренних сетей. |
|
||||||
|
| BANS-940 | Добавлен модуль `decort_vm_list`, позволяющий получить список доступных виртуальных машин. |
|
||||||
|
| BANS-959 | Добавлен модуль `decort_flip_group_list`, позволяющий получить список доступных групп с плавающим IP-адресом. |
|
||||||
|
| BANS-952 | Добавлен модуль `decort_image_list`, позволяющий получить список доступных образов. |
|
||||||
|
| BANS-983 | Добавлен модуль `decort_account_list`, позволяющий получить список доступных аккаунтов. |
|
||||||
|
| BANS-985 | Добавлен модуль `decort_audit_list`, позволяющий получить список аудитов. |
|
||||||
|
| BANS-988 | Добавлен модуль `decort_trunk_list`, позволяющий получить список доступных транковых портов. |
|
||||||
|
| BANS-987 | Добавлен модуль `decort_zone_list`, позволяющий получить список доступных зон. |
|
||||||
|
| BANS-989 | Добавлен модуль `decort_storage_policy_list`, позволяющий получить список политик хранения. |
|
||||||
|
| BANS-945 | Добавлен модуль `decort_user` в связи с переименованием из `decort_user_info`. |
|
||||||
|
|
||||||
## Удалено
|
### Модуль decort_vm
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-926 | Для параметра `chipset` добавлено значение по умолчанию `Q35` при создании ВМ. |
|
||||||
|
| BANS-933 | Добавлено возвращаемое значение `pinned_to_node` в связи с переименованием из `pinned_to_stack`. |
|
||||||
|
| BANS-934 | Добавлено возвращаемое значение `read_only`. |
|
||||||
|
| BANS-994 | Добавлена возможность задать параметр `mtu` при создании сетевого интерфейса для TRUNK-сети и изменить `mtu` у существующего интерфейса, подключённого к TRUNK-сети. |
|
||||||
|
| BANS-991 | Добавлена возможность указать параметр `ip_addr` при присоединении и изменении `DPDK` сети. |
|
||||||
|
| BANS-1017 | Добавлено возвращаемое значение `disks.cache`. |
|
||||||
|
| BANS-1034 | Добавлена возможность указать параметр `ip_addr` при присоединении и изменении `VFNIC` сети. |
|
||||||
|
| BANS-992 | Добавлен параметр `networks.net_prefix`. |
|
||||||
|
|
||||||
## Исправлено
|
|
||||||
### Модуль decort_group
|
### Модуль decort_group
|
||||||
| Идентификатор<br>задачи | Описание |
|
| Идентификатор<br>задачи | Описание |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| BANS-941 | Исправлена ошибка, из-за которой не происходил запуск группы после создании с указанием параметра `timeoutStart`. |
|
| BANS-927 | Для параметра `chipset` добавлено значение по умолчанию `Q35` при создании группы. |
|
||||||
|
|
||||||
|
### Модуль decort_k8s
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-928 | Для параметра `chipset` добавлено значение по умолчанию `Q35` при создании кластера. |
|
||||||
|
|
||||||
|
### Модуль decort_account
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-966 | Добавлен параметр `get_resource_consumption` и возвращаемое значение `resource_consumption`. |
|
||||||
|
|
||||||
|
### Модуль decort_trunk
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-993 | Добавлено возвращаемое значение `mtu`. |
|
||||||
|
| BANS-976 | Добавлены возвращаемые значения `created_datetime`, `deleted_datetime`, `updated_datetime`. |
|
||||||
|
|
||||||
|
### Модуль decort_zone
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-970 | Добавлены возвращаемые значения `created_datetime`, `updated_datetime` и возвращаемые значения `account_ids`, `bservice_ids`, `vm_ids`, `extnet_ids`, `k8s_ids`, `lb_ids`, `vins_ids` в связи с переименованием из `accountIds`, `bserviceIds`, `computeIds`, `extnetIds`, `k8sIds`, `lbIds`, `vinsIds`. |
|
||||||
|
| BANS-1024 | Добавлено возвращаемое значение `node_auto_start`. |
|
||||||
|
|
||||||
|
### Модуль decort_vm_snapshot
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-978 | Добавлено возвращаемое значение `datetime`. |
|
||||||
|
|
||||||
|
### Модуль decort_storage_policy
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-977 | Добавлены возвращаемые значения `sep_name`, `sep_tech_status`. |
|
||||||
|
|
||||||
|
### Модуль decort_disk
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1019 | Добавлено возвращаемое значение `cache_mode`. |
|
||||||
|
| BANS-1050 | Добавлено возвращаемое значение `blkdiscard`. |
|
||||||
|
|
||||||
|
## Удалено
|
||||||
|
### Глобально
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-954 | Удалён модуль `decort_kvmvm` в связи с переименованием в `decort_vm`. |
|
||||||
|
| BANS-969 | Модуль `decort_account_info` расформирован, его функционал перенесён в модули: `decort_disk_list`, `decort_rg_list`, `decort_vins_list`, `decort_vm_list`, `decort_flip_group_list`, `decort_image_list`, `decort_account`. |
|
||||||
|
| BANS-953 | Удалён модуль `decort_osimage` в связи с переименованием в `decort_image`. |
|
||||||
|
| BANS-945 | Удалён модуль `decort_user_info` в связи с переименованием в `decort_user`. |
|
||||||
|
|
||||||
|
### Модуль decort_account
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-924 | Удалён параметр `quotas.ext_traffic`. |
|
||||||
|
| BANS-998 |Для параметра `state` удалено значение по умолчанию. |
|
||||||
|
|
||||||
|
### Модуль decort_rg
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-925 | Удалён параметр `quotas.net_transfer`. |
|
||||||
|
|
||||||
|
### Модуль decort_vm
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-926 | Для параметра `chipset` удалено значение по умолчанию `i440fx` при создании ВМ. |
|
||||||
|
| BANS-933 | Удалено возвращаемое значение `pinned_to_stack` в связи с переименованием в `pinned_to_node`. |
|
||||||
|
| BANS-961 | Параметр `storage_policy_id` удалён из обязательных при пересоздании загрузочного диска. |
|
||||||
|
|
||||||
|
### Модуль decort_group
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-927 | Для параметра `chipset` удалено значение по умолчанию `i440fx` при создании группы. |
|
||||||
|
| BANS-1027 | Удалён параметр `driver`. |
|
||||||
|
|
||||||
|
### Модуль decort_k8s
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-928 | Для параметра `chipset` удалено значение по умолчанию `i440fx` при создании кластера. |
|
||||||
|
|
||||||
|
### Модуль decort_user
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-983 | Удалён параметр `accounts` и возвращаемое значение `accounts` в связи с переносом этой функциональности в модуль `decort_account_list`. |
|
||||||
|
| BANS-985 | Удалён параметр `audits` и возвращаемое значение `audits` в связи с переносом этой функциональности в модуль `decort_audit_list`. |
|
||||||
|
| BANS-988 | Удалён параметр `trunks` и возвращаемое значение `trunks` в связи с переносом этой функциональности в модуль `decort_trunk_list`. |
|
||||||
|
| BANS-987 | Удалён параметр `zones` и возвращаемое значение `zones` в связи с переносом этой функциональности в модуль `decort_zone_list`. |
|
||||||
|
| BANS-989 | Удалён параметр `storage_policies` и возвращаемое значение `storage_policies` в связи с переносом этой функциональности в модуль `decort_storage_policy_list`. |
|
||||||
|
| BANS-997 | Удалён параметр `security_groups` и возвращаемое значение `security_groups` в связи с переносом этой функциональности в модуль `decort_security_group_list`. |
|
||||||
|
|
||||||
|
### Модуль decort_zone
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-970 | Удалены возвращаемые значения `accountIds`, `bserviceIds`, `computeIds`, `extnetIds`, `k8sIds`, `lbIds`, `vinsIds` в связи с переименованием в `account_ids`, `bservice_ids`, `vm_ids`, `extnet_ids`, `k8s_ids`, `lb_ids`, `vins_ids`. |
|
||||||
|
|
||||||
|
### Модуль decort_disk
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1004 | Удалён параметр `reason` |
|
||||||
|
|
||||||
|
### Модуль decort_security_group
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1000 | Удалено возвращаемое значение `rules.remote_ip_prefix` в связи с переименованием в `rules.remote_net_cidr`. |
|
||||||
|
| BANS-1013 | Удален параметр `rules.objects.remote_ip_prefix` в связи с переименованием в `rules.objects.remote_net_cidr`. |
|
||||||
|
|
||||||
|
### Модуль decort_vm_snapshot
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1012 | Удалено возвращаемое значение `disks` в связи с переименованием в `disk_ids`. |
|
||||||
|
|
||||||
|
## Исправлено
|
||||||
|
### Модуль decort_vm
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-996 | Параметры `mac`, `security_groups`, `enable_secgroups`, `enabled` сетевого интерфейса DPDK-сети могли меняться при изменении `mtu`. |
|
||||||
|
| BANS-1052 | Параметры `numa_affinity`, `cpu_pin`, `hp_backed` не применялись при создании ВМ без образа. |
|
||||||
|
|
||||||
|
### Модуль decort_bservice
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-389 | После создания базовой службы, модуль не возвращал информацию о созданном объекте. |
|
||||||
|
|
||||||
|
### Модуль decort_vm_snapshot
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1022 | После создания снимка не возвращалась информация о снимке. |
|
||||||
|
|
||||||
|
### Модуль decort_k8s
|
||||||
|
| Идентификатор<br>задачи | Описание |
|
||||||
|
| --- | --- |
|
||||||
|
| BANS-1033 | Модуль без необходимости выполнял запрос к API `/cloudapi/k8s/update`, передавая в него параметры, не вызывающие изменения. |
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
| Версия платформы | Версия модулей Ansible |
|
| Версия платформы | Версия модулей Ansible |
|
||||||
|:----------------:|:--------------------------:|
|
|:----------------:|:--------------------------:|
|
||||||
| 4.4.0 | 10.0.x |
|
| 4.5.0 | 11.0.x |
|
||||||
|
| 4.4.0 | 10.0.x |
|
||||||
| 4.4.0 build 963 | 9.0.x |
|
| 4.4.0 build 963 | 9.0.x |
|
||||||
| 4.3.0 | 8.0.x |
|
| 4.3.0 | 8.0.x |
|
||||||
| 4.2.0 | 7.0.x, 7.1.x, 7.2.x |
|
| 4.2.0 | 7.0.x, 7.1.x, 7.2.x |
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
#
|
#
|
||||||
# DECORT osimage module example
|
# DECORT image module example
|
||||||
#
|
#
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
tasks:
|
tasks:
|
||||||
- name: create
|
- name: create
|
||||||
decort_osimage:
|
decort_image:
|
||||||
authenticator: oauth2
|
authenticator: oauth2
|
||||||
verify_ssl: False
|
verify_ssl: False
|
||||||
controller_url: "https://ds1.digitalenergy.online"
|
controller_url: "https://ds1.digitalenergy.online"
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
#
|
#
|
||||||
# DECORT osimage module example
|
# DECORT image module example
|
||||||
#
|
#
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
tasks:
|
tasks:
|
||||||
- name: create_virtual_osimage
|
- name: create_virtual_image
|
||||||
decort_osimage:
|
decort_image:
|
||||||
authenticator: oauth2
|
authenticator: oauth2
|
||||||
controller_url: "https://ds1.digitalenergy.online"
|
controller_url: "https://ds1.digitalenergy.online"
|
||||||
image_name: "alpine_linux_3.14.0"
|
image_name: "alpine_linux_3.14.0"
|
||||||
virt_name: "alpine_last"
|
virt_name: "alpine_last"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
register: osimage
|
register: image
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
#
|
#
|
||||||
# DECORT osimage module example
|
# DECORT image module example
|
||||||
#
|
#
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
tasks:
|
tasks:
|
||||||
- name: get_osimage
|
- name: get_image
|
||||||
decort_osimage:
|
decort_image:
|
||||||
authenticator: oauth2
|
authenticator: oauth2
|
||||||
controller_url: "https://ds1.digitalenergy.online"
|
controller_url: "https://ds1.digitalenergy.online"
|
||||||
image_name: "alpine_linux_3.14.0"
|
image_name: "alpine_linux_3.14.0"
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
#
|
#
|
||||||
# DECORT osimage module example
|
# DECORT image module example
|
||||||
#
|
#
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
tasks:
|
tasks:
|
||||||
- name: rename_osimage
|
- name: rename_image
|
||||||
decort_osimage:
|
decort_image:
|
||||||
authenticator: oauth2
|
authenticator: oauth2
|
||||||
controller_url: "https://ds1.digitalenergy.online"
|
controller_url: "https://ds1.digitalenergy.online"
|
||||||
image_name: "alpine_linux_3.14.0v2.0"
|
image_name: "alpine_linux_3.14.0v2.0"
|
||||||
image_id: 54321
|
image_id: 54321
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
register: osimage
|
register: image
|
||||||
@@ -62,6 +62,10 @@ class DecortAccount(DecortController):
|
|||||||
name=dict(
|
name=dict(
|
||||||
type='str',
|
type='str',
|
||||||
),
|
),
|
||||||
|
get_resource_consumption=dict(
|
||||||
|
type='bool',
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
quotas=dict(
|
quotas=dict(
|
||||||
type='dict',
|
type='dict',
|
||||||
options=dict(
|
options=dict(
|
||||||
@@ -71,9 +75,6 @@ class DecortAccount(DecortController):
|
|||||||
disks_size=dict(
|
disks_size=dict(
|
||||||
type='int',
|
type='int',
|
||||||
),
|
),
|
||||||
ext_traffic=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
gpu=dict(
|
gpu=dict(
|
||||||
type='int',
|
type='int',
|
||||||
),
|
),
|
||||||
@@ -94,7 +95,6 @@ class DecortAccount(DecortController):
|
|||||||
'disabled',
|
'disabled',
|
||||||
'present',
|
'present',
|
||||||
],
|
],
|
||||||
default='present',
|
|
||||||
),
|
),
|
||||||
sep_pools=dict(
|
sep_pools=dict(
|
||||||
type='list',
|
type='list',
|
||||||
@@ -131,7 +131,7 @@ class DecortAccount(DecortController):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
arg_state = self.aparams['state']
|
arg_state = self.aparams['state']
|
||||||
if 'absent' in arg_state:
|
if arg_state is not None and 'absent' in arg_state:
|
||||||
# Parameters or combinations of parameters that can
|
# Parameters or combinations of parameters that can
|
||||||
# cause changing the object.
|
# cause changing the object.
|
||||||
changing_params = [
|
changing_params = [
|
||||||
@@ -175,6 +175,7 @@ class DecortAccount(DecortController):
|
|||||||
if check_error:
|
if check_error:
|
||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.get_info()
|
self.get_info()
|
||||||
self.check_amodule_args_for_change()
|
self.check_amodule_args_for_change()
|
||||||
@@ -187,6 +188,7 @@ class DecortAccount(DecortController):
|
|||||||
self.acc_id, self._acc_info = self.account_find(
|
self.acc_id, self._acc_info = self.account_find(
|
||||||
account_name=self.aparams['name'],
|
account_name=self.aparams['name'],
|
||||||
account_id=self.aparams['id'],
|
account_id=self.aparams['id'],
|
||||||
|
resource_consumption=self.aparams['get_resource_consumption'],
|
||||||
)
|
)
|
||||||
# If this is a repeated getting info
|
# If this is a repeated getting info
|
||||||
else:
|
else:
|
||||||
@@ -195,6 +197,9 @@ class DecortAccount(DecortController):
|
|||||||
if not self.amodule.check_mode:
|
if not self.amodule.check_mode:
|
||||||
self.acc_id, self._acc_info = self.account_find(
|
self.acc_id, self._acc_info = self.account_find(
|
||||||
account_id=self.acc_id,
|
account_id=self.acc_id,
|
||||||
|
resource_consumption=(
|
||||||
|
self.aparams['get_resource_consumption']
|
||||||
|
),
|
||||||
)
|
)
|
||||||
self.facts = self.acc_info
|
self.facts = self.acc_info
|
||||||
|
|
||||||
@@ -361,7 +366,6 @@ class DecortAccount(DecortController):
|
|||||||
quotas_naming = [
|
quotas_naming = [
|
||||||
['cpu', 'CU_C', 'cpu_quota'],
|
['cpu', 'CU_C', 'cpu_quota'],
|
||||||
['disks_size', 'CU_DM', 'disks_size_quota'],
|
['disks_size', 'CU_DM', 'disks_size_quota'],
|
||||||
['ext_traffic', 'CU_NP', 'ext_traffic_quota'],
|
|
||||||
['gpu', 'gpu_units', 'gpu_quota'],
|
['gpu', 'gpu_units', 'gpu_quota'],
|
||||||
['public_ip', 'CU_I', 'public_ip_quota'],
|
['public_ip', 'CU_I', 'public_ip_quota'],
|
||||||
['ram', 'CU_M', 'ram_quota'],
|
['ram', 'CU_M', 'ram_quota'],
|
||||||
|
|||||||
@@ -8,565 +8,46 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
|
||||||
|
|
||||||
|
|
||||||
class DecortAccountInfo(DecortController):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(AnsibleModule(**self.amodule_init_args))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def amodule_init_args(self) -> dict:
|
|
||||||
return self.pack_amodule_init_args(
|
|
||||||
argument_spec=dict(
|
|
||||||
audits=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False
|
|
||||||
),
|
|
||||||
computes=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
ext_net_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
ext_net_name=dict(
|
|
||||||
type='str'
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
ip=dict(
|
|
||||||
type='str'
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str'
|
|
||||||
),
|
|
||||||
rg_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
rg_name=dict(
|
|
||||||
type='str'
|
|
||||||
),
|
|
||||||
tech_status=dict(
|
|
||||||
type='str',
|
|
||||||
choices=self.COMPUTE_TECH_STATUSES,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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_COMPUTE_LIST, # noqa: E501
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
disks=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
type=dict(
|
|
||||||
type='str',
|
|
||||||
choices=self.DISK_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_DISK_LIST, # noqa: E501
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
flip_groups=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
ext_net_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
ip=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
vins_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
vins_name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
images=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
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, # noqa: E501
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
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, # noqa: E501
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
resource_consumption=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False
|
|
||||||
),
|
|
||||||
vinses=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
ext_ip=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str'
|
|
||||||
),
|
|
||||||
rg_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_VINS_LIST, # noqa: E501
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
mutually_exclusive=[
|
|
||||||
('id', 'name')
|
|
||||||
],
|
|
||||||
required_one_of=[
|
|
||||||
('id', 'name')
|
|
||||||
],
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_computes_args(self) -> None | dict:
|
|
||||||
"""
|
|
||||||
Map the module argument `computes` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.account_computes`
|
|
||||||
(excluding for `account_id`).
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['computes']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
if input_args['filter']:
|
|
||||||
mapped_args['compute_id'] = input_args['filter']['id']
|
|
||||||
mapped_args['compute_ip'] = input_args['filter']['ip']
|
|
||||||
mapped_args['compute_name'] = input_args['filter']['name']
|
|
||||||
mapped_args['compute_tech_status'] =\
|
|
||||||
input_args['filter']['tech_status']
|
|
||||||
mapped_args['ext_net_id'] = input_args['filter']['ext_net_id']
|
|
||||||
mapped_args['ext_net_name'] =\
|
|
||||||
input_args['filter']['ext_net_name']
|
|
||||||
mapped_args['rg_id'] = input_args['filter']['rg_id']
|
|
||||||
mapped_args['rg_name'] = input_args['filter']['rg_name']
|
|
||||||
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_disks_args(self) -> None | dict:
|
|
||||||
"""
|
|
||||||
Map the module argument `disks` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.account_disks`
|
|
||||||
(excluding for `account_id`).
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['disks']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
if input_args['filter']:
|
|
||||||
mapped_args['disk_id'] = input_args['filter']['id']
|
|
||||||
mapped_args['disk_name'] = input_args['filter']['name']
|
|
||||||
mapped_args['disk_size'] = input_args['filter']['size']
|
|
||||||
mapped_args['disk_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_flip_groups_args(self) -> None | dict:
|
|
||||||
"""
|
|
||||||
Map the module argument `flip_groups` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.account_flip_groups`
|
|
||||||
(excluding for `account_id`).
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['flip_groups']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
if input_args['filter']:
|
|
||||||
mapped_args['ext_net_id'] = input_args['filter']['ext_net_id']
|
|
||||||
mapped_args['flig_group_id'] = input_args['filter']['id']
|
|
||||||
mapped_args['flig_group_ip'] = input_args['filter']['ip']
|
|
||||||
mapped_args['flig_group_name'] = input_args['filter']['name']
|
|
||||||
mapped_args['vins_id'] = input_args['filter']['vins_id']
|
|
||||||
mapped_args['vins_name'] = input_args['filter']['vins_name']
|
|
||||||
if input_args['pagination']:
|
|
||||||
mapped_args['page_number'] =\
|
|
||||||
input_args['pagination']['number']
|
|
||||||
mapped_args['page_size'] =\
|
|
||||||
input_args['pagination']['size']
|
|
||||||
|
|
||||||
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.aparams['images']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
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:
|
|
||||||
"""
|
|
||||||
Map the module argument `resource_groups` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.account_resource_groups`
|
|
||||||
(excluding for `account_id`).
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['resource_groups']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
if input_args['filter']:
|
|
||||||
mapped_args['rg_id'] =\
|
|
||||||
input_args['filter']['id']
|
|
||||||
mapped_args['rg_name'] =\
|
|
||||||
input_args['filter']['name']
|
|
||||||
mapped_args['rg_status'] =\
|
|
||||||
input_args['filter']['status']
|
|
||||||
mapped_args['vins_id'] =\
|
|
||||||
input_args['filter']['vins_id']
|
|
||||||
mapped_args['vm_id'] =\
|
|
||||||
input_args['filter']['vm_id']
|
|
||||||
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_vinses_args(self) -> None | dict:
|
|
||||||
"""
|
|
||||||
Map the module argument `vinses` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.account_vinses`
|
|
||||||
(excluding for `account_id`).
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['vinses']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
if input_args['filter']:
|
|
||||||
mapped_args['vins_id'] = input_args['filter']['id']
|
|
||||||
mapped_args['vins_name'] = input_args['filter']['name']
|
|
||||||
mapped_args['ext_ip'] = input_args['filter']['ext_ip']
|
|
||||||
mapped_args['rg_id'] = input_args['filter']['rg_id']
|
|
||||||
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
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.get_info()
|
|
||||||
self.exit()
|
|
||||||
|
|
||||||
def get_info(self):
|
|
||||||
self.id, self.facts = self.account_find(
|
|
||||||
account_name=self.aparams['name'],
|
|
||||||
account_id=self.aparams['id'],
|
|
||||||
audits=self.aparams['audits'],
|
|
||||||
computes_args=self.mapped_computes_args,
|
|
||||||
disks_args=self.mapped_disks_args,
|
|
||||||
flip_groups_args=self.mapped_flip_groups_args,
|
|
||||||
images_args=self.mapped_images_args,
|
|
||||||
resource_consumption=self.aparams['resource_consumption'],
|
|
||||||
resource_groups_args=self.mapped_rg_args,
|
|
||||||
vinses_args=self.mapped_vinses_args,
|
|
||||||
fail_if_not_found=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
DecortAccountInfo().run()
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
app_id=dict(type='raw'),
|
||||||
|
app_secret=dict(type='raw'),
|
||||||
|
authenticator=dict(type='raw'),
|
||||||
|
controller_url=dict(type='raw'),
|
||||||
|
domain=dict(type='raw'),
|
||||||
|
jwt=dict(type='raw'),
|
||||||
|
oauth2_url=dict(type='raw'),
|
||||||
|
password=dict(type='raw'),
|
||||||
|
username=dict(type='raw'),
|
||||||
|
verify_ssl=dict(type='raw'),
|
||||||
|
ignore_api_compatibility=dict(type='raw'),
|
||||||
|
ignore_sdk_version_check=dict(type='raw'),
|
||||||
|
audits=dict(type='raw'),
|
||||||
|
computes=dict(type='raw'),
|
||||||
|
disks=dict(type='raw'),
|
||||||
|
flip_groups=dict(type='raw'),
|
||||||
|
id=dict(type='raw'),
|
||||||
|
images=dict(type='raw'),
|
||||||
|
name=dict(type='raw'),
|
||||||
|
resource_groups=dict(type='raw'),
|
||||||
|
resource_consumption=dict(type='raw'),
|
||||||
|
vinses=dict(type='raw'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
module.fail_json(
|
||||||
|
msg=(
|
||||||
|
'The functionality of the module has been moved to the modules '
|
||||||
|
'"decort_disk_list", "decort_rg_list", "decort_vm_list", '
|
||||||
|
'"decort_vins_list", "decort_image_list", '
|
||||||
|
'"decort_flip_group_list", "decort_account".'
|
||||||
|
'\nPlease use the new modules to get information about the objects'
|
||||||
|
' available to the account.'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
130
library/decort_account_list.py
Normal file
130
library/decort_account_list.py
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_account_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortAccountList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
access_type=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.AccessType._member_names_,
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.AccountStatus._member_names_,
|
||||||
|
),
|
||||||
|
zone_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.AccountForCAAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_access_type: str | None = aparam_filter['access_type']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.AccountForCAAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.account.list(
|
||||||
|
access_type=(
|
||||||
|
sdk_types.AccessType[aparam_access_type]
|
||||||
|
if aparam_access_type else None
|
||||||
|
),
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
status=(
|
||||||
|
sdk_types.AccountStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
zone_id=aparam_filter['zone_id'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortAccountList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
168
library/decort_audit_list.py
Normal file
168
library/decort_audit_list.py
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_audit_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortAuditList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
api_url_path=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
bservice_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
exclude_audit_lines=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
flip_group_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
request_id=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
k8s_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
lb_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
max_status_code=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
min_status_code=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
request_timestamp_end=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
request_timestamp_start=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
rg_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
sep_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
user_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
vins_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
vm_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.AuditAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.AuditAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.audit.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
api_url_path=aparam_filter['api_url_path'],
|
||||||
|
bservice_id=aparam_filter['bservice_id'],
|
||||||
|
exclude_audit_lines=aparam_filter['exclude_audit_lines'] or False,
|
||||||
|
flip_group_id=aparam_filter['flip_group_id'],
|
||||||
|
request_id=aparam_filter['request_id'],
|
||||||
|
k8s_id=aparam_filter['k8s_id'],
|
||||||
|
lb_id=aparam_filter['lb_id'],
|
||||||
|
max_status_code=aparam_filter['max_status_code'],
|
||||||
|
min_status_code=aparam_filter['min_status_code'],
|
||||||
|
request_timestamp_end=aparam_filter['request_timestamp_end'],
|
||||||
|
request_timestamp_start=aparam_filter['request_timestamp_start'],
|
||||||
|
rg_id=aparam_filter['rg_id'],
|
||||||
|
sep_id=aparam_filter['sep_id'],
|
||||||
|
user_name=aparam_filter['user_name'],
|
||||||
|
vins_id=aparam_filter['vins_id'],
|
||||||
|
vm_id=aparam_filter['vm_id'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortAuditList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -114,6 +114,8 @@ class decort_bservice(DecortController):
|
|||||||
if self.bservice_id:
|
if self.bservice_id:
|
||||||
_, self.bservice_info = self.bservice_get_by_id(self.bservice_id)
|
_, self.bservice_info = self.bservice_get_by_id(self.bservice_id)
|
||||||
self.bservice_state(self.bservice_info, self.aparams['state'])
|
self.bservice_state(self.bservice_info, self.aparams['state'])
|
||||||
|
|
||||||
|
self.bservice_should_exist = True
|
||||||
return
|
return
|
||||||
|
|
||||||
def action(self,d_state):
|
def action(self,d_state):
|
||||||
@@ -259,76 +261,80 @@ class decort_bservice(DecortController):
|
|||||||
if check_errors:
|
if check_errors:
|
||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
amodule = self.amodule
|
||||||
|
|
||||||
|
if self.amodule.check_mode:
|
||||||
|
self.result['changed'] = False
|
||||||
|
if self.bservice_id:
|
||||||
|
self.result['failed'] = False
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
# we exit the module at this point
|
||||||
|
else:
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = ("Cannot locate B-service name '{}'. Other arguments are: B-service ID {}, "
|
||||||
|
"RG name '{}', RG ID {}, Account '{}'.").format(amodule.params['name'],
|
||||||
|
amodule.params['id'],
|
||||||
|
amodule.params['rg_name'],
|
||||||
|
amodule.params['rg_id'],
|
||||||
|
amodule.params['account_name'])
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#MAIN MANAGE PART
|
||||||
|
|
||||||
|
if self.bservice_id:
|
||||||
|
if self.bservice_info['status'] in ("DELETING","DESTROYNG","RECONFIGURING","DESTROYING",
|
||||||
|
"ENABLING","DISABLING","RESTORING","MODELED"):
|
||||||
|
self.error()
|
||||||
|
elif self.bservice_info['status'] == "DELETED":
|
||||||
|
if amodule.params['state'] in (
|
||||||
|
'disabled', 'enabled', 'present', 'started', 'stopped'
|
||||||
|
):
|
||||||
|
self.restore(self.bservice_id)
|
||||||
|
self.action(amodule.params['state'])
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
elif self.bservice_info['status'] in (
|
||||||
|
'ENABLED', 'DISABLED', 'CREATED',
|
||||||
|
):
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.destroy()
|
||||||
|
else:
|
||||||
|
self.action(amodule.params['state'])
|
||||||
|
elif self.bservice_info['status'] == "DESTROYED":
|
||||||
|
if amodule.params['state'] in ('present','enabled'):
|
||||||
|
self.create()
|
||||||
|
self.action(amodule.params['state'])
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
else:
|
||||||
|
state = amodule.params['state']
|
||||||
|
if state is None:
|
||||||
|
state = 'present'
|
||||||
|
if state == 'absent':
|
||||||
|
self.nop()
|
||||||
|
if state in ('present','started'):
|
||||||
|
self.create()
|
||||||
|
elif state in ('stopped', 'disabled','enabled'):
|
||||||
|
self.error()
|
||||||
|
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.bservice_should_exist:
|
||||||
|
_, self.bservice_info = self.bservice_get_by_id(self.bservice_id)
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
else:
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
subj = decort_bservice()
|
decort_bservice().run()
|
||||||
amodule = subj.amodule
|
|
||||||
|
|
||||||
if subj.amodule.check_mode:
|
|
||||||
subj.result['changed'] = False
|
|
||||||
if subj.bservice_id:
|
|
||||||
subj.result['failed'] = False
|
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
# we exit the module at this point
|
|
||||||
else:
|
|
||||||
subj.result['failed'] = True
|
|
||||||
subj.result['msg'] = ("Cannot locate B-service name '{}'. Other arguments are: B-service ID {}, "
|
|
||||||
"RG name '{}', RG ID {}, Account '{}'.").format(amodule.params['name'],
|
|
||||||
amodule.params['id'],
|
|
||||||
amodule.params['rg_name'],
|
|
||||||
amodule.params['rg_id'],
|
|
||||||
amodule.params['account_name'])
|
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
#MAIN MANAGE PART
|
|
||||||
|
|
||||||
if subj.bservice_id:
|
|
||||||
if subj.bservice_info['status'] in ("DELETING","DESTROYNG","RECONFIGURING","DESTROYING",
|
|
||||||
"ENABLING","DISABLING","RESTORING","MODELED"):
|
|
||||||
subj.error()
|
|
||||||
elif subj.bservice_info['status'] == "DELETED":
|
|
||||||
if amodule.params['state'] in (
|
|
||||||
'disabled', 'enabled', 'present', 'started', 'stopped'
|
|
||||||
):
|
|
||||||
subj.restore(subj.bservice_id)
|
|
||||||
subj.action(amodule.params['state'])
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
elif subj.bservice_info['status'] in (
|
|
||||||
'ENABLED', 'DISABLED', 'CREATED',
|
|
||||||
):
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.destroy()
|
|
||||||
else:
|
|
||||||
subj.action(amodule.params['state'])
|
|
||||||
elif subj.bservice_info['status'] == "DESTROYED":
|
|
||||||
if amodule.params['state'] in ('present','enabled'):
|
|
||||||
subj.create()
|
|
||||||
subj.action(amodule.params['state'])
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
else:
|
|
||||||
state = amodule.params['state']
|
|
||||||
if state is None:
|
|
||||||
state = 'present'
|
|
||||||
if state == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
if state in ('present','started'):
|
|
||||||
subj.create()
|
|
||||||
elif state in ('stopped', 'disabled','enabled'):
|
|
||||||
subj.error()
|
|
||||||
|
|
||||||
if subj.result['failed']:
|
if __name__ == '__main__':
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
else:
|
|
||||||
if subj.bservice_should_exist:
|
|
||||||
_, subj.bservice_info = subj.bservice_get_by_id(subj.bservice_id)
|
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
else:
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -73,81 +73,124 @@ class decort_disk(DecortController):
|
|||||||
else:
|
else:
|
||||||
self.check_amodule_args_for_create()
|
self.check_amodule_args_for_create()
|
||||||
|
|
||||||
|
def compare_iotune_params(self, new_iotune: dict, current_iotune: dict):
|
||||||
|
io_fields = sdk_types.IOTuneAPIResultNM.model_fields.keys()
|
||||||
|
|
||||||
|
for field in io_fields:
|
||||||
|
new_value = new_iotune.get(field)
|
||||||
|
current_value = current_iotune.get(field)
|
||||||
|
|
||||||
|
if new_value != current_value:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def limit_io(self, aparam_limit_io: dict):
|
||||||
|
self.sdk_checkmode(self.api.cloudapi.disks.limit_io)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
read_bytes_sec_max=(aparam_limit_io.get('read_bytes_sec_max')),
|
||||||
|
read_bytes_sec=(aparam_limit_io.get('read_bytes_sec')),
|
||||||
|
read_iops_sec_max=(aparam_limit_io.get('read_iops_sec_max')),
|
||||||
|
read_iops_sec=(aparam_limit_io.get('read_iops_sec')),
|
||||||
|
size_iops_sec=(aparam_limit_io.get('size_iops_sec')),
|
||||||
|
total_bytes_sec_max=(aparam_limit_io.get('total_bytes_sec_max')),
|
||||||
|
total_bytes_sec=(aparam_limit_io.get('total_bytes_sec')),
|
||||||
|
total_iops_sec_max=(aparam_limit_io.get('total_iops_sec_max')),
|
||||||
|
total_iops_sec=(aparam_limit_io.get('total_iops_sec')),
|
||||||
|
write_bytes_sec_max=(aparam_limit_io.get('write_bytes_sec_max')),
|
||||||
|
write_bytes_sec=(aparam_limit_io.get('write_bytes_sec')),
|
||||||
|
write_iops_sec_max=(aparam_limit_io.get('write_iops_sec_max')),
|
||||||
|
write_iops_sec=(aparam_limit_io.get('write_iops_sec')),
|
||||||
|
)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self.disk_id = self.disk_create(
|
self.disk_id = self.sdk_checkmode(self.api.cloudapi.disks.create)(
|
||||||
accountId=self.acc_id,
|
account_id=self.acc_id,
|
||||||
name = self.amodule.params['name'],
|
name=self.amodule.params['name'],
|
||||||
description=self.amodule.params['description'],
|
size_gb=self.amodule.params['size'],
|
||||||
size=self.amodule.params['size'],
|
|
||||||
sep_id=self.amodule.params['sep_id'],
|
|
||||||
pool=self.amodule.params['pool'],
|
|
||||||
storage_policy_id=self.aparams['storage_policy_id'],
|
storage_policy_id=self.aparams['storage_policy_id'],
|
||||||
|
description=self.amodule.params['description'],
|
||||||
|
sep_id=self.amodule.params['sep_id'],
|
||||||
|
sep_pool_name=self.amodule.params['pool'],
|
||||||
)
|
)
|
||||||
#IO tune
|
#IO tune
|
||||||
if self.amodule.params['limitIO']:
|
aparam_limit_io: dict[str, int | None] = self.amodule.params['limitIO']
|
||||||
self.disk_limitIO(disk_id=self.disk_id,
|
self.limit_io(aparam_limit_io=aparam_limit_io)
|
||||||
limits=self.amodule.params['limitIO'])
|
|
||||||
#set share status
|
#set share status
|
||||||
if self.amodule.params['shareable']:
|
if self.amodule.params['shareable']:
|
||||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
self.sdk_checkmode(self.api.cloudapi.disks.share)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def action(self,restore=False):
|
def action(self,restore=False):
|
||||||
|
|
||||||
#restore never be done
|
#restore never be done
|
||||||
if restore:
|
if restore:
|
||||||
self.disk_restore(self.disk_id)
|
self.sdk_checkmode(self.api.cloudapi.disks.restore)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
)
|
||||||
#rename if id present
|
#rename if id present
|
||||||
if (
|
if (
|
||||||
self.amodule.params['name'] is not None
|
self.amodule.params['name'] is not None
|
||||||
and self.amodule.params['name'] != self.disk_info['name']
|
and self.amodule.params['name'] != self.disk_info['name']
|
||||||
):
|
):
|
||||||
self.disk_rename(disk_id=self.disk_id,
|
self.rename()
|
||||||
name=self.amodule.params['name'])
|
|
||||||
#resize
|
#resize
|
||||||
if (
|
if (
|
||||||
self.amodule.params['size'] is not None
|
self.amodule.params['size'] is not None
|
||||||
and self.amodule.params['size'] != self.disk_info['sizeMax']
|
and self.amodule.params['size'] != self.disk_info['sizeMax']
|
||||||
):
|
):
|
||||||
self.disk_resize(self.disk_info,self.amodule.params['size'])
|
self.sdk_checkmode(self.api.cloudapi.disks.resize2)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
disk_size_gb=self.amodule.params['size'],
|
||||||
|
)
|
||||||
#IO TUNE
|
#IO TUNE
|
||||||
if self.amodule.params['limitIO']:
|
aparam_limit_io: dict[str, int | None] = self.amodule.params['limitIO']
|
||||||
clean_io = [param for param in self.amodule.params['limitIO'] \
|
if aparam_limit_io:
|
||||||
if self.amodule.params['limitIO'][param] == None]
|
if not self.compare_iotune_params(
|
||||||
for key in clean_io: del self.amodule.params['limitIO'][key]
|
new_iotune=aparam_limit_io,
|
||||||
if self.amodule.params['limitIO'] != self.disk_info['iotune']:
|
current_iotune=self.disk_info['iotune'],
|
||||||
self.disk_limitIO(self.disk_id,self.amodule.params['limitIO'])
|
):
|
||||||
|
self.limit_io(aparam_limit_io=aparam_limit_io)
|
||||||
|
|
||||||
#share check/update
|
#share check/update
|
||||||
#raise Exception(self.amodule.params['shareable'])
|
#raise Exception(self.amodule.params['shareable'])
|
||||||
if self.amodule.params['shareable'] != self.disk_info['shareable']:
|
if self.amodule.params['shareable'] != self.disk_info['shareable']:
|
||||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
if self.amodule.params['shareable']:
|
||||||
|
self.sdk_checkmode(self.api.cloudapi.disks.share)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.sdk_checkmode(self.api.cloudapi.disks.unshare)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
|
)
|
||||||
|
|
||||||
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
||||||
if (
|
if (
|
||||||
aparam_storage_policy_id is not None
|
aparam_storage_policy_id is not None
|
||||||
and aparam_storage_policy_id != self.disk_info['storage_policy_id']
|
and aparam_storage_policy_id != self.disk_info['storage_policy_id']
|
||||||
):
|
):
|
||||||
self.disk_change_storage_policy(
|
self.sdk_checkmode(self.api.ca.disks.change_disk_storage_policy)(
|
||||||
disk_id=self.disk_id,
|
disk_id=self.disk_id,
|
||||||
storage_policy_id=aparam_storage_policy_id,
|
storage_policy_id=aparam_storage_policy_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
self.disk_delete(disk_id=self.disk_id,
|
self.sdk_checkmode(self.api.cloudapi.disks.delete)(
|
||||||
detach=self.amodule.params['force_detach'],
|
disk_id=self.disk_id,
|
||||||
permanently=self.amodule.params['permanently'],
|
detach=self.amodule.params['force_detach'],
|
||||||
reason=self.amodule.params['reason'])
|
permanently=self.amodule.params['permanently'],
|
||||||
|
)
|
||||||
self.disk_id, self.disk_info = self._disk_get_by_id(self.disk_id)
|
self.disk_id, self.disk_info = self._disk_get_by_id(self.disk_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
def rename(self):
|
def rename(self):
|
||||||
|
self.sdk_checkmode(self.api.cloudapi.disks.rename)(
|
||||||
|
disk_id=self.disk_id,
|
||||||
self.disk_rename(diskId = self.disk_id,
|
name=self.amodule.params['name'],
|
||||||
name = self.amodule.params['name'])
|
)
|
||||||
self.disk_info['name'] = self.amodule.params['name']
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def nop(self):
|
def nop(self):
|
||||||
@@ -194,6 +237,8 @@ class decort_disk(DecortController):
|
|||||||
ret_dict['size_used'] = self.disk_info['sizeUsed']
|
ret_dict['size_used'] = self.disk_info['sizeUsed']
|
||||||
ret_dict['storage_policy_id'] = self.disk_info['storage_policy_id']
|
ret_dict['storage_policy_id'] = self.disk_info['storage_policy_id']
|
||||||
ret_dict['to_clean'] = self.disk_info['to_clean']
|
ret_dict['to_clean'] = self.disk_info['to_clean']
|
||||||
|
ret_dict['cache_mode'] = self.disk_info['cache']
|
||||||
|
ret_dict['blkdiscard'] = self.disk_info['blkdiscard']
|
||||||
|
|
||||||
return ret_dict
|
return ret_dict
|
||||||
|
|
||||||
@@ -240,6 +285,7 @@ class decort_disk(DecortController):
|
|||||||
),
|
),
|
||||||
limitIO=dict(
|
limitIO=dict(
|
||||||
type='dict',
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
options=dict(
|
options=dict(
|
||||||
total_bytes_sec=dict(
|
total_bytes_sec=dict(
|
||||||
type='int',
|
type='int',
|
||||||
@@ -290,10 +336,6 @@ class decort_disk(DecortController):
|
|||||||
type='bool',
|
type='bool',
|
||||||
default=False,
|
default=False,
|
||||||
),
|
),
|
||||||
reason=dict(
|
|
||||||
type='str',
|
|
||||||
default='Managed by Ansible decort_disk',
|
|
||||||
),
|
|
||||||
state=dict(
|
state=dict(
|
||||||
type='str',
|
type='str',
|
||||||
default='present',
|
default='present',
|
||||||
@@ -379,57 +421,60 @@ class decort_disk(DecortController):
|
|||||||
|
|
||||||
return not check_errors
|
return not check_errors
|
||||||
|
|
||||||
def main():
|
@DecortController.handle_sdk_exceptions
|
||||||
decon = decort_disk()
|
def run(self):
|
||||||
amodule = decon.amodule
|
#
|
||||||
#
|
#Full range of Disk status is as follows:
|
||||||
#Full range of Disk status is as follows:
|
#
|
||||||
#
|
# "ASSIGNED","MODELED", "CREATING","CREATED","DELETED", "DESTROYED","PURGED",
|
||||||
# "ASSIGNED","MODELED", "CREATING","CREATED","DELETED", "DESTROYED","PURGED",
|
#
|
||||||
#
|
amodule = self.amodule
|
||||||
if decon.disk_id:
|
if self.disk_id:
|
||||||
#disk exist
|
#disk exist
|
||||||
if decon.disk_info['status'] in ["MODELED", "CREATING"]:
|
if self.disk_info['status'] in ["MODELED", "CREATING"]:
|
||||||
decon.result['failed'] = True
|
self.result['failed'] = True
|
||||||
decon.result['changed'] = False
|
self.result['changed'] = False
|
||||||
decon.result['msg'] = ("No change can be done for existing Disk ID {} because of its current "
|
self.result['msg'] = ("No change can be done for existing Disk ID {} because of its current "
|
||||||
"status '{}'").format(decon.disk_id, decon.disk_info['status'])
|
"status '{}'").format(self.disk_id, self.disk_info['status'])
|
||||||
# "ASSIGNED","CREATED","DELETED","PURGED", "DESTROYED"
|
# "ASSIGNED","CREATED","DELETED","PURGED", "DESTROYED"
|
||||||
elif decon.disk_info['status'] in ["ASSIGNED","CREATED"]:
|
elif self.disk_info['status'] in ["ASSIGNED","CREATED"]:
|
||||||
if amodule.params['state'] == 'absent':
|
if amodule.params['state'] == 'absent':
|
||||||
decon.delete()
|
self.delete()
|
||||||
elif amodule.params['state'] == 'present':
|
elif amodule.params['state'] == 'present':
|
||||||
decon.action()
|
self.action()
|
||||||
elif decon.disk_info['status'] in ["PURGED", "DESTROYED"]:
|
elif self.disk_info['status'] in ["PURGED", "DESTROYED"]:
|
||||||
#re-provision disk
|
#re-provision disk
|
||||||
if amodule.params['state'] in ('present'):
|
if amodule.params['state'] in ('present'):
|
||||||
decon.create()
|
self.create()
|
||||||
else:
|
else:
|
||||||
decon.nop()
|
self.nop()
|
||||||
elif decon.disk_info['status'] == "DELETED":
|
elif self.disk_info['status'] == "DELETED":
|
||||||
if amodule.params['state'] in ('present'):
|
if amodule.params['state'] in ('present'):
|
||||||
decon.action(restore=True)
|
self.action(restore=True)
|
||||||
elif (amodule.params['state'] == 'absent' and
|
elif (amodule.params['state'] == 'absent' and
|
||||||
amodule.params['permanently']):
|
amodule.params['permanently']):
|
||||||
decon.delete()
|
self.delete()
|
||||||
else:
|
else:
|
||||||
decon.nop()
|
self.nop()
|
||||||
else:
|
|
||||||
# preexisting Disk was not found
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
decon.nop()
|
|
||||||
else:
|
else:
|
||||||
decon.create()
|
# preexisting Disk was not found
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
else:
|
||||||
|
self.create()
|
||||||
|
|
||||||
if decon.result['failed']:
|
if self.result['failed']:
|
||||||
amodule.fail_json(**decon.result)
|
amodule.fail_json(**self.result)
|
||||||
else:
|
else:
|
||||||
if decon.result['changed']:
|
if self.result['changed']:
|
||||||
_, decon.disk_info = decon.disk_find(decon.disk_id)
|
_, self.disk_info = self.disk_find(self.disk_id)
|
||||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
amodule.exit_json(**decon.result)
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
def main():
|
||||||
|
decort_disk().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
#SHARE
|
|
||||||
|
|||||||
155
library/decort_disk_list.py
Normal file
155
library/decort_disk_list.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_disk_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortDiskList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
account_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
sep_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
sep_pool_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
shared=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
disk_max_size_gb=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.DiskStatus._member_names_,
|
||||||
|
),
|
||||||
|
storage_policy_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
type=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.DiskType._member_names_,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.DiskForListAndListDeletedAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_type: str | None = aparam_filter['type']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.DiskForListAndListDeletedAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.disks.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
account_name=aparam_filter['account_name'],
|
||||||
|
disk_max_size_gb=aparam_filter['disk_max_size_gb'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
sep_id=aparam_filter['sep_id'],
|
||||||
|
sep_pool_name=aparam_filter['sep_pool_name'],
|
||||||
|
shared=aparam_filter['shared'],
|
||||||
|
status=(
|
||||||
|
sdk_types.DiskStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
storage_policy_id=aparam_filter['storage_policy_id'],
|
||||||
|
type=(
|
||||||
|
sdk_types.DiskType[aparam_type]
|
||||||
|
if aparam_type else None
|
||||||
|
),
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortDiskList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
150
library/decort_flip_group_list.py
Normal file
150
library/decort_flip_group_list.py
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_flip_group_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortFlipGroupList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
client_ids=dict(
|
||||||
|
type='list',
|
||||||
|
elements='int',
|
||||||
|
),
|
||||||
|
conn_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
ext_net_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
include_deleted=dict(
|
||||||
|
type='bool',
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
ip_addr=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.FlipGroupStatus._member_names_,
|
||||||
|
),
|
||||||
|
vins_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
vins_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.FlipGroupForListAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.FlipGroupForListAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.flipgroup.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
client_ids=aparam_filter['client_ids'],
|
||||||
|
conn_id=aparam_filter['conn_id'],
|
||||||
|
ext_net_id=aparam_filter['ext_net_id'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
ip_addr=aparam_filter['ip_addr'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
status=(
|
||||||
|
sdk_types.FlipGroupStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
vins_id=aparam_filter['vins_id'],
|
||||||
|
vins_name=aparam_filter['vins_name'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortFlipGroupList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -81,24 +81,13 @@ class decort_group(DecortController):
|
|||||||
def create(self):
|
def create(self):
|
||||||
chipset = self.aparams['chipset']
|
chipset = self.aparams['chipset']
|
||||||
if chipset is None:
|
if chipset is None:
|
||||||
chipset = 'i440fx'
|
chipset = 'Q35'
|
||||||
self.message(
|
self.message(
|
||||||
msg=f'Chipset not specified, '
|
msg=f'Chipset not specified, '
|
||||||
f'default value "{chipset}" will be used.',
|
f'default value "{chipset}" will be used.',
|
||||||
warning=True,
|
warning=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
driver = self.aparams['driver']
|
|
||||||
if driver is None:
|
|
||||||
driver = 'KVM_X86'
|
|
||||||
self.message(
|
|
||||||
msg=self.MESSAGES.default_value_used(
|
|
||||||
param_name='driver',
|
|
||||||
default_value=driver,
|
|
||||||
),
|
|
||||||
warning=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.group_id=self.group_provision(
|
self.group_id=self.group_provision(
|
||||||
bs_id=self.bservice_id,
|
bs_id=self.bservice_id,
|
||||||
arg_name=self.amodule.params['name'],
|
arg_name=self.amodule.params['name'],
|
||||||
@@ -112,7 +101,6 @@ class decort_group(DecortController):
|
|||||||
arg_timeout=self.amodule.params['timeoutStart'],
|
arg_timeout=self.amodule.params['timeoutStart'],
|
||||||
chipset=chipset,
|
chipset=chipset,
|
||||||
storage_policy_id=self.aparams['storage_policy_id'],
|
storage_policy_id=self.aparams['storage_policy_id'],
|
||||||
driver=driver,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.amodule.params['state'] in ('started','present'):
|
if self.amodule.params['state'] in ('started','present'):
|
||||||
@@ -296,9 +284,6 @@ class decort_group(DecortController):
|
|||||||
storage_policy_id=dict(
|
storage_policy_id=dict(
|
||||||
type='int',
|
type='int',
|
||||||
),
|
),
|
||||||
driver=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
required_one_of=[
|
required_one_of=[
|
||||||
@@ -354,17 +339,6 @@ class decort_group(DecortController):
|
|||||||
f'disk ID {disk['id']}'
|
f'disk ID {disk['id']}'
|
||||||
)
|
)
|
||||||
|
|
||||||
aparam_driver = self.aparams['driver']
|
|
||||||
if (
|
|
||||||
aparam_driver is not None
|
|
||||||
and aparam_driver != self.group_info['driver']
|
|
||||||
):
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "driver" failed: '
|
|
||||||
'driver can not be changed'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_errors:
|
if check_errors:
|
||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
@@ -405,54 +379,59 @@ class decort_group(DecortController):
|
|||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
@DecortController.handle_sdk_exceptions
|
||||||
subj = decort_group()
|
def run(self):
|
||||||
amodule = subj.amodule
|
amodule = self.amodule
|
||||||
|
|
||||||
if amodule.params['state'] == 'check':
|
if amodule.params['state'] == 'check':
|
||||||
subj.result['changed'] = False
|
self.result['changed'] = False
|
||||||
if subj.group_id:
|
if self.group_id:
|
||||||
# cluster is found - package facts and report success to Ansible
|
# cluster is found - package facts and report success to Ansible
|
||||||
subj.result['failed'] = False
|
self.result['failed'] = False
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
amodule.exit_json(**subj.result)
|
amodule.exit_json(**self.result)
|
||||||
# we exit the module at this point
|
# we exit the module at this point
|
||||||
else:
|
|
||||||
subj.result['failed'] = True
|
|
||||||
subj.result['msg'] = ("Cannot locate Group name '{}'. "
|
|
||||||
"B-service ID {}").format(amodule.params['name'],
|
|
||||||
amodule.params['bservice_id'],)
|
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
|
|
||||||
if subj.group_id:
|
|
||||||
if subj.group_info['status'] in ("DELETING","DESTROYNG","CREATING","DESTROYING",
|
|
||||||
"ENABLING","DISABLING","RESTORING","MODELED","DESTROYED"):
|
|
||||||
subj.error()
|
|
||||||
elif subj.group_info['status'] in ("DELETED","DESTROYED"):
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
if amodule.params['state'] in ('present','started','stopped'):
|
|
||||||
subj.create()
|
|
||||||
elif subj.group_info['techStatus'] in ("STARTED","STOPPED"):
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.destroy()
|
|
||||||
else:
|
else:
|
||||||
subj.action()
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = ("Cannot locate Group name '{}'. "
|
||||||
|
"B-service ID {}").format(amodule.params['name'],
|
||||||
|
amodule.params['bservice_id'],)
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
|
||||||
|
if self.group_id:
|
||||||
|
if self.group_info['status'] in ("DELETING","DESTROYNG","CREATING","DESTROYING",
|
||||||
|
"ENABLING","DISABLING","RESTORING","MODELED","DESTROYED"):
|
||||||
|
self.error()
|
||||||
|
elif self.group_info['status'] in ("DELETED","DESTROYED"):
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
if amodule.params['state'] in ('present','started','stopped'):
|
||||||
|
self.create()
|
||||||
|
elif self.group_info['techStatus'] in ("STARTED","STOPPED"):
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.destroy()
|
||||||
|
else:
|
||||||
|
self.action()
|
||||||
|
|
||||||
else:
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
if amodule.params['state'] in ('present','started','stopped'):
|
|
||||||
subj.create()
|
|
||||||
|
|
||||||
if subj.result['failed']:
|
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
else:
|
|
||||||
if subj.group_should_exist:
|
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
else:
|
else:
|
||||||
amodule.exit_json(**subj.result)
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
if amodule.params['state'] in ('present','started','stopped'):
|
||||||
|
self.create()
|
||||||
|
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.group_should_exist:
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
else:
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
def main():
|
||||||
|
decort_group().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
558
library/decort_image.py
Normal file
558
library/decort_image.py
Normal file
@@ -0,0 +1,558 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_image
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home).
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
|
from ansible.module_utils.decort_utils import *
|
||||||
|
|
||||||
|
|
||||||
|
class decort_image(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super(decort_image, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
amodule = self.amodule
|
||||||
|
|
||||||
|
self.validated_image_id = 0
|
||||||
|
self.validated_virt_image_id = 0
|
||||||
|
self.validated_image_name = amodule.params['image_name']
|
||||||
|
self.validated_virt_image_name = None
|
||||||
|
self.image_info: dict
|
||||||
|
self.virt_image_info: dict
|
||||||
|
if amodule.params['account_name']:
|
||||||
|
self.validated_account_id, _ = self.account_find(amodule.params['account_name'])
|
||||||
|
else:
|
||||||
|
self.validated_account_id = amodule.params['account_id']
|
||||||
|
|
||||||
|
if self.validated_account_id == 0:
|
||||||
|
# we failed either to find or access the specified account - fail the module
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['changed'] = False
|
||||||
|
self.result['msg'] = ("Cannot find account '{}'").format(amodule.params['account_name'])
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
self.acc_id = self.validated_account_id
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.aparams['virt_id'] != 0
|
||||||
|
or self.aparams['virt_name'] is not None
|
||||||
|
):
|
||||||
|
self.validated_virt_image_id, self.virt_image_info = (
|
||||||
|
self.decort_virt_image_find(amodule)
|
||||||
|
)
|
||||||
|
if self.virt_image_info:
|
||||||
|
_, linked_image_info = self._image_get_by_id(
|
||||||
|
image_id=self.virt_image_info['linkTo']
|
||||||
|
)
|
||||||
|
self.acc_id = linked_image_info['accountId']
|
||||||
|
if (
|
||||||
|
self.aparams['virt_name'] is not None
|
||||||
|
and self.aparams['virt_name']
|
||||||
|
!= self.virt_image_info['name']
|
||||||
|
):
|
||||||
|
self.decort_virt_image_rename(amodule)
|
||||||
|
self.result['msg'] = 'Virtual image renamed successfully'
|
||||||
|
elif (
|
||||||
|
self.aparams['image_id'] != 0
|
||||||
|
or self.aparams['image_name'] is not None
|
||||||
|
):
|
||||||
|
self.validated_image_id, self.image_info = (
|
||||||
|
self.decort_image_find(amodule)
|
||||||
|
)
|
||||||
|
if self.image_info:
|
||||||
|
self.acc_id = self.image_info['accountId']
|
||||||
|
if (
|
||||||
|
amodule.params['image_name']
|
||||||
|
and amodule.params['image_name'] != self.image_info['name']
|
||||||
|
):
|
||||||
|
decort_image.decort_image_rename(self,amodule)
|
||||||
|
self.result['msg'] = ("Image renamed successfully")
|
||||||
|
|
||||||
|
if self.validated_image_id:
|
||||||
|
self.check_amodule_args_for_change()
|
||||||
|
elif self.validated_virt_image_id:
|
||||||
|
self.check_amodule_args_for_change_virt_image()
|
||||||
|
elif self.aparams['virt_name']:
|
||||||
|
self.check_amodule_args_for_create_virt_image()
|
||||||
|
else:
|
||||||
|
self.check_amodule_args_for_create_image()
|
||||||
|
|
||||||
|
def decort_image_find(self, amodule):
|
||||||
|
# function that finds the OS image
|
||||||
|
image_id, image_facts = self.image_find(image_id=amodule.params['image_id'], image_name=self.validated_image_name,
|
||||||
|
account_id=self.validated_account_id, rg_id=0,
|
||||||
|
sepid=amodule.params['sep_id'],
|
||||||
|
pool=amodule.params['pool'])
|
||||||
|
return image_id, image_facts
|
||||||
|
|
||||||
|
def decort_virt_image_find(self, amodule):
|
||||||
|
# function that finds a virtual image
|
||||||
|
image_id, image_facts = self.virt_image_find(image_id=amodule.params['virt_id'],
|
||||||
|
account_id=self.validated_account_id, rg_id=0,
|
||||||
|
sepid=amodule.params['sep_id'],
|
||||||
|
virt_name=amodule.params['virt_name'],
|
||||||
|
pool=amodule.params['pool'])
|
||||||
|
return image_id, image_facts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def decort_image_create(self,amodule):
|
||||||
|
aparam_boot = self.aparams['boot']
|
||||||
|
boot_mode = 'bios'
|
||||||
|
loader_type = 'unknown'
|
||||||
|
if aparam_boot is not None:
|
||||||
|
if aparam_boot['mode'] is None:
|
||||||
|
self.message(
|
||||||
|
msg=self.MESSAGES.default_value_used(
|
||||||
|
param_name='boot.mode',
|
||||||
|
default_value=boot_mode
|
||||||
|
),
|
||||||
|
warning=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
boot_mode = aparam_boot['mode']
|
||||||
|
|
||||||
|
if aparam_boot['loader_type'] is None:
|
||||||
|
self.message(
|
||||||
|
msg=self.MESSAGES.default_value_used(
|
||||||
|
param_name='boot.loader_type',
|
||||||
|
default_value=loader_type
|
||||||
|
),
|
||||||
|
warning=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
loader_type = aparam_boot['loader_type']
|
||||||
|
|
||||||
|
network_interface_naming = self.aparams['network_interface_naming']
|
||||||
|
if network_interface_naming is None:
|
||||||
|
network_interface_naming = 'ens'
|
||||||
|
self.message(
|
||||||
|
msg=self.MESSAGES.default_value_used(
|
||||||
|
param_name='network_interface_naming',
|
||||||
|
default_value=network_interface_naming
|
||||||
|
),
|
||||||
|
warning=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
hot_resize = self.aparams['hot_resize']
|
||||||
|
if hot_resize is None:
|
||||||
|
hot_resize = False
|
||||||
|
self.message(
|
||||||
|
msg=self.MESSAGES.default_value_used(
|
||||||
|
param_name='hot_resize',
|
||||||
|
default_value=hot_resize
|
||||||
|
),
|
||||||
|
warning=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# function that creates OS image
|
||||||
|
image_facts = self.image_create(
|
||||||
|
img_name=self.validated_image_name,
|
||||||
|
url=amodule.params['url'],
|
||||||
|
boot_mode=boot_mode,
|
||||||
|
boot_loader_type=loader_type,
|
||||||
|
hot_resize=hot_resize,
|
||||||
|
username=amodule.params['image_username'],
|
||||||
|
password=amodule.params['image_password'],
|
||||||
|
account_id=self.validated_account_id,
|
||||||
|
usernameDL=amodule.params['usernameDL'],
|
||||||
|
passwordDL=amodule.params['passwordDL'],
|
||||||
|
sepId=amodule.params['sepId'],
|
||||||
|
poolName=amodule.params['poolName'],
|
||||||
|
network_interface_naming=network_interface_naming,
|
||||||
|
storage_policy_id=amodule.params['storage_policy_id'],
|
||||||
|
)
|
||||||
|
self.result['changed'] = True
|
||||||
|
return image_facts
|
||||||
|
|
||||||
|
def decort_virt_image_link(self,amodule):
|
||||||
|
# function that links an OS image to a virtual one
|
||||||
|
self.virt_image_link(imageId=self.validated_virt_image_id, targetId=self.target_image_id)
|
||||||
|
image_id, image_facts = decort_image.decort_virt_image_find(self, amodule)
|
||||||
|
self.result['facts'] = decort_image.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
self.result['msg'] = ("Image '{}' linked to virtual image '{}'").format(self.target_image_id,
|
||||||
|
decort_image.decort_image_package_facts(image_facts)['id'],)
|
||||||
|
return image_id, image_facts
|
||||||
|
|
||||||
|
def decort_image_delete(self,amodule):
|
||||||
|
# function that removes an image
|
||||||
|
self.image_delete(imageId=amodule.image_id_delete)
|
||||||
|
_, image_facts = decort_image._image_get_by_id(self, amodule.image_id_delete)
|
||||||
|
self.result['facts'] = decort_image.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
return
|
||||||
|
|
||||||
|
def decort_virt_image_create(self,amodule):
|
||||||
|
# function that creates a virtual image
|
||||||
|
image_facts = self.virt_image_create(
|
||||||
|
name=amodule.params['virt_name'],
|
||||||
|
target_id=self.target_image_id,
|
||||||
|
account_id=self.aparams['account_id'],
|
||||||
|
)
|
||||||
|
image_id, image_facts = decort_image.decort_virt_image_find(self, amodule)
|
||||||
|
self.result['facts'] = decort_image.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
return image_id, image_facts
|
||||||
|
|
||||||
|
def decort_image_rename(self,amodule):
|
||||||
|
# image renaming function
|
||||||
|
image_facts = self.image_rename(imageId=self.validated_image_id, name=amodule.params['image_name'])
|
||||||
|
self.result['msg'] = ("Image renamed successfully")
|
||||||
|
image_id, image_facts = decort_image.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
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def decort_image_package_facts(
|
||||||
|
arg_image_facts: dict | None,
|
||||||
|
arg_check_mode=False,
|
||||||
|
):
|
||||||
|
"""Package a dictionary of OS image according to the decort_image module specification. This
|
||||||
|
dictionary will be returned to the upstream Ansible engine at the completion of the module run.
|
||||||
|
|
||||||
|
@param arg_image_facts: dictionary with OS image facts as returned by API call to .../images/list
|
||||||
|
@param arg_check_mode: boolean that tells if this Ansible module is run in check mode.
|
||||||
|
|
||||||
|
@return: dictionary with OS image specs populated from arg_image_facts.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ret_dict = dict(id=0,
|
||||||
|
name="none",
|
||||||
|
size=0,
|
||||||
|
type="none",
|
||||||
|
state="CHECK_MODE", )
|
||||||
|
|
||||||
|
if arg_check_mode:
|
||||||
|
# in check mode return immediately with the default values
|
||||||
|
return ret_dict
|
||||||
|
|
||||||
|
if arg_image_facts is None:
|
||||||
|
# if void facts provided - change state value to ABSENT and return
|
||||||
|
ret_dict['state'] = "ABSENT"
|
||||||
|
return ret_dict
|
||||||
|
|
||||||
|
ret_dict['id'] = arg_image_facts['id']
|
||||||
|
ret_dict['name'] = arg_image_facts['name']
|
||||||
|
ret_dict['size'] = arg_image_facts['size']
|
||||||
|
# ret_dict['arch'] = arg_image_facts['architecture']
|
||||||
|
ret_dict['sep_id'] = arg_image_facts['sepId']
|
||||||
|
ret_dict['pool'] = arg_image_facts['pool']
|
||||||
|
ret_dict['state'] = arg_image_facts['status']
|
||||||
|
ret_dict['linkto'] = arg_image_facts['linkTo']
|
||||||
|
ret_dict['accountId'] = arg_image_facts['accountId']
|
||||||
|
ret_dict['boot_mode'] = arg_image_facts['bootType']
|
||||||
|
|
||||||
|
ret_dict['boot_loader_type'] = ''
|
||||||
|
match arg_image_facts['type']:
|
||||||
|
case 'cdrom' | 'virtual' as type:
|
||||||
|
ret_dict['type'] = type
|
||||||
|
case _ as boot_loader_type:
|
||||||
|
ret_dict['type'] = 'template'
|
||||||
|
ret_dict['boot_loader_type'] = boot_loader_type
|
||||||
|
|
||||||
|
ret_dict['network_interface_naming'] = arg_image_facts[
|
||||||
|
'networkInterfaceNaming'
|
||||||
|
]
|
||||||
|
ret_dict['hot_resize'] = arg_image_facts['hotResize']
|
||||||
|
ret_dict['storage_policy_id'] = arg_image_facts['storage_policy_id']
|
||||||
|
ret_dict['to_clean'] = arg_image_facts['to_clean']
|
||||||
|
return ret_dict
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
pool=dict(
|
||||||
|
type='str',
|
||||||
|
default='',
|
||||||
|
),
|
||||||
|
sep_id=dict(
|
||||||
|
type='int',
|
||||||
|
default=0,
|
||||||
|
),
|
||||||
|
account_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
image_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
image_id=dict(
|
||||||
|
type='int',
|
||||||
|
default=0,
|
||||||
|
),
|
||||||
|
virt_id=dict(
|
||||||
|
type='int',
|
||||||
|
default=0,
|
||||||
|
),
|
||||||
|
virt_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
state=dict(
|
||||||
|
type='str',
|
||||||
|
default='present',
|
||||||
|
choices=[
|
||||||
|
'absent',
|
||||||
|
'present',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
url=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
sepId=dict(
|
||||||
|
type='int',
|
||||||
|
default=0,
|
||||||
|
),
|
||||||
|
poolName=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
hot_resize=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
image_username=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
image_password=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
usernameDL=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
passwordDL=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
boot=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
mode=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
'bios',
|
||||||
|
'uefi',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
loader_type=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
'windows',
|
||||||
|
'linux',
|
||||||
|
'unknown',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
network_interface_naming=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
'ens',
|
||||||
|
'eth',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
storage_policy_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_amodule_args_for_change(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
||||||
|
if (
|
||||||
|
aparam_storage_policy_id is not None
|
||||||
|
and aparam_storage_policy_id
|
||||||
|
not in self.acc_info['storage_policy_ids']
|
||||||
|
):
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "storage_policy_id" failed: '
|
||||||
|
f'Account ID {self.acc_id} does not have access to '
|
||||||
|
f'storage_policy_id {aparam_storage_policy_id}'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
def check_amodule_args_for_change_virt_image(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
||||||
|
if (
|
||||||
|
aparam_storage_policy_id is not None
|
||||||
|
and (
|
||||||
|
aparam_storage_policy_id
|
||||||
|
!= self.virt_image_info['storage_policy_id']
|
||||||
|
)
|
||||||
|
):
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "storage_policy_id" failed: '
|
||||||
|
'storage_policy_id can not be changed in virtual image'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
def check_amodule_args_for_create_image(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_account_id = self.aparams['account_id']
|
||||||
|
if aparam_account_id is None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "account_id" failed: '
|
||||||
|
'account_id must be specified when creating '
|
||||||
|
'a new image'
|
||||||
|
)
|
||||||
|
|
||||||
|
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
||||||
|
if aparam_storage_policy_id is None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "storage_policy_id" failed: '
|
||||||
|
'storage_policy_id must be specified when creating '
|
||||||
|
'a new image'
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
aparam_storage_policy_id
|
||||||
|
not in self.acc_info['storage_policy_ids']
|
||||||
|
):
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "storage_policy_id" failed: '
|
||||||
|
f'Account ID {self.acc_id} does not have access to '
|
||||||
|
f'storage_policy_id {aparam_storage_policy_id}'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
def check_amodule_args_for_create_virt_image(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
||||||
|
if aparam_storage_policy_id is not None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "storage_policy_id" failed: '
|
||||||
|
'storage_policy_id can not be specified when creating '
|
||||||
|
'virtual image'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
amodule = self.amodule
|
||||||
|
if amodule.params['virt_name'] or amodule.params['virt_id']:
|
||||||
|
|
||||||
|
image_id, image_facts = self.decort_virt_image_find(amodule)
|
||||||
|
if amodule.params['image_name'] or amodule.params['image_id']:
|
||||||
|
self.target_image_id, _ = self.decort_image_find(amodule)
|
||||||
|
else:
|
||||||
|
self.target_image_id = 0
|
||||||
|
if self.decort_image_package_facts(image_facts)['id'] > 0:
|
||||||
|
self.result['facts'] = self.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
self.validated_virt_image_id = self.decort_image_package_facts(image_facts)['id']
|
||||||
|
self.validated_virt_image_name = self.decort_image_package_facts(image_facts)['name']
|
||||||
|
|
||||||
|
if self.decort_image_package_facts(image_facts)['id'] == 0 and amodule.params['state'] == "present" and self.target_image_id > 0:
|
||||||
|
image_id, image_facts = self.decort_virt_image_create(amodule)
|
||||||
|
self.result['msg'] = ("Virtual image '{}' created").format(self.decort_image_package_facts(image_facts)['id'])
|
||||||
|
self.result['changed'] = True
|
||||||
|
elif self.decort_image_package_facts(image_facts)['id'] == 0 and amodule.params['state'] == "present" and self.target_image_id == 0:
|
||||||
|
self.result['msg'] = ("Cannot find OS image")
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
|
||||||
|
if self.validated_virt_image_id:
|
||||||
|
if (
|
||||||
|
self.target_image_id
|
||||||
|
and self.decort_image_package_facts(image_facts)[
|
||||||
|
'linkto'
|
||||||
|
] != self.target_image_id
|
||||||
|
):
|
||||||
|
self.decort_virt_image_link(amodule)
|
||||||
|
self.result['changed'] = True
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
if (
|
||||||
|
amodule.params['storage_policy_id'] is not None
|
||||||
|
and amodule.params['storage_policy_id']
|
||||||
|
!= image_facts['storage_policy_id']
|
||||||
|
):
|
||||||
|
self.image_change_storage_policy(
|
||||||
|
image_id=self.validated_virt_image_id,
|
||||||
|
storage_policy_id=amodule.params['storage_policy_id'],
|
||||||
|
)
|
||||||
|
|
||||||
|
if amodule.params['state'] == "absent" and self.validated_virt_image_id:
|
||||||
|
amodule.image_id_delete = self.validated_virt_image_id
|
||||||
|
image_id, image_facts = self.decort_virt_image_find(amodule)
|
||||||
|
if image_facts['status'] != 'PURGED':
|
||||||
|
self.decort_image_delete(amodule)
|
||||||
|
|
||||||
|
elif amodule.params['image_name'] or amodule.params['image_id']:
|
||||||
|
image_id, image_facts = self.decort_image_find(amodule)
|
||||||
|
self.validated_image_id = self.decort_image_package_facts(image_facts)['id']
|
||||||
|
if self.decort_image_package_facts(image_facts)['id'] > 0:
|
||||||
|
self.result['facts'] = self.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
|
||||||
|
if amodule.params['state'] == "present" and self.validated_image_id == 0 and amodule.params['image_name'] and amodule.params['url']:
|
||||||
|
self.decort_image_create(amodule)
|
||||||
|
self.result['changed'] = True
|
||||||
|
image_id, image_facts = self.decort_image_find(amodule)
|
||||||
|
self.result['msg'] = ("OS image '{}' created").format(self.decort_image_package_facts(image_facts)['id'])
|
||||||
|
self.result['facts'] = self.decort_image_package_facts(image_facts, amodule.check_mode)
|
||||||
|
self.validated_image_id = self.decort_image_package_facts(image_facts)['id']
|
||||||
|
|
||||||
|
elif amodule.params['state'] == "absent" and self.validated_image_id:
|
||||||
|
amodule.image_id_delete = self.validated_image_id
|
||||||
|
image_id, image_facts = self.decort_image_find(amodule)
|
||||||
|
if image_facts['status'] != 'DESTROYED':
|
||||||
|
self.decort_image_delete(amodule)
|
||||||
|
|
||||||
|
if self.validated_image_id:
|
||||||
|
if (
|
||||||
|
amodule.params['storage_policy_id'] is not None
|
||||||
|
and amodule.params['storage_policy_id']
|
||||||
|
!= image_facts['storage_policy_id']
|
||||||
|
):
|
||||||
|
self.image_change_storage_policy(
|
||||||
|
image_id=self.validated_image_id,
|
||||||
|
storage_policy_id=amodule.params['storage_policy_id'],
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.result['failed'] == True:
|
||||||
|
# we failed to find the specified image - fail the module
|
||||||
|
self.result['changed'] = False
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.validated_image_id:
|
||||||
|
_, image_facts = self.decort_image_find(amodule=amodule)
|
||||||
|
elif self.validated_virt_image_id:
|
||||||
|
_, image_facts = self.decort_virt_image_find(amodule=amodule)
|
||||||
|
self.result['facts'] = self.decort_image_package_facts(
|
||||||
|
arg_image_facts=image_facts,
|
||||||
|
arg_check_mode=amodule.check_mode,
|
||||||
|
)
|
||||||
|
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
decort_image().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
162
library/decort_image_list.py
Normal file
162
library/decort_image_list.py
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_image_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortImageList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
bootable=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
enabled=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
hot_resize=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
size_gb=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
public=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
sep_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
sep_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
sep_pool_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.ImageStatus._member_names_,
|
||||||
|
),
|
||||||
|
type=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.ImageType._member_names_,
|
||||||
|
),
|
||||||
|
storage_policy_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.ImageForListAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_type: str | None = aparam_filter['type']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.ImageForListAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.ca.image.list(
|
||||||
|
bootable=aparam_filter['bootable'],
|
||||||
|
enabled=aparam_filter['enabled'],
|
||||||
|
hot_resize=aparam_filter['hot_resize'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
public=aparam_filter['public'],
|
||||||
|
sep_id=aparam_filter['sep_id'],
|
||||||
|
sep_name=aparam_filter['sep_name'],
|
||||||
|
sep_pool_name=aparam_filter['sep_pool_name'],
|
||||||
|
size_gb=aparam_filter['size_gb'],
|
||||||
|
status=(
|
||||||
|
sdk_types.ImageStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
storage_policy_id=aparam_filter['storage_policy_id'],
|
||||||
|
type=(
|
||||||
|
sdk_types.ImageType[aparam_type]
|
||||||
|
if aparam_type else None
|
||||||
|
),
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortImageList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -25,6 +25,7 @@ class DecortJWT(DecortController):
|
|||||||
|
|
||||||
return amodule_init_args
|
return amodule_init_args
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.result['jwt'] = self.jwt
|
self.result['jwt'] = self.jwt
|
||||||
self.amodule.exit_json(**self.result)
|
self.amodule.exit_json(**self.result)
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ class decort_k8s(DecortController):
|
|||||||
'taints': [],
|
'taints': [],
|
||||||
'annotations': [],
|
'annotations': [],
|
||||||
'ci_user_data': {},
|
'ci_user_data': {},
|
||||||
'chipset': 'i440fx',
|
'chipset': 'Q35',
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg_amodule.params['name'] == "" and arg_amodule.params['id'] is None:
|
if arg_amodule.params['name'] is None and arg_amodule.params['id'] is None:
|
||||||
self.result['failed'] = True
|
self.result['failed'] = True
|
||||||
self.result['changed'] = False
|
self.result['changed'] = False
|
||||||
self.result['msg'] = "Cannot manage k8s cluster when its ID is 0 and name is empty."
|
self.result['msg'] = "Cannot manage k8s cluster when its ID is 0 and name is empty."
|
||||||
@@ -158,7 +158,7 @@ class decort_k8s(DecortController):
|
|||||||
def create(self):
|
def create(self):
|
||||||
master_chipset = self.amodule.params['master_chipset']
|
master_chipset = self.amodule.params['master_chipset']
|
||||||
if master_chipset is None:
|
if master_chipset is None:
|
||||||
master_chipset = 'i440fx'
|
master_chipset = 'Q35'
|
||||||
|
|
||||||
target_wgs = deepcopy(self.amodule.params['workers'])
|
target_wgs = deepcopy(self.amodule.params['workers'])
|
||||||
for wg in target_wgs:
|
for wg in target_wgs:
|
||||||
@@ -301,7 +301,6 @@ class decort_k8s(DecortController):
|
|||||||
),
|
),
|
||||||
name=dict(
|
name=dict(
|
||||||
type='str',
|
type='str',
|
||||||
default='',
|
|
||||||
),
|
),
|
||||||
id=dict(
|
id=dict(
|
||||||
type='int',
|
type='int',
|
||||||
@@ -598,67 +597,72 @@ class decort_k8s(DecortController):
|
|||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
@DecortController.handle_sdk_exceptions
|
||||||
subj = decort_k8s()
|
def run(self):
|
||||||
amodule = subj.amodule
|
amodule = self.amodule
|
||||||
|
|
||||||
if subj.amodule.check_mode:
|
if self.amodule.check_mode:
|
||||||
subj.result['changed'] = False
|
self.result['changed'] = False
|
||||||
if subj.k8s_id:
|
if self.k8s_id:
|
||||||
# cluster is found - package facts and report success to Ansible
|
# cluster is found - package facts and report success to Ansible
|
||||||
subj.result['failed'] = False
|
self.result['failed'] = False
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
amodule.exit_json(**subj.result)
|
amodule.exit_json(**self.result)
|
||||||
# we exit the module at this point
|
# we exit the module at this point
|
||||||
else:
|
|
||||||
subj.result['failed'] = True
|
|
||||||
subj.result['msg'] = ("Cannot locate K8s cluster name '{}'. "
|
|
||||||
"RG ID {}").format(amodule.params['name'],
|
|
||||||
amodule.params['rg_id'],)
|
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
|
|
||||||
if subj.k8s_id:
|
|
||||||
if subj.k8s_info['status'] in ("DELETING","DESTROYNG","CREATING","DESTROYING",
|
|
||||||
"ENABLING","DISABLING","RESTORING","MODELED"):
|
|
||||||
subj.error()
|
|
||||||
elif subj.k8s_info['status'] == "DELETED":
|
|
||||||
if amodule.params['state'] in (
|
|
||||||
'disabled', 'enabled', 'present', 'started', 'stopped'
|
|
||||||
):
|
|
||||||
subj.k8s_restore(subj.k8s_id)
|
|
||||||
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['status'] in ('ENABLED', 'DISABLED'):
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.destroy()
|
|
||||||
else:
|
else:
|
||||||
subj.action(disared_state=amodule.params['state'])
|
self.result['failed'] = True
|
||||||
elif subj.k8s_info['status'] == "DESTROYED":
|
self.result['msg'] = ("Cannot locate K8s cluster name '{}'. "
|
||||||
if amodule.params['state'] in ('present','enabled'):
|
"RG ID {}").format(amodule.params['name'],
|
||||||
subj.create()
|
amodule.params['rg_id'],)
|
||||||
if amodule.params['state'] == 'absent':
|
amodule.fail_json(**self.result)
|
||||||
subj.nop()
|
|
||||||
else:
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
subj.nop()
|
|
||||||
if amodule.params['state'] in ('present','started'):
|
|
||||||
subj.create()
|
|
||||||
elif amodule.params['state'] in ('stopped', 'disabled','enabled'):
|
|
||||||
subj.error()
|
|
||||||
|
|
||||||
if subj.result['failed']:
|
|
||||||
amodule.fail_json(**subj.result)
|
|
||||||
else:
|
|
||||||
if subj.k8s_should_exist:
|
|
||||||
subj.result['facts'] = subj.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
else:
|
|
||||||
amodule.exit_json(**subj.result)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if self.k8s_id:
|
||||||
|
if self.k8s_info['status'] in ("DELETING","DESTROYNG","CREATING","DESTROYING",
|
||||||
|
"ENABLING","DISABLING","RESTORING","MODELED"):
|
||||||
|
self.error()
|
||||||
|
elif self.k8s_info['status'] == "DELETED":
|
||||||
|
if amodule.params['state'] in (
|
||||||
|
'disabled', 'enabled', 'present', 'started', 'stopped'
|
||||||
|
):
|
||||||
|
self.k8s_restore(self.k8s_id)
|
||||||
|
self.action(disared_state=amodule.params['state'],
|
||||||
|
preupdate=True)
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
if amodule.params['permanent']:
|
||||||
|
self.destroy()
|
||||||
|
else:
|
||||||
|
self.nop()
|
||||||
|
elif self.k8s_info['status'] in ('ENABLED', 'DISABLED'):
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.destroy()
|
||||||
|
else:
|
||||||
|
self.action(disared_state=amodule.params['state'])
|
||||||
|
elif self.k8s_info['status'] == "DESTROYED":
|
||||||
|
if amodule.params['state'] in ('present','enabled'):
|
||||||
|
self.create()
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
else:
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
if amodule.params['state'] in ('present','started'):
|
||||||
|
self.create()
|
||||||
|
elif amodule.params['state'] in ('stopped', 'disabled','enabled'):
|
||||||
|
self.error()
|
||||||
|
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.k8s_should_exist:
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
else:
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
decort_k8s().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -361,56 +361,60 @@ class decort_lb(DecortController):
|
|||||||
if check_errors:
|
if check_errors:
|
||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
amodule = self.amodule
|
||||||
|
if self.lb_id:
|
||||||
|
if self.lb_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING","DESTROYING","RESTORING"]:
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['changed'] = False
|
||||||
|
self.result['msg'] = ("No change can be done for existing LB ID {} because of its current "
|
||||||
|
"status '{}'").format(self.lb_id, self.lb_facts['status'])
|
||||||
|
elif self.lb_facts['status'] in ('DISABLED', 'ENABLED', 'CREATED'):
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.delete()
|
||||||
|
else:
|
||||||
|
self.action(d_state=amodule.params['state'])
|
||||||
|
elif self.lb_facts['status'] == "DELETED":
|
||||||
|
if amodule.params['state'] == 'present':
|
||||||
|
self.action(restore=True)
|
||||||
|
elif amodule.params['state'] == 'enabled':
|
||||||
|
self.action(d_state='enabled', restore=True)
|
||||||
|
elif (amodule.params['state'] == 'absent' and
|
||||||
|
amodule.params['permanently']):
|
||||||
|
self.delete()
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
self.error()
|
||||||
|
elif self.lb_facts['status'] == "DESTROYED":
|
||||||
|
if amodule.params['state'] in ('present', 'enabled'):
|
||||||
|
self.create()
|
||||||
|
elif amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
self.error()
|
||||||
|
else:
|
||||||
|
state = amodule.params['state']
|
||||||
|
if state is None:
|
||||||
|
state = 'present'
|
||||||
|
if state == 'absent':
|
||||||
|
self.nop()
|
||||||
|
elif state in ('present', 'enabled', 'stopped', 'started'):
|
||||||
|
self.create()
|
||||||
|
elif state == 'disabled':
|
||||||
|
self.error()
|
||||||
|
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.result['changed']:
|
||||||
|
_, self.lb_facts = self.lb_find(lb_id=self.lb_id)
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
decon = decort_lb()
|
decort_lb().run()
|
||||||
amodule = decon.amodule
|
|
||||||
if decon.lb_id:
|
|
||||||
if decon.lb_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING","DESTROYING","RESTORING"]:
|
|
||||||
decon.result['failed'] = True
|
|
||||||
decon.result['changed'] = False
|
|
||||||
decon.result['msg'] = ("No change can be done for existing LB ID {} because of its current "
|
|
||||||
"status '{}'").format(decon.lb_id, decon.lb_facts['status'])
|
|
||||||
elif decon.lb_facts['status'] in ('DISABLED', 'ENABLED', 'CREATED'):
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
decon.delete()
|
|
||||||
else:
|
|
||||||
decon.action(d_state=amodule.params['state'])
|
|
||||||
elif decon.lb_facts['status'] == "DELETED":
|
|
||||||
if amodule.params['state'] == 'present':
|
|
||||||
decon.action(restore=True)
|
|
||||||
elif amodule.params['state'] == 'enabled':
|
|
||||||
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()
|
|
||||||
elif decon.lb_facts['status'] == "DESTROYED":
|
|
||||||
if amodule.params['state'] in ('present', 'enabled'):
|
|
||||||
decon.create()
|
|
||||||
elif amodule.params['state'] == 'absent':
|
|
||||||
decon.nop()
|
|
||||||
elif amodule.params['state'] == 'disabled':
|
|
||||||
decon.error()
|
|
||||||
else:
|
|
||||||
state = amodule.params['state']
|
|
||||||
if state is None:
|
|
||||||
state = 'present'
|
|
||||||
if state == 'absent':
|
|
||||||
decon.nop()
|
|
||||||
elif state in ('present', 'enabled', 'stopped', 'started'):
|
|
||||||
decon.create()
|
|
||||||
elif state == 'disabled':
|
|
||||||
decon.error()
|
|
||||||
|
|
||||||
if decon.result['failed']:
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
else:
|
|
||||||
if decon.result['changed']:
|
|
||||||
_, decon.lb_facts = decon.lb_find(lb_id=decon.lb_id)
|
|
||||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**decon.result)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -4,552 +4,59 @@ DOCUMENTATION = r'''
|
|||||||
---
|
---
|
||||||
module: decort_osimage
|
module: decort_osimage
|
||||||
|
|
||||||
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home).
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.basic import env_fallback
|
|
||||||
|
|
||||||
from ansible.module_utils.decort_utils import *
|
|
||||||
|
|
||||||
|
|
||||||
class decort_osimage(DecortController):
|
|
||||||
def __init__(self):
|
|
||||||
super(decort_osimage, self).__init__(AnsibleModule(**self.amodule_init_args))
|
|
||||||
amodule = self.amodule
|
|
||||||
|
|
||||||
self.validated_image_id = 0
|
|
||||||
self.validated_virt_image_id = 0
|
|
||||||
self.validated_image_name = amodule.params['image_name']
|
|
||||||
self.validated_virt_image_name = None
|
|
||||||
self.image_info: dict
|
|
||||||
self.virt_image_info: dict
|
|
||||||
if amodule.params['account_name']:
|
|
||||||
self.validated_account_id, _ = self.account_find(amodule.params['account_name'])
|
|
||||||
else:
|
|
||||||
self.validated_account_id = amodule.params['account_id']
|
|
||||||
|
|
||||||
if self.validated_account_id == 0:
|
|
||||||
# we failed either to find or access the specified account - fail the module
|
|
||||||
self.result['failed'] = True
|
|
||||||
self.result['changed'] = False
|
|
||||||
self.result['msg'] = ("Cannot find account '{}'").format(amodule.params['account_name'])
|
|
||||||
amodule.fail_json(**self.result)
|
|
||||||
self.acc_id = self.validated_account_id
|
|
||||||
|
|
||||||
if (
|
|
||||||
self.aparams['virt_id'] != 0
|
|
||||||
or self.aparams['virt_name'] is not None
|
|
||||||
):
|
|
||||||
self.validated_virt_image_id, self.virt_image_info = (
|
|
||||||
self.decort_virt_image_find(amodule)
|
|
||||||
)
|
|
||||||
if self.virt_image_info:
|
|
||||||
_, linked_image_info = self._image_get_by_id(
|
|
||||||
image_id=self.virt_image_info['linkTo']
|
|
||||||
)
|
|
||||||
self.acc_id = linked_image_info['accountId']
|
|
||||||
if (
|
|
||||||
self.aparams['virt_name'] is not None
|
|
||||||
and self.aparams['virt_name']
|
|
||||||
!= self.virt_image_info['name']
|
|
||||||
):
|
|
||||||
self.decort_virt_image_rename(amodule)
|
|
||||||
self.result['msg'] = 'Virtual image renamed successfully'
|
|
||||||
elif (
|
|
||||||
self.aparams['image_id'] != 0
|
|
||||||
or self.aparams['image_name'] is not None
|
|
||||||
):
|
|
||||||
self.validated_image_id, self.image_info = (
|
|
||||||
self.decort_image_find(amodule)
|
|
||||||
)
|
|
||||||
if self.image_info:
|
|
||||||
self.acc_id = self.image_info['accountId']
|
|
||||||
if (
|
|
||||||
amodule.params['image_name']
|
|
||||||
and amodule.params['image_name'] != self.image_info['name']
|
|
||||||
):
|
|
||||||
decort_osimage.decort_image_rename(self,amodule)
|
|
||||||
self.result['msg'] = ("Image renamed successfully")
|
|
||||||
|
|
||||||
if self.validated_image_id:
|
|
||||||
self.check_amodule_args_for_change()
|
|
||||||
elif self.validated_virt_image_id:
|
|
||||||
self.check_amodule_args_for_change_virt_image()
|
|
||||||
elif self.aparams['virt_name']:
|
|
||||||
self.check_amodule_args_for_create_virt_image()
|
|
||||||
else:
|
|
||||||
self.check_amodule_args_for_create_image()
|
|
||||||
|
|
||||||
def decort_image_find(self, amodule):
|
|
||||||
# function that finds the OS image
|
|
||||||
image_id, image_facts = self.image_find(image_id=amodule.params['image_id'], image_name=self.validated_image_name,
|
|
||||||
account_id=self.validated_account_id, rg_id=0,
|
|
||||||
sepid=amodule.params['sep_id'],
|
|
||||||
pool=amodule.params['pool'])
|
|
||||||
return image_id, image_facts
|
|
||||||
|
|
||||||
def decort_virt_image_find(self, amodule):
|
|
||||||
# function that finds a virtual image
|
|
||||||
image_id, image_facts = self.virt_image_find(image_id=amodule.params['virt_id'],
|
|
||||||
account_id=self.validated_account_id, rg_id=0,
|
|
||||||
sepid=amodule.params['sep_id'],
|
|
||||||
virt_name=amodule.params['virt_name'],
|
|
||||||
pool=amodule.params['pool'])
|
|
||||||
return image_id, image_facts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def decort_image_create(self,amodule):
|
|
||||||
aparam_boot = self.aparams['boot']
|
|
||||||
boot_mode = 'bios'
|
|
||||||
loader_type = 'unknown'
|
|
||||||
if aparam_boot is not None:
|
|
||||||
if aparam_boot['mode'] is None:
|
|
||||||
self.message(
|
|
||||||
msg=self.MESSAGES.default_value_used(
|
|
||||||
param_name='boot.mode',
|
|
||||||
default_value=boot_mode
|
|
||||||
),
|
|
||||||
warning=True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
boot_mode = aparam_boot['mode']
|
|
||||||
|
|
||||||
if aparam_boot['loader_type'] is None:
|
|
||||||
self.message(
|
|
||||||
msg=self.MESSAGES.default_value_used(
|
|
||||||
param_name='boot.loader_type',
|
|
||||||
default_value=loader_type
|
|
||||||
),
|
|
||||||
warning=True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
loader_type = aparam_boot['loader_type']
|
|
||||||
|
|
||||||
network_interface_naming = self.aparams['network_interface_naming']
|
|
||||||
if network_interface_naming is None:
|
|
||||||
network_interface_naming = 'ens'
|
|
||||||
self.message(
|
|
||||||
msg=self.MESSAGES.default_value_used(
|
|
||||||
param_name='network_interface_naming',
|
|
||||||
default_value=network_interface_naming
|
|
||||||
),
|
|
||||||
warning=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
hot_resize = self.aparams['hot_resize']
|
|
||||||
if hot_resize is None:
|
|
||||||
hot_resize = False
|
|
||||||
self.message(
|
|
||||||
msg=self.MESSAGES.default_value_used(
|
|
||||||
param_name='hot_resize',
|
|
||||||
default_value=hot_resize
|
|
||||||
),
|
|
||||||
warning=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# function that creates OS image
|
|
||||||
image_facts = self.image_create(
|
|
||||||
img_name=self.validated_image_name,
|
|
||||||
url=amodule.params['url'],
|
|
||||||
boot_mode=boot_mode,
|
|
||||||
boot_loader_type=loader_type,
|
|
||||||
hot_resize=hot_resize,
|
|
||||||
username=amodule.params['image_username'],
|
|
||||||
password=amodule.params['image_password'],
|
|
||||||
account_id=self.validated_account_id,
|
|
||||||
usernameDL=amodule.params['usernameDL'],
|
|
||||||
passwordDL=amodule.params['passwordDL'],
|
|
||||||
sepId=amodule.params['sepId'],
|
|
||||||
poolName=amodule.params['poolName'],
|
|
||||||
network_interface_naming=network_interface_naming,
|
|
||||||
storage_policy_id=amodule.params['storage_policy_id'],
|
|
||||||
)
|
|
||||||
self.result['changed'] = True
|
|
||||||
return image_facts
|
|
||||||
|
|
||||||
def decort_virt_image_link(self,amodule):
|
|
||||||
# function that links an OS image to a virtual one
|
|
||||||
self.virt_image_link(imageId=self.validated_virt_image_id, targetId=self.target_image_id)
|
|
||||||
image_id, image_facts = decort_osimage.decort_virt_image_find(self, amodule)
|
|
||||||
self.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
|
|
||||||
self.result['msg'] = ("Image '{}' linked to virtual image '{}'").format(self.target_image_id,
|
|
||||||
decort_osimage.decort_osimage_package_facts(image_facts)['id'],)
|
|
||||||
return image_id, image_facts
|
|
||||||
|
|
||||||
def decort_image_delete(self,amodule):
|
|
||||||
# function that removes an image
|
|
||||||
self.image_delete(imageId=amodule.image_id_delete)
|
|
||||||
_, image_facts = decort_osimage._image_get_by_id(self, amodule.image_id_delete)
|
|
||||||
self.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
|
|
||||||
return
|
|
||||||
|
|
||||||
def decort_virt_image_create(self,amodule):
|
|
||||||
# function that creates a virtual image
|
|
||||||
image_facts = self.virt_image_create(
|
|
||||||
name=amodule.params['virt_name'],
|
|
||||||
target_id=self.target_image_id,
|
|
||||||
account_id=self.aparams['account_id'],
|
|
||||||
)
|
|
||||||
image_id, image_facts = decort_osimage.decort_virt_image_find(self, amodule)
|
|
||||||
self.result['facts'] = decort_osimage.decort_osimage_package_facts(image_facts, amodule.check_mode)
|
|
||||||
return image_id, image_facts
|
|
||||||
|
|
||||||
def decort_image_rename(self,amodule):
|
|
||||||
# image renaming function
|
|
||||||
image_facts = self.image_rename(imageId=self.validated_image_id, name=amodule.params['image_name'])
|
|
||||||
self.result['msg'] = ("Image renamed successfully")
|
|
||||||
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
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def decort_osimage_package_facts(
|
|
||||||
arg_osimage_facts: dict | None,
|
|
||||||
arg_check_mode=False,
|
|
||||||
):
|
|
||||||
"""Package a dictionary of OS image according to the decort_osimage module specification. This
|
|
||||||
dictionary will be returned to the upstream Ansible engine at the completion of the module run.
|
|
||||||
|
|
||||||
@param arg_osimage_facts: dictionary with OS image facts as returned by API call to .../images/list
|
|
||||||
@param arg_check_mode: boolean that tells if this Ansible module is run in check mode.
|
|
||||||
|
|
||||||
@return: dictionary with OS image specs populated from arg_osimage_facts.
|
|
||||||
"""
|
|
||||||
|
|
||||||
ret_dict = dict(id=0,
|
|
||||||
name="none",
|
|
||||||
size=0,
|
|
||||||
type="none",
|
|
||||||
state="CHECK_MODE", )
|
|
||||||
|
|
||||||
if arg_check_mode:
|
|
||||||
# in check mode return immediately with the default values
|
|
||||||
return ret_dict
|
|
||||||
|
|
||||||
if arg_osimage_facts is None:
|
|
||||||
# if void facts provided - change state value to ABSENT and return
|
|
||||||
ret_dict['state'] = "ABSENT"
|
|
||||||
return ret_dict
|
|
||||||
|
|
||||||
ret_dict['id'] = arg_osimage_facts['id']
|
|
||||||
ret_dict['name'] = arg_osimage_facts['name']
|
|
||||||
ret_dict['size'] = arg_osimage_facts['size']
|
|
||||||
# ret_dict['arch'] = arg_osimage_facts['architecture']
|
|
||||||
ret_dict['sep_id'] = arg_osimage_facts['sepId']
|
|
||||||
ret_dict['pool'] = arg_osimage_facts['pool']
|
|
||||||
ret_dict['state'] = arg_osimage_facts['status']
|
|
||||||
ret_dict['linkto'] = arg_osimage_facts['linkTo']
|
|
||||||
ret_dict['accountId'] = arg_osimage_facts['accountId']
|
|
||||||
ret_dict['boot_mode'] = arg_osimage_facts['bootType']
|
|
||||||
|
|
||||||
ret_dict['boot_loader_type'] = ''
|
|
||||||
match arg_osimage_facts['type']:
|
|
||||||
case 'cdrom' | 'virtual' as type:
|
|
||||||
ret_dict['type'] = type
|
|
||||||
case _ as boot_loader_type:
|
|
||||||
ret_dict['type'] = 'template'
|
|
||||||
ret_dict['boot_loader_type'] = boot_loader_type
|
|
||||||
|
|
||||||
ret_dict['network_interface_naming'] = arg_osimage_facts[
|
|
||||||
'networkInterfaceNaming'
|
|
||||||
]
|
|
||||||
ret_dict['hot_resize'] = arg_osimage_facts['hotResize']
|
|
||||||
ret_dict['storage_policy_id'] = arg_osimage_facts['storage_policy_id']
|
|
||||||
ret_dict['to_clean'] = arg_osimage_facts['to_clean']
|
|
||||||
return ret_dict
|
|
||||||
|
|
||||||
@property
|
|
||||||
def amodule_init_args(self) -> dict:
|
|
||||||
return self.pack_amodule_init_args(
|
|
||||||
argument_spec=dict(
|
|
||||||
pool=dict(
|
|
||||||
type='str',
|
|
||||||
default='',
|
|
||||||
),
|
|
||||||
sep_id=dict(
|
|
||||||
type='int',
|
|
||||||
default=0,
|
|
||||||
),
|
|
||||||
account_name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
account_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
image_name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
image_id=dict(
|
|
||||||
type='int',
|
|
||||||
default=0,
|
|
||||||
),
|
|
||||||
virt_id=dict(
|
|
||||||
type='int',
|
|
||||||
default=0,
|
|
||||||
),
|
|
||||||
virt_name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
state=dict(
|
|
||||||
type='str',
|
|
||||||
default='present',
|
|
||||||
choices=[
|
|
||||||
'absent',
|
|
||||||
'present',
|
|
||||||
],
|
|
||||||
),
|
|
||||||
url=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
sepId=dict(
|
|
||||||
type='int',
|
|
||||||
default=0,
|
|
||||||
),
|
|
||||||
poolName=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
hot_resize=dict(
|
|
||||||
type='bool',
|
|
||||||
),
|
|
||||||
image_username=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
image_password=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
usernameDL=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
passwordDL=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
boot=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
mode=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
'bios',
|
|
||||||
'uefi',
|
|
||||||
],
|
|
||||||
),
|
|
||||||
loader_type=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
'windows',
|
|
||||||
'linux',
|
|
||||||
'unknown',
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
network_interface_naming=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
'ens',
|
|
||||||
'eth',
|
|
||||||
],
|
|
||||||
),
|
|
||||||
storage_policy_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
def check_amodule_args_for_change(self):
|
|
||||||
check_errors = False
|
|
||||||
|
|
||||||
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
|
||||||
if (
|
|
||||||
aparam_storage_policy_id is not None
|
|
||||||
and aparam_storage_policy_id
|
|
||||||
not in self.acc_info['storage_policy_ids']
|
|
||||||
):
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "storage_policy_id" failed: '
|
|
||||||
f'Account ID {self.acc_id} does not have access to '
|
|
||||||
f'storage_policy_id {aparam_storage_policy_id}'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_errors:
|
|
||||||
self.exit(fail=True)
|
|
||||||
|
|
||||||
def check_amodule_args_for_change_virt_image(self):
|
|
||||||
check_errors = False
|
|
||||||
|
|
||||||
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
|
||||||
if (
|
|
||||||
aparam_storage_policy_id is not None
|
|
||||||
and (
|
|
||||||
aparam_storage_policy_id
|
|
||||||
!= self.virt_image_info['storage_policy_id']
|
|
||||||
)
|
|
||||||
):
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "storage_policy_id" failed: '
|
|
||||||
'storage_policy_id can not be changed in virtual image'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_errors:
|
|
||||||
self.exit(fail=True)
|
|
||||||
|
|
||||||
def check_amodule_args_for_create_image(self):
|
|
||||||
check_errors = False
|
|
||||||
|
|
||||||
aparam_account_id = self.aparams['account_id']
|
|
||||||
if aparam_account_id is None:
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "account_id" failed: '
|
|
||||||
'account_id must be specified when creating '
|
|
||||||
'a new image'
|
|
||||||
)
|
|
||||||
|
|
||||||
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
|
||||||
if aparam_storage_policy_id is None:
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "storage_policy_id" failed: '
|
|
||||||
'storage_policy_id must be specified when creating '
|
|
||||||
'a new image'
|
|
||||||
)
|
|
||||||
elif (
|
|
||||||
aparam_storage_policy_id
|
|
||||||
not in self.acc_info['storage_policy_ids']
|
|
||||||
):
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "storage_policy_id" failed: '
|
|
||||||
f'Account ID {self.acc_id} does not have access to '
|
|
||||||
f'storage_policy_id {aparam_storage_policy_id}'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_errors:
|
|
||||||
self.exit(fail=True)
|
|
||||||
|
|
||||||
def check_amodule_args_for_create_virt_image(self):
|
|
||||||
check_errors = False
|
|
||||||
|
|
||||||
aparam_storage_policy_id = self.aparams['storage_policy_id']
|
|
||||||
if aparam_storage_policy_id is not None:
|
|
||||||
check_errors = True
|
|
||||||
self.message(
|
|
||||||
msg='Check for parameter "storage_policy_id" failed: '
|
|
||||||
'storage_policy_id can not be specified when creating '
|
|
||||||
'virtual image'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_errors:
|
|
||||||
self.exit(fail=True)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
decon = decort_osimage()
|
module = AnsibleModule(
|
||||||
amodule = decon.amodule
|
argument_spec=dict(
|
||||||
if amodule.params['virt_name'] or amodule.params['virt_id']:
|
app_id=dict(type='raw'),
|
||||||
|
app_secret=dict(type='raw'),
|
||||||
|
authenticator=dict(type='raw'),
|
||||||
|
controller_url=dict(type='raw'),
|
||||||
|
domain=dict(type='raw'),
|
||||||
|
jwt=dict(type='raw'),
|
||||||
|
oauth2_url=dict(type='raw'),
|
||||||
|
password=dict(type='raw'),
|
||||||
|
username=dict(type='raw'),
|
||||||
|
verify_ssl=dict(type='raw'),
|
||||||
|
ignore_api_compatibility=dict(type='raw'),
|
||||||
|
ignore_sdk_version_check=dict(type='raw'),
|
||||||
|
pool=dict(type='raw'),
|
||||||
|
sep_id=dict(type='raw'),
|
||||||
|
account_name=dict(type='raw'),
|
||||||
|
account_id=dict(type='raw'),
|
||||||
|
image_name=dict(type='raw'),
|
||||||
|
image_id=dict(type='raw'),
|
||||||
|
virt_id=dict(type='raw'),
|
||||||
|
virt_name=dict(type='raw'),
|
||||||
|
state=dict(type='raw'),
|
||||||
|
url=dict(type='raw'),
|
||||||
|
sepId=dict(type='raw'),
|
||||||
|
poolName=dict(type='raw'),
|
||||||
|
hot_resize=dict(type='raw'),
|
||||||
|
image_username=dict(type='raw'),
|
||||||
|
image_password=dict(type='raw'),
|
||||||
|
usernameDL=dict(type='raw'),
|
||||||
|
passwordDL=dict(type='raw'),
|
||||||
|
boot=dict(type='raw'),
|
||||||
|
network_interface_naming=dict(type='raw'),
|
||||||
|
storage_policy_id=dict(type='raw'),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
image_id, image_facts = decort_osimage.decort_virt_image_find(decon, amodule)
|
module.fail_json(
|
||||||
if amodule.params['image_name'] or amodule.params['image_id']:
|
msg=(
|
||||||
decon.target_image_id, _ = decort_osimage.decort_image_find(decon, amodule)
|
'The module "decort_osimage" has been renamed to "decort_image". '
|
||||||
else:
|
'Please update your playbook to use "decort_image" '
|
||||||
decon.target_image_id = 0
|
'instead of "decort_osimage".'
|
||||||
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.target_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'])
|
|
||||||
decon.result['changed'] = True
|
|
||||||
elif decort_osimage.decort_osimage_package_facts(image_facts)['id'] == 0 and amodule.params['state'] == "present" and decon.target_image_id == 0:
|
|
||||||
decon.result['msg'] = ("Cannot find OS image")
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
|
|
||||||
if decon.validated_virt_image_id:
|
|
||||||
if (
|
|
||||||
decon.target_image_id
|
|
||||||
and decort_osimage.decort_osimage_package_facts(image_facts)[
|
|
||||||
'linkto'
|
|
||||||
] != decon.target_image_id
|
|
||||||
):
|
|
||||||
decort_osimage.decort_virt_image_link(decon,amodule)
|
|
||||||
decon.result['changed'] = True
|
|
||||||
amodule.exit_json(**decon.result)
|
|
||||||
if (
|
|
||||||
amodule.params['storage_policy_id'] is not None
|
|
||||||
and amodule.params['storage_policy_id']
|
|
||||||
!= image_facts['storage_policy_id']
|
|
||||||
):
|
|
||||||
decon.image_change_storage_policy(
|
|
||||||
image_id=decon.validated_virt_image_id,
|
|
||||||
storage_policy_id=amodule.params['storage_policy_id'],
|
|
||||||
)
|
|
||||||
|
|
||||||
if amodule.params['state'] == "absent" and decon.validated_virt_image_id:
|
|
||||||
amodule.image_id_delete = decon.validated_virt_image_id
|
|
||||||
image_id, image_facts = decort_osimage.decort_virt_image_find(decon, amodule)
|
|
||||||
if image_facts['status'] != 'PURGED':
|
|
||||||
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)
|
|
||||||
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:
|
|
||||||
amodule.image_id_delete = decon.validated_image_id
|
|
||||||
image_id, image_facts = decort_osimage.decort_image_find(decon, amodule)
|
|
||||||
if image_facts['status'] != 'DESTROYED':
|
|
||||||
decort_osimage.decort_image_delete(decon,amodule)
|
|
||||||
|
|
||||||
if decon.validated_image_id:
|
|
||||||
if (
|
|
||||||
amodule.params['storage_policy_id'] is not None
|
|
||||||
and amodule.params['storage_policy_id']
|
|
||||||
!= image_facts['storage_policy_id']
|
|
||||||
):
|
|
||||||
decon.image_change_storage_policy(
|
|
||||||
image_id=decon.validated_image_id,
|
|
||||||
storage_policy_id=amodule.params['storage_policy_id'],
|
|
||||||
)
|
|
||||||
|
|
||||||
if decon.result['failed'] == True:
|
|
||||||
# we failed to find the specified image - fail the module
|
|
||||||
decon.result['changed'] = False
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
else:
|
|
||||||
if decon.validated_image_id:
|
|
||||||
_, image_facts = decon.decort_image_find(amodule=amodule)
|
|
||||||
elif decon.validated_virt_image_id:
|
|
||||||
_, image_facts = decon.decort_virt_image_find(amodule=amodule)
|
|
||||||
decon.result['facts'] = decort_osimage.decort_osimage_package_facts(
|
|
||||||
arg_osimage_facts=image_facts,
|
|
||||||
arg_check_mode=amodule.check_mode,
|
|
||||||
)
|
|
||||||
|
|
||||||
amodule.exit_json(**decon.result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -86,60 +86,65 @@ class decort_pfw(DecortController):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
amodule = self.amodule
|
||||||
|
|
||||||
|
pfw_facts = None # will hold PFW facts as returned by pfw_configure
|
||||||
|
|
||||||
|
#
|
||||||
|
# Validate module arguments:
|
||||||
|
# 1) specified Compute instance exists in correct state
|
||||||
|
# 2) specified ViNS exists
|
||||||
|
# 3) ViNS has GW function
|
||||||
|
# 4) Compute is connected to this ViNS
|
||||||
|
#
|
||||||
|
|
||||||
|
validated_comp_id, comp_facts, rg_id = self.compute_find(amodule.params['compute_id'])
|
||||||
|
if not validated_comp_id:
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = "Cannot find specified Compute ID {}.".format(amodule.params['compute_id'])
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
|
||||||
|
validated_vins_id, vins_facts = self.vins_find(amodule.params['vins_id'])
|
||||||
|
if not validated_vins_id:
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = "Cannot find specified ViNS ID {}.".format(amodule.params['vins_id'])
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
|
||||||
|
gw_vnf_facts = vins_facts['vnfs'].get('GW')
|
||||||
|
if not gw_vnf_facts or gw_vnf_facts['status'] == "DESTROYED":
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = "ViNS ID {} does not have a configured external connection.".format(validated_vins_id)
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Initial validation of module arguments is complete
|
||||||
|
#
|
||||||
|
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
# ignore amodule.params['rules'] and remove all rules associated with this Compute
|
||||||
|
pfw_facts = self.pfw_configure(comp_facts, vins_facts, None)
|
||||||
|
elif amodule.params['rules'] is not None:
|
||||||
|
# manage PFW rules accodring to the module arguments
|
||||||
|
pfw_facts = self.pfw_configure(comp_facts, vins_facts, amodule.params['rules'])
|
||||||
|
else:
|
||||||
|
pfw_facts = self._pfw_get(comp_facts['id'], vins_facts['id'])
|
||||||
|
|
||||||
|
#
|
||||||
|
# complete module run
|
||||||
|
#
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
# prepare PFW facts to be returned as part of self.result and then call exit_json(...)
|
||||||
|
self.result['facts'] = self.decort_pfw_package_facts(comp_facts, vins_facts, pfw_facts, amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
decon = decort_pfw()
|
decort_pfw().run()
|
||||||
amodule = decon.amodule
|
|
||||||
|
|
||||||
pfw_facts = None # will hold PFW facts as returned by pfw_configure
|
|
||||||
|
|
||||||
#
|
if __name__ == '__main__':
|
||||||
# Validate module arguments:
|
|
||||||
# 1) specified Compute instance exists in correct state
|
|
||||||
# 2) specified ViNS exists
|
|
||||||
# 3) ViNS has GW function
|
|
||||||
# 4) Compute is connected to this ViNS
|
|
||||||
#
|
|
||||||
|
|
||||||
validated_comp_id, comp_facts, rg_id = decon.compute_find(amodule.params['compute_id'])
|
|
||||||
if not validated_comp_id:
|
|
||||||
decon.result['failed'] = True
|
|
||||||
decon.result['msg'] = "Cannot find specified Compute ID {}.".format(amodule.params['compute_id'])
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
|
|
||||||
validated_vins_id, vins_facts = decon.vins_find(amodule.params['vins_id'])
|
|
||||||
if not validated_vins_id:
|
|
||||||
decon.result['failed'] = True
|
|
||||||
decon.result['msg'] = "Cannot find specified ViNS ID {}.".format(amodule.params['vins_id'])
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
|
|
||||||
gw_vnf_facts = vins_facts['vnfs'].get('GW')
|
|
||||||
if not gw_vnf_facts or gw_vnf_facts['status'] == "DESTROYED":
|
|
||||||
decon.result['failed'] = True
|
|
||||||
decon.result['msg'] = "ViNS ID {} does not have a configured external connection.".format(validated_vins_id)
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Initial validation of module arguments is complete
|
|
||||||
#
|
|
||||||
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
# ignore amodule.params['rules'] and remove all rules associated with this Compute
|
|
||||||
pfw_facts = decon.pfw_configure(comp_facts, vins_facts, None)
|
|
||||||
elif amodule.params['rules'] is not None:
|
|
||||||
# manage PFW rules accodring to the module arguments
|
|
||||||
pfw_facts = decon.pfw_configure(comp_facts, vins_facts, amodule.params['rules'])
|
|
||||||
else:
|
|
||||||
pfw_facts = decon._pfw_get(comp_facts['id'], vins_facts['id'])
|
|
||||||
|
|
||||||
#
|
|
||||||
# complete module run
|
|
||||||
#
|
|
||||||
if decon.result['failed']:
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
else:
|
|
||||||
# prepare PFW facts to be returned as part of decon.result and then call exit_json(...)
|
|
||||||
decon.result['facts'] = decon.decort_pfw_package_facts(comp_facts, vins_facts, pfw_facts, amodule.check_mode)
|
|
||||||
amodule.exit_json(**decon.result)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ class decort_rg(DecortController):
|
|||||||
ram='ram',
|
ram='ram',
|
||||||
disk='disksize',
|
disk='disksize',
|
||||||
ext_ips='extips',
|
ext_ips='extips',
|
||||||
net_transfer='exttraffic',
|
|
||||||
storage_policies='policies',
|
storage_policies='policies',
|
||||||
)
|
)
|
||||||
if self.amodule.params['quotas']:
|
if self.amodule.params['quotas']:
|
||||||
@@ -407,73 +406,78 @@ class decort_rg(DecortController):
|
|||||||
# 4) if RG exists: check desired state, desired configuration -> initiate action accordingly
|
# 4) if RG exists: check desired state, desired configuration -> initiate action accordingly
|
||||||
# 5) report result to Ansible
|
# 5) report result to Ansible
|
||||||
|
|
||||||
def main():
|
@DecortController.handle_sdk_exceptions
|
||||||
decon = decort_rg()
|
def run(self):
|
||||||
amodule = decon.amodule
|
amodule = self.amodule
|
||||||
#amodule.check_mode=True
|
#amodule.check_mode=True
|
||||||
if decon.validated_rg_id > 0:
|
if self.validated_rg_id > 0:
|
||||||
if decon.rg_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING", "CONFIRMED"]:
|
if self.rg_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING", "CONFIRMED"]:
|
||||||
decon.error()
|
self.error()
|
||||||
elif decon.rg_facts['status'] in ("CREATED"):
|
elif self.rg_facts['status'] in ("CREATED"):
|
||||||
if amodule.params['state'] == 'absent':
|
if amodule.params['state'] == 'absent':
|
||||||
decon.destroy()
|
self.destroy()
|
||||||
elif amodule.params['state'] == "disabled":
|
elif amodule.params['state'] == "disabled":
|
||||||
decon.enable()
|
self.enable()
|
||||||
if amodule.params['state'] in ['present', 'enabled']:
|
if amodule.params['state'] in ['present', 'enabled']:
|
||||||
if (
|
if (
|
||||||
amodule.params['quotas']
|
amodule.params['quotas']
|
||||||
or amodule.params['resType']
|
or amodule.params['resType']
|
||||||
or amodule.params['rename'] != ""
|
or amodule.params['rename'] != ""
|
||||||
or amodule.params['sep_pools'] is not None
|
or amodule.params['sep_pools'] is not None
|
||||||
or amodule.params['description'] is not None
|
or amodule.params['description'] is not None
|
||||||
):
|
):
|
||||||
decon.update()
|
self.update()
|
||||||
if amodule.params['access']:
|
if amodule.params['access']:
|
||||||
decon.access()
|
self.access()
|
||||||
if amodule.params['def_netType'] is not None:
|
if amodule.params['def_netType'] is not None:
|
||||||
decon.setDefNet()
|
self.setDefNet()
|
||||||
|
|
||||||
elif decon.rg_facts['status'] == "DELETED":
|
elif self.rg_facts['status'] == "DELETED":
|
||||||
if amodule.params['state'] == 'absent' and amodule.params['permanently'] == True:
|
if amodule.params['state'] == 'absent' and amodule.params['permanently'] == True:
|
||||||
decon.destroy()
|
self.destroy()
|
||||||
elif (amodule.params['state'] == 'present'
|
elif (amodule.params['state'] == 'present'
|
||||||
or amodule.params['state'] == 'disabled'):
|
or amodule.params['state'] == 'disabled'):
|
||||||
decon.restore()
|
self.restore()
|
||||||
elif amodule.params['state'] == 'enabled':
|
elif amodule.params['state'] == 'enabled':
|
||||||
decon.restore()
|
self.restore()
|
||||||
decon.enable()
|
self.enable()
|
||||||
elif decon.rg_facts['status'] in ("DISABLED"):
|
elif self.rg_facts['status'] in ("DISABLED"):
|
||||||
if amodule.params['state'] == 'absent':
|
if amodule.params['state'] == 'absent':
|
||||||
decon.destroy()
|
self.destroy()
|
||||||
elif amodule.params['state'] == ("enabled"):
|
elif amodule.params['state'] == ("enabled"):
|
||||||
decon.enable()
|
self.enable()
|
||||||
|
|
||||||
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'] and not amodule.check_mode:
|
|
||||||
decon.access()
|
|
||||||
elif amodule.params['state'] in ('disabled'):
|
|
||||||
decon.error()
|
|
||||||
|
|
||||||
|
|
||||||
if decon.result['failed']:
|
|
||||||
amodule.fail_json(**decon.result)
|
|
||||||
else:
|
|
||||||
if decon.rg_should_exist:
|
|
||||||
if decon.result['changed']:
|
|
||||||
decon.get_info()
|
|
||||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
|
||||||
amodule.exit_json(**decon.result)
|
|
||||||
else:
|
else:
|
||||||
amodule.exit_json(**decon.result)
|
if amodule.params['state'] in ('present', 'enabled'):
|
||||||
|
if not amodule.params['rg_name']:
|
||||||
|
self.result['failed'] = True
|
||||||
|
self.result['msg'] = (
|
||||||
|
'Resource group could not be created because'
|
||||||
|
' the "rg_name" parameter was not specified.'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.create()
|
||||||
|
if amodule.params['access'] and not amodule.check_mode:
|
||||||
|
self.access()
|
||||||
|
elif amodule.params['state'] in ('disabled'):
|
||||||
|
self.error()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
if self.rg_should_exist:
|
||||||
|
if self.result['changed']:
|
||||||
|
self.get_info()
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
else:
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
decort_rg().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
148
library/decort_rg_list.py
Normal file
148
library/decort_rg_list.py
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_rg_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortRGList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
account_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
created_after_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
created_before_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
include_deleted=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
lock_status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.LockStatus._member_names_,
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.ResourceGroupStatus._member_names_
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.ResourceGroupAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_lock_status: str | None = aparam_filter['lock_status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.ResourceGroupAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.rg.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
account_name=aparam_filter['account_name'],
|
||||||
|
created_after_timestamp=aparam_filter['created_after_timestamp'],
|
||||||
|
created_before_timestamp=aparam_filter['created_before_timestamp'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
include_deleted=aparam_filter['include_deleted'] or False,
|
||||||
|
lock_status=(
|
||||||
|
sdk_types.LockStatus[aparam_lock_status]
|
||||||
|
if aparam_lock_status else None
|
||||||
|
),
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
status=(
|
||||||
|
sdk_types.ResourceGroupStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortRGList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -10,6 +10,9 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk import exceptions as sdk_exceptions
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
class DecortSecurityGroup(DecortController):
|
class DecortSecurityGroup(DecortController):
|
||||||
id: int = 0
|
id: int = 0
|
||||||
@@ -52,18 +55,18 @@ class DecortSecurityGroup(DecortController):
|
|||||||
options=dict(
|
options=dict(
|
||||||
direction=dict(
|
direction=dict(
|
||||||
type='str',
|
type='str',
|
||||||
choices=[
|
choices=(
|
||||||
e.name for e in
|
sdk_types.TrafficDirection.
|
||||||
self.SecurityGroupRuleDirection
|
_member_names_
|
||||||
],
|
),
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
ethertype=dict(
|
ethertype=dict(
|
||||||
type='str',
|
type='str',
|
||||||
choices=[
|
choices=(
|
||||||
e.name for e in
|
sdk_types.SGRuleEthertype.
|
||||||
self.SecurityGroupRuleEtherType
|
_member_names_
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
id=dict(
|
id=dict(
|
||||||
type='int',
|
type='int',
|
||||||
@@ -81,12 +84,11 @@ class DecortSecurityGroup(DecortController):
|
|||||||
),
|
),
|
||||||
protocol=dict(
|
protocol=dict(
|
||||||
type='str',
|
type='str',
|
||||||
choices=[
|
choices=(
|
||||||
e.name for e in
|
sdk_types.SGRuleProtocol._member_names_
|
||||||
self.SecurityGroupRuleProtocol
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
remote_ip_prefix=dict(
|
remote_net_cidr=dict(
|
||||||
type='str',
|
type='str',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -101,16 +103,17 @@ class DecortSecurityGroup(DecortController):
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
if self.aparams['id'] is not None:
|
if self.aparams['id'] is not None:
|
||||||
self.id = self.aparams['id']
|
self.id = self.aparams['id']
|
||||||
elif self.aparams['name'] is not None:
|
elif self.aparams['name'] is not None:
|
||||||
security_group = self.security_group_find(
|
security_groups = self.api.cloudapi.security_group.list(
|
||||||
account_id=self.aparams['account_id'],
|
account_id=self.aparams['account_id'],
|
||||||
name=self.aparams['name'],
|
name=self.aparams['name'],
|
||||||
)
|
)
|
||||||
if security_group:
|
if security_groups.data:
|
||||||
self.id = security_group['id']
|
self.id = security_groups.data[0].id
|
||||||
|
|
||||||
if self.id:
|
if self.id:
|
||||||
self.get_info()
|
self.get_info()
|
||||||
@@ -127,14 +130,25 @@ class DecortSecurityGroup(DecortController):
|
|||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
self.facts: dict = self.security_group_get(id=self.id)
|
try:
|
||||||
self.facts['created_timestamp'] = self.facts.pop('created_at')
|
storage_policy_model = self.api.cloudapi.security_group.get(
|
||||||
self.facts['updated_timestamp'] = self.facts.pop('updated_at')
|
security_group_id=self.id
|
||||||
for rule in self.facts['rules']:
|
)
|
||||||
rule['port_range'] = {
|
except sdk_exceptions.RequestException as e:
|
||||||
'min': rule.pop('port_range_min'),
|
if (
|
||||||
'max': rule.pop('port_range_max'),
|
e.orig_exception.response
|
||||||
}
|
and e.orig_exception.response.status_code == 404
|
||||||
|
):
|
||||||
|
self.message(
|
||||||
|
self.MESSAGES.obj_not_found(
|
||||||
|
obj='security_group',
|
||||||
|
id=self.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.exit(fail=True)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
self.facts = storage_policy_model.model_dump()
|
||||||
|
|
||||||
def check_amodule_args_for_create(self):
|
def check_amodule_args_for_create(self):
|
||||||
check_errors = False
|
check_errors = False
|
||||||
@@ -242,16 +256,13 @@ class DecortSecurityGroup(DecortController):
|
|||||||
return not check_errors
|
return not check_errors
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
security_groups_by_account_id = self.user_security_groups(
|
id = self.sdk_checkmode(self.api.cloudapi.security_group.create)(
|
||||||
account_id=self.aparams['account_id']
|
account_id=self.aparams['account_id'],
|
||||||
|
name=self.aparams['name'],
|
||||||
|
description=self.aparams['description'],
|
||||||
)
|
)
|
||||||
sg_names = [sg['name'] for sg in security_groups_by_account_id]
|
if id:
|
||||||
if self.aparams['name'] not in sg_names:
|
self.id = id
|
||||||
self.id = self.security_group_create(
|
|
||||||
account_id=self.aparams['account_id'],
|
|
||||||
name=self.aparams['name'],
|
|
||||||
description=self.aparams['description'],
|
|
||||||
)
|
|
||||||
|
|
||||||
def change(self):
|
def change(self):
|
||||||
self.change_state()
|
self.change_state()
|
||||||
@@ -277,7 +288,7 @@ class DecortSecurityGroup(DecortController):
|
|||||||
):
|
):
|
||||||
new_description = aparam_description
|
new_description = aparam_description
|
||||||
if new_name or new_description:
|
if new_name or new_description:
|
||||||
self.security_group_update(
|
self.sdk_checkmode(self.api.cloudapi.security_group.update)(
|
||||||
security_group_id=self.id,
|
security_group_id=self.id,
|
||||||
name=new_name,
|
name=new_name,
|
||||||
description=new_description,
|
description=new_description,
|
||||||
@@ -317,7 +328,9 @@ class DecortSecurityGroup(DecortController):
|
|||||||
self.create_rule(rule=rule)
|
self.create_rule(rule=rule)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
self.security_group_detele(security_group_id=self.id)
|
self.sdk_checkmode(self.api.cloudapi.security_group.delete)(
|
||||||
|
security_group_id=self.id,
|
||||||
|
)
|
||||||
self.facts = {}
|
self.facts = {}
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
@@ -326,20 +339,22 @@ class DecortSecurityGroup(DecortController):
|
|||||||
if rule.get('port_range'):
|
if rule.get('port_range'):
|
||||||
port_range_min = rule['port_range'].get('min')
|
port_range_min = rule['port_range'].get('min')
|
||||||
port_range_max = rule['port_range'].get('max')
|
port_range_max = rule['port_range'].get('max')
|
||||||
self.security_group_create_rule(
|
self.sdk_checkmode(self.api.cloudapi.security_group.create_rule)(
|
||||||
security_group_id=self.id,
|
security_group_id=self.id,
|
||||||
direction=self.SecurityGroupRuleDirection[rule['direction']],
|
traffic_direction=(
|
||||||
|
sdk_types.TrafficDirection[rule['direction']]
|
||||||
|
),
|
||||||
ethertype=(
|
ethertype=(
|
||||||
self.SecurityGroupRuleEtherType[rule['ethertype']]
|
sdk_types.SGRuleEthertype[rule['ethertype']]
|
||||||
if rule.get('ethertype') else None
|
if rule.get('ethertype') else sdk_types.SGRuleEthertype.IPV4
|
||||||
),
|
),
|
||||||
protocol=(
|
protocol=(
|
||||||
self.SecurityGroupRuleProtocol[rule['protocol']]
|
sdk_types.SGRuleProtocol[rule['protocol']]
|
||||||
if rule.get('protocol') else None
|
if rule.get('protocol') else None
|
||||||
),
|
),
|
||||||
port_range_min=port_range_min,
|
port_range_min=port_range_min,
|
||||||
port_range_max=port_range_max,
|
port_range_max=port_range_max,
|
||||||
remote_ip_prefix=rule.get('remote_ip_prefix'),
|
remote_net_cidr=rule.get('remote_net_cidr'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
132
library/decort_security_group_list.py
Normal file
132
library/decort_security_group_list.py
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_security_group_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortSecurityGroupList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
created_after_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
created_before_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
description=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
updated_after_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
updated_before_timestamp=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.SecurityGroupAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.SecurityGroupAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.security_group.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
created_after_timestamp=aparam_filter['created_after_timestamp'],
|
||||||
|
created_before_timestamp=aparam_filter['created_before_timestamp'],
|
||||||
|
description=aparam_filter['description'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
updated_after_timestamp=aparam_filter['updated_after_timestamp'],
|
||||||
|
updated_before_timestamp=aparam_filter['updated_before_timestamp'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortSecurityGroupList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -10,6 +10,8 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk import exceptions as sdk_exceptions
|
||||||
|
|
||||||
|
|
||||||
class DecortStoragePolicy(DecortController):
|
class DecortStoragePolicy(DecortController):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -28,18 +30,31 @@ class DecortStoragePolicy(DecortController):
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.get_info()
|
self.get_info()
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
self.facts = self.storage_policy_get(id=self.id)
|
try:
|
||||||
self.facts['sep_pools'] = self.facts.pop('access_seps_pools')
|
storage_policy_model = self.api.cloudapi.storage_policy.get(
|
||||||
self.facts['iops_limit'] = self.facts.pop('limit_iops')
|
id=self.id
|
||||||
self.facts['usage']['account_ids'] = self.facts['usage'].pop(
|
)
|
||||||
'accounts'
|
except sdk_exceptions.RequestException as e:
|
||||||
)
|
if (
|
||||||
self.facts['usage']['rg_ids'] = self.facts['usage'].pop('resgroups')
|
e.orig_exception.response
|
||||||
|
and e.orig_exception.response.status_code == 404
|
||||||
|
):
|
||||||
|
self.message(
|
||||||
|
self.MESSAGES.obj_not_found(
|
||||||
|
obj='storage_policy',
|
||||||
|
id=self.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.exit(fail=True)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
self.facts = storage_policy_model.model_dump()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
152
library/decort_storage_policy_list.py
Normal file
152
library/decort_storage_policy_list.py
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_storage_policy_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortStoragePolicyList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
description=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
iops_limit=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
rg_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
sep_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
sep_pool_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.StoragePolicyStatus._member_names_
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sep_tech_status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.SEPTechStatus._member_names_,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.StoragePolicyAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_sep_tech_status: str | None = aparam_filter['sep_tech_status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.StoragePolicyAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.storage_policy.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
description=aparam_filter['description'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
iops_limit=aparam_filter['iops_limit'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
rg_id=aparam_filter['rg_id'],
|
||||||
|
sep_id=aparam_filter['sep_id'],
|
||||||
|
sep_pool_name=aparam_filter['sep_pool_name'],
|
||||||
|
status=(
|
||||||
|
sdk_types.StoragePolicyStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
sep_tech_status=(
|
||||||
|
sdk_types.SEPTechStatus[aparam_sep_tech_status]
|
||||||
|
if aparam_sep_tech_status else None
|
||||||
|
),
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortStoragePolicyList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -10,6 +10,8 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk import exceptions as sdk_exceptions
|
||||||
|
|
||||||
|
|
||||||
class DecortTrunk(DecortController):
|
class DecortTrunk(DecortController):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -28,19 +30,31 @@ class DecortTrunk(DecortController):
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.get_info()
|
self.get_info()
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
self.facts = self.trunk_get(id=self.id)
|
try:
|
||||||
self.facts['account_ids'] = self.facts.pop('accountIds')
|
trunk_model = self.api.cloudapi.trunk.get(
|
||||||
self.facts['created_timestamp'] = self.facts.pop('created_at')
|
id=self.id
|
||||||
self.facts['deleted_timestamp'] = self.facts.pop('deleted_at')
|
)
|
||||||
self.facts['updated_timestamp'] = self.facts.pop('updated_at')
|
except sdk_exceptions.RequestException as e:
|
||||||
self.facts['native_vlan_id'] = self.facts.pop('nativeVlanId')
|
if (
|
||||||
self.facts['ovs_bridge'] = self.facts.pop('ovsBridge')
|
e.orig_exception.response
|
||||||
self.facts['vlan_ids'] = self.facts.pop('trunkTags')
|
and e.orig_exception.response.status_code == 404
|
||||||
|
):
|
||||||
|
self.message(
|
||||||
|
self.MESSAGES.obj_not_found(
|
||||||
|
obj='trunk',
|
||||||
|
id=self.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.exit(fail=True)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
self.facts = trunk_model.model_dump()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
123
library/decort_trunk_list.py
Normal file
123
library/decort_trunk_list.py
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_trunk_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortTrunkList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_ids=dict(
|
||||||
|
type='list',
|
||||||
|
elements='int',
|
||||||
|
),
|
||||||
|
ids=dict(
|
||||||
|
type='list',
|
||||||
|
elements='int',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.TrunkStatus._member_names_,
|
||||||
|
),
|
||||||
|
vlan_ids=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.TrunkAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.TrunkAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.trunk.list(
|
||||||
|
account_ids=aparam_filter['account_ids'],
|
||||||
|
ids=aparam_filter['ids'],
|
||||||
|
status=(
|
||||||
|
sdk_types.TrunkStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
vlan_ids=aparam_filter['vlan_ids'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortTrunkList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
68
library/decort_user.py
Normal file
68
library/decort_user.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_user
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortUser(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
api_methods=dict(
|
||||||
|
type='bool',
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
objects_search=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
resource_consumption=dict(
|
||||||
|
type='bool',
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
self.facts = self.usermanager_whoami_result
|
||||||
|
self.id = self.facts['name']
|
||||||
|
|
||||||
|
user_get = self.user_get(id=self.id)
|
||||||
|
for key in ['emailaddresses', 'data']:
|
||||||
|
self.facts[key] = user_get[key]
|
||||||
|
|
||||||
|
if self.aparams['resource_consumption']:
|
||||||
|
self.facts.update(self.user_resource_consumption())
|
||||||
|
|
||||||
|
if self.aparams['api_methods']:
|
||||||
|
self.facts['api_methods'] = self.user_api_methods(id=self.id)
|
||||||
|
|
||||||
|
search_string = self.aparams['objects_search']
|
||||||
|
if search_string:
|
||||||
|
self.facts['objects_search'] = self.user_objects_search(
|
||||||
|
search_string=search_string,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortUser().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -8,871 +8,37 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
|
||||||
|
|
||||||
|
|
||||||
class DecortUserInfo(DecortController):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(AnsibleModule(**self.amodule_init_args))
|
|
||||||
self.check_amodule_args()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def amodule_init_args(self) -> dict:
|
|
||||||
return self.pack_amodule_init_args(
|
|
||||||
argument_spec=dict(
|
|
||||||
accounts=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
deleted=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
rights=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e in self.AccountUserRights
|
|
||||||
],
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
status=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e in self.AccountStatus
|
|
||||||
],
|
|
||||||
),
|
|
||||||
zone_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
resource_consumption=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value
|
|
||||||
for e in self.AccountSortableField
|
|
||||||
],
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
api_methods=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
audits=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
api_method=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
status_code=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
min=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
max=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
time=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
start=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
timestamp=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
datetime=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
mutually_exclusive=[
|
|
||||||
('timestamp', 'datetime'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
end=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
timestamp=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
datetime=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
mutually_exclusive=[
|
|
||||||
('timestamp', 'datetime'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
apply_defaults=True,
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
default=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value
|
|
||||||
for e in self.AuditsSortableField
|
|
||||||
],
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
objects_search=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
resource_consumption=dict(
|
|
||||||
type='bool',
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
zones=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
deletable=dict(
|
|
||||||
type='bool',
|
|
||||||
),
|
|
||||||
description=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
grid_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
node_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
status=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e in self.ZoneStatus
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
apply_defaults=True,
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
default=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=self.ZoneField._member_names_,
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trunks=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
ids=dict(
|
|
||||||
type='list',
|
|
||||||
),
|
|
||||||
account_ids=dict(
|
|
||||||
type='list',
|
|
||||||
),
|
|
||||||
status=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e in self.TrunkStatus
|
|
||||||
],
|
|
||||||
),
|
|
||||||
vlan_ids=dict(
|
|
||||||
type='list',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
apply_defaults=True,
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
default=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value
|
|
||||||
for e in self.TrunksSortableField
|
|
||||||
],
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
storage_policies=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
account_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
description=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
iops_limit=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
pool_name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
rg_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
sep_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
status=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e
|
|
||||||
in self.StoragePolicyStatus
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
apply_defaults=True,
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
default=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.value for e
|
|
||||||
in self.StoragePoliciesSortableField
|
|
||||||
],
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
security_groups=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
filter=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
account_id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
created_timestamp_max=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
created_timestamp_min=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
description=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
id=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
name=dict(
|
|
||||||
type='str',
|
|
||||||
),
|
|
||||||
updated_timestamp_max=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
updated_timestamp_min=dict(
|
|
||||||
type='int',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pagination=dict(
|
|
||||||
type='dict',
|
|
||||||
apply_defaults=True,
|
|
||||||
options=dict(
|
|
||||||
number=dict(
|
|
||||||
type='int',
|
|
||||||
default=1,
|
|
||||||
),
|
|
||||||
size=dict(
|
|
||||||
type='int',
|
|
||||||
default=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
sorting=dict(
|
|
||||||
type='dict',
|
|
||||||
options=dict(
|
|
||||||
asc=dict(
|
|
||||||
type='bool',
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
field=dict(
|
|
||||||
type='str',
|
|
||||||
choices=[
|
|
||||||
e.name for e
|
|
||||||
in self.SecurityGroupSortableField
|
|
||||||
],
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
def check_amodule_args(self):
|
|
||||||
"""
|
|
||||||
Additional validation of Ansible Module arguments.
|
|
||||||
This validation cannot be implemented using
|
|
||||||
Ansible Argument spec.
|
|
||||||
"""
|
|
||||||
|
|
||||||
check_error = False
|
|
||||||
|
|
||||||
match self.aparams['audits']:
|
|
||||||
case {
|
|
||||||
'filter': {'time': {'start': {'datetime': str() as dt_str}}}
|
|
||||||
}:
|
|
||||||
if self.dt_str_to_sec(dt_str=dt_str) is None:
|
|
||||||
self.message(self.MESSAGES.str_not_parsed(string=dt_str))
|
|
||||||
check_error = True
|
|
||||||
match self.aparams['audits']:
|
|
||||||
case {
|
|
||||||
'filter': {'time': {'end': {'datetime': str() as dt_str}}}
|
|
||||||
}:
|
|
||||||
if self.dt_str_to_sec(dt_str=dt_str) is None:
|
|
||||||
self.message(self.MESSAGES.str_not_parsed(string=dt_str))
|
|
||||||
check_error = True
|
|
||||||
|
|
||||||
aparam_trunks = self.aparams['trunks']
|
|
||||||
if (
|
|
||||||
aparam_trunks is not None
|
|
||||||
and aparam_trunks['filter'] is not None
|
|
||||||
and aparam_trunks['filter']['vlan_ids'] is not None
|
|
||||||
):
|
|
||||||
for vlan_id in aparam_trunks['filter']['vlan_ids']:
|
|
||||||
if not (
|
|
||||||
self.TRUNK_VLAN_ID_MIN_VALUE
|
|
||||||
<= vlan_id
|
|
||||||
<= self.TRUNK_VLAN_ID_MAX_VALUE
|
|
||||||
):
|
|
||||||
check_error = True
|
|
||||||
self.message(
|
|
||||||
'Check for parameter "trunks.filter.vlan_ids" failed: '
|
|
||||||
f'VLAN ID {vlan_id} must be in range 1-4095.'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_error:
|
|
||||||
self.exit(fail=True)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_accounts_args(self) -> None | dict:
|
|
||||||
"""
|
|
||||||
Map the module argument `accounts` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_accounts`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['accounts']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
mapped_args['deleted'] = input_args['deleted']
|
|
||||||
|
|
||||||
mapped_args['resource_consumption'] = (
|
|
||||||
input_args['resource_consumption']
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
input_args_filter_rights = input_args_filter['rights']
|
|
||||||
if input_args_filter_rights:
|
|
||||||
mapped_args['account_user_rights'] = (
|
|
||||||
self.AccountUserRights(input_args_filter_rights)
|
|
||||||
)
|
|
||||||
|
|
||||||
mapped_args['account_id'] = input_args_filter['id']
|
|
||||||
|
|
||||||
mapped_args['account_name'] = input_args_filter['name']
|
|
||||||
|
|
||||||
input_args_filter_status = input_args_filter['status']
|
|
||||||
if input_args_filter_status:
|
|
||||||
mapped_args['account_status'] = (
|
|
||||||
self.AccountStatus(input_args_filter_status)
|
|
||||||
)
|
|
||||||
|
|
||||||
mapped_args['zone_id'] = input_args_filter['zone_id']
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.AccountSortableField(input_args_sorting_field)
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_audits_args(self):
|
|
||||||
"""
|
|
||||||
Map the module argument `audits` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_audits`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['audits']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
mapped_args['api_method'] = input_args_filter['api_method']
|
|
||||||
|
|
||||||
match input_args_filter['status_code']:
|
|
||||||
case {'min': int() as min_status_code}:
|
|
||||||
mapped_args['min_status_code'] = min_status_code
|
|
||||||
match input_args_filter['status_code']:
|
|
||||||
case {'max': int() as max_status_code}:
|
|
||||||
mapped_args['max_status_code'] = max_status_code
|
|
||||||
|
|
||||||
match input_args_filter['time']:
|
|
||||||
case {'start': {'timestamp': int() as start_unix_time}}:
|
|
||||||
mapped_args['start_unix_time'] = start_unix_time
|
|
||||||
case {'start': {'datetime': str() as start_dt_str}}:
|
|
||||||
mapped_args['start_unix_time'] = self.dt_str_to_sec(
|
|
||||||
dt_str=start_dt_str
|
|
||||||
)
|
|
||||||
match input_args_filter['time']:
|
|
||||||
case {'end': {'timestamp': int() as end_unix_time}}:
|
|
||||||
mapped_args['end_unix_time'] = end_unix_time
|
|
||||||
case {'end': {'datetime': str() as end_dt_str}}:
|
|
||||||
mapped_args['end_unix_time'] = self.dt_str_to_sec(
|
|
||||||
dt_str=end_dt_str
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.AuditsSortableField(input_args_sorting_field)
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_zones_args(self):
|
|
||||||
"""
|
|
||||||
Map the module argument `zones` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_zones`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['zones']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
mapped_args.update(input_args_filter)
|
|
||||||
|
|
||||||
input_args_filter_status = input_args_filter['status']
|
|
||||||
if input_args_filter_status:
|
|
||||||
mapped_args['status'] = (
|
|
||||||
self.ZoneStatus(input_args_filter_status)
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.ZoneField._member_map_[input_args_sorting_field]
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_trunks_args(self):
|
|
||||||
"""
|
|
||||||
Map the module argument `trunks` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_trunks`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['trunks']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
mapped_args.update(input_args_filter)
|
|
||||||
|
|
||||||
input_args_filter_status = input_args_filter['status']
|
|
||||||
if input_args_filter_status:
|
|
||||||
mapped_args['status'] = (
|
|
||||||
self.TrunkStatus(input_args_filter_status)
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_filter_vlan_ids = input_args_filter['vlan_ids']
|
|
||||||
if input_args_filter_vlan_ids is not None:
|
|
||||||
mapped_args['vlan_ids'] = ', '.join(
|
|
||||||
map(str, input_args_filter_vlan_ids)
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.TrunksSortableField(input_args_sorting_field)
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_storage_policies_args(self):
|
|
||||||
"""
|
|
||||||
Map the module argument `storage_policies` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_storage_policies`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['storage_policies']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
mapped_args.update(input_args_filter)
|
|
||||||
|
|
||||||
input_args_filter_status = input_args_filter['status']
|
|
||||||
if input_args_filter_status:
|
|
||||||
mapped_args['status'] = (
|
|
||||||
self.StoragePolicyStatus(input_args_filter_status)
|
|
||||||
)
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.StoragePoliciesSortableField(input_args_sorting_field)
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def mapped_security_groups_args(self):
|
|
||||||
"""
|
|
||||||
Map the module argument `security_groups` to
|
|
||||||
arguments dictionary for the method
|
|
||||||
`DecortController.user_security_groups`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_args = self.aparams['security_groups']
|
|
||||||
if not input_args:
|
|
||||||
return input_args
|
|
||||||
|
|
||||||
mapped_args = {}
|
|
||||||
|
|
||||||
input_args_filter = input_args['filter']
|
|
||||||
if input_args_filter:
|
|
||||||
mapped_args.update(input_args_filter)
|
|
||||||
|
|
||||||
input_args_pagination = input_args['pagination']
|
|
||||||
if input_args_pagination:
|
|
||||||
mapped_args['page_number'] = input_args_pagination['number']
|
|
||||||
mapped_args['page_size'] = input_args_pagination['size']
|
|
||||||
|
|
||||||
input_args_sorting = input_args['sorting']
|
|
||||||
if input_args_sorting:
|
|
||||||
mapped_args['sort_by_asc'] = input_args_sorting['asc']
|
|
||||||
|
|
||||||
input_args_sorting_field = input_args_sorting['field']
|
|
||||||
if input_args_sorting_field:
|
|
||||||
mapped_args['sort_by_field'] = (
|
|
||||||
self.SecurityGroupSortableField[input_args_sorting_field]
|
|
||||||
)
|
|
||||||
|
|
||||||
return mapped_args
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.get_info()
|
|
||||||
self.exit()
|
|
||||||
|
|
||||||
def get_info(self):
|
|
||||||
self.facts = self.user_whoami()
|
|
||||||
self.id = self.facts['name']
|
|
||||||
|
|
||||||
user_get = self.user_get(id=self.id)
|
|
||||||
for key in ['emailaddresses', 'data']:
|
|
||||||
self.facts[key] = user_get[key]
|
|
||||||
|
|
||||||
if self.aparams['accounts']:
|
|
||||||
self.facts['accounts'] = self.user_accounts(
|
|
||||||
**self.mapped_accounts_args,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.aparams['resource_consumption']:
|
|
||||||
self.facts.update(self.user_resource_consumption())
|
|
||||||
|
|
||||||
if self.aparams['audits']:
|
|
||||||
self.facts['audits'] = self.user_audits(**self.mapped_audits_args)
|
|
||||||
|
|
||||||
if self.aparams['api_methods']:
|
|
||||||
self.facts['api_methods'] = self.user_api_methods(id=self.id)
|
|
||||||
|
|
||||||
search_string = self.aparams['objects_search']
|
|
||||||
if search_string:
|
|
||||||
self.facts['objects_search'] = self.user_objects_search(
|
|
||||||
search_string=search_string,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.aparams['zones']:
|
|
||||||
self.facts['zones'] = self.user_zones(**self.mapped_zones_args)
|
|
||||||
|
|
||||||
if self.aparams['trunks']:
|
|
||||||
self.facts['trunks'] = self.user_trunks(**self.mapped_trunks_args)
|
|
||||||
for trunk_facts in self.facts['trunks']:
|
|
||||||
trunk_facts['account_ids'] = trunk_facts.pop('accountIds')
|
|
||||||
trunk_facts['created_timestamp'] = trunk_facts.pop(
|
|
||||||
'created_at'
|
|
||||||
)
|
|
||||||
trunk_facts['deleted_timestamp'] = trunk_facts.pop(
|
|
||||||
'deleted_at'
|
|
||||||
)
|
|
||||||
trunk_facts['updated_timestamp'] = trunk_facts.pop(
|
|
||||||
'updated_at'
|
|
||||||
)
|
|
||||||
trunk_facts['native_vlan_id'] = trunk_facts.pop(
|
|
||||||
'nativeVlanId'
|
|
||||||
)
|
|
||||||
trunk_facts['ovs_bridge'] = trunk_facts.pop('ovsBridge')
|
|
||||||
trunk_facts['vlan_ids'] = trunk_facts.pop('trunkTags')
|
|
||||||
|
|
||||||
if self.aparams['storage_policies']:
|
|
||||||
self.facts['storage_policies'] = self.user_storage_policies(
|
|
||||||
**self.mapped_storage_policies_args
|
|
||||||
)
|
|
||||||
for storage_policy_facts in self.facts['storage_policies']:
|
|
||||||
storage_policy_facts['sep_pools'] = storage_policy_facts.pop(
|
|
||||||
'access_seps_pools'
|
|
||||||
)
|
|
||||||
storage_policy_facts['iops_limit'] = storage_policy_facts.pop(
|
|
||||||
'limit_iops'
|
|
||||||
)
|
|
||||||
storage_policy_facts['usage']['account_ids'] = (
|
|
||||||
storage_policy_facts['usage'].pop('accounts')
|
|
||||||
)
|
|
||||||
storage_policy_facts['usage']['rg_ids'] = (
|
|
||||||
storage_policy_facts['usage'].pop('resgroups')
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.aparams['security_groups']:
|
|
||||||
self.facts['security_groups'] = self.user_security_groups(
|
|
||||||
**self.mapped_security_groups_args
|
|
||||||
)
|
|
||||||
for security_groups_facts in self.facts['security_groups']:
|
|
||||||
for rule in security_groups_facts.get('rules', []):
|
|
||||||
rule['port_range'] = {
|
|
||||||
'min': rule.pop('port_range_min'),
|
|
||||||
'max': rule.pop('port_range_max'),
|
|
||||||
}
|
|
||||||
|
|
||||||
security_groups_facts['created_timestamp'] = (
|
|
||||||
security_groups_facts.pop('created_at')
|
|
||||||
)
|
|
||||||
security_groups_facts['created_timestamp_readable'] = (
|
|
||||||
self.sec_to_dt_str(security_groups_facts[
|
|
||||||
'created_timestamp'
|
|
||||||
])
|
|
||||||
)
|
|
||||||
security_groups_facts['updated_timestamp'] = (
|
|
||||||
security_groups_facts.pop('updated_at')
|
|
||||||
)
|
|
||||||
security_groups_facts['updated_timestamp_readable'] = (
|
|
||||||
self.sec_to_dt_str(security_groups_facts[
|
|
||||||
'updated_timestamp'
|
|
||||||
])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
DecortUserInfo().run()
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
app_id=dict(type='raw'),
|
||||||
|
app_secret=dict(type='raw'),
|
||||||
|
authenticator=dict(type='raw'),
|
||||||
|
controller_url=dict(type='raw'),
|
||||||
|
domain=dict(type='raw'),
|
||||||
|
jwt=dict(type='raw'),
|
||||||
|
oauth2_url=dict(type='raw'),
|
||||||
|
password=dict(type='raw'),
|
||||||
|
username=dict(type='raw'),
|
||||||
|
verify_ssl=dict(type='raw'),
|
||||||
|
ignore_api_compatibility=dict(type='raw'),
|
||||||
|
ignore_sdk_version_check=dict(type='raw'),
|
||||||
|
api_methods=dict(type='raw'),
|
||||||
|
objects_search=dict(type='raw'),
|
||||||
|
resource_consumption=dict(type='raw'),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
module.fail_json(
|
||||||
|
msg=(
|
||||||
|
'The module "decort_user_info" has been renamed to "decort_user". '
|
||||||
|
'Please update your playbook to use "decort_user" '
|
||||||
|
'instead of "decort_user_info".'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -365,102 +365,106 @@ class decort_vins(DecortController):
|
|||||||
# 4) if ViNS exists: check desired state, desired configuration -> initiate action(s) accordingly
|
# 4) if ViNS exists: check desired state, desired configuration -> initiate action(s) accordingly
|
||||||
# 5) report result to Ansible
|
# 5) report result to Ansible
|
||||||
|
|
||||||
def main():
|
@DecortController.handle_sdk_exceptions
|
||||||
decon = decort_vins()
|
def run(self):
|
||||||
amodule = decon.amodule
|
amodule = self.amodule
|
||||||
#
|
#
|
||||||
# Initial validation of module arguments is complete
|
# Initial validation of module arguments is complete
|
||||||
#
|
#
|
||||||
# At this point non-zero vins_id means that we will be managing pre-existing ViNS
|
# At this point non-zero vins_id means that we will be managing pre-existing ViNS
|
||||||
# Otherwise we are about to create a new one as follows:
|
# Otherwise we are about to create a new one as follows:
|
||||||
# - if validated_rg_id is non-zero, create ViNS @ RG level
|
# - if validated_rg_id is non-zero, create ViNS @ RG level
|
||||||
# - if validated_rg_id is zero, create ViNS @ account level
|
# - if validated_rg_id is zero, create ViNS @ account level
|
||||||
#
|
#
|
||||||
# When managing existing ViNS we need to account for both "static" and "transient"
|
# When managing existing ViNS we need to account for both "static" and "transient"
|
||||||
# status. Full range of ViNS statii is as follows:
|
# status. Full range of ViNS statii is as follows:
|
||||||
#
|
#
|
||||||
# "MODELED", "CREATED", "ENABLED", "ENABLING", "DISABLED", "DISABLING", "DELETED", "DELETING", "DESTROYED", "DESTROYING"
|
# "MODELED", "CREATED", "ENABLED", "ENABLING", "DISABLED", "DISABLING", "DELETED", "DELETING", "DESTROYED", "DESTROYING"
|
||||||
#
|
#
|
||||||
# if cconfig_save is true, only config save without other updates
|
# if cconfig_save is true, only config save without other updates
|
||||||
vins_should_exist = False
|
vins_should_exist = False
|
||||||
|
|
||||||
if decon.vins_id:
|
if self.vins_id:
|
||||||
vins_should_exist = True
|
|
||||||
if decon.vins_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING"]:
|
|
||||||
# error: nothing can be done to existing ViNS in the listed statii regardless of
|
|
||||||
# the requested state
|
|
||||||
decon.result['failed'] = True
|
|
||||||
decon.result['changed'] = False
|
|
||||||
decon.result['msg'] = ("No change can be done for existing ViNS ID {} because of its current "
|
|
||||||
"status '{}'").format(decon.vins_id, decon.vins_facts['status'])
|
|
||||||
elif decon.vins_facts['status'] == "DISABLED":
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
decon.delete()
|
|
||||||
vins_should_exist = False
|
|
||||||
elif amodule.params['state'] in ('present', 'disabled'):
|
|
||||||
# update ViNS, leave in disabled state
|
|
||||||
decon.action()
|
|
||||||
elif amodule.params['state'] == 'enabled':
|
|
||||||
# update ViNS and enable
|
|
||||||
decon.action('enabled')
|
|
||||||
elif decon.vins_facts['status'] in ["CREATED", "ENABLED"]:
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
decon.delete()
|
|
||||||
vins_should_exist = False
|
|
||||||
elif amodule.params['state'] in ('present', 'enabled'):
|
|
||||||
# update ViNS
|
|
||||||
decon.action()
|
|
||||||
elif amodule.params['state'] == 'disabled':
|
|
||||||
# disable and update ViNS
|
|
||||||
decon.action('disabled')
|
|
||||||
elif decon.vins_facts['status'] == "DELETED":
|
|
||||||
if amodule.params['state'] in ['present', 'enabled']:
|
|
||||||
# restore and enable
|
|
||||||
decon.action(restore=True)
|
|
||||||
vins_should_exist = True
|
|
||||||
elif amodule.params['state'] == 'absent':
|
|
||||||
# destroy permanently
|
|
||||||
if decon.amodule.params['permanently']:
|
|
||||||
decon.delete()
|
|
||||||
vins_should_exist = False
|
|
||||||
elif amodule.params['state'] == 'disabled':
|
|
||||||
decon.error()
|
|
||||||
vins_should_exist = False
|
|
||||||
elif decon.vins_facts['status'] == "DESTROYED":
|
|
||||||
if amodule.params['state'] in ('present', 'enabled'):
|
|
||||||
# need to re-provision ViNS;
|
|
||||||
decon.create()
|
|
||||||
vins_should_exist = True
|
|
||||||
elif amodule.params['state'] == 'absent':
|
|
||||||
decon.nop()
|
|
||||||
vins_should_exist = False
|
|
||||||
elif amodule.params['state'] == 'disabled':
|
|
||||||
decon.error()
|
|
||||||
else:
|
|
||||||
# Preexisting ViNS was not found.
|
|
||||||
vins_should_exist = False # we will change it back to True if ViNS is created or restored
|
|
||||||
# If requested state is 'absent' - nothing to do
|
|
||||||
if amodule.params['state'] == 'absent':
|
|
||||||
decon.nop()
|
|
||||||
elif amodule.params['state'] in ('present', 'enabled'):
|
|
||||||
decon.check_amodule_argument('vins_name')
|
|
||||||
# as we already have account ID and RG ID we can create ViNS and get vins_id on success
|
|
||||||
decon.create()
|
|
||||||
vins_should_exist = True
|
vins_should_exist = True
|
||||||
elif amodule.params['state'] == 'disabled':
|
if self.vins_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING"]:
|
||||||
decon.error()
|
# error: nothing can be done to existing ViNS in the listed statii regardless of
|
||||||
#
|
# the requested state
|
||||||
# conditional switch end - complete module run
|
self.result['failed'] = True
|
||||||
#
|
self.result['changed'] = False
|
||||||
if decon.result['failed']:
|
self.result['msg'] = ("No change can be done for existing ViNS ID {} because of its current "
|
||||||
amodule.fail_json(**decon.result)
|
"status '{}'").format(self.vins_id, self.vins_facts['status'])
|
||||||
else:
|
elif self.vins_facts['status'] == "DISABLED":
|
||||||
# prepare ViNS facts to be returned as part of decon.result and then call exit_json(...)
|
if amodule.params['state'] == 'absent':
|
||||||
if decon.result['changed']:
|
self.delete()
|
||||||
_, decon.vins_facts = decon.vins_find(decon.vins_id)
|
vins_should_exist = False
|
||||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
elif amodule.params['state'] in ('present', 'disabled'):
|
||||||
amodule.exit_json(**decon.result)
|
# update ViNS, leave in disabled state
|
||||||
|
self.action()
|
||||||
|
elif amodule.params['state'] == 'enabled':
|
||||||
|
# update ViNS and enable
|
||||||
|
self.action('enabled')
|
||||||
|
elif self.vins_facts['status'] in ["CREATED", "ENABLED"]:
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.delete()
|
||||||
|
vins_should_exist = False
|
||||||
|
elif amodule.params['state'] in ('present', 'enabled'):
|
||||||
|
# update ViNS
|
||||||
|
self.action()
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
# disable and update ViNS
|
||||||
|
self.action('disabled')
|
||||||
|
elif self.vins_facts['status'] == "DELETED":
|
||||||
|
if amodule.params['state'] in ['present', 'enabled']:
|
||||||
|
# restore and enable
|
||||||
|
self.action(restore=True)
|
||||||
|
vins_should_exist = True
|
||||||
|
elif amodule.params['state'] == 'absent':
|
||||||
|
# destroy permanently
|
||||||
|
if self.amodule.params['permanently']:
|
||||||
|
self.delete()
|
||||||
|
vins_should_exist = False
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
self.error()
|
||||||
|
vins_should_exist = False
|
||||||
|
elif self.vins_facts['status'] == "DESTROYED":
|
||||||
|
if amodule.params['state'] in ('present', 'enabled'):
|
||||||
|
# need to re-provision ViNS;
|
||||||
|
self.create()
|
||||||
|
vins_should_exist = True
|
||||||
|
elif amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
vins_should_exist = False
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
self.error()
|
||||||
|
else:
|
||||||
|
# Preexisting ViNS was not found.
|
||||||
|
vins_should_exist = False # we will change it back to True if ViNS is created or restored
|
||||||
|
# If requested state is 'absent' - nothing to do
|
||||||
|
if amodule.params['state'] == 'absent':
|
||||||
|
self.nop()
|
||||||
|
elif amodule.params['state'] in ('present', 'enabled'):
|
||||||
|
self.check_amodule_argument('vins_name')
|
||||||
|
# as we already have account ID and RG ID we can create ViNS and get vins_id on success
|
||||||
|
self.create()
|
||||||
|
vins_should_exist = True
|
||||||
|
elif amodule.params['state'] == 'disabled':
|
||||||
|
self.error()
|
||||||
|
#
|
||||||
|
# conditional switch end - complete module run
|
||||||
|
#
|
||||||
|
if self.result['failed']:
|
||||||
|
amodule.fail_json(**self.result)
|
||||||
|
else:
|
||||||
|
# prepare ViNS facts to be returned as part of self.result and then call exit_json(...)
|
||||||
|
if self.result['changed']:
|
||||||
|
_, self.vins_facts = self.vins_find(self.vins_id)
|
||||||
|
self.result['facts'] = self.package_facts(amodule.check_mode)
|
||||||
|
amodule.exit_json(**self.result)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main():
|
||||||
|
decort_vins().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
141
library/decort_vins_list.py
Normal file
141
library/decort_vins_list.py
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_vins_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortVINSList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
ext_net_ip=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
include_deleted=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
rg_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.VINSStatus._member_names_,
|
||||||
|
),
|
||||||
|
vnfdev_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
zone_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.VINSForListAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.VINSForListAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.vins.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
ext_net_ip=aparam_filter['ext_net_ip'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
include_deleted=aparam_filter['include_deleted'] or False,
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
rg_id=aparam_filter['rg_id'],
|
||||||
|
status=(
|
||||||
|
sdk_types.VINSStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
vnfdev_id=aparam_filter['vnfdev_id'],
|
||||||
|
zone_id=aparam_filter['zone_id'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortVINSList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
2510
library/decort_vm.py
Normal file
2510
library/decort_vm.py
Normal file
File diff suppressed because it is too large
Load Diff
158
library/decort_vm_list.py
Normal file
158
library/decort_vm_list.py
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_vm_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortVMList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
ext_net_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
ext_net_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
include_deleted=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
ip_addr=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
rg_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
rg_name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.VMStatus._member_names_,
|
||||||
|
),
|
||||||
|
tech_status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.VMTechStatus._member_names_,
|
||||||
|
),
|
||||||
|
zone_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.VMAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
aparam_tech_status: str | None = aparam_filter['tech_status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.VMAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.compute.list(
|
||||||
|
account_id=aparam_filter['account_id'],
|
||||||
|
ext_net_id=aparam_filter['ext_net_id'],
|
||||||
|
ext_net_name=aparam_filter['ext_net_name'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
include_deleted=aparam_filter['include_deleted'] or False,
|
||||||
|
ip_addr=aparam_filter['ip_addr'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
rg_id=aparam_filter['rg_id'],
|
||||||
|
rg_name=aparam_filter['rg_name'],
|
||||||
|
status=(
|
||||||
|
sdk_types.VMStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
tech_status=(
|
||||||
|
sdk_types.VMTechStatus[aparam_tech_status]
|
||||||
|
if aparam_tech_status else None
|
||||||
|
),
|
||||||
|
zone_id=aparam_filter['zone_id'],
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortVMList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -30,9 +30,10 @@ class DecortVMSnapshot(DecortController):
|
|||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
self.vm_name = self.vm_facts['name']
|
self.vm_name = self.vm_facts['name']
|
||||||
self.vm_snapshots = self.vm_facts['snapSets']
|
self.vm_snapshots = self.api.ca.compute.snapshot_list(
|
||||||
|
vm_id=self.vm_id).data
|
||||||
self.vm_snapshot_labels = [
|
self.vm_snapshot_labels = [
|
||||||
snapshot['label'] for snapshot in self.vm_snapshots
|
snapshot.label for snapshot in self.vm_snapshots
|
||||||
]
|
]
|
||||||
|
|
||||||
self.new_snapshot_label = None
|
self.new_snapshot_label = None
|
||||||
@@ -102,21 +103,23 @@ class DecortVMSnapshot(DecortController):
|
|||||||
if check_error:
|
if check_error:
|
||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.get_info(first_run=True)
|
self.get_info()
|
||||||
self.check_amodule_args_for_change()
|
self.check_amodule_args_for_change()
|
||||||
self.change()
|
self.change()
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def get_info(self, first_run: bool = False):
|
def get_info(self, update_vm_snapshots: bool = False):
|
||||||
if not first_run:
|
if update_vm_snapshots:
|
||||||
self.vm_snapshots = self.snapshot_list(
|
self.vm_snapshots = self.api.cloudapi.compute.snapshot_list(
|
||||||
compute_id=self.aparams_vm_id,
|
vm_id=self.aparams_vm_id,
|
||||||
)
|
).data
|
||||||
|
|
||||||
label = self.new_snapshot_label or self.aparams_label
|
label = self.new_snapshot_label or self.aparams_label
|
||||||
for snapshot in self.vm_snapshots:
|
for snapshot in self.vm_snapshots:
|
||||||
if snapshot['label'] == label:
|
if snapshot.label == label:
|
||||||
self.facts = snapshot
|
self.facts = snapshot.model_dump()
|
||||||
if self.aparams['usage']:
|
if self.aparams['usage']:
|
||||||
self.facts['stored'] = self.get_snapshot_usage()
|
self.facts['stored'] = self.get_snapshot_usage()
|
||||||
self.facts['vm_id'] = self.aparams_vm_id
|
self.facts['vm_id'] = self.aparams_vm_id
|
||||||
@@ -134,11 +137,11 @@ class DecortVMSnapshot(DecortController):
|
|||||||
self.abort_merge()
|
self.abort_merge()
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self.snapshot_create(
|
self.sdk_checkmode(self.api.cloudapi.compute.snapshot_create)(
|
||||||
compute_id=self.aparams_vm_id,
|
vm_id=self.aparams_vm_id,
|
||||||
label=self.new_snapshot_label,
|
label=self.new_snapshot_label,
|
||||||
)
|
)
|
||||||
self.get_info()
|
self.get_info(update_vm_snapshots=True)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
self.snapshot_delete(
|
self.snapshot_delete(
|
||||||
@@ -149,7 +152,7 @@ class DecortVMSnapshot(DecortController):
|
|||||||
|
|
||||||
def abort_merge(self):
|
def abort_merge(self):
|
||||||
self.snapshot_abort_merge(
|
self.snapshot_abort_merge(
|
||||||
vm_id=self.aparams_vm_id,
|
vm_id=self.aparams_vm_id,
|
||||||
label=self.aparams_label,
|
label=self.aparams_label,
|
||||||
)
|
)
|
||||||
self.get_info()
|
self.get_info()
|
||||||
@@ -161,7 +164,7 @@ class DecortVMSnapshot(DecortController):
|
|||||||
label=label,
|
label=label,
|
||||||
)
|
)
|
||||||
return common_snapshots_usage_info['stored']
|
return common_snapshots_usage_info['stored']
|
||||||
|
|
||||||
def check_amodule_args_for_change(self):
|
def check_amodule_args_for_change(self):
|
||||||
check_errors = False
|
check_errors = False
|
||||||
|
|
||||||
@@ -171,7 +174,7 @@ class DecortVMSnapshot(DecortController):
|
|||||||
):
|
):
|
||||||
check_errors = True
|
check_errors = True
|
||||||
self.message(
|
self.message(
|
||||||
f'Check for parameter "state" failed: '
|
'Check for parameter "state" failed: '
|
||||||
'Merge can be aborted only for VM in "MERGE" tech status.'
|
'Merge can be aborted only for VM in "MERGE" tech status.'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -179,7 +182,6 @@ class DecortVMSnapshot(DecortController):
|
|||||||
self.exit(fail=True)
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
DecortVMSnapshot().run()
|
DecortVMSnapshot().run()
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ description: See L(Module Documentation,https://repository.basistech.ru/BASIS/de
|
|||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.decort_utils import DecortController
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk import exceptions as sdk_exceptions
|
||||||
|
|
||||||
|
|
||||||
class DecortZone(DecortController):
|
class DecortZone(DecortController):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -28,16 +30,29 @@ class DecortZone(DecortController):
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
def run(self):
|
def run(self):
|
||||||
self.get_info()
|
self.get_info()
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
self.facts = self.zone_get(id=self.id)
|
try:
|
||||||
self.facts['grid_id'] = self.facts.pop('gid')
|
zone_model = self.api.cloudapi.zone.get(id=self.id)
|
||||||
self.facts['created_timestamp'] = self.facts.pop('createdTime')
|
except sdk_exceptions.RequestException as e:
|
||||||
self.facts['updated_timestamp'] = self.facts.pop('updatedTime')
|
if (
|
||||||
self.facts['node_ids'] = self.facts.pop('nodeIds')
|
e.orig_exception.response
|
||||||
|
and e.orig_exception.response.status_code == 404
|
||||||
|
):
|
||||||
|
self.message(
|
||||||
|
self.MESSAGES.obj_not_found(
|
||||||
|
obj='zone',
|
||||||
|
id=self.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.exit(fail=True)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
self.facts = zone_model.model_dump()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
133
library/decort_zone_list.py
Normal file
133
library/decort_zone_list.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_zone_list
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
from dynamix_sdk.base import get_alias, name_mapping_dict
|
||||||
|
import dynamix_sdk.types as sdk_types
|
||||||
|
|
||||||
|
|
||||||
|
class DecortZoneList(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
filter=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
deletable=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
description=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
grid_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
node_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
type='str',
|
||||||
|
choices=sdk_types.ZoneStatus._member_names_,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pagination=dict(
|
||||||
|
type='dict',
|
||||||
|
apply_defaults=True,
|
||||||
|
options=dict(
|
||||||
|
number=dict(
|
||||||
|
type='int',
|
||||||
|
default=1,
|
||||||
|
),
|
||||||
|
size=dict(
|
||||||
|
type='int',
|
||||||
|
default=50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
sorting=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
asc=dict(
|
||||||
|
type='bool',
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
field=dict(
|
||||||
|
type='str',
|
||||||
|
choices=(
|
||||||
|
sdk_types.ZoneForListAPIResultNM
|
||||||
|
.model_fields.keys()
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@DecortController.handle_sdk_exceptions
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
aparam_filter: dict[str, Any] = self.aparams['filter']
|
||||||
|
aparam_status: str | None = aparam_filter['status']
|
||||||
|
|
||||||
|
aparam_pagination: dict[str, Any] = self.aparams['pagination']
|
||||||
|
|
||||||
|
aparam_sorting: dict[str, Any] | None = self.aparams['sorting']
|
||||||
|
sort_by: str | None = None
|
||||||
|
if aparam_sorting:
|
||||||
|
sorting_field = get_alias(
|
||||||
|
field_name=aparam_sorting['field'],
|
||||||
|
model_cls=sdk_types.ZoneForListAPIResultNM,
|
||||||
|
name_mapping_dict=name_mapping_dict,
|
||||||
|
)
|
||||||
|
sort_by_prefix = '+' if aparam_sorting['asc'] else '-'
|
||||||
|
sort_by = f'{sort_by_prefix}{sorting_field}'
|
||||||
|
|
||||||
|
self.facts = self.api.cloudapi.zone.list(
|
||||||
|
deletable=aparam_filter['deletable'],
|
||||||
|
description=aparam_filter['description'],
|
||||||
|
grid_id=aparam_filter['grid_id'],
|
||||||
|
id=aparam_filter['id'],
|
||||||
|
name=aparam_filter['name'],
|
||||||
|
node_id=aparam_filter['node_id'],
|
||||||
|
status=(
|
||||||
|
sdk_types.ZoneStatus[aparam_status]
|
||||||
|
if aparam_status else None
|
||||||
|
),
|
||||||
|
page_number=aparam_pagination['number'],
|
||||||
|
page_size=aparam_pagination['size'],
|
||||||
|
sort_by=sort_by,
|
||||||
|
).model_dump()['data']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortZoneList().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
|||||||
-r requirements.txt
|
|
||||||
pre-commit==4.1.0
|
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
ansible==11.6.0
|
ansible==11.6.0
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
|
git+https://repository.basistech.ru/BASIS/dynamix-python-sdk.git@1.4.latest
|
||||||
|
|||||||
Reference in New Issue
Block a user