summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Aragonés Muniesa <iaragone@redhat.com>2022-02-09 18:58:51 +0100
committerIvan Aragonés Muniesa <iaragone@redhat.com>2022-02-09 18:59:53 +0100
commit9cd43d044e445e89898857060f812d46f130ae0b (patch)
tree0c4a1026bdf335cc042497047799117a3fc8ab3d
parentMerge pull request #11710 from nixocio/ui_npm_audit (diff)
downloadawx-9cd43d044e445e89898857060f812d46f130ae0b.tar.xz
awx-9cd43d044e445e89898857060f812d46f130ae0b.zip
let an organization admin to add new users to it's tower organization
-rw-r--r--awx_collection/plugins/modules/user.py23
-rw-r--r--awx_collection/test/awx/test_completeness.py4
-rw-r--r--awx_collection/tests/integration/targets/user/tasks/main.yml170
3 files changed, 193 insertions, 4 deletions
diff --git a/awx_collection/plugins/modules/user.py b/awx_collection/plugins/modules/user.py
index c21db2fe30..3d5f76bb02 100644
--- a/awx_collection/plugins/modules/user.py
+++ b/awx_collection/plugins/modules/user.py
@@ -42,6 +42,10 @@ options:
description:
- Email address of the user.
type: str
+ organization:
+ description:
+ - The user will be created as a member of that organization (needed for organization admins to create new organization users).
+ type: str
is_superuser:
description:
- Designates that this user has all permissions without explicitly assigning them.
@@ -103,6 +107,14 @@ EXAMPLES = '''
state: present
controller_config_file: "~/tower_cli.cfg"
+- name: Add user as a member of an organization (permissions on the organization are required)
+ user:
+ username: jdoe
+ password: foobarbaz
+ email: jdoe@example.org
+ organization: devopsorg
+ state: present
+
- name: Delete user
user:
username: jdoe
@@ -126,6 +138,7 @@ def main():
is_system_auditor=dict(type='bool', default=False, aliases=['auditor']),
password=dict(no_log=True),
update_secrets=dict(type='bool', default=True, no_log=False),
+ organization=dict(),
state=dict(choices=['present', 'absent'], default='present'),
)
@@ -141,6 +154,7 @@ def main():
is_superuser = module.params.get('is_superuser')
is_system_auditor = module.params.get('is_system_auditor')
password = module.params.get('password')
+ organization = module.params.get('organization')
state = module.params.get('state')
# Attempt to look up the related items the user specified (these will fail the module if not found)
@@ -169,8 +183,13 @@ def main():
if password is not None:
new_fields['password'] = password
- # If the state was present and we can let the module build or update the existing item, this will return on its own
- module.create_or_update_if_needed(existing_item, new_fields, endpoint='users', item_type='user')
+ if organization:
+ org_id = module.resolve_name_to_id('organizations', organization)
+ # If the state was present and we can let the module build or update the existing item, this will return on its own
+ module.create_or_update_if_needed(existing_item, new_fields, endpoint='organizations/{0}/users'.format(org_id), item_type='user')
+ else:
+ # If the state was present and we can let the module build or update the existing item, this will return on its own
+ module.create_or_update_if_needed(existing_item, new_fields, endpoint='users', item_type='user')
if __name__ == '__main__':
diff --git a/awx_collection/test/awx/test_completeness.py b/awx_collection/test/awx/test_completeness.py
index 00a3d0577e..98a6598dff 100644
--- a/awx_collection/test/awx/test_completeness.py
+++ b/awx_collection/test/awx/test_completeness.py
@@ -67,8 +67,8 @@ no_api_parameter_ok = {
'ad_hoc_command': ['interval', 'timeout', 'wait'],
# group parameters to perserve hosts and children.
'group': ['preserve_existing_children', 'preserve_existing_hosts'],
- # user parameters to rename a user.
- 'user': ['new_username'],
+ # new_username parameter to rename a user and organization allows for org admin user creation
+ 'user': ['new_username', 'organization'],
# workflow_approval parameters that do not apply when approving an approval node.
'workflow_approval': ['action', 'interval', 'timeout', 'workflow_job_id'],
}
diff --git a/awx_collection/tests/integration/targets/user/tasks/main.yml b/awx_collection/tests/integration/targets/user/tasks/main.yml
index 2e82275b27..1d5cc5de5e 100644
--- a/awx_collection/tests/integration/targets/user/tasks/main.yml
+++ b/awx_collection/tests/integration/targets/user/tasks/main.yml
@@ -129,3 +129,173 @@
that:
- "'Unable to resolve controller_host' in result.msg or
'Can not verify ssl with non-https protocol' in result.exception"
+
+- block:
+ - name: Generate a test ID
+ set_fact:
+ test_id: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
+
+ - name: Generate an org name
+ set_fact:
+ org_name: "AWX-Collection-tests-organization-org-{{ test_id }}"
+
+ - name: Make sure {{ org_name }} is not there
+ organization:
+ name: "{{ org_name }}"
+ state: absent
+ register: result
+
+ - name: Create a new Organization
+ organization:
+ name: "{{ org_name }}"
+ galaxy_credentials:
+ - Ansible Galaxy
+ register: result
+
+ - assert:
+ that: "result is changed"
+
+ - name: Create a User to become admin of an organization {{ org_name }}
+ user:
+ username: "{{ username }}-orgadmin"
+ password: "{{ username }}-orgadmin"
+ state: present
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Add the user {{ username }}-orgadmin as an admin of the organization {{ org_name }}
+ role:
+ user: "{{ username }}-orgadmin"
+ role: admin
+ organization: "{{ org_name }}"
+ state: present
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Create a User as {{ username }}-orgadmin without using an organization (must fail)
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ username }}"
+ first_name: Joe
+ password: "{{ 65535 | random | to_uuid }}"
+ state: present
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - "result is failed"
+
+ - name: Create a User as {{ username }}-orgadmin using an organization
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ username }}"
+ first_name: Joe
+ password: "{{ 65535 | random | to_uuid }}"
+ state: present
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Change a User as {{ username }}-orgadmin by ID using an organization
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ result.id }}"
+ last_name: User
+ email: joe@example.org
+ state: present
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Check idempotency as {{ username }}-orgadmin using an organization
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ username }}"
+ first_name: Joe
+ last_name: User
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is not changed"
+
+ - name: Rename a User as {{ username }}-orgadmin using an organization
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ username }}"
+ new_username: "{{ username }}-renamed"
+ email: joe@example.org
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Delete a User as {{ username }}-orgadmin using an organization
+ user:
+ controller_username: "{{ username }}-orgadmin"
+ controller_password: "{{ username }}-orgadmin"
+ username: "{{ username }}-renamed"
+ email: joe@example.org
+ state: absent
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Remove the user {{ username }}-orgadmin as an admin of the organization {{ org_name }}
+ role:
+ user: "{{ username }}-orgadmin"
+ role: admin
+ organization: "{{ org_name }}"
+ state: absent
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Delete the User {{ username }}-orgadmin
+ user:
+ username: "{{ username }}-orgadmin"
+ password: "{{ username }}-orgadmin"
+ state: absent
+ organization: "{{ org_name }}"
+ register: result
+
+ - assert:
+ that:
+ - "result is changed"
+
+ - name: Delete the Organization {{ org_name }}
+ organization:
+ name: "{{ org_name }}"
+ state: absent
+ register: result
+
+ - assert:
+ that: "result is changed"
+...