From a3e88379635b5fab91b79e4e168fa2851a7b9c6f Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 15 Aug 2024 14:36:25 -0700 Subject: [PATCH] Add decision environment module (#248) * Added module to manage decision environment * Added module to gather information about decision environment * tests Signed-off-by: Abhijeet Kasurde --- plugins/modules/decision_environment.py | 195 ++++++++++++++++++ plugins/modules/decision_environment_info.py | 108 ++++++++++ .../decision_environment/tasks/create.yml | 81 ++++++++ .../decision_environment/tasks/delete.yml | 45 ++++ .../decision_environment/tasks/main.yml | 35 ++++ .../decision_environment/tasks/update.yml | 67 ++++++ .../decision_environment_info/tasks/list.yml | 75 +++++++ .../decision_environment_info/tasks/main.yml | 32 +++ 8 files changed, 638 insertions(+) create mode 100644 plugins/modules/decision_environment.py create mode 100644 plugins/modules/decision_environment_info.py create mode 100644 tests/integration/targets/decision_environment/tasks/create.yml create mode 100644 tests/integration/targets/decision_environment/tasks/delete.yml create mode 100644 tests/integration/targets/decision_environment/tasks/main.yml create mode 100644 tests/integration/targets/decision_environment/tasks/update.yml create mode 100644 tests/integration/targets/decision_environment_info/tasks/list.yml create mode 100644 tests/integration/targets/decision_environment_info/tasks/main.yml diff --git a/plugins/modules/decision_environment.py b/plugins/modules/decision_environment.py new file mode 100644 index 00000000..fa6149ed --- /dev/null +++ b/plugins/modules/decision_environment.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: decision_environment +author: + - Nikhil Jain (@jainnikhil30) + - Abhijeet Kasurde (@akasurde) +short_description: Create, update or delete decision environment in EDA Controller +description: + - This module allows user to create, update or delete decision environment in a EDA controller. +version_added: '2.0.0' +options: + name: + description: + - The name of the decision environment. + type: str + required: true + new_name: + description: + - Setting this option will change the existing name. + type: str + description: + description: + - The description of the decision environment. + type: str + image_url: + description: + - Image URL of the decision environment. + type: str + credential: + description: + - Name of the credential to associate with the decision environment. + type: str + state: + description: + - Desired state of the resource. + default: "present" + choices: ["present", "absent"] + type: str +extends_documentation_fragment: + - ansible.eda.eda_controller.auths +""" + +EXAMPLES = """ +- name: Create EDA Decision Environment + ansible.eda.decision_environment: + controller_host: https://my_eda_host/ + controller_username: admin + controller_password: MySuperSecretPassw0rd + name: "Example Decision Environment" + description: "Example Decision Environment description" + image_url: "quay.io/test" + credential: "Example Credential" + state: present + +- name: Update the name of the Decision Environment + ansible.eda.decision_environment: + controller_host: https://my_eda_host/ + controller_username: admin + controller_password: MySuperSecretPassw0rd + name: "Example Decision Environment" + new_name: "Latest Example Decision Environment" + state: present + +- name: Delete the the Decision Environment + ansible.eda.decision_environment: + controller_host: https://my_eda_host/ + controller_username: admin + controller_password: MySuperSecretPassw0rd + name: "Example Decision Environment" + state: absent +""" + +RETURN = """ +id: + description: ID of the decision environment + returned: when exists + type: int + sample: 37 +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.arguments import AUTH_ARGSPEC +from ..module_utils.client import Client +from ..module_utils.controller import Controller +from ..module_utils.errors import EDAError + + +def main(): + argument_spec = dict( + name=dict(required=True), + new_name=dict(), + description=dict(), + image_url=dict(), + credential=dict(), + state=dict(choices=["present", "absent"], default="present"), + ) + + argument_spec.update(AUTH_ARGSPEC) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + client = Client( + host=module.params.get("controller_host"), + username=module.params.get("controller_username"), + password=module.params.get("controller_password"), + timeout=module.params.get("request_timeout"), + validate_certs=module.params.get("validate_certs"), + ) + + decision_environment_endpoint = "decision-environments" + controller = Controller(client, module) + + decision_environment_name = module.params.get("name") + new_name = module.params.get("new_name") + description = module.params.get("description") + image_url = module.params.get("image_url") + state = module.params.get("state") + credential = module.params.get("credential") + ret = {} + + try: + decision_environment_type = controller.get_one_or_many( + decision_environment_endpoint, name=decision_environment_name + ) + except EDAError as eda_err: + module.fail_json(msg=str(eda_err)) + + if state == "absent": + # If the state was absent we can let the module delete it if needed, the module will handle exiting from this + try: + ret = controller.delete_if_needed( + decision_environment_type, endpoint=decision_environment_endpoint + ) + except EDAError as eda_err: + module.fail_json(msg=str(eda_err)) + module.exit_json(**ret) + + decision_environment_type_params = {} + if description: + decision_environment_type_params["description"] = description + if image_url: + decision_environment_type_params["image_url"] = image_url + + credential_type = None + if credential: + try: + credential_type = controller.get_one_or_many( + "eda-credentials", name=credential + ) + except EDAError as eda_err: + module.fail_json(msg=str(eda_err)) + + if credential_type is not None: + # this is resolved earlier, so save an API call and don't do it again + # in the loop above + decision_environment_type_params["credential"] = credential_type["id"] + + if new_name: + decision_environment_type_params["name"] = new_name + elif decision_environment_type: + decision_environment_type_params["name"] = controller.get_item_name( + decision_environment_type + ) + else: + decision_environment_type_params["name"] = decision_environment_name + + # If the state was present and we can let the module build or update + # the existing decision environment type, + # this will return on its own + try: + ret = controller.create_or_update_if_needed( + decision_environment_type, + decision_environment_type_params, + endpoint=decision_environment_endpoint, + item_type="decision environment type", + ) + except EDAError as eda_err: + module.fail_json(msg=str(eda_err)) + + module.exit_json(**ret) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/decision_environment_info.py b/plugins/modules/decision_environment_info.py new file mode 100644 index 00000000..588250c9 --- /dev/null +++ b/plugins/modules/decision_environment_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: decision_environment_info +author: + - Abhijeet Kasurde (@akasurde) +short_description: List a decision environment in EDA Controller +description: + - This module allows user to list a decision environment in a EDA controller. +version_added: '2.0.0' +options: + name: + description: + - The name of the decision environment. + type: str +extends_documentation_fragment: + - ansible.eda.eda_controller.auths +""" + +EXAMPLES = """ +- name: List all EDA Decision Environments + ansible.eda.decision_environment_info: + controller_host: https://my_eda_host/ + controller_username: admin + controller_password: MySuperSecretPassw0rd + +- name: List a particular EDA Decision Environments + ansible.eda.decision_environment_info: + controller_host: https://my_eda_host/ + controller_username: admin + controller_password: MySuperSecretPassw0rd + name: Example +""" + +RETURN = """ +decision_environments: + description: List of dict containing information about decision environments + returned: when exists + type: list + sample: [ + { + "created_at": "2024-08-15T21:12:52.218969Z", + "description": "Example decision environment description", + "eda_credential_id": null, + "id": 35, + "image_url": "https://quay.io/repository/ansible/eda-server", + "modified_at": "2024-08-15T21:12:52.218994Z", + "name": "Example Decision environment", + "organization_id": 1 + } + ] +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.arguments import AUTH_ARGSPEC +from ..module_utils.client import Client +from ..module_utils.common import to_list_of_dict +from ..module_utils.controller import Controller +from ..module_utils.errors import EDAError + + +def main(): + argument_spec = dict( + name=dict(), + ) + + argument_spec.update(AUTH_ARGSPEC) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + client = Client( + host=module.params.get("controller_host"), + username=module.params.get("controller_username"), + password=module.params.get("controller_password"), + timeout=module.params.get("request_timeout"), + validate_certs=module.params.get("validate_certs"), + ) + + decision_environment_endpoint = "decision-environments" + controller = Controller(client, module) + + decision_environment_name = module.params.get("name") + ret = {} + + try: + ret = controller.get_one_or_many( + decision_environment_endpoint, + name=decision_environment_name, + want_one=False, + ) + except EDAError as eda_err: + module.fail_json(msg=str(eda_err)) + + module.exit_json(decision_environments=to_list_of_dict(ret)) + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/decision_environment/tasks/create.yml b/tests/integration/targets/decision_environment/tasks/create.yml new file mode 100644 index 00000000..30124a5a --- /dev/null +++ b/tests/integration/targets/decision_environment/tasks/create.yml @@ -0,0 +1,81 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Create decision environment in check mode + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + check_mode: true + register: r + +- name: Check decision environment in check mode + assert: + that: + - r.changed + +- name: Create decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment creation + assert: + that: + - r.changed + +- name: Create decision environment again + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment is not created again + assert: + that: + - not r.changed + +- name: Delete decision environment in check mode + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + state: absent + check_mode: true + register: r + +- name: Check if decision environment deleted in check mode + assert: + that: + - r.changed + +- name: Delete decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + state: absent + register: r + +- name: Check if delete decision environment + assert: + that: + - r.changed diff --git a/tests/integration/targets/decision_environment/tasks/delete.yml b/tests/integration/targets/decision_environment/tasks/delete.yml new file mode 100644 index 00000000..9e24c206 --- /dev/null +++ b/tests/integration/targets/decision_environment/tasks/delete.yml @@ -0,0 +1,45 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Delete operation without required name parameter + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + state: absent + ignore_errors: true + register: r + +- name: Check if decision environment name is required + assert: + that: + - r.failed + - "'missing required arguments: name' in r.msg" + +- name: Delete non-existing decision environment in check mode + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: Example + state: absent + check_mode: true + register: r + +- name: Check if delete non-existing decision environment in check mode + assert: + that: + - not r.changed + +- name: Delete non-existing decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: Example + state: absent + register: r + +- name: Check if delete non-existing project + assert: + that: + - not r.changed diff --git a/tests/integration/targets/decision_environment/tasks/main.yml b/tests/integration/targets/decision_environment/tasks/main.yml new file mode 100644 index 00000000..0d6b0331 --- /dev/null +++ b/tests/integration/targets/decision_environment/tasks/main.yml @@ -0,0 +1,35 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- block: + - name: Generate a random_string for the test + set_fact: + random_string: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}" + when: random_string is not defined + + - name: Generate a ID for the test + set_fact: + test_id: "{{ random_string | to_uuid }}" + when: test_id is not defined + + - name: Define variables for credential and decision environment + set_fact: + decision_env_name: "Test_Decision_Env_{{ test_id }}" + image_url: "https://quay.io/repository/ansible/eda-server" + + - include_tasks: create.yml + - include_tasks: delete.yml + - include_tasks: update.yml + always: + - name: Clean up - decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ item }}" + state: absent + loop: + - "{{ decision_env_name }}" + - "{{ decision_env_name }}_new" + ignore_errors: true diff --git a/tests/integration/targets/decision_environment/tasks/update.yml b/tests/integration/targets/decision_environment/tasks/update.yml new file mode 100644 index 00000000..046801c1 --- /dev/null +++ b/tests/integration/targets/decision_environment/tasks/update.yml @@ -0,0 +1,67 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Create decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment creation + assert: + that: + - r.changed + +- name: Update decision environment name + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + new_name: "{{ decision_env_name }}_new" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment update + assert: + that: + - r.changed + +- name: Update decision environment again + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}_new" + new_name: "{{ decision_env_name }}_new" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment is not updated again + assert: + that: + - not r.changed + +- name: Delete updated decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}_new" + state: absent + register: r + +- name: Check if delete decision environment + assert: + that: + - r.changed diff --git a/tests/integration/targets/decision_environment_info/tasks/list.yml b/tests/integration/targets/decision_environment_info/tasks/list.yml new file mode 100644 index 00000000..299ae39a --- /dev/null +++ b/tests/integration/targets/decision_environment_info/tasks/list.yml @@ -0,0 +1,75 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Create decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + description: "Example decision environment description" + image_url: "{{ image_url }}" + state: present + register: r + +- name: Check decision environment creation + assert: + that: + - r.changed + +- name: List all decision environments in check mode + ansible.eda.decision_environment_info: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + check_mode: true + register: r + +- name: Check if list decision environments in check mode + assert: + that: + - not r.changed + - "'decision_environments' in r" + +- name: List all decision environments + ansible.eda.decision_environment_info: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + register: r + +- name: Check if list decision environments + assert: + that: + - not r.changed + - "'decision_environments' in r" + +- name: List a particular decision environment + ansible.eda.decision_environment_info: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + register: r + +- name: Check if list decision environments + assert: + that: + - not r.changed + - "'decision_environments' in r" + - "r['decision_environments'][0]['name'] == decision_env_name" + +- name: Delete decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ decision_env_name }}" + state: absent + register: r + +- name: Check if delete decision environment + assert: + that: + - r.changed diff --git a/tests/integration/targets/decision_environment_info/tasks/main.yml b/tests/integration/targets/decision_environment_info/tasks/main.yml new file mode 100644 index 00000000..59a5fcf3 --- /dev/null +++ b/tests/integration/targets/decision_environment_info/tasks/main.yml @@ -0,0 +1,32 @@ +--- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- block: + - name: Generate a random_string for the test + set_fact: + random_string: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}" + when: random_string is not defined + + - name: Generate a ID for the test + set_fact: + test_id: "{{ random_string | to_uuid }}" + when: test_id is not defined + + - name: Define variables for credential and decision environment + set_fact: + decision_env_name: "Test_Decision_Env_{{ test_id }}" + image_url: "https://quay.io/repository/ansible/eda-server" + + - include_tasks: list.yml + always: + - name: Clean up - decision environment + ansible.eda.decision_environment: + controller_host: "{{ controller_host }}" + controller_username: "{{ controller_user }}" + validate_certs: "{{ validate_certs }}" + name: "{{ item }}" + state: absent + loop: + - "{{ decision_env_name }}" + ignore_errors: true