Files
decort-ansible/library/decort_pfw.py

173 lines
5.3 KiB
Python
Raw Normal View History

#!/usr/bin/python
2024-11-29 13:48:11 +03:00
DOCUMENTATION = r'''
---
module: decort_pfw
2024-11-29 13:48:11 +03:00
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 *
2024-12-26 12:37:38 +03:00
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,
)
2026-06-01 18:27:15 +03:00
def decort_pfw_package_facts(
self,
comp_facts,
vins_model: sdk_types.CloudapiVinsGetResultModel,
pfw_facts,
check_mode=False,
):
2024-12-26 12:37:38 +03:00
"""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
2026-06-01 18:27:15 +03:00
gw_vnf = vins_model.vnfs.gw
2024-12-26 12:37:38 +03:00
ret_dict['compute_id'] = comp_facts['id']
2026-06-01 18:27:15 +03:00
ret_dict['vins_id'] = vins_model.id
if gw_vnf:
ret_dict['public_ip'] = gw_vnf.config.ext_net_ip
else:
raise RuntimeError('VINS GW VNF must exist.')
2024-12-26 12:37:38 +03:00
if len(pfw_facts) != 0:
ret_dict['state'] = 'PRESENT'
ret_dict['rules'] = pfw_facts
else:
ret_dict['state'] = 'ABSENT'
return ret_dict
2024-12-26 12:37:38 +03:00
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."""
2024-12-26 12:37:38 +03:00
return
2026-02-11 13:50:28 +03:00
@DecortController.handle_sdk_exceptions
def run(self):
amodule = self.amodule
pfw_facts = None # will hold PFW facts as returned by pfw_configure
#
# Validate module arguments:
# 1) specified Compute instance exists in correct state
# 2) specified ViNS exists
# 3) ViNS has GW function
# 4) Compute is connected to this ViNS
#
validated_comp_id, comp_facts, rg_id = self.compute_find(amodule.params['compute_id'])
if not validated_comp_id:
self.result['failed'] = True
self.result['msg'] = "Cannot find specified Compute ID {}.".format(amodule.params['compute_id'])
amodule.fail_json(**self.result)
2026-06-01 18:27:15 +03:00
vins_model = self._vins_get_by_id(vins_id=amodule.params['vins_id'])
2026-02-11 13:50:28 +03:00
2026-06-01 18:27:15 +03:00
gw_vnf = vins_model.vnfs.gw
if not gw_vnf or gw_vnf.status == sdk_types.VNFStatus.DESTROYED:
2026-02-11 13:50:28 +03:00
self.result['failed'] = True
2026-06-01 18:27:15 +03:00
self.result['msg'] = (
f'ViNS ID {vins_model.id} does not '
f'have a configured external connection.'
)
2026-02-11 13:50:28 +03:00
amodule.fail_json(**self.result)
#
# Initial validation of module arguments is complete
#
if amodule.params['state'] == 'absent':
# ignore amodule.params['rules'] and remove all rules associated with this Compute
2026-06-01 18:27:15 +03:00
pfw_facts = self.pfw_configure(
comp_facts,
vins_model,
None,
)
2026-02-11 13:50:28 +03:00
elif amodule.params['rules'] is not None:
# manage PFW rules accodring to the module arguments
2026-06-01 18:27:15 +03:00
pfw_facts = self.pfw_configure(
comp_facts,
vins_model,
amodule.params['rules'],
)
2026-02-11 13:50:28 +03:00
else:
2026-06-01 18:27:15 +03:00
pfw_facts = self._pfw_get(comp_facts['id'], vins_model.id)
2026-02-11 13:50:28 +03:00
#
# complete module run
#
if self.result['failed']:
amodule.fail_json(**self.result)
else:
# prepare PFW facts to be returned as part of self.result and then call exit_json(...)
2026-06-01 18:27:15 +03:00
self.result['facts'] = self.decort_pfw_package_facts(
comp_facts,
vins_model,
pfw_facts,
amodule.check_mode,
)
2026-02-11 13:50:28 +03:00
amodule.exit_json(**self.result)
def main():
2026-02-11 13:50:28 +03:00
decort_pfw().run()
if __name__ == '__main__':
main()