Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add controller_token module #256

Merged
merged 2 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions plugins/modules/controller_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/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: controller_token
author:
- Abhijeet Kasurde (@akasurde)
short_description: Manage AWX tokens in EDA controller
description:
- This module allows the user to manage AWX tokens in a EDA controller.
version_added: '2.0.0'
options:
name:
description:
- The name of the AWX token.
type: str
required: true
description:
description:
- The description of the project.
- Required when O(state=present).
type: str
token:
description:
- The AWX token value.
- Required when O(state=present).
type: str
state:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
type: str
notes:
- Controller Token API does not support PATCH method, due to this reason the module deletes
and re-creates the token when existing controller token is found.
This will cause module to report changed, every time update is called.
extends_documentation_fragment:
- ansible.eda.eda_controller.auths
"""

EXAMPLES = """
- name: Create AWX token
ansible.eda.controller_token:
controller_host: https://my_eda_host/
controller_username: admin
controller_password: MySuperSecretPassw0rd
name: "Example AWX token"
description: "Example AWX token description"
token: "<TOKEN_VALUE>"
state: present
no_log: true
- name: Delete AWX token
ansible.eda.controller_token:
controller_host: https://my_eda_host/
controller_username: admin
controller_password: MySuperSecretPassw0rd
name: "Example AWX token"
state: absent
"""


RETURN = """
id:
description: ID of the managed AWX token.
returned: when state is 'present' and successful
type: str
sample: "123"
"""

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),
description=dict(),
token=dict(no_log=True),
state=dict(choices=["present", "absent"], default="present"),
)

required_if = [("state", "present", ("name", "token"))]

argument_spec.update(AUTH_ARGSPEC)

module = AnsibleModule(
argument_spec=argument_spec, required_if=required_if, supports_check_mode=True
)

client = Client(

Check warning on line 104 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L104

Added line #L104 was not covered by tests
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"),
)

token_endpoint = "/users/me/awx-tokens/"
controller = Controller(client, module)

Check warning on line 113 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L112-L113

Added lines #L112 - L113 were not covered by tests

token_name = module.params.get("name")
description = module.params.get("description")
state = module.params.get("state")
token = module.params.get("token")
ret = {}

Check warning on line 119 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L115-L119

Added lines #L115 - L119 were not covered by tests

try:
token_type = controller.get_one_or_many(token_endpoint, name=token_name)
except EDAError as eda_err:
module.fail_json(msg=str(eda_err))

Check warning on line 124 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L121-L124

Added lines #L121 - L124 were not covered by tests

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(token_type, endpoint=token_endpoint)
except EDAError as eda_err:
module.fail_json(msg=str(eda_err))
module.exit_json(**ret)

Check warning on line 132 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L128-L132

Added lines #L128 - L132 were not covered by tests

# Method 'PATCH' is not allowed, so delete and re-create the token
if token_type:
controller.delete_if_needed(token_type, endpoint=token_endpoint)

Check warning on line 136 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L136

Added line #L136 was not covered by tests

token_param = {

Check warning on line 138 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L138

Added line #L138 was not covered by tests
"name": token_name,
"description": description,
"token": token,
}
# Attempt to create the new AWX token
ret = controller.create_if_needed(

Check warning on line 144 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L144

Added line #L144 was not covered by tests
existing_item=None,
new_item=token_param,
endpoint=token_endpoint,
item_type="controller token type",
)
module.exit_json(**ret)

Check warning on line 150 in plugins/modules/controller_token.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/controller_token.py#L150

Added line #L150 was not covered by tests


if __name__ == "__main__":
main()
57 changes: 57 additions & 0 deletions tests/integration/targets/controller_token/tasks/create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
# 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 controller token in check mode
ansible.eda.controller_token:
controller_host: "{{ controller_host }}"
controller_username: "{{ controller_user }}"
validate_certs: "{{ validate_certs }}"
name: "{{ controller_token_name }}"
description: "Example controller token description"
token: "TOKEN_VALUE"
state: present
check_mode: true
no_log: true
register: r

- name: Check controller token creation in check mode
assert:
that:
- r.changed

- name: Create controller token
ansible.eda.controller_token:
controller_host: "{{ controller_host }}"
controller_username: "{{ controller_user }}"
validate_certs: "{{ validate_certs }}"
name: "{{ controller_token_name }}"
description: "Example controller token description"
token: "TOKEN_VALUE"
state: present
no_log: true
register: r

- name: Check controller token creation
assert:
that:
- r.changed
- "'id' in r"

- name: Create controller token again
ansible.eda.controller_token:
controller_host: "{{ controller_host }}"
controller_username: "{{ controller_user }}"
validate_certs: "{{ validate_certs }}"
name: "{{ controller_token_name }}"
description: "Example controller token description"
token: "TOKEN_VALUE"
state: present
no_log: true
register: r

- name: Check controller token creation again
assert:
that:
- r.changed
- "'id' in r"
31 changes: 31 additions & 0 deletions tests/integration/targets/controller_token/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# 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 controller token
set_fact:
controller_token_name: "controller_token_{{ test_id }}"

- include_tasks: create.yml
always:
- name: Clean up - controller token
ansible.eda.controller_token:
controller_host: "{{ controller_host }}"
controller_username: "{{ controller_user }}"
validate_certs: "{{ validate_certs }}"
name: "{{ item }}"
state: absent
loop:
- "{{ controller_token_name }}"
ignore_errors: true
Loading