From 583770f5975a37603eb32059c69032f94c526329 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 25 Mar 2020 17:33:56 +0100 Subject: [PATCH] New Module: os_keystone_federation_protocol_info Add support for getting information about Keystone federation Protocols Change-Id: Id389b094465967a2a8a0eff428f1f6679865c6f6 --- .../tasks/main.yml | 120 +++++++++--------- meta/action_groups.yml | 1 + .../os_keystone_federation_protocol_info.py | 116 +++++++++++++++++ 3 files changed, 177 insertions(+), 60 deletions(-) create mode 100644 plugins/modules/os_keystone_federation_protocol_info.py diff --git a/ci/roles/keystone_federation_protocol/tasks/main.yml b/ci/roles/keystone_federation_protocol/tasks/main.yml index ce5e81b1..4ab99915 100644 --- a/ci/roles/keystone_federation_protocol/tasks/main.yml +++ b/ci/roles/keystone_federation_protocol/tasks/main.yml @@ -18,9 +18,9 @@ openstack.cloud.os_keystone_federation_protocol: cloud: "{{ cloud }}" idp_id: "{{ idp_name }}" - #openstack.cloud.os_keystone_federation_protocol_info: - # cloud: "{{ cloud }}" - # idp_id: "{{ idp_name }}" + openstack.cloud.os_keystone_federation_protocol_info: + cloud: "{{ cloud }}" + idp_id: "{{ idp_name }}" block: # ======================================================================== # Initial setup @@ -91,14 +91,14 @@ - create_protocol is successful - create_protocol is changed - #- name: 'Fetch Protocol info (should be absent)' - # openstack.cloud.os_keystone_federation_protocol_info: - # name: '{{ protocol_name }}' - # register: protocol_info - # ignore_errors: yes - #- assert: - # that: - # - protocol_info is failed + - name: 'Fetch Protocol info (should be absent)' + openstack.cloud.os_keystone_federation_protocol_info: + name: '{{ protocol_name }}' + register: protocol_info + ignore_errors: yes + - assert: + that: + - protocol_info is failed - name: 'Create protocol' openstack.cloud.os_keystone_federation_protocol: @@ -255,56 +255,56 @@ # ======================================================================== # Basic tests of os_keystone_federation_protocol_info - #- name: 'Fetch Protocol info (a specific protocol)' - # openstack.cloud.os_keystone_federation_protocol_info: - # name: '{{ protocol_name }}' - # register: protocol_info - #- assert: - # that: - # - protocol_info is successful - # - '"protocols" in protocol_info' - # - protocol_info.protocols | length == 1 - # - '"id" in protocol' - # - '"name" in protocol' - # - '"idp_id" in protocol' - # - '"mapping_id" in protocol' - # - protocol.id == protocol_name - # - protocol.name == protocol_name - # - protocol.idp_id == idp_name - # - protocol.mapping_id == mapping_name_2 - # vars: - # protocol: '{{ protocol_info.protocols[0] }}' + - name: 'Fetch Protocol info (a specific protocol)' + openstack.cloud.os_keystone_federation_protocol_info: + name: '{{ protocol_name }}' + register: protocol_info + - assert: + that: + - protocol_info is successful + - '"protocols" in protocol_info' + - protocol_info.protocols | length == 1 + - '"id" in protocol' + - '"name" in protocol' + - '"idp_id" in protocol' + - '"mapping_id" in protocol' + - protocol.id == protocol_name + - protocol.name == protocol_name + - protocol.idp_id == idp_name + - protocol.mapping_id == mapping_name_2 + vars: + protocol: '{{ protocol_info.protocols[0] }}' - #- name: 'Fetch Protocol info (all protocols on our test IDP)' - # openstack.cloud.os_keystone_federation_protocol_info: {} - # # idp_id defined in defaults at the start - # register: protocol_info - #- assert: - # that: - # - protocol_info is successful - # - '"protocols" in protocol_info' - # # We created the IDP, and we're going to delete it: - # # we should be able to trust what's attached to it - # - protocol_info.protocols | length == 2 - # - '"id" in protocol_1' - # - '"name" in protocol_1' - # - '"idp_id" in protocol_1' - # - '"mapping_id" in protocol_1' - # - '"id" in protocol_2' - # - '"name" in protocol_2' - # - '"idp_id" in protocol_2' - # - '"mapping_id" in protocol_2' - # - protocol_name in (protocol_info.protocols | map(attribute='id')) - # - protocol_name in (protocol_info.protocols | map(attribute='id')) - # - protocol_name_2 in (protocol_info.protocols | map(attribute='name')) - # - protocol_name_2 in (protocol_info.protocols | map(attribute='name')) - # - mapping_name_1 in (protocol_info.protocols | map(attribute='mapping_id')) - # - mapping_name_2 in (protocol_info.protocols | map(attribute='mapping_id')) - # - protocol_1.idp_id == idp_name - # - protocol_2.idp_id == idp_name - # vars: - # protocol_1: '{{ protocol_info.protocols[0] }}' - # protocol_2: '{{ protocol_info.protocols[1] }}' + - name: 'Fetch Protocol info (all protocols on our test IDP)' + openstack.cloud.os_keystone_federation_protocol_info: {} + # idp_id defined in defaults at the start + register: protocol_info + - assert: + that: + - protocol_info is successful + - '"protocols" in protocol_info' + # We created the IDP, and we're going to delete it: + # we should be able to trust what's attached to it + - protocol_info.protocols | length == 2 + - '"id" in protocol_1' + - '"name" in protocol_1' + - '"idp_id" in protocol_1' + - '"mapping_id" in protocol_1' + - '"id" in protocol_2' + - '"name" in protocol_2' + - '"idp_id" in protocol_2' + - '"mapping_id" in protocol_2' + - protocol_name in (protocol_info.protocols | map(attribute='id')) + - protocol_name in (protocol_info.protocols | map(attribute='id')) + - protocol_name_2 in (protocol_info.protocols | map(attribute='name')) + - protocol_name_2 in (protocol_info.protocols | map(attribute='name')) + - mapping_name_1 in (protocol_info.protocols | map(attribute='mapping_id')) + - mapping_name_2 in (protocol_info.protocols | map(attribute='mapping_id')) + - protocol_1.idp_id == idp_name + - protocol_2.idp_id == idp_name + vars: + protocol_1: '{{ protocol_info.protocols[0] }}' + protocol_2: '{{ protocol_info.protocols[1] }}' # ======================================================================== # Deletion diff --git a/meta/action_groups.yml b/meta/action_groups.yml index 7bb63aaf..ce7560ad 100644 --- a/meta/action_groups.yml +++ b/meta/action_groups.yml @@ -21,6 +21,7 @@ os: - os_keystone_mapping - os_keystone_mapping_info - os_keystone_federation_protocol +- os_keystone_federation_protocol_info - os_keystone_role - os_keystone_service - os_listener diff --git a/plugins/modules/os_keystone_federation_protocol_info.py b/plugins/modules/os_keystone_federation_protocol_info.py new file mode 100644 index 00000000..5355dba2 --- /dev/null +++ b/plugins/modules/os_keystone_federation_protocol_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/python +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: os_keystone_federation_protocol_info +short_description: get information about federation Protocols +author: + - "Mark Chappell (@tremble) " +description: + - Get information about federation Protocols. +options: + name: + description: + - The name of the Protocol. + type: str + aliases: ['id'] + idp_id: + description: + - The name of the Identity Provider this Protocol is associated with. + aliases: ['idp_name'] + required: true + type: str +requirements: + - "python >= 3.6" + - "openstacksdk >= 0.44" +extends_documentation_fragment: + - openstack.cloud.openstack +''' + +EXAMPLES = ''' +- name: Describe a protocol + os_keystone_federation_protocol_info: + cloud: example_cloud + name: example_protocol + idp_id: example_idp + mapping_name: example_mapping + +- name: Describe all protocols attached to an IDP + os_keystone_federation_protocol_info: + cloud: example_cloud + idp_id: example_idp +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import openstack_full_argument_spec +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import openstack_module_kwargs +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import openstack_cloud_from_module + + +def normalize_protocol(protocol): + """ + Normalizes the protocol definitions so that the outputs are consistent with the + parameters + + - "name" (parameter) == "id" (SDK) + """ + if protocol is None: + return None + + _protocol = protocol.to_dict() + _protocol['name'] = protocol['id'] + # As of 0.44 SDK doesn't copy the URI parameters over, so let's add them + _protocol['idp_id'] = protocol['idp_id'] + return _protocol + + +def main(): + """ Module entry point """ + + argument_spec = openstack_full_argument_spec( + name=dict(aliases=['id']), + idp_id=dict(required=True, aliases=['idp_name']), + ) + module_kwargs = openstack_module_kwargs( + ) + module = AnsibleModule( + argument_spec, + supports_check_mode=True, + **module_kwargs + ) + + name = module.params.get('name') + idp = module.params.get('idp_id') + + sdk, cloud = openstack_cloud_from_module(module, min_version="0.44") + + if name: + try: + protocol = cloud.identity.get_federation_protocol(idp, name) + protocol = normalize_protocol(protocol) + except sdk.exceptions.ResourceNotFound: + module.fail_json(msg='Failed to find protocol') + except sdk.exceptions.OpenStackCloudException as ex: + module.fail_json(msg='Failed to get protocol: {0}'.format(str(ex))) + module.exit_json(changed=False, protocols=[protocol]) + + else: + try: + protocols = list(map(normalize_protocol, cloud.identity.federation_protocols(idp))) + except sdk.exceptions.OpenStackCloudException as ex: + module.fail_json(msg='Failed to list protocols: {0}'.format(str(ex))) + module.exit_json(changed=False, protocols=protocols) + + +if __name__ == '__main__': + main()