diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 3dfd201cc0..d2ff77a2b9 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -9,6 +9,7 @@ import distutils.version import json import logging import os +import pipes import re import subprocess import stat @@ -128,6 +129,9 @@ class BaseTask(Task): env[k] = '*'*len(str(v)) return env + def args2cmdline(self, *args): + return ' '.join([pipes.quote(a) for a in args]) + def build_args(self, instance, **kwargs): raise NotImplementedError @@ -378,8 +382,8 @@ class RunJob(BaseTask): args.append(job.playbook) # relative path to project.local_path ssh_key_path = kwargs.get('private_data_file', '') if ssh_key_path: - cmd = ' '.join([subprocess.list2cmdline(['ssh-add', ssh_key_path]), - '&&', subprocess.list2cmdline(args)]) + cmd = ' '.join([self.args2cmdline('ssh-add', ssh_key_path), + '&&', self.args2cmdline(*args)]) args = ['ssh-agent', 'sh', '-c', cmd] return args @@ -612,7 +616,7 @@ class RunProjectUpdate(BaseTask): ssh_key_path = kwargs.get('private_data_file', '') if ssh_key_path: subcmds = [('ssh-add', ssh_key_path), args] - cmd = ' && '.join([subprocess.list2cmdline(x) for x in subcmds]) + cmd = ' && '.join([self.args2cmdline(*x) for x in subcmds]) args = ['ssh-agent', 'sh', '-c', cmd] return args diff --git a/awx/main/tests/tasks.py b/awx/main/tests/tasks.py index 137772c4cc..9f8e59b427 100644 --- a/awx/main/tests/tasks.py +++ b/awx/main/tests/tasks.py @@ -160,14 +160,13 @@ class RunJobTest(BaseCeleryTest): self.test_project_path = None self.setup_users() self.organization = self.make_organizations(self.super_django_user, 1)[0] - self.inventory = Inventory.objects.create(name='test-inventory', - description='description for test-inventory', - organization=self.organization) - self.host = self.inventory.hosts.create(name='host.example.com', - inventory=self.inventory) - self.group = self.inventory.groups.create(name='test-group', - inventory=self.inventory) + self.inventory = self.organization.inventories.create(name='test-inventory', + description='description for test-inventory') + self.host = self.inventory.hosts.create(name='host.example.com') + self.group = self.inventory.groups.create(name='test-group') + self.group2 = self.inventory.groups.create(name='test-group2') self.group.hosts.add(self.host) + self.group2.hosts.add(self.host) self.project = None self.credential = None # Monkeypatch RunJob to capture list of command line arguments. @@ -703,6 +702,19 @@ class RunJobTest(BaseCeleryTest): self.check_job_result(job, 'failed') self.assertTrue('-l' in self.run_job_args) + def test_limit_option_with_group_pattern_and_ssh_agent(self): + self.create_test_credential(ssh_key_data=TEST_SSH_KEY_DATA) + self.create_test_project(TEST_PLAYBOOK) + job_template = self.create_test_job_template(limit='test-group:&test-group2') + job = self.create_test_job(job_template=job_template) + self.assertEqual(job.status, 'new') + self.assertFalse(job.passwords_needed_to_start) + self.assertTrue(job.start()) + self.assertEqual(job.status, 'pending') + job = Job.objects.get(pk=job.pk) + self.check_job_result(job, 'successful') + self.assertTrue('ssh-agent' in self.run_job_args) + def test_ssh_username_and_password(self): self.create_test_credential(username='sshuser', password='sshpass') self.create_test_project(TEST_PLAYBOOK)