diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 66ba251f40..8a4c6ca27b 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -2138,14 +2138,27 @@ class RunAdHocCommand(BaseTask): if ad_hoc_command.verbosity: args.append('-%s' % ('v' * min(5, ad_hoc_command.verbosity))) + # Define special extra_vars for AWX, combine with ad_hoc_command.extra_vars + extra_vars = { + 'tower_job_id': ad_hoc_command.pk, + 'awx_job_id': ad_hoc_command.pk, + } + if ad_hoc_command.created_by: + extra_vars.update({ + 'tower_user_id': ad_hoc_command.created_by.pk, + 'tower_user_name': ad_hoc_command.created_by.username, + 'awx_user_id': ad_hoc_command.created_by.pk, + 'awx_user_name': ad_hoc_command.created_by.username, + }) + if ad_hoc_command.extra_vars_dict: redacted_extra_vars, removed_vars = extract_ansible_vars(ad_hoc_command.extra_vars_dict) if removed_vars: raise ValueError(_( "{} are prohibited from use in ad hoc commands." ).format(", ".join(removed_vars))) - - args.extend(['-e', json.dumps(ad_hoc_command.extra_vars_dict)]) + extra_vars.update(ad_hoc_command.extra_vars_dict) + args.extend(['-e', json.dumps(extra_vars)]) args.extend(['-m', ad_hoc_command.module_name]) args.extend(['-a', ad_hoc_command.module_args]) diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 8cb748eb30..ed6c5c9929 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -16,6 +16,7 @@ from django.conf import settings from awx.main.models import ( + AdHocCommand, Credential, CredentialType, Inventory, @@ -26,6 +27,7 @@ from awx.main.models import ( Project, ProjectUpdate, UnifiedJob, + User ) from awx.main import tasks @@ -292,6 +294,18 @@ class TestGenericRun(TestJobExecution): assert '--ro-bind %s %s' % (settings.ANSIBLE_VENV_PATH, settings.ANSIBLE_VENV_PATH) in ' '.join(args) # noqa assert '--ro-bind %s %s' % (settings.AWX_VENV_PATH, settings.AWX_VENV_PATH) in ' '.join(args) # noqa + def test_created_by_extra_vars(self): + self.instance.created_by = User(pk=123, username='angry-spud') + self.task.run(self.pk) + + assert self.run_pexpect.call_count == 1 + call_args, _ = self.run_pexpect.call_args_list[0] + args, cwd, env, stdout = call_args + assert '"tower_user_id": 123,' in ' '.join(args) + assert '"tower_user_name": "angry-spud"' in ' '.join(args) + assert '"awx_user_id": 123,' in ' '.join(args) + assert '"awx_user_name": "angry-spud"' in ' '.join(args) + def test_awx_task_env(self): patch = mock.patch('awx.main.tasks.settings.AWX_TASK_ENV', {'FOO': 'BAR'}) patch.start() @@ -304,6 +318,35 @@ class TestGenericRun(TestJobExecution): assert env['FOO'] == 'BAR' +class TestAdhocRun(TestJobExecution): + + TASK_CLS = tasks.RunAdHocCommand + + def get_instance(self): + return AdHocCommand( + pk=1, + created=datetime.utcnow(), + inventory=Inventory(pk=1), + status='new', + cancel_flag=False, + verbosity=3, + extra_vars={'awx_foo': 'awx-bar'} + ) + + def test_created_by_extra_vars(self): + self.instance.created_by = User(pk=123, username='angry-spud') + self.task.run(self.pk) + + assert self.run_pexpect.call_count == 1 + call_args, _ = self.run_pexpect.call_args_list[0] + args, cwd, env, stdout = call_args + assert '"tower_user_id": 123,' in ' '.join(args) + assert '"tower_user_name": "angry-spud"' in ' '.join(args) + assert '"awx_user_id": 123,' in ' '.join(args) + assert '"awx_user_name": "angry-spud"' in ' '.join(args) + assert '"awx_foo": "awx-bar' in ' '.join(args) + + class TestIsolatedExecution(TestJobExecution): REMOTE_HOST = 'some-isolated-host'