security_group_rule: use OpenStackModule class

Refactoring of security_group_rule to depend on the OpenStackModule
class.

See: I487e79fe18c0b9a75df7dacd224ab40ed7f4e1ab

Change-Id: Ide09bdd6a57324a0e1d2ec29c4c49db8dc1c3843
This commit is contained in:
Gonéri Le Bouder 2020-07-02 12:06:35 -04:00 committed by Gonéri Le Bouder
parent 94e518e42c
commit 9600baec6e

View File

@ -179,10 +179,8 @@ security_group_id:
returned: state == present returned: state == present
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec, OpenStackModule)
openstack_module_kwargs,
openstack_cloud_from_module)
def _ports_match(protocol, module_min, module_max, rule_min, rule_max): def _ports_match(protocol, module_min, module_max, rule_min, rule_max):
@ -244,51 +242,10 @@ def _ports_match(protocol, module_min, module_max, rule_min, rule_max):
return module_min == rule_min and module_max == rule_max return module_min == rule_min and module_max == rule_max
def _find_matching_rule(module, secgroup, remotegroup): class SecurityGroupRuleModule(OpenStackModule):
""" deprecated_names = ('os_security_group_rule', 'openstack.cloud.os_security_group_rule')
Find a rule in the group that matches the module parameters.
:returns: The matching rule dict, or None if no matches.
"""
protocol = module.params['protocol']
remote_ip_prefix = module.params['remote_ip_prefix']
ethertype = module.params['ethertype']
direction = module.params['direction']
remote_group_id = remotegroup['id']
for rule in secgroup['security_group_rules']: argument_spec = dict(
if (
protocol == rule['protocol']
and remote_ip_prefix == rule['remote_ip_prefix']
and ethertype == rule['ethertype']
and direction == rule['direction']
and remote_group_id == rule['remote_group_id']
and _ports_match(
protocol,
module.params['port_range_min'],
module.params['port_range_max'],
rule['port_range_min'],
rule['port_range_max'])
):
return rule
return None
def _system_state_change(module, secgroup, remotegroup):
state = module.params['state']
if secgroup:
rule_exists = _find_matching_rule(module, secgroup, remotegroup)
else:
return False
if state == 'present' and not rule_exists:
return True
if state == 'absent' and rule_exists:
return True
return False
def main():
argument_spec = openstack_full_argument_spec(
security_group=dict(required=True), security_group=dict(required=True),
# NOTE(Shrews): None is an acceptable protocol value for # NOTE(Shrews): None is an acceptable protocol value for
# Neutron, but Nova will balk at this. # Neutron, but Nova will balk at this.
@ -307,85 +264,122 @@ def main():
project=dict(default=None), project=dict(default=None),
) )
module_kwargs = openstack_module_kwargs( module_kwargs = dict(
mutually_exclusive=[ mutually_exclusive=[
['remote_ip_prefix', 'remote_group'], ['remote_ip_prefix', 'remote_group'],
] ]
) )
module = AnsibleModule(argument_spec, def _find_matching_rule(self, secgroup, remotegroup):
supports_check_mode=True, """
**module_kwargs) Find a rule in the group that matches the module parameters.
:returns: The matching rule dict, or None if no matches.
"""
protocol = self.params['protocol']
remote_ip_prefix = self.params['remote_ip_prefix']
ethertype = self.params['ethertype']
direction = self.params['direction']
remote_group_id = remotegroup['id']
state = module.params['state'] for rule in secgroup['security_group_rules']:
security_group = module.params['security_group'] if (
remote_group = module.params['remote_group'] protocol == rule['protocol']
project = module.params['project'] and remote_ip_prefix == rule['remote_ip_prefix']
changed = False and ethertype == rule['ethertype']
and direction == rule['direction']
and remote_group_id == rule['remote_group_id']
and _ports_match(
protocol,
self.params['port_range_min'],
self.params['port_range_max'],
rule['port_range_min'],
rule['port_range_max'])
):
return rule
return None
def _system_state_change(self, secgroup, remotegroup):
state = self.params['state']
if secgroup:
rule_exists = self._find_matching_rule(secgroup, remotegroup)
else:
return False
if state == 'present' and not rule_exists:
return True
if state == 'absent' and rule_exists:
return True
return False
def run(self):
state = self.params['state']
security_group = self.params['security_group']
remote_group = self.params['remote_group']
project = self.params['project']
changed = False
sdk, cloud = openstack_cloud_from_module(module)
try:
if project is not None: if project is not None:
proj = cloud.get_project(project) proj = self.conn.get_project(project)
if proj is None: if proj is None:
module.fail_json(msg='Project %s could not be found' % project) self.fail_json(msg='Project %s could not be found' % project)
project_id = proj['id'] project_id = proj['id']
else: else:
project_id = cloud.current_project_id project_id = self.conn.current_project_id
if project_id and not remote_group: if project_id and not remote_group:
filters = {'tenant_id': project_id} filters = {'tenant_id': project_id}
else: else:
filters = None filters = None
secgroup = cloud.get_security_group(security_group, filters=filters) secgroup = self.conn.get_security_group(security_group, filters=filters)
if remote_group: if remote_group:
remotegroup = cloud.get_security_group(remote_group, remotegroup = self.conn.get_security_group(remote_group, filters=filters)
filters=filters)
else: else:
remotegroup = {'id': None} remotegroup = {'id': None}
if module.check_mode: if self.ansible.check_mode:
module.exit_json(changed=_system_state_change(module, secgroup, remotegroup)) self.exit_json(changed=self._system_state_change(secgroup, remotegroup))
if state == 'present': if state == 'present':
if module.params['protocol'] == 'any': if self.params['protocol'] == 'any':
module.params['protocol'] = None self.params['protocol'] = None
if not secgroup: if not secgroup:
module.fail_json(msg='Could not find security group %s' % self.fail_json(msg='Could not find security group %s' % security_group)
security_group)
rule = _find_matching_rule(module, secgroup, remotegroup) rule = self._find_matching_rule(secgroup, remotegroup)
if not rule: if not rule:
kwargs = {} kwargs = {}
if project_id: if project_id:
kwargs['project_id'] = project_id kwargs['project_id'] = project_id
rule = cloud.create_security_group_rule( rule = self.conn.create_security_group_rule(
secgroup['id'], secgroup['id'],
port_range_min=module.params['port_range_min'], port_range_min=self.params['port_range_min'],
port_range_max=module.params['port_range_max'], port_range_max=self.params['port_range_max'],
protocol=module.params['protocol'], protocol=self.params['protocol'],
remote_ip_prefix=module.params['remote_ip_prefix'], remote_ip_prefix=self.params['remote_ip_prefix'],
remote_group_id=remotegroup['id'], remote_group_id=remotegroup['id'],
direction=module.params['direction'], direction=self.params['direction'],
ethertype=module.params['ethertype'], ethertype=self.params['ethertype'],
**kwargs **kwargs
) )
changed = True changed = True
module.exit_json(changed=changed, rule=rule, id=rule['id']) self.exit_json(changed=changed, rule=rule, id=rule['id'])
if state == 'absent' and secgroup: if state == 'absent' and secgroup:
rule = _find_matching_rule(module, secgroup, remotegroup) rule = self._find_matching_rule(secgroup, remotegroup)
if rule: if rule:
cloud.delete_security_group_rule(rule['id']) self.conn.delete_security_group_rule(rule['id'])
changed = True changed = True
module.exit_json(changed=changed) self.exit_json(changed=changed)
except sdk.exceptions.OpenStackCloudException as e:
module.fail_json(msg=str(e)) def main():
module = SecurityGroupRuleModule()
module()
if __name__ == '__main__': if __name__ == '__main__':