Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Aleksandr Malyavin | a4800cd041 | 3 years ago |
Aleksandr Malyavin | ba8165bcf9 | 3 years ago |
Aleksandr Malyavin | d36ab8f36f | 3 years ago |
Aleksandr Malyavin | 587f0d9c0b | 3 years ago |
@ -1,19 +1,12 @@
|
||||
# decort-ansible
|
||||
Модули Ansible для платформы Digital Energy Orchestration Technology (DECORT).
|
||||
Ansible modules for Digital Energy Orchestration Technology (DECORT) platform v3.6.1 and above.
|
||||
|
||||
## Соответствие версий платформы версиям модулей Ansible
|
||||
Note that this module may produce unreliable results when used with older DECORT API versions.
|
||||
|
||||
| Версия платформы | Версия модулей Ansible |
|
||||
|:----------------:|:--------------------------:|
|
||||
| 4.2.0 | 7.0.x, 7.1.x |
|
||||
| 4.1.0 | 6.0.x, 6.1.x |
|
||||
| 4.0.0 | 5.6.x, 5.5.x, 5.4.x, 5.3.x |
|
||||
| 3.8.8, 3.8.9 | 5.2.6 |
|
||||
| 3.8.7 | 5.2.5 |
|
||||
| 3.8.6 | 5.2.4 |
|
||||
|
||||
## Ссылки
|
||||
|
||||
- [Документация](./wiki/Home.md)
|
||||
|
||||
- [Список изменений](./CHANGELOG.md)
|
||||
Requirements:
|
||||
* Ansible 2.7 or higher
|
||||
* Python 3.7 or higher
|
||||
* PyJWT 2.0.0 Python module or higher
|
||||
* requests Python module
|
||||
* netaddr Python module
|
||||
* DECORT cloud platform version 3.5.0 or higher
|
||||
|
@ -0,0 +1,36 @@
|
||||
---
|
||||
#
|
||||
# DECORT kvmvm module example
|
||||
#
|
||||
- hosts: ansible_master
|
||||
tasks:
|
||||
- name: create a VM named cloud-init_example
|
||||
decort_kvmvm:
|
||||
name: affinity_example
|
||||
annotation: "VM managed by decort_kvmvm module"
|
||||
authenticator: oauth2
|
||||
app_id: "" # Application id from SSO Digital Energy
|
||||
app_secret: "" # API key from SSO Digital Energy
|
||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
||||
rg_id: # Resource group id
|
||||
cpu: 2
|
||||
ram: 2048
|
||||
boot_disk: 10
|
||||
image_name: "DECS Ubuntu 18.04 v1.2.3" # Name of OS image
|
||||
networks:
|
||||
- type: VINS
|
||||
id: # VINS id
|
||||
tags: "Ansible cloud init example"
|
||||
aff_lable: "Affinity lable"
|
||||
tag:
|
||||
- key: bd
|
||||
value: main
|
||||
aff_rule:
|
||||
- key: app
|
||||
value: main
|
||||
topology: compute
|
||||
policy: REQUIRED
|
||||
mode: EQ
|
||||
state: present
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -0,0 +1,36 @@
|
||||
---
|
||||
#
|
||||
# DECORT kvmvm module example
|
||||
#
|
||||
- hosts: ansible_master
|
||||
tasks:
|
||||
- name: create a VM named cloud-init_example
|
||||
decort_kvmvm:
|
||||
name: anti-affinity_example
|
||||
annotation: "VM managed by decort_kvmvm module"
|
||||
authenticator: oauth2
|
||||
app_id: "" # Application id from SSO Digital Energy
|
||||
app_secret: "" # API key from SSO Digital Energy
|
||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
||||
rg_id: # Resource group id
|
||||
cpu: 2
|
||||
ram: 2048
|
||||
boot_disk: 10
|
||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
||||
networks:
|
||||
- type: VINS
|
||||
id: #VINS id
|
||||
tags: "Ansible cloud init example"
|
||||
aff_lable: "Anti affinity lable"
|
||||
tag:
|
||||
- key: bd
|
||||
value: main
|
||||
aaff_rule:
|
||||
- key: app
|
||||
value: main
|
||||
topology: compute
|
||||
policy: REQUIRED
|
||||
mode: ANY
|
||||
state: present
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -0,0 +1,38 @@
|
||||
#
|
||||
# DECORT kvmvm module example
|
||||
#
|
||||
- hosts: ansible_master
|
||||
tasks:
|
||||
- name: create a VM named cloud-init_example
|
||||
decort_kvmvm:
|
||||
annotation: "VM managed by decort_kvmvm module"
|
||||
authenticator: oauth2
|
||||
app_id: "" # Application id from SSO Digital Energy
|
||||
app_secret: "" # API key from SSO Digital Energy
|
||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
||||
name: cloud-init_example
|
||||
cpu: 2
|
||||
ram: 2048
|
||||
boot_disk: 10
|
||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
||||
networks:
|
||||
- type: VINS
|
||||
id: #VINS id
|
||||
tags: "Ansible cloud init example"
|
||||
state: present
|
||||
rg_id: #Resource group id
|
||||
ci_user_data:
|
||||
- packages:
|
||||
- apache2
|
||||
- write_files:
|
||||
- content: |
|
||||
<div>
|
||||
Hello World!
|
||||
</div>
|
||||
owner: user:user
|
||||
path: /var/www/html/index.html
|
||||
- hostname: test-apache
|
||||
- ssh_keys:
|
||||
- rsa_public: ssh-rsa AAAAOasDmLxnD= user@pc
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: oauth2
|
||||
app_id: #Application id from SSO DigitalEnergy
|
||||
app_secret: #Application secret from SSO DigitalEnergy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
account_name: "account_name"
|
||||
name: "example_disk"
|
||||
sep_id: 1
|
||||
pool: 0
|
||||
gid: 0
|
||||
size: 2
|
||||
type: "D"
|
||||
description: "Disk created by decort_disk module"
|
||||
iops: 2000
|
||||
state: present
|
||||
verify_ssl: false
|
||||
|
||||
delegate_to: localhost
|
@ -1,18 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: oauth2
|
||||
app_id: #Application id from SSO DigitalEnergy
|
||||
app_secret: #Application secret from SSO DigitalEnergy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
account_name: "account_name"
|
||||
name: "example_disk"
|
||||
permanently: False
|
||||
force_detach: True
|
||||
reason: "Just to test module decort_disk"
|
||||
state: absent
|
||||
verify_ssl: false
|
||||
|
||||
delegate_to: localhost
|
@ -1,28 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: oauth2
|
||||
app_id: #Application id from SSO DigitalEnergy
|
||||
app_secret: #Application secret from SSO DigitalEnergy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
account_name: "account_name"
|
||||
id: 111
|
||||
limitIO:
|
||||
read_bytes_sec: 100
|
||||
read_bytes_sec_max: 100
|
||||
read_iops_sec: 100
|
||||
read_iops_sec_max: 100
|
||||
size_iops_sec: 100
|
||||
write_bytes_sec: 100
|
||||
write_bytes_sec_max: 100
|
||||
write_iops_sec: 100
|
||||
write_iops_sec_max: 100
|
||||
total_bytes_sec: 0
|
||||
total_iops_sec: 0
|
||||
total_bytes_sec_max: 0
|
||||
total_iops_sec_max: 0
|
||||
verify_ssl: false
|
||||
|
||||
delegate_to: localhost
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: oauth2
|
||||
app_id: #Application id from SSO DigitalEnergy
|
||||
app_secret: #Application secret from SSO DigitalEnergy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
account_name: "account_name"
|
||||
id: 111
|
||||
name: "example_disk2"
|
||||
verify_ssl: false
|
||||
|
||||
delegate_to: localhost
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: oauth2
|
||||
app_id: #Application id from SSO DigitalEnergy
|
||||
app_secret: #Application secret from SSO DigitalEnergy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
account_name: "account_name"
|
||||
id: 111
|
||||
state: present
|
||||
verify_ssl: false
|
||||
|
||||
delegate_to: localhost
|
@ -1,20 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
quotas:
|
||||
cpu: 8
|
||||
ram: 4096
|
||||
disk: 20
|
||||
ext_ips: 10
|
||||
net_transfer: 200
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,21 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
resType:
|
||||
- vins
|
||||
- compute
|
||||
- k8s
|
||||
- openshift
|
||||
- lb
|
||||
- flipgroup
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,30 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
account_id: 99
|
||||
owner: "user_1" #Leave blank to set current user as owner.
|
||||
quotas:
|
||||
cpu: 8
|
||||
ram: 4096
|
||||
disk: 20
|
||||
ext_ips: 10
|
||||
net_transfer: 200
|
||||
access:
|
||||
action: "grant"
|
||||
user: "user_2"
|
||||
right: "RCX"
|
||||
def_netType: "PRIVATE"
|
||||
ipcidr: "" "192.168.1.1"
|
||||
extNetId: 0
|
||||
extNetIp: "" "10.100.1.10"
|
||||
resType:
|
||||
- vins
|
||||
- compute
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,15 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "test_rg"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
state: present
|
||||
permanently: True
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,12 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_id: 999 # rg can be restored only by rg id
|
||||
account_id: 99
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,14 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
state: enabled
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,18 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
access:
|
||||
action: "grant"
|
||||
user: "new_user"
|
||||
right: "R"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,15 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "old_rg_name"
|
||||
# or
|
||||
#rg_id: 1737
|
||||
account_id: 99
|
||||
rename: "new_rg_name"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,17 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
access:
|
||||
action: "revoke"
|
||||
user: "old_user"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,16 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_rg:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
rg_name: "rg_created_by_module"
|
||||
# or
|
||||
#rg_id: 999
|
||||
account_id: 99
|
||||
def_netType: "PRIVATE"
|
||||
def_netId: 199
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
#
|
||||
# This playbook create engine "test".
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- hashivault_secret_engine:
|
||||
url: "https://vault.domain.local"
|
||||
authtype: ldap
|
||||
username: "user"
|
||||
password: "p@ssword"
|
||||
state: present
|
||||
name: test
|
||||
backend: generic
|
@ -1,17 +0,0 @@
|
||||
---
|
||||
#
|
||||
# This playbook create secret "secret" with data foo:foe. If secret "secret" exists - add data foo:foe.
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- hashivault_secret:
|
||||
url: "https://vault.domain.local"
|
||||
authtype: ldap
|
||||
username: "user"
|
||||
password: "p@ssword"
|
||||
mount_point: "kv"
|
||||
state: present
|
||||
permanent: true
|
||||
secret: secret
|
||||
data:
|
||||
foo: foe
|
@ -1,35 +0,0 @@
|
||||
---
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- hashivault_read:
|
||||
url: "https://vault.domain.local"
|
||||
authtype: ldap
|
||||
username: "user"
|
||||
password: "p@ssword"
|
||||
mount_point: kv
|
||||
secret: secrets/myaccount
|
||||
key: app_secret
|
||||
version: 2
|
||||
register: key
|
||||
|
||||
- name: create a VM using app_secret from hashicorp vault
|
||||
decort_kvmvm:
|
||||
annotation: "VM managed by decort_kvmvm module"
|
||||
authenticator: oauth2
|
||||
app_id: "" # Application id from SSO Digital Energy
|
||||
app_secret: "{{ key }}" # API key from SSO Digital Energy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
name: hashivault_read_example
|
||||
cpu: 2
|
||||
ram: 2048
|
||||
boot_disk: 10
|
||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
||||
networks:
|
||||
- type: VINS
|
||||
id: 99 #VINS id
|
||||
tags: "Ansible hashivault_read example"
|
||||
state: present
|
||||
rg_id: 99 #Resource group id
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -1,31 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: Read a kv2 secret with kv mount point
|
||||
vars:
|
||||
ansible_hashi_vault_auth_method: ldap
|
||||
ansible_hashi_vault_username: username
|
||||
ansible_hashi_vault_password: pwd
|
||||
ansible_hashi_vault_engine_mount_point: kv
|
||||
ansible.builtin.set_fact:
|
||||
response: "{{ lookup('community.hashi_vault.vault_kv2_get', 'secret', url='https://vault.domain.local') }}"
|
||||
|
||||
- name: create a VM using app_secret from hashicorp vault
|
||||
decort_kvmvm:
|
||||
annotation: "VM managed by decort_kvmvm module"
|
||||
authenticator: oauth2
|
||||
app_id: "" # Application id from SSO Digital Energy
|
||||
app_secret: "{{ response.data.password }}" # API key from SSO Digital Energy
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
name: hashivault_read_example
|
||||
cpu: 2
|
||||
ram: 2048
|
||||
boot_disk: 10
|
||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
||||
networks:
|
||||
- type: VINS
|
||||
id: 99 #VINS id
|
||||
tags: "Ansible hashivault_read example"
|
||||
state: present
|
||||
rg_id: 99 #Resource group id
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -1,16 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: Get auth token from vault
|
||||
set_fact:
|
||||
login_data: "{{ lookup('community.hashi_vault.vault_login', url='https://vault.domain.local', auth_method='ldap', username='username', password='pwd') }}"
|
||||
|
||||
- name: Perform multiple kv2 reads with a single Vault login, showing the secrets
|
||||
vars:
|
||||
ansible_hashi_vault_auth_method: token
|
||||
ansible_hashi_vault_token: '{{ login_data | community.hashi_vault.vault_login_token }}'
|
||||
ansible_hashi_vault_engine_mount_point: kv
|
||||
paths:
|
||||
- secret
|
||||
- secret2
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.hashi_vault.vault_kv2_get', *paths, auth_method='token', url='https://vault.domain.local') }}"
|
@ -1,18 +0,0 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: Read a kv2 secret with the default mount point
|
||||
vars:
|
||||
ansible_hashi_vault_auth_method: ldap
|
||||
ansible_hashi_vault_username: username
|
||||
ansible_hashi_vault_password: pwd
|
||||
ansible_hashi_vault_engine_mount_point: kv
|
||||
ansible.builtin.set_fact:
|
||||
response: "{{ lookup('community.hashi_vault.vault_kv2_get', 'secret', url='https://vault.domain.local') }}"
|
||||
|
||||
- name: Display the results
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "Secret: {{ response.secret }}"
|
||||
- "Data: {{ response.data }} (contains secret data & metadata in kv2)"
|
||||
- "Metadata: {{ response.metadata }}"
|
||||
- "Full response: {{ response.raw }}"
|
@ -1,13 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- hashivault_read:
|
||||
url: "https://vault.domain.local"
|
||||
authtype: ldap
|
||||
username: "uset"
|
||||
password: "p@ssword"
|
||||
mount_point: kv
|
||||
secret: secret
|
||||
key: foo
|
||||
version: 2
|
||||
register: key
|
@ -0,0 +1,2 @@
|
||||
[all]
|
||||
ansible_master ansible_host=<ansible host IP address> ansible_port=<SSH port on ansible host> ansible_user=root
|
@ -0,0 +1,18 @@
|
||||
#
|
||||
# More details on how to use DECORT Ansible module can be found at:
|
||||
# https://github.com/rudecs/decort-ansible/wiki
|
||||
#
|
||||
|
||||
- hosts: ansible_master
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "{{ decort_sso }}" # "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
register: my_jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out JWT
|
||||
debug:
|
||||
var: my_jwt.jwt
|
||||
delegate_to: localhost
|
@ -0,0 +1,323 @@
|
||||
#
|
||||
# More details on how to use DECORT Ansible module can be found at:
|
||||
# https://github.com/rudecs/decort-ansible/wiki
|
||||
#
|
||||
|
||||
- hosts: ansible_master
|
||||
vars_files:
|
||||
- vars.yaml
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
validity: 1200
|
||||
register: token
|
||||
delegate_to: localhost
|
||||
|
||||
- name: obtain OS image
|
||||
decort_osimage:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
image_name: "{{ os_image_name }}"
|
||||
account_name: "{{ target_account_name }}"
|
||||
verify_ssl: false
|
||||
register: my_image
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_image.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage RG
|
||||
decort_rg:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
account_id: 32
|
||||
rg_name: "{{ target_rg_name }}"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_rg
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_rg.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage ViNS 01
|
||||
decort_vins:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
vins_name: "{{ vins01_name }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
ext_net_id: "{{ target_ext_net_id }}"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_vins01
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_vins01.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage ViNS 02
|
||||
decort_vins:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
vins_name: "{{ vins02_name }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
ext_net_id: -1
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_vins02
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_vins02.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage data disk 01
|
||||
decort_disk:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
name: "{{ datadisk01_name }}"
|
||||
size: "{{ datadisk01_size }}"
|
||||
account_name: "{{ target_account_name }}"
|
||||
pool: data01
|
||||
place_with: "{{ my_image.facts.id }}"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_disk01
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_disk01.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage data disk 02
|
||||
decort_disk:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
name: "{{ datadisk02_name }}"
|
||||
size: "{{ datadisk02_size }}"
|
||||
account_name: "{{ target_account_name }}"
|
||||
pool: data01
|
||||
place_with: "{{ my_image.facts.id }}"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_disk02
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_disk02.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage KVM X86 VM
|
||||
decort_kvmvm:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
name: "{{ vm01_name }}"
|
||||
arch: KVM_X86
|
||||
ram: "{{ vm01_ram }}"
|
||||
cpu: "{{ vm01_cpu }}"
|
||||
image_id: "{{ my_image.facts.id }}"
|
||||
boot_disk: "{{ vm01_boot_disk }}"
|
||||
data_disks:
|
||||
- "{{ my_disk01.facts.id }}"
|
||||
- "{{ my_disk02.facts.id }}"
|
||||
networks:
|
||||
- type: VINS
|
||||
id: "{{ my_vins01.facts.id }}"
|
||||
- type: VINS
|
||||
id: "{{ my_vins02.facts.id }}"
|
||||
- type: EXTNET
|
||||
id: "{{ target_ext_net_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_kvmvm
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_kvmvm.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: manage PFW rules on Compute
|
||||
decort_pfw:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
oauth2_url: "{{ decort_sso }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
compute_id: "{{ my_kvmvm.facts.id }}"
|
||||
vins_id: "{{ my_vins01.facts.id }}"
|
||||
rules:
|
||||
- public_port_start: 30022
|
||||
local_port: 22
|
||||
proto: tcp
|
||||
- public_port_start: 30080
|
||||
public_port_end: 30085
|
||||
local_port: 30080
|
||||
proto: tcp
|
||||
state: present
|
||||
verify_ssl: false
|
||||
register: my_pfw
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: my_pfw.facts
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create k8s cluster with params
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
master_count: 1
|
||||
master_cpu: 2
|
||||
master_ram_mb: 2048
|
||||
master_disk_gb: 20
|
||||
worker_count: 3
|
||||
worker_cpu: 1
|
||||
worker_ram_mb: 1024
|
||||
worker_disk_gb: 20
|
||||
extnet_id: "{{ target_ext_net_id }}"
|
||||
with_lb: True
|
||||
state: present
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Disable k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: disabled
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Delete in trash k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: absent
|
||||
permanent: False
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Restore from trash deleted k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: enabled
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Enable k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: enabled
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Enable k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: enabled
|
||||
started: True
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Destroy k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "{{ decort_ctrl }}"
|
||||
k8s_name: "k8s_cluster_name"
|
||||
wg_name: "k8s_wg_name"
|
||||
k8ci_id: "{{ k8ci_id }}"
|
||||
rg_id: "{{ my_rg.facts.id }}"
|
||||
state: absent
|
||||
permanent: True
|
||||
register: k8s
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out the result
|
||||
debug:
|
||||
var: k8s
|
||||
delegate_to: localhost
|
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 1. As this file will contain sensitive data (application ID & Secret pair) put this file
|
||||
# in a directory, where only you will have access to it, e.g. your ~/.ssh directory.
|
||||
# 2. Make sure this file is not readable by anybody else (chmod 400).
|
||||
# 3. Paste your Application ID (obtained from DECORT SSO application) to DECORT_APP_ID.
|
||||
# 4. Paste your Application Secret (obtained from DECORT SSO application) to DECORT_APP_SECRET.
|
||||
# 5. Paste DECORT SSO application URL to DECORT_OAUTH2_URL.
|
||||
#
|
||||
# Source this file into shell to prepare environment for running DECORT Ansible module, e.g.
|
||||
# . ~/.ssh/prepenv.sh
|
||||
#
|
||||
# More informaiton on DECORT Ansible module can be found at:
|
||||
# https://github.com/rudecs/decort-ansible/wiki
|
||||
#
|
||||
|
||||
export DECORT_APP_ID="put your application ID here"
|
||||
export DECORT_APP_SECRET="put your application secret here"
|
||||
export DECORT_OAUTH2_URL="put DECORT SSO URL here" # "https://sso.digitalenergy.online"
|
||||
|
||||
export ANSIBLE_HOST_KEY_CHEKCING=False
|
@ -0,0 +1,26 @@
|
||||
#
|
||||
# More details on how to use DECORT Ansible module can be found at:
|
||||
# https://github.com/rudecs/decort-ansible/wiki
|
||||
#
|
||||
|
||||
decort_sso: "put DECORT SSO application URL here" # "https://sso.digitalenergy.online"
|
||||
decort_ctrl: "put DECORT controller URL here" # "https://ds1.digitalenergy.online"
|
||||
|
||||
target_account_name: "your account name"
|
||||
target_rg_name: "target resource group name"
|
||||
os_image_name: "OS image name"
|
||||
|
||||
vins01_name: "Vins01-ansible"
|
||||
vins02_name: "Vins02-ansible"
|
||||
target_ext_net_id: 0
|
||||
|
||||
datadisk01_name: "Data01-ansible"
|
||||
datadisk01_size: 5
|
||||
|
||||
datadisk02_name: "Data02-ansible"
|
||||
datadisk02_size: 5
|
||||
|
||||
vm01_name: "Vm01-ansible"
|
||||
vm01_cpu: 1
|
||||
vm01_ram: 1024
|
||||
vm01_boot_disk: 10
|
@ -1,369 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_account
|
||||
|
||||
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home).
|
||||
'''
|
||||
|
||||
from typing import Iterable
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.decort_utils import DecortController
|
||||
|
||||
|
||||
class DecortAccount(DecortController):
|
||||
OBJ = 'account'
|
||||
|
||||
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(
|
||||
access_emails=dict(
|
||||
type='bool',
|
||||
),
|
||||
acl=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
mode=dict(
|
||||
type='str',
|
||||
choices=[
|
||||
'match',
|
||||
'revoke',
|
||||
'update',
|
||||
],
|
||||
default='update',
|
||||
),
|
||||
users=dict(
|
||||
type='list',
|
||||
required=True,
|
||||
elements='dict',
|
||||
options=dict(
|
||||
rights=dict(
|
||||
type='str',
|
||||
choices=['R', 'RCX', 'ARCXDU'],
|
||||
default='R',
|
||||
),
|
||||
id=dict(
|
||||
type='str',
|
||||
required=True,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
),
|
||||
name=dict(
|
||||
type='str',
|
||||
),
|
||||
quotas=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
cpu=dict(
|
||||
type='int',
|
||||
),
|
||||
disks_size=dict(
|
||||
type='int',
|
||||
),
|
||||
ext_traffic=dict(
|
||||
type='int',
|
||||
),
|
||||
gpu=dict(
|
||||
type='int',
|
||||
),
|
||||
public_ip=dict(
|
||||
type='int',
|
||||
),
|
||||
ram=dict(
|
||||
type='int',
|
||||
),
|
||||
),
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
choices=[
|
||||
'absent',
|
||||
'absent_permanently',
|
||||
'confirmed',
|
||||
'disabled',
|
||||
'present',
|
||||
],
|
||||
default='present',
|
||||
),
|
||||
sep_pools=dict(
|
||||
type='list',
|
||||
elements='dict',
|
||||
options=dict(
|
||||
sep_id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
pool_names=dict(
|
||||
type='list',
|
||||
required=True,
|
||||
elements='str',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
required_one_of=[
|
||||
('id', 'name')
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
def check_amodule_args(self):
|
||||
"""
|
||||
Additional Ansible Module arguments validation that
|
||||
cannot be implemented using Ansible Argument spec.
|
||||
"""
|
||||
|
||||
arg_state = self.aparams['state']
|
||||
if 'absent' in arg_state:
|
||||
# Parameters or combinations of parameters that can
|
||||
# cause changing the object.
|
||||
changing_params = [
|
||||
'access_emails',
|
||||
'acl',
|
||||
['id', 'name'],
|
||||
'quotas',
|
||||
]
|
||||
check_error = False
|
||||
for elem in changing_params:
|
||||
if isinstance(elem, str):
|
||||
param = elem
|
||||
if self.aparams[elem] is not None:
|
||||
self.message(
|
||||
f'If the parameter "state" is set to'
|
||||
f' "{arg_state}", then using the parameter'
|
||||
f' "{param}" is not allowed.'
|
||||
)
|
||||
check_error = True
|
||||
elif isinstance(elem, Iterable):
|
||||
params = elem
|
||||
params_using = map(
|
||||
lambda x: self.aparams[x] is not None, params
|
||||
)
|
||||
if all(params_using):
|
||||
params_str = ', '.join(f'"{p}"' for p in params)
|
||||
self.message(
|
||||
f'If the parameter "state" is set to'
|
||||
f' "{arg_state}", then using the combination'
|
||||
f' of parameters {params_str} are not allowed.'
|
||||
)
|
||||
check_error = True
|
||||
if check_error:
|
||||
self.exit(fail=True)
|
||||
|
||||
def run(self):
|
||||
self.get_info()
|
||||
self.change()
|
||||
self.exit()
|
||||
|
||||
def get_info(self):
|
||||
# If this is the first getting info
|
||||
if not getattr(self, 'id', None):
|
||||
self.id, self.facts = self.account_find(
|
||||
account_name=self.aparams['name'],
|
||||
account_id=self.aparams['id'],
|
||||
)
|
||||
# If this is a repeated getting info
|
||||
else:
|
||||
# If check mode is enabled, there is no needed to
|
||||
# request info again
|
||||
if not self.amodule.check_mode:
|
||||
self.id, self.facts = self.account_find(account_id=self.id)
|
||||
|
||||
def change(self):
|
||||
self.change_state()
|
||||
|
||||
self.change_acl()
|
||||
|
||||
if self.account_update_args:
|
||||
self.account_update(account_id=self.id,
|
||||
**self.account_update_args)
|
||||
self.get_info()
|
||||
|
||||
def change_state(self):
|
||||
match self.facts:
|
||||
case None:
|
||||
self.message(self.MESSAGES.obj_not_found(obj=self.OBJ))
|
||||
match self.aparams:
|
||||
case {'state': 'absent' | 'absent_permanently'}:
|
||||
pass
|
||||
case {'state': 'confirmed' | 'disabled' | 'present'}:
|
||||
self.exit(fail=True)
|
||||
case {'status': 'DESTROYED'}:
|
||||
match self.aparams:
|
||||
case {'state': 'absent' | 'absent_permanently'}:
|
||||
self.message(
|
||||
self.MESSAGES.obj_deleted(
|
||||
obj=self.OBJ,
|
||||
id=self.id,
|
||||
permanently=True,
|
||||
already=True,
|
||||
)
|
||||
)
|
||||
case {'state': 'confirmed' | 'disabled' | 'present'}:
|
||||
self.message(
|
||||
self.MESSAGES.obj_not_restored(obj=self.OBJ,
|
||||
id=self.id)
|
||||
)
|
||||
self.exit(fail=True)
|
||||
case {'status': 'DELETED'}:
|
||||
match self.aparams:
|
||||
case {'state': 'absent'}:
|
||||
self.message(
|
||||
self.MESSAGES.obj_deleted(
|
||||
obj=self.OBJ,
|
||||
id=self.id,
|
||||
permanently=False,
|
||||
already=True,
|
||||
)
|
||||
)
|
||||
case {'state': 'absent_permanently'}:
|
||||
self.delete(permanently=True)
|
||||
case {'state': 'confirmed' | 'present'}:
|
||||
self.restore()
|
||||
case {'state': 'disabled'}:
|
||||
self.restore()
|
||||
self.disable()
|
||||
case {'status': 'CONFIRMED'}:
|
||||
match self.aparams:
|
||||
case {'state': 'absent'}:
|
||||
self.delete()
|
||||
case {'state': 'absent_permanently'}:
|
||||
self.delete(permanently=True)
|
||||
case {'state': 'confirmed' | 'present'}:
|
||||
pass
|
||||
case {'state': 'disabled'}:
|
||||
self.disable()
|
||||
case {'status': 'DISABLED'}:
|
||||
match self.aparams:
|
||||
case {'state': 'absent'}:
|
||||
self.delete()
|
||||
case {'state': 'absent_permanently'}:
|
||||
self.delete(permanently=True)
|
||||
case {'state': 'confirmed'}:
|
||||
self.enable()
|
||||
case {'state': 'present' | 'disabled'}:
|
||||
pass
|
||||
|
||||
def delete(self, permanently=False):
|
||||
self.account_delete(account_id=self.id, permanently=permanently)
|
||||
self.get_info()
|
||||
|
||||
def disable(self):
|
||||
self.account_disable(account_id=self.id)
|
||||
self.get_info()
|
||||
|
||||
def enable(self):
|
||||
self.account_enable(account_id=self.id)
|
||||
self.get_info()
|
||||
|
||||
def restore(self):
|
||||
self.account_restore(account_id=self.id)
|
||||
self.get_info()
|
||||
|
||||
def change_acl(self):
|
||||
if not self.aparams['acl']:
|
||||
return
|
||||
|
||||
actual_users = {u['userGroupId']: u['right'] for u in self.facts['acl']}
|
||||
actual_users_ids = set(actual_users.keys())
|
||||
|
||||
aparams_acl = self.aparams['acl']
|
||||
aparams_users = {u['id']: u['rights'] for u in aparams_acl['users']}
|
||||
aparams_users_ids = set(aparams_users.keys())
|
||||
|
||||
del_users_ids = None
|
||||
upd_users = None
|
||||
new_users = None
|
||||
|
||||
match aparams_acl:
|
||||
case {'mode': 'revoke'}:
|
||||
del_users_ids = aparams_users_ids.intersection(actual_users_ids)
|
||||
case {'mode': 'update' | 'match' as mode}:
|
||||
new_users_ids = aparams_users_ids.difference(actual_users_ids)
|
||||
new_users = dict(
|
||||
u for u in aparams_users.items() if u[0] in new_users_ids
|
||||
)
|
||||
|
||||
upd_users_ids =\
|
||||
aparams_users_ids.intersection(actual_users_ids)
|
||||
upd_users = dict()
|
||||
for id in upd_users_ids:
|
||||
if actual_users[id] == 'CXDRAU':
|
||||
actual_user_rights = 'ARCXDU'
|
||||
else:
|
||||
actual_user_rights = actual_users[id]
|
||||
|
||||
if actual_user_rights != aparams_users[id]:
|
||||
upd_users[id] = aparams_users[id]
|
||||
|
||||
if mode == 'match':
|
||||
del_users_ids =\
|
||||
actual_users_ids.difference(aparams_users_ids)
|
||||
|
||||
if del_users_ids or new_users or upd_users:
|
||||
self.account_change_acl(account_id=self.id,
|
||||
del_users=del_users_ids,
|
||||
add_users=new_users,
|
||||
upd_users=upd_users)
|
||||
self.get_info()
|
||||
|
||||
@property
|
||||
def account_update_args(self) -> dict:
|
||||
result_args = dict()
|
||||
|
||||
aparam_access_emails = self.aparams['access_emails']
|
||||
if (aparam_access_emails is not None
|
||||
and self.facts['sendAccessEmails'] != aparam_access_emails):
|
||||
result_args['access_emails'] = aparam_access_emails
|
||||
|
||||
aparam_name = self.aparams['name']
|
||||
if (self.aparams['id'] and aparam_name
|
||||
and self.facts['name'] != aparam_name):
|
||||
result_args['name'] = aparam_name
|
||||
|
||||
aparam_quotas = self.aparams['quotas']
|
||||
if aparam_quotas:
|
||||
quotas_naming = [
|
||||
['cpu', 'CU_C', 'cpu_quota'],
|
||||
['disks_size', 'CU_DM', 'disks_size_quota'],
|
||||
['ext_traffic', 'CU_NP', 'ext_traffic_quota'],
|
||||
['gpu', 'gpu_units', 'gpu_quota'],
|
||||
['public_ip', 'CU_I', 'public_ip_quota'],
|
||||
['ram', 'CU_M', 'ram_quota'],
|
||||
]
|
||||
for aparam, info_key, result_arg in quotas_naming:
|
||||
current_value = int(self.facts['resourceLimits'][info_key])
|
||||
if (aparam_quotas[aparam] is not None
|
||||
and current_value != aparam_quotas[aparam]):
|
||||
result_args[result_arg] = aparam_quotas[aparam]
|
||||
|
||||
aparam_sep_pools = self.aparams['sep_pools']
|
||||
if aparam_sep_pools is not None:
|
||||
sep_pools = set()
|
||||
for sep in aparam_sep_pools:
|
||||
for pool_name in sep['pool_names']:
|
||||
sep_pools.add(
|
||||
f'{sep["sep_id"]}_{pool_name}'
|
||||
)
|
||||
if set(self.facts['uniqPools']) != sep_pools:
|
||||
result_args['sep_pools'] = sep_pools
|
||||
return result_args
|
||||
|
||||
|
||||
def main():
|
||||
DecortAccount().run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,578 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_account_info
|
||||
|
||||
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.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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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():
|
||||
DecortAccountInfo().run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,38 +1,157 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Digital Enegry Cloud Orchestration Technology (DECORT) modules for Ansible
|
||||
# Copyright: (c) 2018-2021 Digital Energy Cloud Solutions LLC
|
||||
#
|
||||
# Apache License 2.0 (see http://www.apache.org/licenses/LICENSE-2.0.txt)
|
||||
#
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
#
|
||||
# Author: Sergey Shubin (sergey.shubin@digitalenergy.online)
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: decort_jwt
|
||||
short_description: Obtain access token to be used for authentication to DECORT cloud controller
|
||||
description:
|
||||
- Obtain JWT (JSON Web Token) from the specified Oauth2 provider. This JWT can be used in subsequent DECS modules'
|
||||
invocations to authenticate them to the DECS cloud controller.
|
||||
version_added: "2.4"
|
||||
author: "Sergey Shubin (sergey.shubin@digitalenergy.online)"
|
||||
notes:
|
||||
- Environment variables can be used to pass parameters to the module (see options below for details).
|
||||
- Specified Oauth2 provider must be trusted by the DECORT cloud controller on which JWT will be used.
|
||||
- 'If you register module output as I(my_jwt), the JWT value is accessed as I(my_jwt.jwt)'
|
||||
requirements:
|
||||
- python >= 2.6
|
||||
- PyJWT module
|
||||
- requests module
|
||||
- decort_utils utility library (module)
|
||||
- DECORT cloud platform version 3.6.1 or higher
|
||||
options:
|
||||
app_id:
|
||||
description:
|
||||
- 'Application ID for authenticating to the Oauth2 provider specified in I(oauth2_url).'
|
||||
- 'If not found in the playbook or command line arguments, the value will be taken from DECORT_APP_ID
|
||||
environment variable.'
|
||||
required: no
|
||||
app_secret:
|
||||
description:
|
||||
- 'Application API secret used for authenticating to the Oauth2 provider specified in I(oauth2_url).'
|
||||
- 'If not found in the playbook or command line arguments, the value will be taken from DECORT_APP_SECRET
|
||||
environment variable.'
|
||||
required: no
|
||||
oauth2_url:
|
||||
description:
|
||||
- 'URL of the oauth2 authentication provider to obtain JWT from.'
|
||||
- If not specified in the playbook, the value will be taken from DECORT_OAUTH2_URL environment variable.
|
||||
validity:
|
||||
description:
|
||||
- Validity of the JWT in seconds. Default value is 3600 (one hour).
|
||||
required: no
|
||||
verify_ssl:
|
||||
description:
|
||||
- 'Controls SSL verification mode when making API calls to DECS controller. Set it to False if you
|
||||
want to disable SSL certificate verification.'
|
||||
- `Intended use case is when you run module in a trusted environment that uses self-signed certificates.
|
||||
Note that disabling SSL verification in any other scenario can lead to security issues, so please use
|
||||
with caution.'
|
||||
default: True
|
||||
required: no
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Obtain JWT and store it as my_jwt for authenticating subsequent task to DECORT cloud controller
|
||||
decort_jwt:
|
||||
app_id: "{{ my_app_id }}"
|
||||
app_secret: "{{ my_app_secret }}"
|
||||
oauth2_url: https://sso.decs.online
|
||||
delegate_to: localhost
|
||||
register: my_jwt
|
||||
'''
|
||||
|
||||
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home).
|
||||
RETURN = '''
|
||||
jwt:
|
||||
description: JSON Web Token that can be used to access DECS cloud controller
|
||||
returned: always
|
||||
type: string
|
||||
sample: None
|
||||
'''
|
||||
|
||||
import requests
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.decort_utils import DecortController
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
|
||||
def decort_jwt_parameters():
|
||||
"""Build and return a dictionary of parameters expected by decort_jwt module in a form accepted
|
||||
by AnsibleModule utility class"""
|
||||
|
||||
return dict(
|
||||
app_id=dict(type='str',
|
||||
required=True,
|
||||
fallback=(env_fallback, ['DECORT_APP_ID'])),
|
||||
app_secret=dict(type='str',
|
||||
required=True,
|
||||
fallback=(env_fallback, ['DECORT_APP_SECRET']),
|
||||
no_log=True),
|
||||
oauth2_url=dict(type='str',
|
||||
required=True,
|
||||
fallback=(env_fallback, ['DECORT_OAUTH2_URL'])),
|
||||
validity=dict(type='int',
|
||||
required=False,
|
||||
default=3600),
|
||||
verify_ssl=dict(type='bool', required=False, default=True),
|
||||
workflow_callback=dict(type='str', required=False),
|
||||
workflow_context=dict(type='str', required=False),
|
||||
)
|
||||
|
||||
class DecortJWT(DecortController):
|
||||
def __init__(self):
|
||||
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||
def main():
|
||||
module_parameters = decort_jwt_parameters()
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
amodule_init_args = self.common_amodule_init_args
|
||||
amodule_argument_spec = amodule_init_args['argument_spec']
|
||||
del amodule_argument_spec['controller_url']
|
||||
del amodule_argument_spec['jwt']
|
||||
amodule_argument_spec['authenticator']['choices'].remove('jwt')
|
||||
amodule = AnsibleModule(argument_spec=module_parameters,
|
||||
supports_check_mode=True,)
|
||||
|
||||
return amodule_init_args
|
||||
result = {'failed': False, 'changed': False}
|
||||
|
||||
def run(self):
|
||||
self.result['jwt'] = self.jwt
|
||||
self.amodule.exit_json(**self.result)
|
||||
token_get_url = amodule.params['oauth2_url'] + "/v1/oauth/access_token"
|
||||
req_data = dict(grant_type="client_credentials",
|
||||
client_id=amodule.params['app_id'],
|
||||
client_secret=amodule.params['app_secret'],
|
||||
response_type="id_token",
|
||||
validity=amodule.params['validity'],)
|
||||
# TODO: Need standard code snippet to handle server timeouts gracefully
|
||||
# Consider a few retries before giving up or use requests.Session & requests.HTTPAdapter
|
||||
# see https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request
|
||||
|
||||
# catch requests.exceptions.ConnectionError to handle incorrect oauth2_url case
|
||||
try:
|
||||
token_get_resp = requests.post(token_get_url, data=req_data, verify=amodule.params['verify_ssl'])
|
||||
except requests.exceptions.ConnectionError as errco:
|
||||
result.update(failed=True)
|
||||
result['msg'] = "Failed to connect to {}: {}".format(token_get_url, errco)
|
||||
amodule.fail_json(**result)
|
||||
except requests.exceptions.Timeout as errti:
|
||||
result.update(failed=True)
|
||||
result['msg'] = "Timeout when trying to connect to {}: {}".format(token_get_url, errti)
|
||||
amodule.fail_json(**result)
|
||||
|
||||
def main():
|
||||
DecortJWT().run()
|
||||
# alternative -- if resp == requests.codes.ok
|
||||
if token_get_resp.status_code != 200:
|
||||
result.update(failed=True)
|
||||
result['msg'] = "Failed to obtain JWT access token from oauth2_url {} for app_id {}: {} {}".format(
|
||||
token_get_url, amodule.params['app_id'],
|
||||
token_get_resp.status_code, token_get_resp.reason)
|
||||
amodule.fail_json(**result)
|
||||
|
||||
# Common return values: https://docs.ansible.com/ansible/2.3/common_return_values.html
|
||||
result['jwt'] = token_get_resp.content.decode('utf8')
|
||||
amodule.exit_json(**result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,361 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_lb
|
||||
|
||||
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_lb(DecortController):
|
||||
def __init__(self) -> None:
|
||||
super(decort_lb,self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
self.lb_id = 0
|
||||
self.lb_facts = None
|
||||
self.vins_id = 0
|
||||
self.vins_facts = None
|
||||
self.rg_id = 0
|
||||
self.rg_facts = None
|
||||
self.acc_id = 0
|
||||
self.acc_facts = None
|
||||
self.default_server_check = "enabled"
|
||||
self.default_alg = "roundrobin"
|
||||
self.default_settings = {
|
||||
"downinter": 10000,
|
||||
"fall": 2,
|
||||
"inter": 5000,
|
||||
"maxconn": 250,
|
||||
"maxqueue": 256,
|
||||
"rise": 2,
|
||||
"slowstart": 60000,
|
||||
"weight": 100,
|
||||
}
|
||||
if arg_amodule.params['lb_id']:
|
||||
self.lb_id, self.lb_facts = self.lb_find(arg_amodule.params['lb_id'])
|
||||
if not self.lb_id:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "Specified LB ID {} not found."\
|
||||
.format(arg_amodule.params['lb _id'])
|
||||
self.fail_json(**self.result)
|
||||
self.rg_id = self.lb_facts['rgId']
|
||||
self.vins_id = self.lb_facts['vinsId']
|
||||
return
|
||||
|
||||
if arg_amodule.params['rg_id']:
|
||||
self.rg_id, self.rg_facts = self.rg_find(0,arg_amodule.params['rg_id'], arg_rg_name="")
|
||||
if not self.rg_id:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "Specified RG ID {} not found.".format(arg_amodule.params['vins_id'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
elif arg_amodule.params['account_id'] or arg_amodule.params['account_name'] != "":
|
||||
|
||||
if not arg_amodule.params['rg_name']:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = ("RG name must be specified with account present")
|
||||
self.amodule.fail_json(**self.result)
|
||||
self.acc_id, self.acc_facts = self.account_find(arg_amodule.params['account_name'],
|
||||
arg_amodule.params['account_id'])
|
||||
if not self.acc_id:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = ("Current user does not have access to the requested account "
|
||||
"or non-existent account specified.")
|
||||
self.amodule.fail_json(**self.result)
|
||||
self.rg_id, self.rg_facts = self.rg_find(self.acc_id,0, arg_rg_name=arg_amodule.params['rg_name'])
|
||||
|
||||
if arg_amodule.params['vins_id']:
|
||||
self.vins_id, self.vins_facts = self.vins_find(
|
||||
vins_id=arg_amodule.params['vins_id']
|
||||
)
|
||||
if not self.vins_id:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = (
|
||||
f'Specified ViNS ID {arg_amodule.params["vins_id"]}'
|
||||
f' not found'
|
||||
)
|
||||
self.amodule.fail_json(**self.result)
|
||||
elif arg_amodule.params['vins_name']:
|
||||
self.vins_id, self.vins_facts = self.vins_find(
|
||||
vins_id=arg_amodule.params['vins_id'],
|
||||
vins_name=arg_amodule.params['vins_name'],
|
||||
rg_id=self.rg_id)
|
||||
if not self.vins_id:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = (
|
||||
f'Specified ViNS name {arg_amodule.params["vins_name"]}'
|
||||
f' not found in RG ID {self.rg_id}'
|
||||
)
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
if self.rg_id and arg_amodule.params['lb_name']:
|
||||
self.lb_id, self.lb_facts = self.lb_find(0,arg_amodule.params['lb_name'],self.rg_id)
|
||||
return
|
||||
|
||||
def create(self):
|
||||
self.lb_id = self.lb_provision(self.amodule.params['lb_name'],
|
||||
self.rg_id,self.vins_id,
|
||||
self.amodule.params['ext_net_id'],
|
||||
self.amodule.params['ha_lb'],
|
||||
self.amodule.params['description'])
|
||||
if self.lb_id and (self.amodule.params['backends'] or
|
||||
self.amodule.params['frontends']):
|
||||
self.lb_id, self.lb_facts = self.lb_find(0,self.amodule.params['lb_name'],self.rg_id)
|
||||
self.lb_update(
|
||||
self.lb_facts['primaryNode'],
|
||||
self.lb_facts['frontendHAIP'],
|
||||
self.lb_facts['backendHAIP'],
|
||||
self.lb_facts['backends'],
|
||||
self.lb_facts['frontends'],
|
||||
self.amodule.params['backends'],
|
||||
self.amodule.params['servers'],
|
||||
self.amodule.params['frontends']
|
||||
)
|
||||
return
|
||||
|
||||
def action(self,d_state='',restore=False):
|
||||
if restore == True:
|
||||
self.lb_restore(lb_id=self.lb_id)
|
||||
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
|
||||
self.lb_state(self.lb_facts, 'enabled')
|
||||
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
|
||||
|
||||
self.lb_update(
|
||||
self.lb_facts['primaryNode'],
|
||||
self.lb_facts['frontendHAIP'],
|
||||
self.lb_facts['backendHAIP'],
|
||||
self.lb_facts['backends'],
|
||||
self.lb_facts['frontends'],
|
||||
self.amodule.params['backends'],
|
||||
self.amodule.params['servers'],
|
||||
self.amodule.params['frontends'],
|
||||
)
|
||||
|
||||
if d_state != '':
|
||||
self.lb_state(self.lb_facts, d_state)
|
||||
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
|
||||
|
||||
if (d_state == 'enabled' and
|
||||
self.lb_facts.get('status') == 'ENABLED' and
|
||||
self.lb_facts.get('techStatus') == 'STOPPED'):
|
||||
self.lb_state(self.lb_facts, 'started')
|
||||
_, self.lb_facts = self._lb_get_by_id(lb_id=self.lb_id)
|
||||
|
||||
return
|
||||
|
||||
def delete(self):
|
||||
self.lb_delete(self.lb_id, self.amodule.params['permanently'])
|
||||
self.lb_facts['status'] = 'DESTROYED'
|
||||
return
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for LB management by decort_lb module.
|
||||
This function is intended to be called from the main switch construct of the module
|
||||
when current state -> desired state change logic does not require any changes to
|
||||
the actual LB state.
|
||||
"""
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.lb_id:
|
||||
self.result['msg'] = ("No state change required for LB ID {} because of its "
|
||||
"current status '{}'.").format(self.lb_id, self.lb_facts['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent LB instance.").format(self.amodule.params['state'])
|
||||
return
|
||||
def error(self):
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
if self.vins_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for LB ID {} in the "
|
||||
"current status '{}'").format(self.lb_id,
|
||||
self.amodule.params['state'],
|
||||
self.lb_facts['status'])
|
||||
else:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent "
|
||||
"LB name '{}'").format(self.amodule.params['state'],
|
||||
self.amodule.params['lb_name'])
|
||||
return
|
||||
def package_facts(self, arg_check_mode=False):
|
||||
"""Package a dictionary of LB facts according to the decort_lb module specification.
|
||||
This dictionary will be returned to the upstream Ansible engine at the completion of
|
||||
the module run.
|
||||
|
||||
@param arg_check_mode: boolean that tells if this Ansible module is run in check mode
|
||||
"""
|
||||
|
||||
ret_dict = dict(id=0,
|
||||
name="none",
|
||||
state="CHECK_MODE",
|
||||
)
|
||||
|
||||
if arg_check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
|
||||
if self.lb_facts is None:
|
||||
# if void facts provided - change state value to ABSENT and return
|
||||
ret_dict['state'] = "ABSENT"
|
||||
return ret_dict
|
||||
|
||||
ret_dict['id'] = self.lb_facts['id']
|
||||
ret_dict['name'] = self.lb_facts['name']
|
||||
ret_dict['state'] = self.lb_facts['status']
|
||||
#ret_dict['account_id'] = self.lb_facts['accountId']
|
||||
ret_dict['rg_id'] = self.lb_facts['rgId']
|
||||
ret_dict['gid'] = self.lb_facts['gid']
|
||||
if self.amodule.params['state']!="absent":
|
||||
ret_dict['backends'] = self.lb_facts['backends']
|
||||
ret_dict['frontends'] = self.lb_facts['frontends']
|
||||
return ret_dict
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
argument_spec=dict(
|
||||
account_id=dict(
|
||||
type='int',
|
||||
),
|
||||
account_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
description=dict(
|
||||
type='str',
|
||||
default='Managed by Ansible module decort_lb',
|
||||
),
|
||||
ext_net_id=dict(
|
||||
type='int',
|
||||
default=-1,
|
||||
),
|
||||
ext_ip_addr=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'disabled',
|
||||
'enabled',
|
||||
'present',
|
||||
'restart',
|
||||
],
|
||||
),
|
||||
rg_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
rg_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
vins_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
vins_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
lb_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
lb_name=dict(
|
||||
type='str',
|
||||
),
|
||||
ha_lb=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
backends=dict(
|
||||
type='list',
|
||||
),
|
||||
frontends=dict(
|
||||
type='list',
|
||||
),
|
||||
servers=dict(
|
||||
type='list',
|
||||
),
|
||||
permanently=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('rg_id', 'rg_name'),
|
||||
('lb_id', 'lb_name'),
|
||||
('vins_id', 'vins_name'),
|
||||
],
|
||||
)
|
||||
|
||||
def main():
|
||||
decon = decort_lb()
|
||||
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'] == "DISABLED":
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.delete()
|
||||
elif amodule.params['state'] == 'disabled':
|
||||
decon.action()
|
||||
elif amodule.params['state'] in ('enabled', 'present'):
|
||||
decon.action('enabled')
|
||||
elif decon.lb_facts['status'] in ["CREATED", "ENABLED"]:
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.delete()
|
||||
elif amodule.params['state'] in ('present', 'enabled'):
|
||||
decon.action(d_state='enabled')
|
||||
elif amodule.params['state'] == 'disabled':
|
||||
decon.action('disabled')
|
||||
elif amodule.params['state'] in ('stopped', 'started','restart'):
|
||||
decon.action(amodule.params['state'])
|
||||
elif decon.lb_facts['status'] == "DELETED":
|
||||
if amodule.params['state'] in ['present', 'enabled']:
|
||||
decon.action(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:
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.nop()
|
||||
elif amodule.params['state'] in ('present', 'enabled'):
|
||||
decon.create()
|
||||
elif amodule.params['state'] == 'disabled':
|
||||
decon.error()
|
||||
|
||||
if decon.result['failed']:
|
||||
amodule.fail_json(**decon.result)
|
||||
else:
|
||||
if decon.result['changed'] and amodule.params['state'] != 'absent':
|
||||
_, decon.lb_facts = decon.lb_find(decon.lb_id)
|
||||
if decon.lb_id:
|
||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
||||
amodule.exit_json(**decon.result)
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,157 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_snapshot
|
||||
|
||||
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home).
|
||||
'''
|
||||
|
||||
import time
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.decort_utils import DecortController
|
||||
|
||||
|
||||
class DecortSnapshot(DecortController):
|
||||
def __init__(self):
|
||||
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||
self.check_amodule_args()
|
||||
|
||||
self.aparams_label = self.aparams['label']
|
||||
self.aparams_vm_id = self.aparams['vm_id']
|
||||
|
||||
vm_id, vm_facts, _ = self._compute_get_by_id(
|
||||
comp_id=self.aparams_vm_id,
|
||||
)
|
||||
if not vm_id:
|
||||
self.message(f'VM {self.aparams_vm_id} not found')
|
||||
self.exit(fail=True)
|
||||
|
||||
self.vm_name = vm_facts['name']
|
||||
self.vm_snapshots = vm_facts['snapSets']
|
||||
self.vm_snapshot_labels = [
|
||||
snapshot['label'] for snapshot in self.vm_snapshots
|
||||
]
|
||||
|
||||
if (
|
||||
self.aparams_label is not None
|
||||
and self.aparams_label not in self.vm_snapshot_labels
|
||||
and self.aparams['state'] is None
|
||||
):
|
||||
self.message(
|
||||
f'Snapshot {self.aparams_label} '
|
||||
f'not found for VM {self.aparams_vm_id}'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
self.new_snapshot_label = None
|
||||
if self.aparams['state'] == 'present':
|
||||
if self.aparams_label is None:
|
||||
self.new_snapshot_label = (
|
||||
f'{self.vm_name}_{self.sec_to_dt_str(time.time())}'
|
||||
)
|
||||
elif self.aparams_label not in self.vm_snapshot_labels:
|
||||
self.new_snapshot_label = self.aparams_label
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
argument_spec=dict(
|
||||
label=dict(
|
||||
type='str',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
choices=(
|
||||
'absent',
|
||||
'present',
|
||||
),
|
||||
),
|
||||
usage=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
vm_id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_if=[
|
||||
('state', 'absent', ('label',)),
|
||||
],
|
||||
required_one_of=[
|
||||
('label', 'state'),
|
||||
],
|
||||
)
|
||||
|
||||
def check_amodule_args(self):
|
||||
check_error = False
|
||||
if (
|
||||
self.aparams['state'] == 'absent'
|
||||
and self.aparams['usage']
|
||||
):
|
||||
self.message(
|
||||
'Parameter "usage" is not supported when deleting snapshot'
|
||||
)
|
||||
check_error = True
|
||||
|
||||
if check_error:
|
||||
self.exit(fail=True)
|
||||
|
||||
def run(self):
|
||||
self.get_info(first_run=True)
|
||||
self.change()
|
||||
self.exit()
|
||||
|
||||
def get_info(self, first_run: bool = False):
|
||||
if not first_run:
|
||||
self.vm_snapshots = self.snapshot_list(
|
||||
compute_id=self.aparams_vm_id,
|
||||
)
|
||||
label = self.new_snapshot_label or self.aparams_label
|
||||
for snapshot in self.vm_snapshots:
|
||||
if snapshot['label'] == label:
|
||||
self.facts = snapshot
|
||||
if self.aparams['usage']:
|
||||
self.facts['stored'] = self.get_snapshot_usage()
|
||||
self.facts['vm_id'] = self.aparams_vm_id
|
||||
break
|
||||
|
||||
def change(self):
|
||||
match self.aparams['state']:
|
||||
case 'present':
|
||||
if self.new_snapshot_label:
|
||||
self.create()
|
||||
case 'absent':
|
||||
if self.aparams_label in self.vm_snapshot_labels:
|
||||
self.delete()
|
||||
|
||||
def create(self):
|
||||
self.snapshot_create(
|
||||
compute_id=self.aparams_vm_id,
|
||||
label=self.new_snapshot_label,
|
||||
)
|
||||
self.get_info()
|
||||
|
||||
def delete(self):
|
||||
self.snapshot_delete(
|
||||
compute_id=self.aparams_vm_id,
|
||||
label=self.aparams_label,
|
||||
)
|
||||
self.facts = {}
|
||||
|
||||
def get_snapshot_usage(self) -> int:
|
||||
label = self.new_snapshot_label or self.aparams_label
|
||||
common_snapshots_usage_info, _ = self.snapshot_usage(
|
||||
compute_id=self.aparams_vm_id,
|
||||
label=label,
|
||||
)
|
||||
return common_snapshots_usage_info['stored']
|
||||
|
||||
def main():
|
||||
DecortSnapshot().run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,346 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_user_info
|
||||
|
||||
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.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
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
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(
|
||||
unix=dict(
|
||||
type='int',
|
||||
),
|
||||
date_time=dict(
|
||||
type='str',
|
||||
),
|
||||
),
|
||||
mutually_exclusive=[
|
||||
('unix', 'date_time'),
|
||||
],
|
||||
),
|
||||
end=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
unix=dict(
|
||||
type='int',
|
||||
),
|
||||
date_time=dict(
|
||||
type='str',
|
||||
),
|
||||
),
|
||||
mutually_exclusive=[
|
||||
('unix', 'date_time'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
pagination=dict(
|
||||
type='dict',
|
||||
apply_defaults=True,
|
||||
options=dict(
|
||||
number=dict(
|
||||
type='int',
|
||||
default=1,
|
||||
),
|
||||
size=dict(
|
||||
type='int',
|
||||
default=50,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
objects_search=dict(
|
||||
type='str',
|
||||
),
|
||||
resource_consumption=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
),
|
||||
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': {'date_time': 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': {'date_time': 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
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
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': {'unix': int() as start_unix_time}}:
|
||||
mapped_args['start_unix_time'] = start_unix_time
|
||||
case {'start': {'date_time': 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': {'unix': int() as end_unix_time}}:
|
||||
mapped_args['end_unix_time'] = end_unix_time
|
||||
case {'end': {'date_time': 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']
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
DecortUserInfo().run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
File diff suppressed because it is too large
Load Diff
@ -1,16 +0,0 @@
|
||||
1. [Введение](./введение.md)
|
||||
- [Введение](./введение.md#введение)
|
||||
- [Системные требования](./введение.md#системные-требования)
|
||||
- [Подготовка к работе](./введение.md#подготовка-к-работе)
|
||||
1. Ansible модули DECORT:
|
||||
- [Модуль decort_kvmvm](./модуль-decort_kvmvm.md) - управление виртуальными машинами
|
||||
- [Модуль decort_osimage](./модуль-decort_osimage.md) - управление образами
|
||||
- [Модуль decort_disk](./модуль-decort_disk.md) - управление дисками
|
||||
- [Модуль decort_pfw](./модуль-decort_pfw.md) - управление правилами переадресации портов
|
||||
- [Модуль decort_rg](./модуль-decort_rg.md) - управление ресурсными группами
|
||||
- [Модуль decort_vins](./модуль-decort_vins.md) - управление внутренними сетями
|
||||
- [Модуль decort_jwt](./модуль-decort_jwt.md) - получение авторизационного токена
|
||||
- [Модуль decort_bservice](./модуль-decort_bservice.md) - управление базовыми службами
|
||||
- [Модуль decort_group](./модуль-decort_group.md)- управление группами базовой службы
|
||||
- [Модуль decort_k8s](./модуль-decort_k8s.md) - управление кластерами Kubernetes
|
||||
- [Модуль decort_lb](./модуль-decort_lb.md) - управление балансировщиками нагрузки
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue