diff --git a/ci/roles/keystone_idp/tasks/main.yml b/ci/roles/keystone_idp/tasks/main.yml index 85ac3341..5ee99716 100644 --- a/ci/roles/keystone_idp/tasks/main.yml +++ b/ci/roles/keystone_idp/tasks/main.yml @@ -13,8 +13,8 @@ cloud: "{{ cloud }}" openstack.cloud.os_keystone_identity_provider: cloud: "{{ cloud }}" - #openstack.cloud.os_keystone_identity_provider_info: - # cloud: "{{ cloud }}" + openstack.cloud.os_keystone_identity_provider_info: + cloud: "{{ cloud }}" block: # ======================================================================== # Initial setup @@ -56,14 +56,14 @@ - create_idp is successful - create_idp is changed - #- name: 'Fetch identity_provider info (provider should be absent)' - # openstack.cloud.os_keystone_identity_provider_info: - # name: '{{ idp_name }}' - # register: identity_provider_info - # ignore_errors: yes - #- assert: - # that: - # - identity_provider_info is failed + - name: 'Fetch identity_provider info (provider should be absent)' + openstack.cloud.os_keystone_identity_provider_info: + name: '{{ idp_name }}' + register: identity_provider_info + ignore_errors: yes + - assert: + that: + - identity_provider_info is failed - name: 'Create IDP' openstack.cloud.os_keystone_identity_provider: @@ -93,53 +93,53 @@ vars: idp: '{{ create_identity_provider.identity_provider }}' - #- name: 'Fetch IDP info - with name' - # openstack.cloud.os_keystone_identity_provider_info: - # name: '{{ idp_name }}' - # register: identity_provider_info - #- assert: - # that: - # - identity_provider_info is successful - # - '"identity_providers" in identity_provider_info' - # - idps | length == 1 - # - '"id" in idp' - # - '"name" in idp' - # - '"domain_id" in idp' - # - '"description" in idp' - # - '"enabled" in idp' - # - '"is_enabled" in idp' - # - '"remote_ids" in idp' - # - idp.id == idp_name - # - idp.name == idp_name - # - idp.domain_id == domain_id - # - not idp.description - # - idp.enabled == True - # - idp.is_enabled == True - # - idp.remote_ids == [] - # vars: - # idps: '{{ identity_provider_info.identity_providers }}' - # idp: '{{ identity_provider_info.identity_providers[0] }}' + - name: 'Fetch IDP info - with name' + openstack.cloud.os_keystone_identity_provider_info: + name: '{{ idp_name }}' + register: identity_provider_info + - assert: + that: + - identity_provider_info is successful + - '"identity_providers" in identity_provider_info' + - idps | length == 1 + - '"id" in idp' + - '"name" in idp' + - '"domain_id" in idp' + - '"description" in idp' + - '"enabled" in idp' + - '"is_enabled" in idp' + - '"remote_ids" in idp' + - idp.id == idp_name + - idp.name == idp_name + - idp.domain_id == domain_id + - not idp.description + - idp.enabled == True + - idp.is_enabled == True + - idp.remote_ids == [] + vars: + idps: '{{ identity_provider_info.identity_providers }}' + idp: '{{ identity_provider_info.identity_providers[0] }}' - #- name: 'Fetch identity_provider info - without name' - # openstack.cloud.os_keystone_identity_provider_info: {} - # register: identity_provider_info - #- assert: - # that: - # - identity_provider_info is successful - # - '"identity_providers" in identity_provider_info' - # # In CI we generally have a clean slate, but this might - # # not be true for everyone... - # - idps | length >= 1 - # - '"id" in idp' - # - '"name" in idp' - # - '"domain_id" in idp' - # - '"description" in idp' - # - '"enabled" in idp' - # - '"is_enabled" in idp' - # - '"remote_ids" in idp' - # vars: - # idps: '{{ identity_provider_info.identity_providers }}' - # idp: '{{ identity_provider_info.identity_providers[0] }}' + - name: 'Fetch identity_provider info - without name' + openstack.cloud.os_keystone_identity_provider_info: {} + register: identity_provider_info + - assert: + that: + - identity_provider_info is successful + - '"identity_providers" in identity_provider_info' + # In CI we generally have a clean slate, but this might + # not be true for everyone... + - idps | length >= 1 + - '"id" in idp' + - '"name" in idp' + - '"domain_id" in idp' + - '"description" in idp' + - '"enabled" in idp' + - '"is_enabled" in idp' + - '"remote_ids" in idp' + vars: + idps: '{{ identity_provider_info.identity_providers }}' + idp: '{{ identity_provider_info.identity_providers[0] }}' - name: 'Create identity_provider (retry - no change) - CHECK_MODE' check_mode: yes @@ -651,74 +651,74 @@ vars: idp: '{{ create_identity_provider.identity_provider }}' - ## Attempt to ensure that if we search we only get the one we expect - #- name: 'Fetch Complex IDP info - with name' - # openstack.cloud.os_keystone_identity_provider_info: - # name: '{{ idp_name_2 }}' - # register: identity_provider_info - #- assert: - # that: - # - identity_provider_info is successful - # - '"identity_providers" in identity_provider_info' - # - identity_provider_info.identity_providers | length == 1 - # - '"id" in idp' - # - '"name" in idp' - # - '"domain_id" in idp' - # - '"description" in idp' - # - '"enabled" in idp' - # - '"is_enabled" in idp' - # - '"remote_ids" in idp' - # - idp.id == idp_name_2 - # - idp.name == idp_name_2 - # - idp.domain_id == domain_id - # - idp.description == idp_description - # - idp.enabled == False - # - idp.is_enabled == False - # - idp.remote_ids == remote_ids_3 - # vars: - # idp: '{{ identity_provider_info.identity_providers[0] }}' + # Attempt to ensure that if we search we only get the one we expect + - name: 'Fetch Complex IDP info - with name' + openstack.cloud.os_keystone_identity_provider_info: + name: '{{ idp_name_2 }}' + register: identity_provider_info + - assert: + that: + - identity_provider_info is successful + - '"identity_providers" in identity_provider_info' + - identity_provider_info.identity_providers | length == 1 + - '"id" in idp' + - '"name" in idp' + - '"domain_id" in idp' + - '"description" in idp' + - '"enabled" in idp' + - '"is_enabled" in idp' + - '"remote_ids" in idp' + - idp.id == idp_name_2 + - idp.name == idp_name_2 + - idp.domain_id == domain_id + - idp.description == idp_description + - idp.enabled == False + - idp.is_enabled == False + - idp.remote_ids == remote_ids_3 + vars: + idp: '{{ identity_provider_info.identity_providers[0] }}' - ## Ensure that if we do search we get both of the results we expect - #- name: 'Fetch multiple IDP info - without name' - # openstack.cloud.os_keystone_identity_provider_info: {} - # register: identity_provider_info - #- assert: - # that: - # - identity_provider_info is successful - # - '"identity_providers" in identity_provider_info' - # # In CI we generally have a clean slate, but this might - # # not be true for everyone... - # - identity_provider_info.identity_providers | length >= 2 - # - '"id" in idp_0' - # - '"name" in idp_0' - # - '"domain_id" in idp_0' - # - '"description" in idp_0' - # - '"enabled" in idp_0' - # - '"is_enabled" in idp_0' - # - '"remote_ids" in idp_0' - # - '"id" in idp_1' - # - '"name" in idp_1' - # - '"domain_id" in idp_1' - # - '"description" in idp_1' - # - '"enabled" in idp_1' - # - '"is_enabled" in idp_1' - # - '"remote_ids" in idp_1' - # # In theory these could be attached to different IDPs but let's keep - # # things simple - # - idp_name in (identity_provider_info.identity_providers | map(attribute='id')) - # - idp_name in (identity_provider_info.identity_providers | map(attribute='name')) - # - idp_name_2 in (identity_provider_info.identity_providers | map(attribute='id')) - # - idp_name_2 in (identity_provider_info.identity_providers | map(attribute='name')) - # - domain_id in (identity_provider_info.identity_providers | map(attribute='domain_id')) - # - idp_description in (identity_provider_info.identity_providers | map(attribute='description')) - # - idp_description_2 in (identity_provider_info.identity_providers | map(attribute='description')) - # - True in (identity_provider_info.identity_providers | map(attribute='enabled')) - # - False in (identity_provider_info.identity_providers | map(attribute='enabled')) - # - True in (identity_provider_info.identity_providers | map(attribute='is_enabled')) - # - False in (identity_provider_info.identity_providers | map(attribute='is_enabled')) - # vars: - # idp_0: '{{ identity_provider_info.identity_providers[0] }}' - # idp_1: '{{ identity_provider_info.identity_providers[1] }}' + # Ensure that if we do search we get both of the results we expect + - name: 'Fetch multiple IDP info - without name' + openstack.cloud.os_keystone_identity_provider_info: {} + register: identity_provider_info + - assert: + that: + - identity_provider_info is successful + - '"identity_providers" in identity_provider_info' + # In CI we generally have a clean slate, but this might + # not be true for everyone... + - identity_provider_info.identity_providers | length >= 2 + - '"id" in idp_0' + - '"name" in idp_0' + - '"domain_id" in idp_0' + - '"description" in idp_0' + - '"enabled" in idp_0' + - '"is_enabled" in idp_0' + - '"remote_ids" in idp_0' + - '"id" in idp_1' + - '"name" in idp_1' + - '"domain_id" in idp_1' + - '"description" in idp_1' + - '"enabled" in idp_1' + - '"is_enabled" in idp_1' + - '"remote_ids" in idp_1' + # In theory these could be attached to different IDPs but let's keep + # things simple + - idp_name in (identity_provider_info.identity_providers | map(attribute='id')) + - idp_name in (identity_provider_info.identity_providers | map(attribute='name')) + - idp_name_2 in (identity_provider_info.identity_providers | map(attribute='id')) + - idp_name_2 in (identity_provider_info.identity_providers | map(attribute='name')) + - domain_id in (identity_provider_info.identity_providers | map(attribute='domain_id')) + - idp_description in (identity_provider_info.identity_providers | map(attribute='description')) + - idp_description_2 in (identity_provider_info.identity_providers | map(attribute='description')) + - True in (identity_provider_info.identity_providers | map(attribute='enabled')) + - False in (identity_provider_info.identity_providers | map(attribute='enabled')) + - True in (identity_provider_info.identity_providers | map(attribute='is_enabled')) + - False in (identity_provider_info.identity_providers | map(attribute='is_enabled')) + vars: + idp_0: '{{ identity_provider_info.identity_providers[0] }}' + idp_1: '{{ identity_provider_info.identity_providers[1] }}' - name: 'Delete identity_provider - CHECK_MODE' check_mode: yes @@ -762,14 +762,14 @@ - delete_identity_provider is successful - delete_identity_provider is not changed - #- name: 'Fetch identity_provider info after deletion' - # openstack.cloud.os_keystone_identity_provider_info: - # name: '{{ idp_name }}' - # register: identity_provider_info - # ignore_errors: True - #- assert: - # that: - # - identity_provider_info is failed + - name: 'Fetch identity_provider info after deletion' + openstack.cloud.os_keystone_identity_provider_info: + name: '{{ idp_name }}' + register: identity_provider_info + ignore_errors: True + - assert: + that: + - identity_provider_info is failed - name: 'Delete second identity_provider' openstack.cloud.os_keystone_identity_provider: diff --git a/meta/action_groups.yml b/meta/action_groups.yml index 384f64b6..b2fa5671 100644 --- a/meta/action_groups.yml +++ b/meta/action_groups.yml @@ -17,6 +17,7 @@ os: - os_keystone_domain_info - os_keystone_endpoint - os_keystone_identity_provider +- os_keystone_identity_provider_info - os_keystone_mapping - os_keystone_mapping_info - os_keystone_role diff --git a/plugins/modules/os_keystone_identity_provider_info.py b/plugins/modules/os_keystone_identity_provider_info.py new file mode 100644 index 00000000..ae2746a0 --- /dev/null +++ b/plugins/modules/os_keystone_identity_provider_info.py @@ -0,0 +1,107 @@ +#!/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_identity_provider_info +short_description: Get the information about the available federation identity + providers +author: + - "Mark Chappell (@tremble) " +description: + - Fetch a federation identity provider. +options: + name: + description: + - The name of the identity provider to fetch. + - If I(name) is specified, the module will return failed if the identity + provider doesn't exist. + type: str + aliases: ['id'] +requirements: + - "python >= 3.6" + - "openstacksdk >= 0.44" +extends_documentation_fragment: + - openstack.cloud.openstack +''' + +EXAMPLES = ''' +- name: Fetch a specific identity provider + os_keystone_identity_provider_info: + cloud: example_cloud + name: example_provider + +- name: Fetch all providers + os_keystone_identity_provider_info: + cloud: example_cloud +''' + +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_idp(idp): + """ + Normalizes the IDP definitions so that the outputs are consistent with the + parameters + + - "enabled" (parameter) == "is_enabled" (SDK) + - "name" (parameter) == "id" (SDK) + """ + if idp is None: + return + + _idp = idp.to_dict() + _idp['enabled'] = idp['is_enabled'] + _idp['name'] = idp['id'] + return _idp + + +def main(): + """ Module entry point """ + + argument_spec = openstack_full_argument_spec( + name=dict(aliases=['id']), + ) + module_kwargs = openstack_module_kwargs( + ) + module = AnsibleModule( + argument_spec, + supports_check_mode=True, + **module_kwargs + ) + + name = module.params.get('name') + + sdk, cloud = openstack_cloud_from_module(module, min_version="0.44") + + if name: + try: + idp = normalize_idp(cloud.identity.get_identity_provider(name)) + except sdk.exceptions.ResourceNotFound: + module.fail_json(msg='Failed to find identity provider') + except sdk.exceptions.OpenStackCloudException as ex: + module.fail_json(msg='Failed to get identity provider: {0}'.format(str(ex))) + module.exit_json(changed=False, identity_providers=[idp]) + + else: + try: + providers = list(map(normalize_idp, cloud.identity.identity_providers())) + except sdk.exceptions.OpenStackCloudException as ex: + module.fail_json(msg='Failed to list identity providers: {0}'.format(str(ex))) + module.exit_json(changed=False, identity_providers=providers) + + +if __name__ == '__main__': + main()