Skip to content

Instantly share code, notes, and snippets.

@AlanCoding
Last active September 28, 2023 13:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlanCoding/bca128a1b391e28819f4020eb9b6536e to your computer and use it in GitHub Desktop.
Save AlanCoding/bca128a1b391e28819f4020eb9b6536e to your computer and use it in GitHub Desktop.

AWX Resource Graph Visualizer

This is a widget hacky thing for visualizing things in AWX which do not otherwise have visualization.

https://github.com/ansible/awx/compare/devel...AlanCoding:inspector?expand=1

SVG here for the job was produced by

dnf install graphviz
/var/lib/awx/venv/awx/bin/pip install graphviz
awx-manage inspect_job --job 243 --file alan --ext svg

The SVG for the roles was produced by

awx-manage inspect_role --role=1520 --file alan --method downup --ext svg

This is where 1520 is the admin role of the organization from the full house script. More on that in the next section

Creating the Example Data

The job is created by a playbook that generates all forms of status.

https://github.com/ansible/test-playbooks/blob/master/gen_host_status.yml

The exact structure will depend heavily on the inventory you use this against.

The RBAC example is done by running the test_full_house script. After this is ran, search for the organization with "Full house" in its name. Then get the admin role for that organization. Exact instructions for running this from the CLI might be somewhat more complicated than these instructions suggest. You need an awxkit environment.

RBAC Relevance

There is some more information in comments in this issue:

ansible/awx#3600

The core idea is that a visualization in order to allow the proliferation of more permissions types.

from awxkit.utils import random_title
class TestAlan(object):
def test_alan(self, factories):
"""Make stuff of every type."""
for i in range(300):
ujts = [
factories.project(),
factories.job_template(),
factories.inventory_source(),
factories.workflow_job_template()
]
factories.ad_hoc_command() # special case
for ujt in ujts:
if hasattr(ujt, 'launch'):
ujt.launch()
else:
ujt.update()
def test_org(self, factories):
"""This makes an organization to test deletion warnings with"""
o = factories.organization(name='Delete Meeeee! {}'.format(random_title()))
print('Creating Resources:')
for res in dir(factories):
if res.startswith('__') or res in ('clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem',
'setdefault', 'update', 'values',
'access_token', 'ad_hoc_command', 'credential_type',
'group', 'host', 'instance_group', 'inventory_source', 'job_template',
'organization', 'workflow_job_template_node'):
continue
print(' {}'.format(res))
obj = getattr(factories, res)(organization=o)
if res != 'user':
assert obj.organization == o.id
if res == 'project':
factories.job_template(project=obj)
def test_full_house(self, factories):
"""Makes every object in an organization and delegates all permissions to everything"""
o = factories.organization(name='Full house!!! {}'.format(random_title()))
print('Adding people to organization roles, org name: {}'.format(o.name))
for role in o.get_related('object_roles').results:
u = factories.user()
role_field = role['name']
o.set_object_roles(u, role_field)
if role_field.lower() not in ('admin', 'member'):
team = factories.team()
o.set_object_roles(team, role_field)
to = team.ds.organization
u2 = factories.user()
to.set_object_roles(u2, 'admin')
u3 = factories.user()
team.set_object_roles(u3, 'member')
u4 = factories.user()
team.set_object_roles(u4, 'admin')
print('Creating Resources:')
for res in dir(factories):
if res.startswith('__') or res in ('clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem',
'setdefault', 'update', 'values',
'access_token', 'ad_hoc_command', 'credential_type',
'group', 'host', 'instance_group', 'inventory_source',
'organization', 'workflow_job_template_node'):
continue
print(' {}'.format(res))
if res == 'job_template':
obj = factories.job_template(project=factories.project(organization=o))
else:
obj = getattr(factories, res)(organization=o)
if res not in ('user', 'job_template'):
assert obj.organization == o.id
if res not in ('user',):
if 'object_roles' not in obj.related:
print(' resource {} does not have roles??? okay?'.format(res))
continue
obj_roles = obj.get_related('object_roles').results
for role in obj_roles:
if res == 'credential':
u = factories.user(organization=o)
team = factories.team(organization=o)
else:
u = factories.user()
team = factories.team()
role_field = role['name']
obj.set_object_roles(u, role_field)
obj.set_object_roles(team, role_field)
to = team.ds.organization
u2 = factories.user()
to.set_object_roles(u2, 'admin')
u3 = factories.user()
team.set_object_roles(u3, 'member')
u4 = factories.user()
team.set_object_roles(u4, 'admin')
def test_inventory_org_admin(self, factories):
o = factories.organization(name='Inventory organization {}'.format(random_title()))
inv = factories.inventory(organization=o)
assert inv.organization == o.id
jt = factories.job_template(inventory=inv)
user = factories.user(organization=o, username='has_inventory_admin_{}'.format(random_title(non_ascii=False)))
o.set_object_roles(user, 'admin')
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment