AWX Collections for DAB RBAC

Adds new modules for CRUD operations on the
following endpoints:

- api/v2/role_definitions
- api/v2/role_user_assignments
- api/v2/role_team_assignments

Note: assignment is Create or Delete only

Additional changes:
- Currently DAB endpoints do not have "type"
field on the resource list items. So this modifies
the create_or_update_if_needed to allow manually
specifying item type.

Signed-off-by: Seth Foster <fosterbseth@gmail.com>
This commit is contained in:
Seth Foster
2024-04-02 15:26:07 -04:00
committed by Alan Rominger
parent 389a729b75
commit 3bb559dd09
13 changed files with 807 additions and 6 deletions

View File

@@ -17,6 +17,7 @@ import pytest
from ansible.module_utils.six import raise_from
from ansible_base.rbac.models import RoleDefinition, DABPermission
from awx.main.tests.functional.conftest import _request
from awx.main.tests.functional.conftest import credentialtype_scm, credentialtype_ssh # noqa: F401; pylint: disable=unused-variable
from awx.main.models import (
@@ -31,9 +32,11 @@ from awx.main.models import (
WorkflowJobTemplate,
NotificationTemplate,
Schedule,
Team,
)
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
HAS_TOWER_CLI = False
@@ -258,6 +261,11 @@ def job_template(project, inventory):
return JobTemplate.objects.create(name='test-jt', project=project, inventory=inventory, playbook='helloworld.yml')
@pytest.fixture
def team(organization):
return Team.objects.create(name='test-team', organization=organization)
@pytest.fixture
def machine_credential(credentialtype_ssh, organization): # noqa: F811
return Credential.objects.create(credential_type=credentialtype_ssh, name='machine-cred', inputs={'username': 'test_user', 'password': 'pas4word'})
@@ -331,6 +339,15 @@ def notification_template(organization):
)
@pytest.fixture
def job_template_role_definition():
rd = RoleDefinition.objects.create(name='test_view_jt', content_type=ContentType.objects.get_for_model(JobTemplate))
permission_codenames = ['view_jobtemplate', 'execute_jobtemplate']
permissions = DABPermission.objects.filter(codename__in=permission_codenames)
rd.permissions.add(*permissions)
return rd
@pytest.fixture
def scm_credential(credentialtype_scm, organization): # noqa: F811
return Credential.objects.create(

View File

@@ -0,0 +1,122 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
from ansible_base.rbac.models import RoleDefinition
@pytest.mark.django_db
def test_create_new(run_module, admin_user):
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert result['changed']
role_definition = RoleDefinition.objects.get(name='test_view_jt')
assert role_definition
permission_codenames = [p.codename for p in role_definition.permissions.all()]
assert set(permission_codenames) == set(['view_jobtemplate', 'execute_jobtemplate'])
assert role_definition.content_type.model == 'jobtemplate'
@pytest.mark.django_db
def test_update_existing(run_module, admin_user):
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert result['changed']
role_definition = RoleDefinition.objects.get(name='test_view_jt')
permission_codenames = [p.codename for p in role_definition.permissions.all()]
assert set(permission_codenames) == set(['view_jobtemplate'])
assert role_definition.content_type.model == 'jobtemplate'
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert result['changed']
role_definition.refresh_from_db()
permission_codenames = [p.codename for p in role_definition.permissions.all()]
assert set(permission_codenames) == set(['view_jobtemplate', 'execute_jobtemplate'])
assert role_definition.content_type.model == 'jobtemplate'
@pytest.mark.django_db
def test_delete_existing(run_module, admin_user):
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert result['changed']
role_definition = RoleDefinition.objects.get(name='test_view_jt')
assert role_definition
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
'state': 'absent',
},
admin_user)
assert result['changed']
with pytest.raises(RoleDefinition.DoesNotExist):
role_definition.refresh_from_db()
@pytest.mark.django_db
def test_idempotence(run_module, admin_user):
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert result['changed']
result = run_module(
'role_definition',
{
'name': 'test_view_jt',
'permissions': ['awx.view_jobtemplate', 'awx.execute_jobtemplate'],
'content_type': 'awx.jobtemplate',
},
admin_user)
assert not result['changed']
role_definition = RoleDefinition.objects.get(name='test_view_jt')
permission_codenames = [p.codename for p in role_definition.permissions.all()]
assert set(permission_codenames) == set(['view_jobtemplate', 'execute_jobtemplate'])

View File

@@ -0,0 +1,70 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
from ansible_base.rbac.models import RoleTeamAssignment
@pytest.mark.django_db
def test_create_new(run_module, admin_user, team, job_template, job_template_role_definition):
result = run_module(
'role_team_assignment',
{
'team': team.name,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
assert RoleTeamAssignment.objects.filter(team=team, object_id=job_template.id, role_definition=job_template_role_definition).exists()
@pytest.mark.django_db
def test_idempotence(run_module, admin_user, team, job_template, job_template_role_definition):
result = run_module(
'role_team_assignment',
{
'team': team.name,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
result = run_module(
'role_team_assignment',
{
'team': team.name,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert not result['changed']
@pytest.mark.django_db
def test_delete_existing(run_module, admin_user, team, job_template, job_template_role_definition):
result = run_module(
'role_team_assignment',
{
'team': team.name,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
assert RoleTeamAssignment.objects.filter(team=team, object_id=job_template.id, role_definition=job_template_role_definition).exists()
result = run_module(
'role_team_assignment',
{
'team': team.name,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
'state': 'absent'
},
admin_user)
assert result['changed']
assert not RoleTeamAssignment.objects.filter(team=team, object_id=job_template.id, role_definition=job_template_role_definition).exists()

View File

@@ -0,0 +1,70 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
from ansible_base.rbac.models import RoleUserAssignment
@pytest.mark.django_db
def test_create_new(run_module, admin_user, job_template, job_template_role_definition):
result = run_module(
'role_user_assignment',
{
'user': admin_user.username,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
assert RoleUserAssignment.objects.filter(user=admin_user, object_id=job_template.id, role_definition=job_template_role_definition).exists()
@pytest.mark.django_db
def test_idempotence(run_module, admin_user, job_template, job_template_role_definition):
result = run_module(
'role_user_assignment',
{
'user': admin_user.username,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
result = run_module(
'role_user_assignment',
{
'user': admin_user.username,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert not result['changed']
@pytest.mark.django_db
def test_delete_existing(run_module, admin_user, job_template, job_template_role_definition):
result = run_module(
'role_user_assignment',
{
'user': admin_user.username,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
},
admin_user)
assert result['changed']
assert RoleUserAssignment.objects.filter(user=admin_user, object_id=job_template.id, role_definition=job_template_role_definition).exists()
result = run_module(
'role_user_assignment',
{
'user': admin_user.username,
'object_id': job_template.id,
'role_definition': job_template_role_definition.name,
'state': 'absent'
},
admin_user)
assert result['changed']
assert not RoleUserAssignment.objects.filter(user=admin_user, object_id=job_template.id, role_definition=job_template_role_definition).exists()