Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
8c554c8edd | 5 days ago |
|
|
becbe65993 | 3 weeks ago |
|
|
06336697a6 | 5 months ago |
|
|
4113719334 | 7 months ago |
|
|
f8c32d609b | 9 months ago |
|
|
e537eadda6 | 10 months ago |
|
|
5f3df12742 | 12 months ago |
@ -0,0 +1,3 @@
|
|||||||
|
dev:
|
||||||
|
pip install -r requirements-dev.txt
|
||||||
|
pre-commit install
|
||||||
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
#
|
|
||||||
# DECORT kvmvm module example
|
|
||||||
#
|
|
||||||
- hosts: ansible_master
|
|
||||||
tasks:
|
|
||||||
- name: create a VM named cloud-init_example
|
|
||||||
decort_kvmvm:
|
|
||||||
name: affinity_example
|
|
||||||
annotation: "VM managed by decort_kvmvm module"
|
|
||||||
authenticator: oauth2
|
|
||||||
app_id: "" # Application id from SSO Digital Energy
|
|
||||||
app_secret: "" # API key from SSO Digital Energy
|
|
||||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
|
||||||
rg_id: # Resource group id
|
|
||||||
cpu: 2
|
|
||||||
ram: 2048
|
|
||||||
boot_disk: 10
|
|
||||||
image_name: "DECS Ubuntu 18.04 v1.2.3" # Name of OS image
|
|
||||||
networks:
|
|
||||||
- type: VINS
|
|
||||||
id: # VINS id
|
|
||||||
tags: "Ansible cloud init example"
|
|
||||||
aff_lable: "Affinity lable"
|
|
||||||
tag:
|
|
||||||
- key: bd
|
|
||||||
value: main
|
|
||||||
aff_rule:
|
|
||||||
- key: app
|
|
||||||
value: main
|
|
||||||
topology: compute
|
|
||||||
policy: REQUIRED
|
|
||||||
mode: EQ
|
|
||||||
state: present
|
|
||||||
delegate_to: localhost
|
|
||||||
register: simple_vm
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
#
|
|
||||||
# DECORT kvmvm module example
|
|
||||||
#
|
|
||||||
- hosts: ansible_master
|
|
||||||
tasks:
|
|
||||||
- name: create a VM named cloud-init_example
|
|
||||||
decort_kvmvm:
|
|
||||||
name: anti-affinity_example
|
|
||||||
annotation: "VM managed by decort_kvmvm module"
|
|
||||||
authenticator: oauth2
|
|
||||||
app_id: "" # Application id from SSO Digital Energy
|
|
||||||
app_secret: "" # API key from SSO Digital Energy
|
|
||||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
|
||||||
rg_id: # Resource group id
|
|
||||||
cpu: 2
|
|
||||||
ram: 2048
|
|
||||||
boot_disk: 10
|
|
||||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
|
||||||
networks:
|
|
||||||
- type: VINS
|
|
||||||
id: #VINS id
|
|
||||||
tags: "Ansible cloud init example"
|
|
||||||
aff_lable: "Anti affinity lable"
|
|
||||||
tag:
|
|
||||||
- key: bd
|
|
||||||
value: main
|
|
||||||
aaff_rule:
|
|
||||||
- key: app
|
|
||||||
value: main
|
|
||||||
topology: compute
|
|
||||||
policy: REQUIRED
|
|
||||||
mode: ANY
|
|
||||||
state: present
|
|
||||||
delegate_to: localhost
|
|
||||||
register: simple_vm
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
#
|
|
||||||
# DECORT kvmvm module example
|
|
||||||
#
|
|
||||||
- hosts: ansible_master
|
|
||||||
tasks:
|
|
||||||
- name: create a VM named cloud-init_example
|
|
||||||
decort_kvmvm:
|
|
||||||
annotation: "VM managed by decort_kvmvm module"
|
|
||||||
authenticator: oauth2
|
|
||||||
app_id: "" # Application id from SSO Digital Energy
|
|
||||||
app_secret: "" # API key from SSO Digital Energy
|
|
||||||
controller_url: "" #"https://mr4.digitalenergy.online"
|
|
||||||
name: cloud-init_example
|
|
||||||
cpu: 2
|
|
||||||
ram: 2048
|
|
||||||
boot_disk: 10
|
|
||||||
image_name: "DECS Ubuntu 18.04 v1.2.3" #Name of OS image
|
|
||||||
networks:
|
|
||||||
- type: VINS
|
|
||||||
id: #VINS id
|
|
||||||
tags: "Ansible cloud init example"
|
|
||||||
state: present
|
|
||||||
rg_id: #Resource group id
|
|
||||||
ci_user_data:
|
|
||||||
packages:
|
|
||||||
- apache2
|
|
||||||
write_files:
|
|
||||||
- content: |
|
|
||||||
<div>
|
|
||||||
Hello World!
|
|
||||||
</div>
|
|
||||||
owner: user:user
|
|
||||||
path: /var/www/html/index.html
|
|
||||||
hostname: test-apache
|
|
||||||
ssh_keys:
|
|
||||||
- rsa_public: ssh-rsa AAAAOasDmLxnD= user@pc
|
|
||||||
delegate_to: localhost
|
|
||||||
register: simple_vm
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,351 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_security_group
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortSecurityGroup(DecortController):
|
||||||
|
id: int = 0
|
||||||
|
facts: dict = dict()
|
||||||
|
|
||||||
|
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(
|
||||||
|
account_id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
description=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
name=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
rules=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
mode=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
e.value
|
||||||
|
for e in self.SecurityGroupRuleMode
|
||||||
|
],
|
||||||
|
default=self.SecurityGroupRuleMode.update.value,
|
||||||
|
),
|
||||||
|
objects=dict(
|
||||||
|
type='list',
|
||||||
|
elements='dict',
|
||||||
|
required=True,
|
||||||
|
options=dict(
|
||||||
|
direction=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
e.name for e in
|
||||||
|
self.SecurityGroupRuleDirection
|
||||||
|
],
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
ethertype=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
e.name for e in
|
||||||
|
self.SecurityGroupRuleEtherType
|
||||||
|
],
|
||||||
|
),
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
port_range=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
min=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
max=dict(
|
||||||
|
type='int',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
protocol=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[
|
||||||
|
e.name for e in
|
||||||
|
self.SecurityGroupRuleProtocol
|
||||||
|
],
|
||||||
|
),
|
||||||
|
remote_ip_prefix=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
state=dict(
|
||||||
|
type='str',
|
||||||
|
choices=[e.value for e in self.SecurityGroupState],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.aparams['id'] is not None:
|
||||||
|
self.id = self.aparams['id']
|
||||||
|
elif self.aparams['name'] is not None:
|
||||||
|
security_group = self.security_group_find(
|
||||||
|
account_id=self.aparams['account_id'],
|
||||||
|
name=self.aparams['name'],
|
||||||
|
)
|
||||||
|
if security_group:
|
||||||
|
self.id = security_group['id']
|
||||||
|
|
||||||
|
if self.id:
|
||||||
|
self.get_info()
|
||||||
|
self.check_amodule_args_for_change()
|
||||||
|
self.change()
|
||||||
|
else:
|
||||||
|
self.check_amodule_args_for_create()
|
||||||
|
self.create()
|
||||||
|
if not self.amodule.check_mode:
|
||||||
|
self.change_rules()
|
||||||
|
|
||||||
|
if self.result['changed']:
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
self.facts: dict = self.security_group_get(id=self.id)
|
||||||
|
self.facts['created_timestamp'] = self.facts.pop('created_at')
|
||||||
|
self.facts['updated_timestamp'] = self.facts.pop('updated_at')
|
||||||
|
for rule in self.facts['rules']:
|
||||||
|
rule['port_range'] = {
|
||||||
|
'min': rule.pop('port_range_min'),
|
||||||
|
'max': rule.pop('port_range_max'),
|
||||||
|
}
|
||||||
|
|
||||||
|
def check_amodule_args_for_create(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_account_id = self.aparams['account_id']
|
||||||
|
if aparam_account_id is None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "account_id" failed: '
|
||||||
|
'account_id must be specified when creating '
|
||||||
|
'a new security group'
|
||||||
|
)
|
||||||
|
|
||||||
|
aparam_name = self.aparams['name']
|
||||||
|
if aparam_name is None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "name" failed: '
|
||||||
|
'name must be specified when creating '
|
||||||
|
'a new security group'
|
||||||
|
)
|
||||||
|
|
||||||
|
aparam_state = self.aparams['state']
|
||||||
|
if (
|
||||||
|
aparam_state is not None
|
||||||
|
and aparam_state == self.SecurityGroupState.absent.value
|
||||||
|
):
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "state" failed: '
|
||||||
|
'state can not be "absent" when creating '
|
||||||
|
'a new security group'
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.check_aparam_rules(for_create=True) is False:
|
||||||
|
check_errors = True
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
def check_amodule_args_for_change(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
if self.check_aparam_rules() is False:
|
||||||
|
check_errors = True
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
def check_aparam_rules(self, for_create: bool = False):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
aparam_rules = self.aparams['rules']
|
||||||
|
if aparam_rules is None:
|
||||||
|
return True
|
||||||
|
|
||||||
|
mode = aparam_rules['mode']
|
||||||
|
rules = aparam_rules['objects']
|
||||||
|
|
||||||
|
if for_create and mode == self.SecurityGroupRuleMode.delete.value:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "rules.mode" failed: '
|
||||||
|
'mode can not be "delete" when creating '
|
||||||
|
'new security group'
|
||||||
|
)
|
||||||
|
|
||||||
|
sg_rules_ids = []
|
||||||
|
if self.facts.get('rules'):
|
||||||
|
sg_rules_ids = [rule['id'] for rule in self.facts['rules']]
|
||||||
|
for rule in rules:
|
||||||
|
rule_id = rule.get('id')
|
||||||
|
if rule_id is not None:
|
||||||
|
if for_create:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "rules.objects.id" failed: '
|
||||||
|
'can not set rule id when creating new '
|
||||||
|
'security group'
|
||||||
|
)
|
||||||
|
elif rule_id not in sg_rules_ids:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "rules.objects.id" failed: '
|
||||||
|
f'rule ID {rule_id} not found for '
|
||||||
|
f'security group ID {self.id}'
|
||||||
|
)
|
||||||
|
if mode == self.SecurityGroupRuleMode.delete.value:
|
||||||
|
for param, value in rule.items():
|
||||||
|
if param != 'id' and value is not None:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "rules.objects" '
|
||||||
|
'failed: only rule id can be specified if'
|
||||||
|
'rules.mode is "delete"'
|
||||||
|
)
|
||||||
|
break
|
||||||
|
elif mode == self.SecurityGroupRuleMode.delete.value:
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
msg='Check for parameter "rules.objects" '
|
||||||
|
'failed: rule id must be specified if mode is delete'
|
||||||
|
)
|
||||||
|
|
||||||
|
return not check_errors
|
||||||
|
|
||||||
|
def create(self):
|
||||||
|
security_groups_by_account_id = self.user_security_groups(
|
||||||
|
account_id=self.aparams['account_id']
|
||||||
|
)
|
||||||
|
sg_names = [sg['name'] for sg in security_groups_by_account_id]
|
||||||
|
if self.aparams['name'] not in sg_names:
|
||||||
|
self.id = self.security_group_create(
|
||||||
|
account_id=self.aparams['account_id'],
|
||||||
|
name=self.aparams['name'],
|
||||||
|
description=self.aparams['description'],
|
||||||
|
)
|
||||||
|
|
||||||
|
def change(self):
|
||||||
|
self.change_state()
|
||||||
|
self.change_params()
|
||||||
|
self.change_rules()
|
||||||
|
|
||||||
|
def change_state(self):
|
||||||
|
if self.aparams['state'] == self.SecurityGroupState.absent.value:
|
||||||
|
self.delete()
|
||||||
|
|
||||||
|
def change_params(self):
|
||||||
|
aparam_name = self.aparams['name']
|
||||||
|
aparam_description = self.aparams['description']
|
||||||
|
new_name, new_description = None, None
|
||||||
|
if (
|
||||||
|
aparam_name is not None
|
||||||
|
and aparam_name != self.facts['name']
|
||||||
|
):
|
||||||
|
new_name = aparam_name
|
||||||
|
if (
|
||||||
|
aparam_description is not None
|
||||||
|
and aparam_description != self.facts['description']
|
||||||
|
):
|
||||||
|
new_description = aparam_description
|
||||||
|
if new_name or new_description:
|
||||||
|
self.security_group_update(
|
||||||
|
security_group_id=self.id,
|
||||||
|
name=new_name,
|
||||||
|
description=new_description,
|
||||||
|
)
|
||||||
|
|
||||||
|
def change_rules(self):
|
||||||
|
aparam_rules = self.aparams['rules']
|
||||||
|
if aparam_rules is not None:
|
||||||
|
rules = aparam_rules['objects']
|
||||||
|
match aparam_rules['mode']:
|
||||||
|
case self.SecurityGroupRuleMode.delete.value:
|
||||||
|
for rule in rules:
|
||||||
|
self.security_group_detele_rule(
|
||||||
|
security_group_id=self.id,
|
||||||
|
rule_id=rule['id'],
|
||||||
|
)
|
||||||
|
case self.SecurityGroupRuleMode.match.value:
|
||||||
|
for rule in rules:
|
||||||
|
if rule.get('id') is None:
|
||||||
|
self.create_rule(rule=rule)
|
||||||
|
|
||||||
|
sg_rules_ids = set(
|
||||||
|
[rule['id'] for rule in self.facts['rules']]
|
||||||
|
)
|
||||||
|
aparam_rules_ids = set(
|
||||||
|
[rule['id'] for rule in rules if rule.get('id')]
|
||||||
|
)
|
||||||
|
rules_ids_to_delete = sg_rules_ids - aparam_rules_ids
|
||||||
|
for rule_id in rules_ids_to_delete:
|
||||||
|
self.security_group_detele_rule(
|
||||||
|
security_group_id=self.id,
|
||||||
|
rule_id=rule_id,
|
||||||
|
)
|
||||||
|
case self.SecurityGroupRuleMode.update.value:
|
||||||
|
for rule in rules:
|
||||||
|
if rule.get('id') is None:
|
||||||
|
self.create_rule(rule=rule)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
self.security_group_detele(security_group_id=self.id)
|
||||||
|
self.facts = {}
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def create_rule(self, rule: dict):
|
||||||
|
port_range_min, port_range_max = None, None
|
||||||
|
if rule.get('port_range'):
|
||||||
|
port_range_min = rule['port_range'].get('min')
|
||||||
|
port_range_max = rule['port_range'].get('max')
|
||||||
|
self.security_group_create_rule(
|
||||||
|
security_group_id=self.id,
|
||||||
|
direction=self.SecurityGroupRuleDirection[rule['direction']],
|
||||||
|
ethertype=(
|
||||||
|
self.SecurityGroupRuleEtherType[rule['ethertype']]
|
||||||
|
if rule.get('ethertype') else None
|
||||||
|
),
|
||||||
|
protocol=(
|
||||||
|
self.SecurityGroupRuleProtocol[rule['protocol']]
|
||||||
|
if rule.get('protocol') else None
|
||||||
|
),
|
||||||
|
port_range_min=port_range_min,
|
||||||
|
port_range_max=port_range_max,
|
||||||
|
remote_ip_prefix=rule.get('remote_ip_prefix'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortSecurityGroup().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_storage_policy
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortStoragePolicy(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
self.id: int = self.aparams['id']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
self.facts = self.storage_policy_get(id=self.id)
|
||||||
|
self.facts['sep_pools'] = self.facts.pop('access_seps_pools')
|
||||||
|
self.facts['iops_limit'] = self.facts.pop('limit_iops')
|
||||||
|
self.facts['usage']['account_ids'] = self.facts['usage'].pop(
|
||||||
|
'accounts'
|
||||||
|
)
|
||||||
|
self.facts['usage']['rg_ids'] = self.facts['usage'].pop('resgroups')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortStoragePolicy().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_trunk
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortTrunk(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
self.id: int = self.aparams['id']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
self.facts = self.trunk_get(id=self.id)
|
||||||
|
self.facts['account_ids'] = self.facts.pop('accountIds')
|
||||||
|
self.facts['created_timestamp'] = self.facts.pop('created_at')
|
||||||
|
self.facts['deleted_timestamp'] = self.facts.pop('deleted_at')
|
||||||
|
self.facts['updated_timestamp'] = self.facts.pop('updated_at')
|
||||||
|
self.facts['native_vlan_id'] = self.facts.pop('nativeVlanId')
|
||||||
|
self.facts['ovs_bridge'] = self.facts.pop('ovsBridge')
|
||||||
|
self.facts['vlan_ids'] = self.facts.pop('trunkTags')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortTrunk().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -0,0 +1,188 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_vm_snapshot
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
import time
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortVMSnapshot(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
self.check_amodule_args()
|
||||||
|
|
||||||
|
self.vm_id: int
|
||||||
|
self.vm_facts: dict
|
||||||
|
self.aparams_label = self.aparams['label']
|
||||||
|
self.aparams_vm_id = self.aparams['vm_id']
|
||||||
|
|
||||||
|
self.vm_id, self.vm_facts, _ = self._compute_get_by_id(
|
||||||
|
comp_id=self.aparams_vm_id,
|
||||||
|
)
|
||||||
|
if not self.vm_id:
|
||||||
|
self.message(f'VM {self.aparams_vm_id} not found')
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
self.vm_name = self.vm_facts['name']
|
||||||
|
self.vm_snapshots = self.vm_facts['snapSets']
|
||||||
|
self.vm_snapshot_labels = [
|
||||||
|
snapshot['label'] for snapshot in self.vm_snapshots
|
||||||
|
]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.new_snapshot_label is None
|
||||||
|
and self.aparams_label is not None
|
||||||
|
and self.aparams_label not in self.vm_snapshot_labels
|
||||||
|
):
|
||||||
|
self.message(
|
||||||
|
f'Snapshot {self.aparams_label} '
|
||||||
|
f'not found for VM {self.aparams_vm_id}'
|
||||||
|
)
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
@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',
|
||||||
|
'merge_aborted',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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.check_amodule_args_for_change()
|
||||||
|
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()
|
||||||
|
case 'merge_aborted':
|
||||||
|
self.abort_merge()
|
||||||
|
|
||||||
|
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 abort_merge(self):
|
||||||
|
self.snapshot_abort_merge(
|
||||||
|
vm_id=self.aparams_vm_id,
|
||||||
|
label=self.aparams_label,
|
||||||
|
)
|
||||||
|
self.get_info()
|
||||||
|
|
||||||
|
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 check_amodule_args_for_change(self):
|
||||||
|
check_errors = False
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.aparams['state'] == 'merge_aborted'
|
||||||
|
and self.vm_facts['techStatus'] != 'MERGE'
|
||||||
|
):
|
||||||
|
check_errors = True
|
||||||
|
self.message(
|
||||||
|
f'Check for parameter "state" failed: '
|
||||||
|
'Merge can be aborted only for VM in "MERGE" tech status.'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_errors:
|
||||||
|
self.exit(fail=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortVMSnapshot().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: decort_zone
|
||||||
|
|
||||||
|
description: See L(Module Documentation,https://repository.basistech.ru/BASIS/decort-ansible/wiki/Home). # noqa: E501
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.decort_utils import DecortController
|
||||||
|
|
||||||
|
|
||||||
|
class DecortZone(DecortController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(AnsibleModule(**self.amodule_init_args))
|
||||||
|
self.id: int = self.aparams['id']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amodule_init_args(self) -> dict:
|
||||||
|
return self.pack_amodule_init_args(
|
||||||
|
argument_spec=dict(
|
||||||
|
id=dict(
|
||||||
|
type='int',
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.get_info()
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def get_info(self):
|
||||||
|
self.facts = self.zone_get(id=self.id)
|
||||||
|
self.facts['grid_id'] = self.facts.pop('gid')
|
||||||
|
self.facts['created_timestamp'] = self.facts.pop('createdTime')
|
||||||
|
self.facts['updated_timestamp'] = self.facts.pop('updatedTime')
|
||||||
|
self.facts['node_ids'] = self.facts.pop('nodeIds')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DecortZone().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
|||||||
|
-r requirements.txt
|
||||||
|
pre-commit==4.1.0
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
ansible==11.6.0
|
||||||
|
requests==2.32.3
|
||||||
@ -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
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