Compare commits
No commits in common. 'main' and 'rc-1.0' have entirely different histories.
@ -1,19 +1,2 @@
|
||||
# decort-ansible
|
||||
Модули Ansible для платформы Digital Energy Orchestration Technology (DECORT).
|
||||
|
||||
## Соответствие версий платформы версиям модулей Ansible
|
||||
|
||||
| Версия платформы | Версия модулей 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)
|
||||
Ansible modules for Digital Energy Orchestration Technology (DECORT) platform v3.4.0 and above
|
||||
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT vins module example
|
||||
#
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
register: my_jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out JWT
|
||||
debug:
|
||||
var: my_jwt.jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Manage ViNS at resource group level
|
||||
decort_vins:
|
||||
authenticator: jwt
|
||||
jwt: "{{ my_jwt.jwt }}"
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
vins_name: "vins_created_by_decort_VINS_module"
|
||||
state: present
|
||||
rg_id: 198
|
||||
ext_net_id: -1
|
||||
ipcidr: "10.20.30.0/24"
|
||||
mgmtaddr: "10.20.30.1"
|
||||
custom_config: false
|
||||
config_save: false
|
||||
verify_ssl: false
|
||||
|
||||
register: managed_vins
|
||||
|
||||
- name: print VINS facter
|
||||
debug:
|
||||
msg: "{{managed_vins.facts.password}}"
|
||||
when: managed_vins.facts.password is defined
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT k8s module labels, taints, annotations example
|
||||
#
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
register: my_jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out JWT
|
||||
debug:
|
||||
var: my_jwt.jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create k8s cluster
|
||||
decort_k8s:
|
||||
authenticator: jwt
|
||||
jwt: "{{ my_jwt.jwt }}"
|
||||
controller_url: "https://mr4.digitalenergy.online"
|
||||
name: "example_kubernetes"
|
||||
rg_id: 199
|
||||
k8ci_id: 4
|
||||
state: present
|
||||
workers:
|
||||
- name: workgroup1
|
||||
labels:
|
||||
- disktype1=ssd1
|
||||
- disktype2=ssd2
|
||||
taints:
|
||||
- key1=value1:NoSchedule
|
||||
- key2=value2:NoSchedule
|
||||
annotations:
|
||||
- node.deckhouse.io/group1=g1
|
||||
- node.deckhouse.io/group2=g2
|
||||
register: kube
|
@ -1,31 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT bservice module example
|
||||
#
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
register: my_jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out JWT
|
||||
debug:
|
||||
var: my_jwt.jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Manage bservice at RG
|
||||
decort_bservice:
|
||||
account_id: 98
|
||||
verify_ssl: false
|
||||
authenticator: jwt
|
||||
jwt: "{{ my_jwt.jwt }}"
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
rg_id: 1629
|
||||
state: present
|
||||
name: databases
|
||||
started: True
|
||||
register: db_bservice
|
@ -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,27 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT osimage module example
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create
|
||||
decort_osimage:
|
||||
authenticator: oauth2
|
||||
verify_ssl: False
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
state: present
|
||||
image_name: "alpine_linux3.14.0"
|
||||
account_Id: 12345
|
||||
url: "https://dl-cdn.alpinelinux.org/alpine/v3.14/releases/x86_64/alpine-virt-3.14.0-x86_64.iso"
|
||||
boottype: "uefi"
|
||||
imagetype: "linux"
|
||||
hotresize: False
|
||||
image_username: "test"
|
||||
image_password: "p@ssword"
|
||||
usernameDL: "testDL"
|
||||
passwordDL: "p@sswordDL"
|
||||
architecture: "X86_64"
|
||||
drivers: "KVM_X86"
|
||||
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT osimage module example
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: create_virtual_osimage
|
||||
decort_osimage:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
image_name: "alpine_linux_3.14.0"
|
||||
virt_name: "alpine_last"
|
||||
delegate_to: localhost
|
||||
register: osimage
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT osimage module example
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: get_osimage
|
||||
decort_osimage:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
image_name: "alpine_linux_3.14.0"
|
||||
account_Id: 79349
|
||||
delegate_to: localhost
|
||||
register: simple_vm
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT osimage module example
|
||||
#
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: rename_osimage
|
||||
decort_osimage:
|
||||
authenticator: oauth2
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
image_name: "alpine_linux_3.14.0v2.0"
|
||||
image_id: 54321
|
||||
delegate_to: localhost
|
||||
register: osimage
|
||||
|
@ -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
|
@ -1,39 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT k8s module example
|
||||
#
|
||||
- hosts: ansible_master
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
verify_ssl: false
|
||||
register: token
|
||||
delegate_to: localhost
|
||||
|
||||
- name: create a VM named cluster-test
|
||||
decort_k8s:
|
||||
state: present
|
||||
started: True
|
||||
getConfig: True
|
||||
authenticator: jwt
|
||||
jwt: "{{ token.jwt }}"
|
||||
controller_url: "https://ds1.digitalenergy.online"
|
||||
name: "cluster-test"
|
||||
rg_id: 125
|
||||
k8ci_id: 18
|
||||
workers:
|
||||
- name: wg1
|
||||
ram: 1024
|
||||
cpu: 10
|
||||
disk: 10
|
||||
num: 1
|
||||
- name: wg2
|
||||
ram: 1024
|
||||
cpu: 10
|
||||
disk: 10
|
||||
num: 2
|
||||
verify_ssl: false
|
||||
delegate_to: localhost
|
||||
register: kube
|
@ -1,42 +0,0 @@
|
||||
---
|
||||
#
|
||||
# DECORT vins module example
|
||||
#
|
||||
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: obtain JWT
|
||||
decort_jwt:
|
||||
oauth2_url: "https://sso.digitalenergy.online"
|
||||
validity: 1200
|
||||
register: my_jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: print out JWT
|
||||
debug:
|
||||
var: my_jwt.jwt
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Manage ViNS at resource group level
|
||||
decort_vins:
|
||||
authenticator: jwt
|
||||
jwt: "{{ my_jwt.jwt }}"
|
||||
controller_url: "https://cloud.digitalenergy.online"
|
||||
vins_name: "vins_connected_by_decort_vins_module"
|
||||
state: present
|
||||
rg_id: 98
|
||||
connect_to:
|
||||
- type: VINS
|
||||
id: 864
|
||||
ipaddr: 192.168.5.66
|
||||
netmask: 24
|
||||
- type: VINS
|
||||
id: 196
|
||||
ipaddr: 192.168.9.133
|
||||
netmask: 24
|
||||
register: managed_vins
|
||||
|
||||
- name: print VINS facter
|
||||
debug:
|
||||
msg: "{{managed_vins.facts.password}}"
|
||||
when: managed_vins.facts.password is defined
|
@ -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,280 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_bservice
|
||||
|
||||
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_bservice(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_bservice, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
validated_acc_id = 0
|
||||
validated_rg_id = 0
|
||||
self.bservice_info = None
|
||||
if arg_amodule.params['name'] == "" and arg_amodule.params['id'] == 0:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot manage Basic Services when its ID is 0 and name is empty."
|
||||
self.fail_json(**self.result)
|
||||
if not arg_amodule.params['id']:
|
||||
if not arg_amodule.params['rg_id']: # RG ID is not set -> locate RG by name -> need account ID
|
||||
validated_acc_id, _ = self.account_find(arg_amodule.params['account_name'],
|
||||
arg_amodule.params['account_id'])
|
||||
if not validated_acc_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Current user does not have access to the account ID {} / "
|
||||
"name '{}' or non-existent account specified.").format(arg_amodule.params['account_id'],
|
||||
arg_amodule.params['account_name'])
|
||||
self.fail_json(**self.result)
|
||||
# fail the module -> exit
|
||||
# now validate RG
|
||||
validated_rg_id, validated_rg_facts = self.rg_find(
|
||||
arg_account_id=validated_acc_id,
|
||||
arg_rg_id=arg_amodule.params['rg_id'],
|
||||
arg_rg_name=arg_amodule.params['rg_name']
|
||||
)
|
||||
if not validated_rg_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot find RG ID {} / name '{}'.".format(arg_amodule.params['rg_id'],
|
||||
arg_amodule.params['rg_name'])
|
||||
self.fail_json(**self.result)
|
||||
|
||||
arg_amodule.params['rg_id'] = validated_rg_id
|
||||
arg_amodule.params['rg_name'] = validated_rg_facts['name']
|
||||
validated_acc_id = validated_rg_facts['accountId']
|
||||
|
||||
self.bservice_id, self.bservice_info = self.bservice_find(
|
||||
validated_acc_id,
|
||||
validated_rg_id,
|
||||
arg_amodule.params['name'],
|
||||
arg_amodule.params['id']
|
||||
)
|
||||
|
||||
if self.bservice_id == 0:
|
||||
self.bservice_should_exist = False
|
||||
else:
|
||||
self.bservice_should_exist = True
|
||||
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for B-service.
|
||||
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 Compute state.
|
||||
"""
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.bservice_id:
|
||||
self.result['msg'] = ("No state change required for B-service ID {} because of its "
|
||||
"current status '{}'.").format(self.bservice_id, self.bservice_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent B-service instance.").format(self.amodule.params['state'])
|
||||
return
|
||||
|
||||
def error(self):
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
if self.bservice_id:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for B-service ID {} in the "
|
||||
"current status '{}'.").format(self.bservice_id,
|
||||
self.amodule.params['state'],
|
||||
self.bservice_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent B-service name '{}' "
|
||||
"in RG ID {} / name '{}'").format(self.amodule.params['state'],
|
||||
self.amodule.params['name'],
|
||||
self.amodule.params['rg_id'],
|
||||
self.amodule.params['rg_name'])
|
||||
return
|
||||
|
||||
def create(self):
|
||||
self.bservice_id = self.bservice_id = self.bservice_provision(
|
||||
self.amodule.params['name'],
|
||||
self.amodule.params['rg_id'],
|
||||
self.amodule.params['sshuser'],
|
||||
self.amodule.params['sshkey']
|
||||
)
|
||||
if self.bservice_id:
|
||||
_, self.bservice_info = self.bservice_get_by_id(self.bservice_id)
|
||||
self.bservice_state(self.bservice_info,'enabled',self.amodule.params['started'])
|
||||
return
|
||||
|
||||
def action(self,d_state,started=False):
|
||||
self.bservice_state(self.bservice_info,d_state,started)
|
||||
return
|
||||
|
||||
def restore(self):
|
||||
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "Restore B-Service ID {} manualy.".format(self.bservice_id)
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
self.bservice_delete(self.bservice_id)
|
||||
self.bservice_info['status'] = 'DELETED'
|
||||
self.bservice_should_exist = False
|
||||
return
|
||||
|
||||
def package_facts(self,check_mode=False):
|
||||
|
||||
ret_dict = dict(
|
||||
name="",
|
||||
state="CHECK_MODE",
|
||||
account_id=0,
|
||||
rg_id=0,
|
||||
config=None,
|
||||
)
|
||||
|
||||
if check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
|
||||
ret_dict['id'] = self.bservice_info['id']
|
||||
ret_dict['name'] = self.bservice_info['name']
|
||||
ret_dict['techStatus'] = self.bservice_info['techStatus']
|
||||
ret_dict['state'] = self.bservice_info['status']
|
||||
ret_dict['rg_id'] = self.bservice_info['rgId']
|
||||
ret_dict['account_id'] = self.bservice_info['accountId']
|
||||
ret_dict['groups'] = self.bservice_info['groups']
|
||||
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='',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'disabled',
|
||||
'enabled',
|
||||
'present',
|
||||
'check',
|
||||
],
|
||||
),
|
||||
started=dict(
|
||||
type='bool',
|
||||
default=True,
|
||||
),
|
||||
name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
sshuser=dict(
|
||||
type='str',
|
||||
),
|
||||
sshkey=dict(
|
||||
type='str',
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
rg_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
rg_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('id', 'name'),
|
||||
('rg_id', 'rg_name'),
|
||||
],
|
||||
)
|
||||
|
||||
def main():
|
||||
subj = decort_bservice()
|
||||
amodule = subj.amodule
|
||||
|
||||
if amodule.params['state'] == 'check':
|
||||
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'):
|
||||
subj.restore(subj.bservice_id)
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
if amodule.params['state'] == 'absent':
|
||||
subj.nop()
|
||||
elif subj.bservice_info['techStatus'] in ("STARTED","STOPPED"):
|
||||
if amodule.params['state'] == 'disabled':
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
elif amodule.params['state'] == 'absent':
|
||||
subj.destroy()
|
||||
else:
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
elif subj.bservice_info['status'] == "DISABLED":
|
||||
if amodule.params['state'] == 'absent':
|
||||
subj.destroy()
|
||||
elif amodule.params['state'] in ('present','enabled'):
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
else:
|
||||
subj.nop()
|
||||
elif subj.bservice_info['status'] == "DESTROED":
|
||||
if amodule.params['state'] in ('present','enabled'):
|
||||
subj.create()
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
if amodule.params['state'] == 'absent':
|
||||
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.bservice_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__":
|
||||
main()
|
@ -1,360 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_disk
|
||||
|
||||
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_disk(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_disk, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
validated_acc_id = 0
|
||||
validated_acc_info = None
|
||||
self.disk_id = 0
|
||||
self.account_id = 0
|
||||
# limitIO check for exclusive parameters
|
||||
|
||||
if arg_amodule.params['limitIO']:
|
||||
self.disk_check_iotune_arg(arg_amodule.params['limitIO'])
|
||||
|
||||
if not arg_amodule.params['id']:
|
||||
if (
|
||||
not arg_amodule.params['account_id']
|
||||
and not arg_amodule.params['account_name']
|
||||
):
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = (
|
||||
'Cannot manage Disk by name without specifying account ID '
|
||||
'or name.'
|
||||
)
|
||||
self.amodule.fail_json(**self.result)
|
||||
validated_acc_id, validated_acc_info = self.account_find(
|
||||
arg_amodule.params['account_name'],
|
||||
arg_amodule.params['account_id'])
|
||||
if not validated_acc_id:
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = (
|
||||
f"Current user does not have access to the account "
|
||||
f"ID {arg_amodule.params['account_id']} / "
|
||||
f"name '{arg_amodule.params['account_name']}' "
|
||||
f"or non-existent account specified."
|
||||
)
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
self.acc_id = validated_acc_id
|
||||
self.acc_info = validated_acc_info
|
||||
validated_disk_id, validated_disk_facts = self.disk_find(
|
||||
disk_id=arg_amodule.params['id'],
|
||||
name=arg_amodule.params['name'] if "name" in arg_amodule.params else "",
|
||||
account_id=self.acc_id,
|
||||
check_state=False,
|
||||
)
|
||||
|
||||
if arg_amodule.params['place_with']:
|
||||
image_id, image_facts = self.image_find(arg_amodule.params['place_with'], "", 0)
|
||||
arg_amodule.params['sep_id'] = image_facts['sepId']
|
||||
|
||||
self.disk_id = validated_disk_id
|
||||
self.disk_info = validated_disk_facts
|
||||
|
||||
def create(self):
|
||||
|
||||
self.disk_id = self.disk_create(accountId=self.acc_id,
|
||||
name = self.amodule.params['name'],
|
||||
description=self.amodule.params['description'],
|
||||
size=self.amodule.params['size'],
|
||||
type=self.amodule.params['type'],
|
||||
iops=self.amodule.params['iops'],
|
||||
sep_id=self.amodule.params['sep_id'],
|
||||
pool=self.amodule.params['pool'],
|
||||
)
|
||||
#IO tune
|
||||
if self.amodule.params['limitIO']:
|
||||
self.disk_limitIO(disk_id=self.disk_id,
|
||||
limits=self.amodule.params['limitIO'])
|
||||
#set share status
|
||||
if self.amodule.params['shareable'] and self.amodule.params['type'] == "D":
|
||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
||||
return
|
||||
|
||||
def action(self,restore=False):
|
||||
|
||||
#restore never be done
|
||||
if restore:
|
||||
self.disk_restore(self.disk_id)
|
||||
#rename if id present
|
||||
if (
|
||||
self.amodule.params['name'] is not None
|
||||
and self.amodule.params['name'] != self.disk_info['name']
|
||||
):
|
||||
self.disk_rename(disk_id=self.disk_id,
|
||||
name=self.amodule.params['name'])
|
||||
#resize
|
||||
if (
|
||||
self.amodule.params['size'] is not None
|
||||
and self.amodule.params['size'] != self.disk_info['sizeMax']
|
||||
):
|
||||
self.disk_resize(self.disk_info,self.amodule.params['size'])
|
||||
#IO TUNE
|
||||
if self.amodule.params['limitIO']:
|
||||
clean_io = [param for param in self.amodule.params['limitIO'] \
|
||||
if self.amodule.params['limitIO'][param] == None]
|
||||
for key in clean_io: del self.amodule.params['limitIO'][key]
|
||||
if self.amodule.params['limitIO'] != self.disk_info['iotune']:
|
||||
self.disk_limitIO(self.disk_id,self.amodule.params['limitIO'])
|
||||
#share check/update
|
||||
#raise Exception(self.amodule.params['shareable'])
|
||||
if self.amodule.params['shareable'] != self.disk_info['shareable'] and \
|
||||
self.amodule.params['type'] == "D":
|
||||
self.disk_share(self.disk_id,self.amodule.params['shareable'])
|
||||
return
|
||||
|
||||
def delete(self):
|
||||
self.disk_id = self.disk_delete(disk_id=self.disk_id,
|
||||
detach=self.amodule.params['force_detach'],
|
||||
permanently=self.amodule.params['permanently'],
|
||||
reason=self.amodule.params['reason'])
|
||||
self.disk_info['status'] = "DELETED"
|
||||
return
|
||||
|
||||
def rename(self):
|
||||
|
||||
|
||||
self.disk_rename(diskId = self.disk_id,
|
||||
name = self.amodule.params['name'])
|
||||
self.disk_info['name'] = self.amodule.params['name']
|
||||
return
|
||||
|
||||
def nop(self):
|
||||
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.disk_id:
|
||||
self.result['msg'] = ("No state change required for Disk ID {} because of its "
|
||||
"current status '{}'.").format(self.disk_id, self.disk_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent Disk.").format(self.amodule.params['state'])
|
||||
return
|
||||
|
||||
def package_facts(self, check_mode=False):
|
||||
ret_dict = dict(id=0,
|
||||
name="none",
|
||||
state="CHECK_MODE",
|
||||
size=0,
|
||||
account_id=0,
|
||||
sep_id=0,
|
||||
pool="none",
|
||||
gid=0
|
||||
)
|
||||
|
||||
if check_mode or self.disk_info is None:
|
||||
return ret_dict
|
||||
|
||||
# remove io param with zero value
|
||||
clean_io = [param for param in self.disk_info['iotune'] if self.disk_info['iotune'][param] == 0]
|
||||
for key in clean_io: del self.disk_info['iotune'][key]
|
||||
|
||||
ret_dict['id'] = self.disk_info['id']
|
||||
ret_dict['name'] = self.disk_info['name']
|
||||
ret_dict['size'] = self.disk_info['sizeMax']
|
||||
ret_dict['state'] = self.disk_info['status']
|
||||
ret_dict['account_id'] = self.disk_info['accountId']
|
||||
ret_dict['sep_id'] = self.disk_info['sepId']
|
||||
ret_dict['pool'] = self.disk_info['pool']
|
||||
ret_dict['computes'] = self.disk_info['computes']
|
||||
ret_dict['gid'] = self.disk_info['gid']
|
||||
ret_dict['iotune'] = self.disk_info['iotune']
|
||||
|
||||
return ret_dict
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
argument_spec=dict(
|
||||
account_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
account_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
description=dict(
|
||||
type='str',
|
||||
default='Disk by decort_disk',
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
name=dict(
|
||||
type='str',
|
||||
),
|
||||
force_detach=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
place_with=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
pool=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
sep_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
size=dict(
|
||||
type='int',
|
||||
),
|
||||
type=dict(
|
||||
type='str',
|
||||
default='D',
|
||||
choices=[
|
||||
'B',
|
||||
'D',
|
||||
'T',
|
||||
],
|
||||
),
|
||||
iops=dict(
|
||||
type='int',
|
||||
default=2000,
|
||||
),
|
||||
limitIO=dict(
|
||||
type='dict',
|
||||
options=dict(
|
||||
total_bytes_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
read_bytes_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
write_bytes_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
total_iops_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
read_iops_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
write_iops_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
total_bytes_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
read_bytes_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
write_bytes_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
total_iops_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
read_iops_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
write_iops_sec_max=dict(
|
||||
type='int',
|
||||
),
|
||||
size_iops_sec=dict(
|
||||
type='int',
|
||||
),
|
||||
),
|
||||
),
|
||||
permanently=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
shareable=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
reason=dict(
|
||||
type='str',
|
||||
default='Managed by Ansible decort_disk',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'present',
|
||||
],
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('id', 'name'),
|
||||
],
|
||||
)
|
||||
|
||||
def main():
|
||||
decon = decort_disk()
|
||||
amodule = decon.amodule
|
||||
#
|
||||
#Full range of Disk status is as follows:
|
||||
#
|
||||
# "ASSIGNED","MODELED", "CREATING","CREATED","DELETED", "DESTROYED","PURGED",
|
||||
#
|
||||
if decon.disk_id:
|
||||
#disk exist
|
||||
if decon.disk_info['status'] in ["MODELED", "CREATING"]:
|
||||
decon.result['failed'] = True
|
||||
decon.result['changed'] = False
|
||||
decon.result['msg'] = ("No change can be done for existing Disk ID {} because of its current "
|
||||
"status '{}'").format(decon.disk_id, decon.disk_info['status'])
|
||||
# "ASSIGNED","CREATED","DELETED","PURGED", "DESTROYED"
|
||||
elif decon.disk_info['status'] in ["ASSIGNED","CREATED"]:
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.delete()
|
||||
elif amodule.params['state'] == 'present':
|
||||
decon.action()
|
||||
elif decon.disk_info['status'] in ["PURGED", "DESTROYED"]:
|
||||
#re-provision disk
|
||||
if amodule.params['state'] in ('present'):
|
||||
decon.create()
|
||||
else:
|
||||
decon.nop()
|
||||
elif decon.disk_info['status'] == "DELETED":
|
||||
if amodule.params['state'] in ('present'):
|
||||
decon.action(restore=True)
|
||||
elif (amodule.params['state'] == 'absent' and
|
||||
amodule.params['permanently']):
|
||||
decon.delete()
|
||||
else:
|
||||
decon.nop()
|
||||
else:
|
||||
# preexisting Disk was not found
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.nop()
|
||||
else:
|
||||
decon.create()
|
||||
|
||||
if decon.result['failed']:
|
||||
amodule.fail_json(**decon.result)
|
||||
else:
|
||||
if decon.result['changed'] and amodule.params['state'] in ('present'):
|
||||
_, decon.disk_info = decon.disk_find(decon.disk_id)
|
||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
||||
amodule.exit_json(**decon.result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
#SHARE
|
@ -1,322 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_group
|
||||
|
||||
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_group(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_group, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
self.group_should_exist = False
|
||||
validated_bservice_id = None
|
||||
#find and validate B-Service
|
||||
|
||||
validated_bservice_id, bservice_info = self.bservice_get_by_id(arg_amodule.params['bservice_id'])
|
||||
if not validated_bservice_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Cannot find B-service ID {}.").format(arg_amodule.params['bservice_id'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
#find group
|
||||
self.bservice_id = validated_bservice_id
|
||||
self.bservice_info = bservice_info
|
||||
self.group_id,self.group_info = self.group_find(
|
||||
bs_id=validated_bservice_id,
|
||||
bs_info=bservice_info,
|
||||
group_id=arg_amodule.params['id'],
|
||||
group_name=arg_amodule.params['name'],
|
||||
)
|
||||
|
||||
if self.group_id:
|
||||
self.group_should_exist = True
|
||||
|
||||
return
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for B-service.
|
||||
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 Compute state.
|
||||
"""
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.group_id:
|
||||
self.result['msg'] = ("No state change required for B-service ID {} because of its "
|
||||
"current status '{}'.").format(self.group_id, self.group_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent B-service instance.").format(self.amodule.params['state'])
|
||||
return
|
||||
|
||||
def error(self):
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
if self.group_id:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for Group ID {} in the "
|
||||
"current status '{}'.").format(self.group_id,
|
||||
self.amodule.params['state'],
|
||||
self.group_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent Group name '{}' "
|
||||
"in B-service {}").format(self.amodule.params['state'],
|
||||
self.amodule.params['name'],
|
||||
self.amodule.params['bservice_id'],
|
||||
)
|
||||
return
|
||||
|
||||
def create(self):
|
||||
self.group_id=self.group_provision(
|
||||
self.bservice_id,
|
||||
self.amodule.params['name'],
|
||||
self.amodule.params['count'],
|
||||
self.amodule.params['cpu'],
|
||||
self.amodule.params['ram'],
|
||||
self.amodule.params['boot_disk'],
|
||||
self.amodule.params['image_id'],
|
||||
self.amodule.params['driver'],
|
||||
self.amodule.params['role'],
|
||||
self.amodule.params['networks'],
|
||||
self.amodule.params['timeoutStart'],
|
||||
)
|
||||
|
||||
if self.amodule.params['state'] in ('started','present'):
|
||||
self.group_state(self.bservice_id,self.group_id,self.amodule.params['state'])
|
||||
return
|
||||
|
||||
def action(self):
|
||||
#change desired state
|
||||
if (
|
||||
self.group_info['techStatus'] == 'STARTED' and self.amodule.params['state'] == 'stopped') or (
|
||||
self.group_info['techStatus'] == 'STOPPED' and self.amodule.params['state'] in ('started','present')
|
||||
):
|
||||
self.group_state(self.bservice_id,self.group_id,self.amodule.params['state'])
|
||||
|
||||
if self.aparams['count'] != None:
|
||||
self.group_resize_count(
|
||||
bs_id=self.bservice_id,
|
||||
gr_dict=self.group_info,
|
||||
desired_count=self.aparams['count'],
|
||||
)
|
||||
|
||||
for aparam_name, info_key in {'cpu': 'cpu',
|
||||
'boot_disk': 'disk',
|
||||
'role': 'role',
|
||||
'ram': 'ram',
|
||||
'name': 'name',
|
||||
}.items():
|
||||
aparam_value = self.aparams[aparam_name]
|
||||
group_info_value = self.group_info[info_key]
|
||||
if aparam_value != None and aparam_value != group_info_value:
|
||||
self.group_update(
|
||||
bs_id=self.bservice_id,
|
||||
gr_dict=self.group_info,
|
||||
arg_cpu=self.aparams['cpu'],
|
||||
arg_disk=self.aparams['boot_disk'],
|
||||
arg_name=self.aparams['name'],
|
||||
arg_role=self.aparams['role'],
|
||||
arg_ram=self.aparams['ram'],
|
||||
)
|
||||
break
|
||||
|
||||
if self.aparams['networks'] != None:
|
||||
self.group_update_net(
|
||||
bs_id=self.bservice_id,
|
||||
gr_dict=self.group_info,
|
||||
arg_net=self.aparams['networks'],
|
||||
)
|
||||
|
||||
def destroy(self):
|
||||
|
||||
self.group_delete(
|
||||
self.bservice_id,
|
||||
self.group_id
|
||||
)
|
||||
self.group_should_exist = False
|
||||
|
||||
return
|
||||
|
||||
def package_facts(self,check_mode=False):
|
||||
|
||||
ret_dict = dict(
|
||||
name="",
|
||||
state="CHECK_MODE",
|
||||
account_id=0,
|
||||
rg_id=0,
|
||||
)
|
||||
|
||||
if check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
if self.result['changed'] == True:
|
||||
self.group_id,self.group_info = self.group_find(
|
||||
self.bservice_id,
|
||||
self.bservice_info,
|
||||
self.group_id
|
||||
)
|
||||
|
||||
ret_dict['account_id'] = self.group_info['accountId']
|
||||
ret_dict['rg_id'] = self.group_info['rgId']
|
||||
ret_dict['id'] = self.group_info['id']
|
||||
ret_dict['name'] = self.group_info['name']
|
||||
ret_dict['techStatus'] = self.group_info['techStatus']
|
||||
ret_dict['state'] = self.group_info['status']
|
||||
ret_dict['Computes'] = self.group_info['computes']
|
||||
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='',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'started',
|
||||
'stopped',
|
||||
'present',
|
||||
'check',
|
||||
],
|
||||
),
|
||||
name=dict(
|
||||
type='str',
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
),
|
||||
image_id=dict(
|
||||
type='int',
|
||||
),
|
||||
image_name=dict(
|
||||
type='str',
|
||||
),
|
||||
driver=dict(
|
||||
type='str',
|
||||
choices=[
|
||||
'KVM_X86',
|
||||
'SVA_KVM_X86',
|
||||
],
|
||||
default='KVM_X86',
|
||||
),
|
||||
boot_disk=dict(
|
||||
type='int',
|
||||
),
|
||||
bservice_id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
count=dict(
|
||||
type='int',
|
||||
),
|
||||
timeoutStart=dict(
|
||||
type='int',
|
||||
),
|
||||
role=dict(
|
||||
type='str',
|
||||
),
|
||||
cpu=dict(
|
||||
type='int',
|
||||
),
|
||||
ram=dict(
|
||||
type='int',
|
||||
),
|
||||
networks=dict(
|
||||
type='list',
|
||||
elements='dict',
|
||||
options=dict(
|
||||
type=dict(
|
||||
type='str',
|
||||
required=True,
|
||||
choices=[
|
||||
'VINS',
|
||||
'EXTNET',
|
||||
]
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('id', 'name'),
|
||||
('id', 'networks'),
|
||||
('id', 'count'),
|
||||
('id', 'cpu'),
|
||||
('id', 'ram'),
|
||||
('id', 'boot_disk'),
|
||||
('id', 'image_id'),
|
||||
('id', 'driver'),
|
||||
],
|
||||
)
|
||||
|
||||
def main():
|
||||
subj = decort_group()
|
||||
amodule = subj.amodule
|
||||
|
||||
if amodule.params['state'] == 'check':
|
||||
subj.result['changed'] = False
|
||||
if subj.group_id:
|
||||
# cluster is found - package facts and report success to Ansible
|
||||
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 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",
|
||||
"DISABLED","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:
|
||||
subj.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:
|
||||
amodule.exit_json(**subj.result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_jwt
|
||||
|
||||
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 DecortJWT(DecortController):
|
||||
def __init__(self):
|
||||
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||
|
||||
@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')
|
||||
|
||||
return amodule_init_args
|
||||
|
||||
def run(self):
|
||||
self.result['jwt'] = self.jwt
|
||||
self.amodule.exit_json(**self.result)
|
||||
|
||||
|
||||
def main():
|
||||
DecortJWT().run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,514 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_k8s
|
||||
|
||||
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 *
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
class decort_k8s(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_k8s, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
validated_acc_id = 0
|
||||
validated_rg_id = 0
|
||||
validated_rg_facts = None
|
||||
validated_k8ci_id = 0
|
||||
self.k8s_should_exist = False
|
||||
|
||||
self.wg_default_params = {
|
||||
'num': 1,
|
||||
'cpu': 1,
|
||||
'ram': 1024,
|
||||
'labels': [],
|
||||
'taints': [],
|
||||
'annotations': [],
|
||||
'ci_user_data': {},
|
||||
'chipset': 'i440fx',
|
||||
}
|
||||
|
||||
if arg_amodule.params['name'] == "" and arg_amodule.params['id'] is None:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot manage k8s cluster when its ID is 0 and name is empty."
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
if arg_amodule.params['id'] is None:
|
||||
if not arg_amodule.params['rg_id']: # RG ID is not set -> locate RG by name -> need account ID
|
||||
validated_acc_id, _ = self.account_find(arg_amodule.params['account_name'],
|
||||
arg_amodule.params['account_id'])
|
||||
if not validated_acc_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Current user does not have access to the account ID {} / "
|
||||
"name '{}' or non-existent account specified.").format(arg_amodule.params['account_id'],
|
||||
arg_amodule.params['account_name'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
# fail the module -> exit
|
||||
# now validate RG
|
||||
validated_rg_id, validated_rg_facts = self.rg_find(
|
||||
arg_account_id=validated_acc_id,
|
||||
arg_rg_id=arg_amodule.params['rg_id'],
|
||||
arg_rg_name=arg_amodule.params['rg_name']
|
||||
)
|
||||
if not validated_rg_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot find RG ID {} / name '{}'.".format(arg_amodule.params['rg_id'],
|
||||
arg_amodule.params['rg_name'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
# fail the module - exit
|
||||
|
||||
self.rg_id = validated_rg_id
|
||||
arg_amodule.params['rg_id'] = validated_rg_id
|
||||
arg_amodule.params['rg_name'] = validated_rg_facts['name']
|
||||
self.acc_id = validated_rg_facts['accountId']
|
||||
|
||||
self.k8s_id,self.k8s_info = self.k8s_find(k8s_id=arg_amodule.params['id'],
|
||||
k8s_name=arg_amodule.params['name'],
|
||||
rg_id=validated_rg_id,
|
||||
check_state=False)
|
||||
|
||||
if self.k8s_id:
|
||||
self.k8s_should_exist = True
|
||||
self.acc_id = self.k8s_info['accountId']
|
||||
# check workers and groups for add or remove?
|
||||
|
||||
if not self.k8s_id:
|
||||
validated_k8ci_id = self.k8s_k8ci_find(arg_amodule.params['k8ci_id'])
|
||||
if not validated_k8ci_id:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "Cannot find K8CI ID {}.".format(arg_amodule.params['k8ci_id'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
if not arg_amodule.params['workers']:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = "At least one worker group must be present"
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
return
|
||||
|
||||
def package_facts(self,check_mode=False):
|
||||
|
||||
ret_dict = dict(
|
||||
name="",
|
||||
state="CHECK_MODE",
|
||||
account_id=0,
|
||||
rg_id=0,
|
||||
config=None,
|
||||
)
|
||||
|
||||
if self.amodule.params['getConfig'] and self.k8s_info['techStatus'] == "STARTED":
|
||||
ret_dict['config'] = self.k8s_getConfig()
|
||||
|
||||
if check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
|
||||
#if self.k8s_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.k8s_info['id']
|
||||
ret_dict['name'] = self.k8s_info['name']
|
||||
ret_dict['techStatus'] = self.k8s_info['techStatus']
|
||||
ret_dict['state'] = self.k8s_info['status']
|
||||
ret_dict['rg_id'] = self.k8s_info['rgId']
|
||||
ret_dict['vins_id'] = self.k8s_vins_id
|
||||
ret_dict['account_id'] = self.acc_id
|
||||
ret_dict['k8s_Masters'] = self.k8s_info['k8sGroups']['masters']
|
||||
ret_dict['k8s_Workers'] = self.k8s_info['k8sGroups']['workers']
|
||||
|
||||
return ret_dict
|
||||
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for k8s cluster management by decort_k8s 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 k8s cluster state.
|
||||
"""
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.k8s_id:
|
||||
self.result['msg'] = ("No state change required for K8s ID {} because of its "
|
||||
"current status '{}'.").format(self.k8s_id, self.k8s_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent K8s instance.").format(self.amodule.params['state'])
|
||||
return
|
||||
|
||||
def error(self):
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
if self.k8s_id:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for K8s cluster ID {} in the "
|
||||
"current status '{}'.").format(self.k8s_id,
|
||||
self.amodule.params['state'],
|
||||
self.k8s_info['status'])
|
||||
else:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent K8s Cluster name '{}' "
|
||||
"in RG ID {} / name '{}'").format(self.amodule.params['state'],
|
||||
self.amodule.params['name'],
|
||||
self.amodule.params['rg_id'],
|
||||
self.amodule.params['rg_name'])
|
||||
return
|
||||
|
||||
def create(self):
|
||||
master_chipset = self.amodule.params['master_chipset']
|
||||
if master_chipset is None:
|
||||
master_chipset = 'i440fx'
|
||||
|
||||
target_wgs = deepcopy(self.amodule.params['workers'])
|
||||
for wg in target_wgs:
|
||||
for param, default_value in self.wg_default_params.items():
|
||||
if wg[param] is None:
|
||||
wg[param] = default_value
|
||||
|
||||
k8s_id = self.k8s_provision(self.amodule.params['name'],
|
||||
self.amodule.params['k8ci_id'],
|
||||
self.amodule.params['rg_id'],
|
||||
self.amodule.params['vins_id'],
|
||||
self.amodule.params['network_plugin'],
|
||||
self.amodule.params['master_count'],
|
||||
self.amodule.params['master_cpu'],
|
||||
self.amodule.params['master_ram'],
|
||||
self.amodule.params['master_disk'],
|
||||
self.amodule.params['master_sepid'],
|
||||
self.amodule.params['master_pool'],
|
||||
target_wgs[0],
|
||||
self.amodule.params['extnet_id'],
|
||||
self.amodule.params['with_lb'],
|
||||
self.amodule.params['ha_lb'],
|
||||
self.amodule.params['additionalSANs'],
|
||||
self.amodule.params['init_conf'],
|
||||
self.amodule.params['cluster_conf'],
|
||||
self.amodule.params['kublet_conf'],
|
||||
self.amodule.params['kubeproxy_conf'],
|
||||
self.amodule.params['join_conf'],
|
||||
self.amodule.params['oidc_cert'],
|
||||
self.amodule.params['description'],
|
||||
self.amodule.params['extnet_only'],
|
||||
master_chipset,
|
||||
)
|
||||
|
||||
if not k8s_id:
|
||||
if k8s_id == 0:
|
||||
return
|
||||
else:
|
||||
self.result['failed'] = True
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
self.k8s_id,self.k8s_info = self.k8s_find(k8s_id=k8s_id,
|
||||
k8s_name=self.amodule.params['name'],
|
||||
rg_id=self.rg_id,
|
||||
check_state=False)
|
||||
|
||||
if self.k8s_id:
|
||||
self.k8s_should_exist = True
|
||||
self.k8s_workers_modify(
|
||||
arg_k8swg=self.k8s_info,
|
||||
arg_modwg=target_wgs,
|
||||
)
|
||||
return
|
||||
|
||||
def destroy(self):
|
||||
self.k8s_delete(self.k8s_id,self.amodule.params['permanent'])
|
||||
self.k8s_info['status'] = 'DELETED'
|
||||
self.k8s_should_exist = False
|
||||
return
|
||||
|
||||
def action(self, disared_state, started=True, preupdate: bool = False):
|
||||
if self.amodule.params['master_chipset'] is not None:
|
||||
self.result['msg'] = (
|
||||
'"master_chipset" parameter must not be specified '
|
||||
'when modifying an existing K8s cluster.'
|
||||
)
|
||||
self.exit(fail=True)
|
||||
|
||||
if preupdate:
|
||||
# K8s info updating
|
||||
self.k8s_info = self.k8s_get_by_id(k8s_id=self.k8s_id)
|
||||
#k8s state
|
||||
self.k8s_state(self.k8s_info, disared_state, started)
|
||||
self.k8s_info = self.k8s_get_by_id(k8s_id=self.k8s_id)
|
||||
if started == True and self.k8s_info['techStatus'] == "STOPPED":
|
||||
self.k8s_state(self.k8s_info, disared_state,started)
|
||||
self.k8s_info['techStatus'] == "STARTED"
|
||||
#check groups and modify if needed
|
||||
if self.aparams['workers'] is not None:
|
||||
self.k8s_workers_modify(self.k8s_info, self.amodule.params['workers'])
|
||||
if self.result['changed'] == True:
|
||||
self.k8s_info = self.k8s_get_by_id(k8s_id=self.k8s_id)
|
||||
#TODO check workers metadata and modify if needed
|
||||
|
||||
return
|
||||
|
||||
@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='',
|
||||
),
|
||||
quotas=dict(
|
||||
type='dict',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'disabled',
|
||||
'enabled',
|
||||
'present',
|
||||
'check',
|
||||
],
|
||||
),
|
||||
permanent=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
started=dict(
|
||||
type='bool',
|
||||
default=True,
|
||||
),
|
||||
name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
id=dict(
|
||||
type='int',
|
||||
),
|
||||
getConfig=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
rg_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
rg_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
vins_id=dict(
|
||||
type='int',
|
||||
),
|
||||
k8ci_id=dict(
|
||||
type='int',
|
||||
),
|
||||
network_plugin=dict(
|
||||
type='str',
|
||||
default='flannel',
|
||||
),
|
||||
master_count=dict(
|
||||
type='int',
|
||||
default=1,
|
||||
),
|
||||
master_cpu=dict(
|
||||
type='int',
|
||||
default=2,
|
||||
),
|
||||
master_ram=dict(
|
||||
type='int',
|
||||
default=2048,
|
||||
),
|
||||
master_disk=dict(
|
||||
type='int',
|
||||
default=10,
|
||||
),
|
||||
master_sepid=dict(
|
||||
type='int',
|
||||
),
|
||||
master_pool=dict(
|
||||
type='str',
|
||||
),
|
||||
workers=dict(
|
||||
type='list',
|
||||
elements='dict',
|
||||
options=dict(
|
||||
name=dict(
|
||||
type='str',
|
||||
required=True,
|
||||
),
|
||||
num=dict(
|
||||
type='int',
|
||||
),
|
||||
cpu=dict(
|
||||
type='int',
|
||||
),
|
||||
ram=dict(
|
||||
type='int',
|
||||
),
|
||||
disk=dict(
|
||||
type='int',
|
||||
),
|
||||
sep_id=dict(
|
||||
type='int',
|
||||
),
|
||||
pool=dict(
|
||||
type='str',
|
||||
),
|
||||
annotations=dict(
|
||||
type='list',
|
||||
elements='str',
|
||||
),
|
||||
ci_user_data=dict(
|
||||
type='dict',
|
||||
),
|
||||
labels=dict(
|
||||
type='list',
|
||||
elements='str',
|
||||
),
|
||||
taints=dict(
|
||||
type='list',
|
||||
elements='str',
|
||||
),
|
||||
chipset=dict(
|
||||
type='str',
|
||||
choices=['Q35', 'i440fx'],
|
||||
),
|
||||
),
|
||||
),
|
||||
workers_metadata=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
extnet_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
description=dict(
|
||||
type='str',
|
||||
default='Created by decort ansible module',
|
||||
),
|
||||
with_lb=dict(
|
||||
type='bool',
|
||||
default=True,
|
||||
),
|
||||
ha_lb=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
extnet_only=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
additionalSANs=dict(
|
||||
type='list',
|
||||
),
|
||||
init_conf=dict(
|
||||
type='dict',
|
||||
),
|
||||
cluster_conf=dict(
|
||||
type='dict',
|
||||
),
|
||||
kublet_conf=dict(
|
||||
type='dict',
|
||||
),
|
||||
kubeproxy_conf=dict(
|
||||
type='dict',
|
||||
),
|
||||
join_conf=dict(
|
||||
type='dict',
|
||||
),
|
||||
oidc_cert=dict(
|
||||
type='raw',
|
||||
),
|
||||
master_chipset=dict(
|
||||
type='str',
|
||||
choices=['Q35', 'i440fx'],
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('id', 'name'),
|
||||
],
|
||||
)
|
||||
|
||||
def main():
|
||||
subj = decort_k8s()
|
||||
amodule = subj.amodule
|
||||
|
||||
if amodule.params['state'] == 'check':
|
||||
subj.result['changed'] = False
|
||||
if subj.k8s_id:
|
||||
# cluster is found - package facts and report success to Ansible
|
||||
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 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'):
|
||||
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['techStatus'] in ("STARTED","STOPPED"):
|
||||
if amodule.params['state'] == 'disabled':
|
||||
subj.action(amodule.params['state'])
|
||||
elif amodule.params['state'] == 'absent':
|
||||
subj.destroy()
|
||||
else:
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
elif subj.k8s_info['status'] == "DISABLED":
|
||||
if amodule.params['state'] == 'absent':
|
||||
subj.destroy()
|
||||
elif amodule.params['state'] in ('present','enabled'):
|
||||
subj.action(amodule.params['state'],amodule.params['started'])
|
||||
else:
|
||||
subj.nop()
|
||||
elif subj.k8s_info['status'] == "DESTROED":
|
||||
if amodule.params['state'] in ('present','enabled'):
|
||||
subj.create()
|
||||
if amodule.params['state'] == 'absent':
|
||||
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__":
|
||||
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,313 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_osimage
|
||||
|
||||
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_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.validated_virt_image_id = amodule.params['virt_id']
|
||||
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)
|
||||
|
||||
|
||||
if amodule.params['virt_id'] != 0 and amodule.params['virt_name']:
|
||||
self.validated_virt_image_id, image_facts =\
|
||||
self.decort_virt_image_find(amodule)
|
||||
if (self.validated_virt_image_id and
|
||||
amodule.params['virt_name'] != image_facts['name']):
|
||||
self.decort_virt_image_rename(amodule)
|
||||
self.result['msg'] = 'Virtual image renamed successfully'
|
||||
elif amodule.params['image_id'] != 0 and amodule.params['image_name']:
|
||||
self.validated_image_id, image_facts = self.decort_image_find(amodule)
|
||||
if (self.validated_image_id and
|
||||
amodule.params['image_name'] != image_facts['name']):
|
||||
decort_osimage.decort_image_rename(self,amodule)
|
||||
self.result['msg'] = ("Image renamed successfully")
|
||||
|
||||
|
||||
|
||||
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):
|
||||
# function that creates OS image
|
||||
image_facts = self.image_create(img_name=self.validated_image_name,
|
||||
url=amodule.params['url'],
|
||||
gid=amodule.params['gid'],
|
||||
boottype=amodule.params['boottype'],
|
||||
imagetype=amodule.params['imagetype'],
|
||||
hotresize=amodule.params['hotresize'],
|
||||
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'],
|
||||
drivers=amodule.params['drivers'])
|
||||
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)
|
||||
self.result['changed'] = True
|
||||
self.result['msg'] = ("Image '{}' deleted").format(amodule.image_id_delete)
|
||||
|
||||
def decort_virt_image_create(self,amodule):
|
||||
# function that creates a virtual image
|
||||
image_facts = self.virt_image_create(name=amodule.params['virt_name'], 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)
|
||||
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
|
||||
|
||||
def decort_osimage_package_facts(arg_osimage_facts, 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['type'] = arg_osimage_facts['type']
|
||||
# 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']
|
||||
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',
|
||||
],
|
||||
),
|
||||
drivers=dict(
|
||||
type='str',
|
||||
default='KVM_X86',
|
||||
),
|
||||
imagetype=dict(
|
||||
type='str',
|
||||
default='linux',
|
||||
),
|
||||
boottype=dict(
|
||||
type='str',
|
||||
default='uefi',
|
||||
),
|
||||
url=dict(
|
||||
type='str',
|
||||
),
|
||||
gid=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
sepId=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
poolName=dict(
|
||||
type='str',
|
||||
),
|
||||
hotresize=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
image_username=dict(
|
||||
type='str',
|
||||
),
|
||||
image_password=dict(
|
||||
type='str',
|
||||
),
|
||||
usernameDL=dict(
|
||||
type='str',
|
||||
),
|
||||
passwordDL=dict(
|
||||
type='str',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
def main():
|
||||
decon = decort_osimage()
|
||||
amodule = decon.amodule
|
||||
if amodule.params['virt_name'] or amodule.params['virt_id']:
|
||||
|
||||
image_id, image_facts = decort_osimage.decort_virt_image_find(decon, amodule)
|
||||
if amodule.params['image_name'] or amodule.params['image_id']:
|
||||
decon.target_image_id, _ = decort_osimage.decort_image_find(decon, amodule)
|
||||
else:
|
||||
decon.target_image_id = 0
|
||||
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 and decon.target_image_id:
|
||||
if 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 decon.validated_virt_image_id > 0 and amodule.params['state'] == "absent":
|
||||
decon.result['msg'] = ("Osimage module cannot delete virtual images.")
|
||||
decon.result['failed'] = True
|
||||
amodule.exit_json(**decon.result)
|
||||
|
||||
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
|
||||
decort_osimage.decort_image_delete(decon,amodule)
|
||||
|
||||
if decon.result['failed'] == True:
|
||||
# we failed to find the specified image - fail the module
|
||||
decon.result['changed'] = False
|
||||
amodule.fail_json(**decon.result)
|
||||
|
||||
amodule.exit_json(**decon.result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,145 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_pfw
|
||||
|
||||
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 *
|
||||
|
||||
|
||||
class decort_pfw(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_pfw, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
argument_spec=dict(
|
||||
compute_id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
rules=dict(
|
||||
type='list',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'present',
|
||||
],
|
||||
),
|
||||
vins_id=dict(
|
||||
type='int',
|
||||
required=True,
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
def decort_pfw_package_facts(self, comp_facts, vins_facts, pfw_facts, check_mode=False):
|
||||
"""Package a dictionary of PFW rules facts according to the decort_pfw module specification.
|
||||
This dictionary will be returned to the upstream Ansible engine at the completion of
|
||||
the module run.
|
||||
|
||||
@param (dict) pfw_facts: dictionary with PFW facts as returned by API call to .../???/get
|
||||
@param (bool) check_mode: boolean that tells if this Ansible module is run in check mode
|
||||
"""
|
||||
|
||||
ret_dict = dict(state="CHECK_MODE",
|
||||
compute_id=0,
|
||||
public_ip="",
|
||||
rules=[],
|
||||
vins_id=0,
|
||||
)
|
||||
|
||||
if check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
|
||||
if pfw_facts is None:
|
||||
# if void facts provided - change state value to ABSENT and return
|
||||
ret_dict['state'] = "ABSENT"
|
||||
return ret_dict
|
||||
|
||||
ret_dict['compute_id'] = comp_facts['id']
|
||||
ret_dict['vins_id'] = vins_facts['id']
|
||||
ret_dict['public_ip'] = vins_facts['vnfs']['GW']['config']['ext_net_ip']
|
||||
|
||||
if len(pfw_facts) != 0:
|
||||
ret_dict['state'] = 'PRESENT'
|
||||
ret_dict['rules'] = pfw_facts
|
||||
else:
|
||||
ret_dict['state'] = 'ABSENT'
|
||||
|
||||
return ret_dict
|
||||
|
||||
def decort_pfw_parameters(self):
|
||||
"""Build and return a dictionary of parameters expected by decort_pfw module in a form accepted
|
||||
by AnsibleModule utility class."""
|
||||
|
||||
return
|
||||
|
||||
def main():
|
||||
decon = decort_pfw()
|
||||
amodule = decon.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 = 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()
|
@ -1,415 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_rg
|
||||
|
||||
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_rg(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_rg, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
amodule = self.amodule
|
||||
|
||||
self.validated_acc_id = 0
|
||||
self.validated_rg_id = 0
|
||||
self.validated_rg_facts = None
|
||||
|
||||
if amodule.params['rg_id'] is None:
|
||||
if self.amodule.params['account_id']:
|
||||
self.validated_acc_id, _ = self.account_find("", amodule.params['account_id'])
|
||||
elif amodule.params['account_name']:
|
||||
self.validated_acc_id, _ = self.account_find(amodule.params['account_name'])
|
||||
if not self.validated_acc_id:
|
||||
# we failed to locate account by either name or ID - abort with an error
|
||||
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)
|
||||
|
||||
# Check if the RG with the specified parameters already exists
|
||||
self.get_info()
|
||||
|
||||
if amodule.params['state'] != "absent":
|
||||
self.rg_should_exist = True
|
||||
else:
|
||||
self.rg_should_exist = False
|
||||
|
||||
def get_info(self):
|
||||
# If this is the first getting info
|
||||
if not self.validated_rg_id:
|
||||
self.validated_rg_id, self.rg_facts = self.rg_find(
|
||||
arg_account_id=self.validated_acc_id,
|
||||
arg_rg_id=self.aparams['rg_id'],
|
||||
arg_rg_name=self.aparams['rg_name'],
|
||||
arg_check_state=False,
|
||||
)
|
||||
# If this is a repeated getting info
|
||||
else:
|
||||
# If check mode is enabled, there is no needed to
|
||||
# request info again
|
||||
if self.amodule.check_mode:
|
||||
return
|
||||
|
||||
_, self.rg_facts = self.rg_find(arg_rg_id=self.validated_rg_id)
|
||||
|
||||
def access(self):
|
||||
should_change_access = False
|
||||
acc_granted = False
|
||||
for rg_item in self.rg_facts['acl']:
|
||||
if rg_item['userGroupId'] == self.amodule.params['access']['user']:
|
||||
acc_granted = True
|
||||
if self.amodule.params['access']['action'] == 'grant':
|
||||
if rg_item['right'] != self.amodule.params['access']['right']:
|
||||
should_change_access = True
|
||||
if self.amodule.params['access']['action'] == 'revoke':
|
||||
should_change_access = True
|
||||
if acc_granted == False and self.amodule.params['access']['action'] == 'grant':
|
||||
should_change_access = True
|
||||
|
||||
if should_change_access == True:
|
||||
self.rg_access(self.validated_rg_id, self.amodule.params['access'])
|
||||
self.rg_facts['access'] = self.amodule.params['access']
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def error(self):
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
if self.validated_rg_id > 0:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for rg ID {} in the "
|
||||
"current status '{}'.").format(self.validated_rg_id,
|
||||
self.amodule.params['state'],
|
||||
self.rg_facts['status'])
|
||||
else:
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent rg name '{}' "
|
||||
"in account ID {} ").format(self.amodule.params['state'],
|
||||
self.amodule.params['rg_name'],
|
||||
self.validated_acc_id)
|
||||
return
|
||||
|
||||
def update(self):
|
||||
resources = self.rg_facts['Resources']['Reserved']
|
||||
incorrect_quota = dict(Requested=dict(),
|
||||
Reserved=dict(),)
|
||||
query_key_map = dict(cpu='cpu',
|
||||
ram='ram',
|
||||
disk='disksize',
|
||||
ext_ips='extips',
|
||||
net_transfer='exttraffic',)
|
||||
if self.amodule.params['quotas']:
|
||||
for quota_item in self.amodule.params['quotas']:
|
||||
if self.amodule.params['quotas'][quota_item] < resources[query_key_map[quota_item]]:
|
||||
incorrect_quota['Requested'][quota_item]=self.amodule.params['quotas'][quota_item]
|
||||
incorrect_quota['Reserved'][quota_item]=resources[query_key_map[quota_item]]
|
||||
|
||||
if incorrect_quota['Requested']:
|
||||
self.result['msg'] = ("Cannot limit less than already reserved'{}'").format(incorrect_quota)
|
||||
self.result['failed'] = True
|
||||
|
||||
if not self.result['failed']:
|
||||
self.rg_update(
|
||||
arg_rg_dict=self.rg_facts,
|
||||
arg_quotas=self.amodule.params['quotas'],
|
||||
arg_res_types=self.amodule.params['resType'],
|
||||
arg_newname=self.amodule.params['rename'],
|
||||
arg_sep_pools=self.amodule.params['sep_pools'],
|
||||
)
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def setDefNet(self):
|
||||
rg_def_net_type = self.rg_facts['def_net_type']
|
||||
rg_def_net_id = self.rg_facts['def_net_id']
|
||||
aparam_def_net_type = self.aparams['def_netType']
|
||||
aparam_def_net_id = self.aparams['def_netId']
|
||||
|
||||
need_to_reset = (aparam_def_net_type == 'NONE'
|
||||
and rg_def_net_type != aparam_def_net_type)
|
||||
|
||||
need_to_change = False
|
||||
if aparam_def_net_id is not None:
|
||||
need_to_change = (aparam_def_net_id != rg_def_net_id
|
||||
or aparam_def_net_type != rg_def_net_type)
|
||||
|
||||
if need_to_reset or need_to_change:
|
||||
self.rg_setDefNet(
|
||||
arg_rg_id=self.validated_rg_id,
|
||||
arg_net_type=aparam_def_net_type,
|
||||
arg_net_id=aparam_def_net_id,
|
||||
)
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def create(self):
|
||||
self.validated_rg_id = self.rg_provision(self.validated_acc_id,
|
||||
self.amodule.params['rg_name'],
|
||||
self.amodule.params['owner'],
|
||||
self.amodule.params['description'],
|
||||
self.amodule.params['resType'],
|
||||
self.amodule.params['def_netType'],
|
||||
self.amodule.params['ipcidr'],
|
||||
self.amodule.params['extNetId'],
|
||||
self.amodule.params['extNetIp'],
|
||||
self.amodule.params['quotas'],
|
||||
"", # this is location code. TODO: add module argument
|
||||
)
|
||||
|
||||
if self.validated_rg_id:
|
||||
self.validated_rg_id, self.rg_facts = self.rg_find(
|
||||
arg_account_id=self.validated_acc_id,
|
||||
arg_rg_id=self.validated_rg_id,
|
||||
arg_rg_name="",
|
||||
arg_check_state=False
|
||||
)
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def enable(self):
|
||||
self.rg_enable(self.validated_rg_id,
|
||||
self.amodule.params['state'])
|
||||
if self.amodule.params['state'] == "enabled":
|
||||
self.rg_facts['status'] = 'CREATED'
|
||||
else:
|
||||
self.rg_facts['status'] = 'DISABLED'
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def restore(self):
|
||||
self.rg_restore(self.validated_rg_id)
|
||||
self.rg_facts['status'] = 'DISABLED'
|
||||
self.rg_should_exist = True
|
||||
return
|
||||
|
||||
def destroy(self):
|
||||
self.rg_delete(
|
||||
rg_id=self.validated_rg_id,
|
||||
permanently=self.amodule.params['permanently'],
|
||||
recursively=self.aparams['recursive_deletion'],
|
||||
)
|
||||
if self.amodule.params['permanently'] == True:
|
||||
self.rg_facts['status'] = 'DESTROYED'
|
||||
else:
|
||||
self.rg_facts['status'] = 'DELETED'
|
||||
self.rg_should_exist = False
|
||||
return
|
||||
|
||||
def package_facts(self, check_mode=False):
|
||||
"""Package a dictionary of RG facts according to the decort_rg module specification. This dictionary will
|
||||
be returned to the upstream Ansible engine at the completion of the module run.
|
||||
|
||||
@param arg_rg_facts: dictionary with RG facts as returned by API call to .../rg/get
|
||||
@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 check_mode:
|
||||
# in check mode return immediately with the default values
|
||||
return ret_dict
|
||||
|
||||
#if arg_rg_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.rg_facts['id']
|
||||
ret_dict['name'] = self.rg_facts['name']
|
||||
ret_dict['state'] = self.rg_facts['status']
|
||||
ret_dict['account_id'] = self.rg_facts['accountId']
|
||||
ret_dict['gid'] = self.rg_facts['gid']
|
||||
ret_dict['quota'] = self.rg_facts['resourceLimits']
|
||||
ret_dict['resTypes'] = self.rg_facts['resourceTypes']
|
||||
ret_dict['defNetId'] = self.rg_facts['def_net_id']
|
||||
ret_dict['defNetType'] = self.rg_facts['def_net_type']
|
||||
ret_dict['ViNS'] = self.rg_facts['vins']
|
||||
ret_dict['computes'] = self.rg_facts['vms']
|
||||
ret_dict['uniqPools'] = self.rg_facts['uniqPools']
|
||||
|
||||
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='',
|
||||
),
|
||||
access=dict(
|
||||
type='dict',
|
||||
),
|
||||
description=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
def_netType=dict(
|
||||
type='str',
|
||||
choices=[
|
||||
'PRIVATE',
|
||||
'PUBLIC',
|
||||
'NONE',
|
||||
],
|
||||
default='PRIVATE',
|
||||
),
|
||||
def_netId=dict(
|
||||
type='int',
|
||||
),
|
||||
extNetId=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
extNetIp=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
owner=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
ipcidr=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
rename=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
quotas=dict(
|
||||
type='dict',
|
||||
),
|
||||
resType=dict(
|
||||
type='list',
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'disabled',
|
||||
'enabled',
|
||||
'present',
|
||||
],
|
||||
),
|
||||
permanently=dict(
|
||||
type='bool',
|
||||
default='False',
|
||||
),
|
||||
rg_name=dict(
|
||||
type='str',
|
||||
),
|
||||
rg_id=dict(
|
||||
type='int',
|
||||
),
|
||||
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',
|
||||
),
|
||||
),
|
||||
),
|
||||
recursive_deletion=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
)
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
# Workflow digest:
|
||||
# 1) authenticate to DECORT controller & validate authentication by issuing API call - done when creating DECORTController
|
||||
# 2) check if the RG with the specified id or rg_name:name exists
|
||||
# 3) if RG does not exist -> deploy
|
||||
# 4) if RG exists: check desired state, desired configuration -> initiate action accordingly
|
||||
# 5) report result to Ansible
|
||||
|
||||
def main():
|
||||
decon = decort_rg()
|
||||
amodule = decon.amodule
|
||||
#amodule.check_mode=True
|
||||
if decon.validated_rg_id > 0:
|
||||
if decon.rg_facts['status'] in ["MODELED", "DISABLING", "ENABLING", "DELETING", "DESTROYING", "CONFIRMED"]:
|
||||
decon.error()
|
||||
elif decon.rg_facts['status'] in ("CREATED"):
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.destroy()
|
||||
elif amodule.params['state'] == "disabled":
|
||||
decon.enable()
|
||||
if amodule.params['state'] in ['present', 'enabled']:
|
||||
if (
|
||||
amodule.params['quotas']
|
||||
or amodule.params['resType']
|
||||
or amodule.params['rename'] != ""
|
||||
or amodule.params['sep_pools'] is not None
|
||||
):
|
||||
decon.update()
|
||||
if amodule.params['access']:
|
||||
decon.access()
|
||||
if amodule.params['def_netType'] is not None:
|
||||
decon.setDefNet()
|
||||
|
||||
elif decon.rg_facts['status'] == "DELETED":
|
||||
if amodule.params['state'] == 'absent' and amodule.params['permanently'] == True:
|
||||
decon.destroy()
|
||||
elif (amodule.params['state'] == 'present'
|
||||
or amodule.params['state'] == 'disabled'):
|
||||
decon.restore()
|
||||
elif amodule.params['state'] == 'enabled':
|
||||
decon.restore()
|
||||
decon.enable()
|
||||
elif decon.rg_facts['status'] in ("DISABLED"):
|
||||
if amodule.params['state'] == 'absent':
|
||||
decon.destroy()
|
||||
elif amodule.params['state'] == ("enabled"):
|
||||
decon.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:
|
||||
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()
|
@ -1,423 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: decort_vins
|
||||
|
||||
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_vins(DecortController):
|
||||
def __init__(self):
|
||||
super(decort_vins, self).__init__(AnsibleModule(**self.amodule_init_args))
|
||||
arg_amodule = self.amodule
|
||||
|
||||
self.vins_id = 0
|
||||
self.vins_level = "" # "ID" if specified by ID, "RG" - at resource group, "ACC" - at account level
|
||||
vins_facts = None # will hold ViNS facts
|
||||
validated_rg_id = 0
|
||||
rg_facts = None # will hold RG facts
|
||||
validated_acc_id = 0
|
||||
acc_facts = None # will hold Account facts
|
||||
|
||||
if arg_amodule.params['vins_id']:
|
||||
# expect existing ViNS with the specified ID
|
||||
# This call to vins_find will abort the module if no ViNS with such ID is present
|
||||
self.vins_id, self.vins_facts = self.vins_find(arg_amodule.params['vins_id'],check_state=False)
|
||||
if self.vins_id == 0:
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "Specified ViNS ID {} not found.".format(arg_amodule.params['vins_id'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
self.vins_level = "ID"
|
||||
#raise Exception(self.vins_facts)
|
||||
validated_acc_id = self.vins_facts['accountId']
|
||||
validated_rg_id = self.vins_facts['rgId']
|
||||
|
||||
elif arg_amodule.params['rg_id']:
|
||||
# expect ViNS @ RG level in the RG with specified ID
|
||||
self.vins_level = "RG"
|
||||
# This call to rg_find will abort the module if no RG with such ID is present
|
||||
validated_rg_id, rg_facts = self.rg_find(0, # account ID set to 0 as we search for RG by RG ID
|
||||
arg_amodule.params['rg_id'], arg_rg_name="")
|
||||
|
||||
# This call to vins_find may return vins_id=0 if no ViNS found
|
||||
self.vins_id, self.vins_facts = self.vins_find(vins_id=0, vins_name=arg_amodule.params['vins_name'],
|
||||
account_id=0,
|
||||
rg_id=arg_amodule.params['rg_id'],
|
||||
rg_facts=rg_facts,
|
||||
check_state=False)
|
||||
# TODO: add checks and setup ViNS presence flags accordingly
|
||||
pass
|
||||
elif arg_amodule.params['account_id'] or arg_amodule.params['account_name'] != "":
|
||||
# Specified account must be present and accessible by the user, otherwise abort the module
|
||||
validated_acc_id, acc_facts = self.account_find(arg_amodule.params['account_name'], arg_amodule.params['account_id'])
|
||||
if not validated_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)
|
||||
if arg_amodule.params['rg_name'] != "": # at this point we know that rg_id=0
|
||||
# expect ViNS @ RG level in the RG with specified name under specified account
|
||||
# RG with the specified name must be present under the account, otherwise abort the module
|
||||
validated_rg_id, rg_facts = self.rg_find(validated_acc_id, 0, arg_amodule.params['rg_name'])
|
||||
if (not validated_rg_id or
|
||||
rg_facts['status'] in ["DESTROYING", "DESTROYED", "DELETING", "DELETED", "DISABLING", "ENABLING"]):
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "RG name '{}' not found or has invalid state.".format(arg_amodule.params['rg_name'])
|
||||
self.amodule.fail_json(**self.result)
|
||||
# This call to vins_find may return vins_id=0 if no ViNS with this name found under specified RG
|
||||
self.vins_id, self.vins_facts = self.vins_find(vins_id=0, vins_name=arg_amodule.params['vins_name'],
|
||||
account_id=0, # set to 0, as we are looking for ViNS under RG
|
||||
rg_id=validated_rg_id,
|
||||
rg_facts=rg_facts,
|
||||
check_state=False)
|
||||
self.vins_level = "RG"
|
||||
# TODO: add checks and setup ViNS presence flags accordingly
|
||||
else: # At this point we know for sure that rg_name="" and rg_id=0
|
||||
# So we expect ViNS @ account level
|
||||
# This call to vins_find may return vins_id=0 if no ViNS found
|
||||
self.vins_id, self.vins_facts = self.vins_find(vins_id=0, vins_name=arg_amodule.params['vins_name'],
|
||||
account_id=validated_acc_id,
|
||||
rg_id=0,
|
||||
rg_facts=rg_facts,
|
||||
check_state=False)
|
||||
self.vins_level = "ACC"
|
||||
# TODO: add checks and setup ViNS presence flags accordingly
|
||||
else:
|
||||
# this is "invalid arguments combination" sink
|
||||
# if we end up here, it means that module was invoked with vins_id=0 and rg_id=0
|
||||
self.result['failed'] = True
|
||||
self.result['msg'] = "Cannot find ViNS by name"
|
||||
if arg_amodule.params['account_id'] == 0 and arg_amodule.params['account_name'] == '':
|
||||
self.result['msg'] = "Cannot find ViNS by name when account name is empty and account ID is 0."
|
||||
if arg_amodule.params['rg_name'] == "":
|
||||
# rg_name without account specified
|
||||
self.result['msg'] = "Cannot find ViNS by name when RG name is empty and RG ID is 0."
|
||||
self.amodule.fail_json(**self.result)
|
||||
|
||||
return
|
||||
self.rg_id = validated_rg_id
|
||||
self.acc_id = validated_acc_id
|
||||
return
|
||||
def create(self):
|
||||
self.vins_id = self.vins_provision(self.amodule.params['vins_name'],
|
||||
self.acc_id, self.rg_id,
|
||||
self.amodule.params['ipcidr'],
|
||||
self.amodule.params['ext_net_id'], self.amodule.params['ext_ip_addr'],
|
||||
self.amodule.params['description'])
|
||||
|
||||
if self.amodule.params['mgmtaddr'] or self.amodule.params['connect_to']:
|
||||
_, self.vins_facts = self.vins_find(self.vins_id)
|
||||
if self.amodule.params['connect_to']:
|
||||
self.vins_update_ifaces(self.vins_facts,self.amodule.params['connect_to'],)
|
||||
if self.amodule.params['mgmtaddr']:
|
||||
self.vins_update_mgmt(self.vins_facts,self.amodule.params['mgmtaddr'])
|
||||
|
||||
return
|
||||
def action(self,d_state='',restore=False):
|
||||
if restore == True:
|
||||
self.vins_restore(arg_vins_id=self.vins_id)
|
||||
self.vins_state(self.vins_facts, 'enabled')
|
||||
self.vins_facts['status'] = "ENABLED"
|
||||
self.vins_facts['VNFDev']['techStatus'] = "STARTED"
|
||||
|
||||
self.vins_update_extnet(self.vins_facts,
|
||||
self.amodule.params['ext_net_id'],
|
||||
self.amodule.params['ext_ip_addr'],
|
||||
)
|
||||
|
||||
if d_state == 'enabled' and self.vins_facts['status'] == "DISABLED":
|
||||
self.vins_state(self.vins_facts, d_state)
|
||||
self.vins_facts['status'] = "ENABLED"
|
||||
self.vins_facts['VNFDev']['techStatus'] = "STARTED"
|
||||
d_state = ''
|
||||
|
||||
if self.vins_facts['status'] == "ENABLED" and self.vins_facts['VNFDev']['techStatus'] == "STARTED":
|
||||
self.vins_update_ifaces(self.vins_facts,
|
||||
self.amodule.params['connect_to'],
|
||||
)
|
||||
if self.result['changed']:
|
||||
_, self.vins_facts = self.vins_find(self.vins_id)
|
||||
self.vins_update_mgmt(self.vins_facts,
|
||||
self.amodule.params['mgmtaddr'],
|
||||
)
|
||||
|
||||
if d_state != '':
|
||||
self.vins_state(self.vins_facts, d_state)
|
||||
return
|
||||
def delete(self):
|
||||
self.vins_delete(self.vins_id, permanently=True)
|
||||
self.vins_facts['status'] = 'DESTROYED'
|
||||
return
|
||||
def nop(self):
|
||||
"""No operation (NOP) handler for ViNS management by decort_vins 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 ViNS state.
|
||||
"""
|
||||
self.result['failed'] = False
|
||||
self.result['changed'] = False
|
||||
if self.vins_id:
|
||||
self.result['msg'] = ("No state change required for ViNS ID {} because of its "
|
||||
"current status '{}'.").format(self.vins_id, self.vins_facts['status'])
|
||||
else:
|
||||
self.result['msg'] = ("No state change to '{}' can be done for "
|
||||
"non-existent ViNS 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 ViNS ID {} in the "
|
||||
"current status '{}'").format(self.vins_id,
|
||||
self.amodule.params['state'],
|
||||
self.vins_facts['status'])
|
||||
else:
|
||||
self.result['failed'] = True
|
||||
self.result['changed'] = False
|
||||
self.result['msg'] = ("Invalid target state '{}' requested for non-existent "
|
||||
"ViNS name '{}'").format(self.amodule.params['state'],
|
||||
self.amodule.params['vins_name'])
|
||||
return
|
||||
def package_facts(self, arg_check_mode=False):
|
||||
"""Package a dictionary of ViNS facts according to the decort_vins 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.vins_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.vins_facts['id']
|
||||
ret_dict['name'] = self.vins_facts['name']
|
||||
ret_dict['state'] = self.vins_facts['status']
|
||||
ret_dict['account_id'] = self.vins_facts['accountId']
|
||||
ret_dict['rg_id'] = self.vins_facts['rgId']
|
||||
ret_dict['int_net_addr'] = self.vins_facts['network']
|
||||
ret_dict['gid'] = self.vins_facts['gid']
|
||||
custom_interfaces = list(filter(lambda i: i['type']=="CUSTOM",self.vins_facts['VNFDev']['interfaces']))
|
||||
if custom_interfaces:
|
||||
ret_dict['custom_net_addr'] = []
|
||||
for runner in custom_interfaces:
|
||||
ret_dict['custom_net_addr'].append(runner['ipAddress'])
|
||||
mgmt_interfaces = list(filter(lambda i: i['listenSsh'] and i['name']!="ens9",self.vins_facts['VNFDev']['interfaces']))
|
||||
if mgmt_interfaces:
|
||||
ret_dict['ssh_ipaddr'] = []
|
||||
for runner in mgmt_interfaces:
|
||||
ret_dict['ssh_ipaddr'].append(runner['ipAddress'])
|
||||
ret_dict['ssh_password'] = self.vins_facts['VNFDev']['config']['mgmt']['password']
|
||||
ret_dict['ssh_port'] = 9022
|
||||
if self.vins_facts['vnfs'].get('GW'):
|
||||
gw_config = self.vins_facts['vnfs']['GW']['config']
|
||||
ret_dict['ext_ip_addr'] = gw_config['ext_net_ip']
|
||||
ret_dict['ext_net_id'] = gw_config['ext_net_id']
|
||||
else:
|
||||
ret_dict['ext_ip_addr'] = ""
|
||||
ret_dict['ext_net_id'] = -1
|
||||
|
||||
return ret_dict
|
||||
|
||||
|
||||
@property
|
||||
def amodule_init_args(self) -> dict:
|
||||
return self.pack_amodule_init_args(
|
||||
argument_spec=dict(
|
||||
account_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
account_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
description=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
ext_net_id=dict(
|
||||
type='int',
|
||||
default=-1,
|
||||
),
|
||||
ext_ip_addr=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
ipcidr=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
mgmtaddr=dict(
|
||||
type='list',
|
||||
default=[],
|
||||
),
|
||||
custom_config=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
config_save=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
),
|
||||
connect_to=dict(
|
||||
type='list',
|
||||
default=[],
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
default='present',
|
||||
choices=[
|
||||
'absent',
|
||||
'disabled',
|
||||
'enabled',
|
||||
'present',
|
||||
],
|
||||
),
|
||||
rg_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
rg_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
vins_id=dict(
|
||||
type='int',
|
||||
default=0,
|
||||
),
|
||||
vins_name=dict(
|
||||
type='str',
|
||||
default='',
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[
|
||||
('vins_id', 'vins_name'),
|
||||
],
|
||||
)
|
||||
|
||||
# Workflow digest:
|
||||
# 1) authenticate to DECORT controller & validate authentication by issuing API call - done when creating DECORTController
|
||||
# 2) check if the ViNS with this id or name exists under specified account / resource group
|
||||
# 3) if ViNS does not exist -> deploy
|
||||
# 4) if ViNS exists: check desired state, desired configuration -> initiate action(s) accordingly
|
||||
# 5) report result to Ansible
|
||||
|
||||
def main():
|
||||
decon = decort_vins()
|
||||
amodule = decon.amodule
|
||||
#
|
||||
# Initial validation of module arguments is complete
|
||||
#
|
||||
# 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:
|
||||
# - if validated_rg_id is non-zero, create ViNS @ RG level
|
||||
# - if validated_rg_id is zero, create ViNS @ account level
|
||||
#
|
||||
# When managing existing ViNS we need to account for both "static" and "transient"
|
||||
# status. Full range of ViNS statii is as follows:
|
||||
#
|
||||
# "MODELED", "CREATED", "ENABLED", "ENABLING", "DISABLED", "DISABLING", "DELETED", "DELETING", "DESTROYED", "DESTROYING"
|
||||
#
|
||||
# if cconfig_save is true, only config save without other updates
|
||||
vins_should_exist = False
|
||||
|
||||
if decon.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
|
||||
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
|
||||
elif amodule.params['state'] == 'disabled':
|
||||
decon.error()
|
||||
#
|
||||
# conditional switch end - complete module run
|
||||
#
|
||||
if decon.result['failed']:
|
||||
amodule.fail_json(**decon.result)
|
||||
else:
|
||||
# prepare ViNS facts to be returned as part of decon.result and then call exit_json(...)
|
||||
if decon.result['changed']:
|
||||
_, decon.vins_facts = decon.vins_find(decon.vins_id)
|
||||
decon.result['facts'] = decon.package_facts(amodule.check_mode)
|
||||
amodule.exit_json(**decon.result)
|
||||
|
||||
|
||||
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