diff --git a/awx/main/tests/conftest.py b/awx/main/tests/conftest.py index d2a29fc220..470f43e661 100644 --- a/awx/main/tests/conftest.py +++ b/awx/main/tests/conftest.py @@ -25,3 +25,17 @@ def notification_template_factory(): def survey_spec_factory(): return create_survey_spec +@pytest.fixture +def job_with_secret_key_factory(job_template_factory): + def rf(persisted): + "Returns job with linked JT survey with password survey questions" + objects = job_template_factory('jt', organization='org1', survey=[ + {'variable': 'submitter_email', 'type': 'text', 'default': 'foobar@redhat.com'}, + {'variable': 'secret_key', 'default': '6kQngg3h8lgiSTvIEb21', 'type': 'password'}, + {'variable': 'SSN', 'type': 'password'}], jobs=[1], persisted=persisted) + return objects.jobs[1] + return rf + +@pytest.fixture +def job_with_secret_key_unit(job_with_secret_key_factory): + return job_with_secret_key_factory(persisted=False) diff --git a/awx/main/tests/factories/fixtures.py b/awx/main/tests/factories/fixtures.py index 19841349d4..008f3fca4b 100644 --- a/awx/main/tests/factories/fixtures.py +++ b/awx/main/tests/factories/fixtures.py @@ -1,3 +1,5 @@ +import json + from django.contrib.auth.models import User from awx.main.models import ( @@ -6,6 +8,7 @@ from awx.main.models import ( Team, Instance, JobTemplate, + Job, NotificationTemplate, Credential, Inventory, @@ -103,11 +106,30 @@ def mk_inventory(name, organization=None, persisted=True): return inv +def mk_job(job_type='run', status='new', job_template=None, inventory=None, + credential=None, project=None, extra_vars={}, + persisted=True): + job = Job(job_type=job_type, status=status, extra_vars=json.dumps(extra_vars)) + + job.job_template = job_template + job.inventory = inventory + job.credential = credential + job.project = project + + if persisted: + job.save() + return job + + def mk_job_template(name, job_type='run', organization=None, inventory=None, - credential=None, persisted=True, + credential=None, persisted=True, extra_vars='', project=None, spec=None): - jt = JobTemplate(name=name, job_type=job_type, playbook='mocked') + if extra_vars: + extra_vars = json.dumps(extra_vars) + + jt = JobTemplate(name=name, job_type=job_type, extra_vars=extra_vars, + playbook='mocked') jt.inventory = inventory if jt.inventory is None: diff --git a/awx/main/tests/factories/tower.py b/awx/main/tests/factories/tower.py index 612ff80644..5247f4195a 100644 --- a/awx/main/tests/factories/tower.py +++ b/awx/main/tests/factories/tower.py @@ -7,6 +7,7 @@ from awx.main.models import ( NotificationTemplate, Credential, Inventory, + Job, Label, ) @@ -21,6 +22,7 @@ from .fixtures import ( mk_team, mk_user, mk_job_template, + mk_job, mk_credential, mk_inventory, mk_project, @@ -173,7 +175,7 @@ def create_survey_spec(variables=None, default_type='integer', required=True): # def create_job_template(name, roles=None, persisted=True, **kwargs): - Objects = generate_objects(["job_template", + Objects = generate_objects(["job_template", "jobs", "organization", "inventory", "project", @@ -186,7 +188,9 @@ def create_job_template(name, roles=None, persisted=True, **kwargs): inv = None cred = None spec = None + jobs = {} job_type = kwargs.get('job_type', 'run') + extra_vars = kwargs.get('extra_vars', '') if 'organization' in kwargs: org = kwargs['organization'] @@ -213,13 +217,27 @@ def create_job_template(name, roles=None, persisted=True, **kwargs): jt = mk_job_template(name, project=proj, inventory=inv, credential=cred, - job_type=job_type, spec=spec, + job_type=job_type, spec=spec, extra_vars=extra_vars, persisted=persisted) + if 'jobs' in kwargs: + for i in kwargs['jobs']: + if type(i) is Job: + jobs[i.pk] = i + else: + # Fill in default survey answers + job_extra_vars = {} + for question in spec['spec']: + job_extra_vars[question['variable']] = question['default'] + jobs[i] = mk_job(job_template=jt, project=proj, inventory=inv, credential=cred, + extra_vars=job_extra_vars, + job_type=job_type, persisted=persisted) + role_objects = generate_role_objects([org, proj, inv, cred]) apply_roles(roles, role_objects, persisted) return Objects(job_template=jt, + jobs=jobs, project=proj, inventory=inv, credential=cred, diff --git a/awx/main/tests/functional/conftest.py b/awx/main/tests/functional/conftest.py index bb6f902802..3aab7a2537 100644 --- a/awx/main/tests/functional/conftest.py +++ b/awx/main/tests/functional/conftest.py @@ -187,13 +187,8 @@ def notification_template(organization): headers={"Test": "Header"})) @pytest.fixture -def job_with_secret_key(job_template_factory): - "Returns a job from a Job Template with secret_key as password question" - objects = job_template_factory( - 'jt', organization='org1', survey=[{'variable': 'secret_key', 'type': 'password'}]) - job = objects.job_template.jobs.create( - job_type="run", extra_vars=json.dumps({'secret_key': '6kQngg3h8lgiSTvIEb21'})) - return job +def job_with_secret_key(job_with_secret_key_factory): + return job_with_secret_key_factory(persisted=True) @pytest.fixture def admin(user): diff --git a/awx/main/tests/functional/test_fixture_factories.py b/awx/main/tests/functional/test_fixture_factories.py index bd0e85fc50..bb6dd6cd63 100644 --- a/awx/main/tests/functional/test_fixture_factories.py +++ b/awx/main/tests/functional/test_fixture_factories.py @@ -77,7 +77,8 @@ def test_org_factory(organization_factory): def test_job_template_factory(job_template_factory): jt_objects = job_template_factory('testJT', organization='org1', project='proj1', inventory='inventory1', - credential='cred1', survey='test-survey') + credential='cred1', survey='test-survey', + jobs=[1]) assert jt_objects.job_template.name == 'testJT' assert jt_objects.project.name == 'proj1' assert jt_objects.inventory.name == 'inventory1' @@ -85,6 +86,7 @@ def test_job_template_factory(job_template_factory): assert jt_objects.inventory.organization.name == 'org1' assert jt_objects.job_template.survey_enabled is True assert jt_objects.job_template.survey_spec is not None + assert 'test-survey' in jt_objects.jobs[1].extra_vars def test_survey_spec_generator_simple(survey_spec_factory): survey_spec = survey_spec_factory('survey_variable') diff --git a/awx/main/tests/unit/models/test_job_template_unit.py b/awx/main/tests/unit/models/test_job_template_unit.py index 7ed24ce173..ff9f2c6e67 100644 --- a/awx/main/tests/unit/models/test_job_template_unit.py +++ b/awx/main/tests/unit/models/test_job_template_unit.py @@ -1,21 +1,9 @@ import pytest import json -from awx.main.tests.factories import create_job_template -from awx.main.models.jobs import Job - -@pytest.fixture -def job_template_sensitive_data(): - return create_job_template( - 'jt', project='prj', persisted=False, - survey=['submitter_email', - {'variable': 'secret_key', 'type': 'password'}, - {'variable': 'SSN', 'type': 'password'}] - ).job_template - -def test_missing_project_error(): - objects = create_job_template( +def test_missing_project_error(job_template_factory): + objects = job_template_factory( 'missing-project-jt', organization='org1', inventory='inventory1', @@ -26,8 +14,8 @@ def test_missing_project_error(): validation_errors, resources_needed_to_start = obj.resource_validation_data() assert 'project' in validation_errors -def test_inventory_credential_need_to_start(): - objects = create_job_template( +def test_inventory_credential_need_to_start(job_template_factory): + objects = job_template_factory( 'job-template-few-resources', project='project1', persisted=False) @@ -35,8 +23,8 @@ def test_inventory_credential_need_to_start(): assert 'inventory' in obj.resources_needed_to_start assert 'credential' in obj.resources_needed_to_start -def test_inventory_credential_contradictions(): - objects = create_job_template( +def test_inventory_credential_contradictions(job_template_factory): + objects = job_template_factory( 'job-template-paradox', project='project1', persisted=False) @@ -48,21 +36,14 @@ def test_inventory_credential_contradictions(): assert 'credential' in validation_errors @pytest.mark.survey -def test_survey_password_list(job_template_sensitive_data): - """Verify the output of the survey_passwords function - gives a list of survey variable names which are passwords""" - assert job_template_sensitive_data.survey_password_variables() == ['secret_key', 'SSN'] +def test_survey_password_list(job_with_secret_key_unit): + """Verify that survey_password_variables method gives a list of survey passwords""" + assert job_with_secret_key_unit.job_template.survey_password_variables() == ['secret_key', 'SSN'] @pytest.mark.survey -def test_job_redacted_extra_vars(job_template_sensitive_data): +def test_job_redacted_extra_vars(job_with_secret_key_unit): """Verify that this method redacts vars marked as passwords in a survey""" - job_obj = Job( - job_type="run", job_template=job_template_sensitive_data, - extra_vars=json.dumps({'submitter_email': 'foobar@redhat.com', - 'secret_key': 'b86hpFChM2XSb40Zld9x', - 'SSN': '123-45-6789'})) - assert json.loads(job_obj.display_extra_vars()) == { + assert json.loads(job_with_secret_key_unit.display_extra_vars()) == { 'submitter_email': 'foobar@redhat.com', 'secret_key': '$encrypted$', - 'SSN': '$encrypted$' - } + 'SSN': '$encrypted$'} diff --git a/awx/main/tests/unit/models/test_job_unit.py b/awx/main/tests/unit/models/test_job_unit.py index 633f6a0470..6b6946b136 100644 --- a/awx/main/tests/unit/models/test_job_unit.py +++ b/awx/main/tests/unit/models/test_job_unit.py @@ -1,40 +1,23 @@ -import pytest import json -from awx.main.models.jobs import Job from awx.main.tasks import RunJob -from awx.main.tests.factories import create_job_template - -@pytest.fixture -def job_with_secret_vars(): - job_template = create_job_template( - 'jt', persisted=False, - survey=['submitter_email', - {'variable': 'secret_key', 'type': 'password'}] - ).job_template - job = Job(id=1, job_template=job_template, extra_vars=json.dumps({ - 'submitter_email': 'foobar@redhat.com', - 'secret_key': '6kQngg3h8lgiSTvIEb21' - })) - return job - -def test_job_args_redacted_passwords(job_with_secret_vars): +def test_job_safe_args_redacted_passwords(job_with_secret_key_unit): """Verify that safe_args hides passwords in the job extra_vars""" kwargs = {'ansible_version': '2.1'} run_job = RunJob() - safe_args = run_job.build_safe_args(job_with_secret_vars, **kwargs) + safe_args = run_job.build_safe_args(job_with_secret_key_unit, **kwargs) ev_index = safe_args.index('-e') + 1 extra_vars = json.loads(safe_args[ev_index]) assert extra_vars['secret_key'] == '$encrypted$' assert extra_vars['submitter_email'] == 'foobar@redhat.com' -def test_job_args_unredacted_passwords(job_with_secret_vars): +def test_job_args_unredacted_passwords(job_with_secret_key_unit): kwargs = {'ansible_version': '2.1'} run_job = RunJob() - safe_args = run_job.build_args(job_with_secret_vars, **kwargs) - ev_index = safe_args.index('-e') + 1 - extra_vars = json.loads(safe_args[ev_index]) + args = run_job.build_args(job_with_secret_key_unit, **kwargs) + ev_index = args.index('-e') + 1 + extra_vars = json.loads(args[ev_index]) assert extra_vars['secret_key'] == '6kQngg3h8lgiSTvIEb21' assert extra_vars['submitter_email'] == 'foobar@redhat.com'