mirror of
https://github.com/ansible/awx.git
synced 2026-03-01 16:58:46 -03:30
Merge pull request #6691 from chrismeyersfsu/enhancement-migrate_scan_job
Migrate scan job to use tower fact cache instead
This commit is contained in:
@@ -76,14 +76,6 @@ def job_template_prompts_null(project):
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bad_scan_JT(job_template_prompts):
|
||||
job_template = job_template_prompts(True)
|
||||
job_template.job_type = 'scan'
|
||||
job_template.save()
|
||||
return job_template
|
||||
|
||||
|
||||
# End of setup, tests start here
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.job_runtime_vars
|
||||
@@ -259,18 +251,6 @@ def test_job_block_scan_job_type_change(job_template_prompts, post, admin_user):
|
||||
assert 'job_type' in response.data
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.job_runtime_vars
|
||||
def test_job_block_scan_job_inv_change(mocker, bad_scan_JT, runtime_data, post, admin_user):
|
||||
# Assure that giving a new inventory for a scan job blocks the launch
|
||||
with mocker.patch('awx.main.access.BaseAccess.check_license'):
|
||||
response = post(reverse('api:job_template_launch', kwargs={'pk': bad_scan_JT.pk}),
|
||||
dict(inventory=runtime_data['inventory']), admin_user,
|
||||
expect=400)
|
||||
|
||||
assert 'inventory' in response.data
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_job_launch_JT_with_validation(machine_credential, deploy_jobtemplate):
|
||||
deploy_jobtemplate.extra_vars = '{"job_template_var": 3}'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
# AWX
|
||||
from awx.api.serializers import JobTemplateSerializer, JobLaunchSerializer
|
||||
from awx.api.serializers import JobTemplateSerializer
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.models.jobs import Job
|
||||
from awx.main.migrations import _save_password_keys as save_password_keys
|
||||
@@ -387,7 +387,6 @@ def test_edit_nonsenstive(patch, job_template_factory, alice):
|
||||
'ask_inventory_on_launch':True,
|
||||
'ask_credential_on_launch': True,
|
||||
}, alice, expect=200)
|
||||
print(res.data)
|
||||
assert res.data['name'] == 'updated'
|
||||
|
||||
|
||||
@@ -430,48 +429,6 @@ def test_jt_admin_copy_edit_functional(jt_copy_edit, rando, get, post):
|
||||
assert post_response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_scan_jt_no_inventory(job_template_factory):
|
||||
# A user should be able to create a scan job without a project, but an inventory is required
|
||||
objects = job_template_factory('jt',
|
||||
credential='c',
|
||||
job_type="scan",
|
||||
project='p',
|
||||
inventory='i',
|
||||
organization='o')
|
||||
serializer = JobTemplateSerializer(data={"name": "Test", "job_type": "scan",
|
||||
"project": None, "inventory": objects.inventory.pk})
|
||||
assert serializer.is_valid()
|
||||
serializer = JobTemplateSerializer(data={"name": "Test", "job_type": "scan",
|
||||
"project": None, "inventory": None})
|
||||
assert not serializer.is_valid()
|
||||
assert "inventory" in serializer.errors
|
||||
serializer = JobTemplateSerializer(data={"name": "Test", "job_type": "scan",
|
||||
"project": None, "inventory": None,
|
||||
"ask_inventory_on_launch": True})
|
||||
assert not serializer.is_valid()
|
||||
assert "inventory" in serializer.errors
|
||||
|
||||
# A user shouldn't be able to launch a scan job template which is missing an inventory
|
||||
obj_jt = objects.job_template
|
||||
obj_jt.inventory = None
|
||||
serializer = JobLaunchSerializer(instance=obj_jt,
|
||||
context={'obj': obj_jt,
|
||||
"data": {}},
|
||||
data={})
|
||||
assert not serializer.is_valid()
|
||||
assert 'inventory' in serializer.errors
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_scan_jt_surveys(inventory):
|
||||
serializer = JobTemplateSerializer(data={"name": "Test", "job_type": "scan",
|
||||
"project": None, "inventory": inventory.pk,
|
||||
"survey_enabled": True})
|
||||
assert not serializer.is_valid()
|
||||
assert "survey_enabled" in serializer.errors
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_launch_with_pending_deletion_inventory(get, post, organization_factory,
|
||||
job_template_factory, machine_credential,
|
||||
@@ -641,9 +598,6 @@ def test_jt_without_project(inventory):
|
||||
serializer = JobTemplateSerializer(data=data)
|
||||
assert not serializer.is_valid()
|
||||
assert "project" in serializer.errors
|
||||
data["job_type"] = "scan"
|
||||
serializer = JobTemplateSerializer(data=data)
|
||||
assert serializer.is_valid()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -163,12 +163,7 @@ def test_two_organizations(resourced_organization, organizations, user, get):
|
||||
@pytest.mark.django_db
|
||||
def test_scan_JT_counted(resourced_organization, user, get):
|
||||
admin_user = user('admin', True)
|
||||
# Add a scan job template to the org
|
||||
resourced_organization.projects.all()[0].jobtemplates.create(
|
||||
job_type='scan', inventory=resourced_organization.inventories.all()[0],
|
||||
name='scan-job-template')
|
||||
counts_dict = COUNTS_PRIMES
|
||||
counts_dict['job_templates'] += 1
|
||||
|
||||
# Test list view
|
||||
list_response = get(reverse('api:organization_list'), admin_user)
|
||||
@@ -184,7 +179,7 @@ def test_scan_JT_counted(resourced_organization, user, get):
|
||||
@pytest.mark.django_db
|
||||
def test_JT_not_double_counted(resourced_organization, user, get):
|
||||
admin_user = user('admin', True)
|
||||
# Add a scan job template to the org
|
||||
# Add a run job template to the org
|
||||
resourced_organization.projects.all()[0].jobtemplates.create(
|
||||
job_type='run',
|
||||
inventory=resourced_organization.inventories.all()[0],
|
||||
|
||||
100
awx/main/tests/functional/test_scan_jobs_migration.py
Normal file
100
awx/main/tests/functional/test_scan_jobs_migration.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2017 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
import pytest
|
||||
|
||||
from django.apps import apps
|
||||
|
||||
from awx.main.models.base import PERM_INVENTORY_SCAN, PERM_INVENTORY_DEPLOY
|
||||
from awx.main.models import (
|
||||
JobTemplate,
|
||||
Project,
|
||||
Inventory,
|
||||
Organization,
|
||||
)
|
||||
|
||||
from awx.main.migrations._scan_jobs import _migrate_scan_job_templates
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def organizations():
|
||||
return [Organization.objects.create(name="org-{}".format(x)) for x in range(3)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def inventories(organizations):
|
||||
return [Inventory.objects.create(name="inv-{}".format(x),
|
||||
organization=organizations[x]) for x in range(3)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def job_templates_scan(inventories):
|
||||
return [JobTemplate.objects.create(name="jt-scan-{}".format(x),
|
||||
job_type=PERM_INVENTORY_SCAN,
|
||||
inventory=inventories[x]) for x in range(3)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def job_templates_deploy(inventories):
|
||||
return [JobTemplate.objects.create(name="jt-deploy-{}".format(x),
|
||||
job_type=PERM_INVENTORY_DEPLOY,
|
||||
inventory=inventories[x]) for x in range(3)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def project_custom(organizations):
|
||||
return Project.objects.create(name="proj-scan_custom",
|
||||
scm_url='https://giggity.com',
|
||||
organization=organizations[0])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def job_templates_custom_scan_project(project_custom):
|
||||
return [JobTemplate.objects.create(name="jt-scan-custom-{}".format(x),
|
||||
project=project_custom,
|
||||
job_type=PERM_INVENTORY_SCAN) for x in range(3)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def job_template_scan_no_org():
|
||||
return JobTemplate.objects.create(name="jt-scan-no-org",
|
||||
job_type=PERM_INVENTORY_SCAN)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_scan_jobs_migration(job_templates_scan, job_templates_deploy, job_templates_custom_scan_project, project_custom, job_template_scan_no_org):
|
||||
_migrate_scan_job_templates(apps)
|
||||
|
||||
# Ensure there are no scan job templates after the migration
|
||||
assert 0 == JobTemplate.objects.filter(job_type=PERM_INVENTORY_SCAN).count()
|
||||
|
||||
# Ensure special No Organization proj created
|
||||
# And No Organization project is associated with correct jt
|
||||
proj = Project.objects.get(name="Tower Fact Scan - No Organization")
|
||||
assert proj.id == JobTemplate.objects.get(id=job_template_scan_no_org.id).project.id
|
||||
|
||||
# Ensure per-org projects were created
|
||||
projs = Project.objects.filter(name__startswith="Tower Fact Scan")
|
||||
assert projs.count() == 4
|
||||
|
||||
# Ensure scan job templates with Tower project are migrated
|
||||
for i, jt_old in enumerate(job_templates_scan):
|
||||
jt = JobTemplate.objects.get(id=jt_old.id)
|
||||
assert PERM_INVENTORY_DEPLOY == jt.job_type
|
||||
assert jt.use_fact_cache is True
|
||||
assert projs[i] == jt.project
|
||||
|
||||
# Ensure scan job templates with custom projects are migrated
|
||||
for jt_old in job_templates_custom_scan_project:
|
||||
jt = JobTemplate.objects.get(id=jt_old.id)
|
||||
assert PERM_INVENTORY_DEPLOY == jt.job_type
|
||||
assert jt.use_fact_cache is True
|
||||
assert project_custom == jt.project
|
||||
|
||||
# Ensure other job template aren't touched
|
||||
for jt_old in job_templates_deploy:
|
||||
jt = JobTemplate.objects.get(id=jt_old.id)
|
||||
assert PERM_INVENTORY_DEPLOY == jt.job_type
|
||||
assert jt.project is None
|
||||
|
||||
@@ -8,6 +8,7 @@ from awx.main.models import (
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import base64
|
||||
from dateutil.tz import tzutc
|
||||
|
||||
|
||||
@@ -89,8 +90,8 @@ def test_start_job_fact_cache(hosts, job, inventory, mocker):
|
||||
|
||||
job._get_memcache_connection().set.assert_any_call('5', [h.name for h in hosts])
|
||||
for host in hosts:
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}'.format(5, host.name), json.dumps(host.ansible_facts))
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}-modified'.format(5, host.name), host.ansible_facts_modified.isoformat())
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}'.format(5, base64.b64encode(host.name)), json.dumps(host.ansible_facts))
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}-modified'.format(5, base64.b64encode(host.name)), host.ansible_facts_modified.isoformat())
|
||||
|
||||
|
||||
def test_start_job_fact_cache_existing_host(hosts, hosts2, job, job2, inventory, mocker):
|
||||
@@ -98,15 +99,15 @@ def test_start_job_fact_cache_existing_host(hosts, hosts2, job, job2, inventory,
|
||||
job.start_job_fact_cache()
|
||||
|
||||
for host in hosts:
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}'.format(5, host.name), json.dumps(host.ansible_facts))
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}-modified'.format(5, host.name), host.ansible_facts_modified.isoformat())
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}'.format(5, base64.b64encode(host.name)), json.dumps(host.ansible_facts))
|
||||
job._get_memcache_connection().set.assert_any_call('{}-{}-modified'.format(5, base64.b64encode(host.name)), host.ansible_facts_modified.isoformat())
|
||||
|
||||
job._get_memcache_connection().set.reset_mock()
|
||||
|
||||
job2.start_job_fact_cache()
|
||||
|
||||
# Ensure hosts2 ansible_facts didn't overwrite hosts ansible_facts
|
||||
ansible_facts_cached = job._get_memcache_connection().get('{}-{}'.format(5, hosts2[0].name))
|
||||
ansible_facts_cached = job._get_memcache_connection().get('{}-{}'.format(5, base64.b64encode(hosts2[0].name)))
|
||||
assert ansible_facts_cached == json.dumps(hosts[1].ansible_facts)
|
||||
|
||||
|
||||
|
||||
@@ -242,11 +242,3 @@ class TestWorkflowWarnings:
|
||||
assert 'credential' in job_node_with_prompts.get_prompts_warnings()['ignored']
|
||||
assert len(job_node_with_prompts.get_prompts_warnings()['ignored']) == 2
|
||||
|
||||
def test_warn_scan_errors_node_prompts(self, job_node_with_prompts):
|
||||
job_node_with_prompts.unified_job_template.job_type = 'scan'
|
||||
job_node_with_prompts.char_prompts['job_type'] = 'run'
|
||||
job_node_with_prompts.inventory = Inventory(name='different-inventory', pk=23)
|
||||
assert 'ignored' in job_node_with_prompts.get_prompts_warnings()
|
||||
assert 'job_type' in job_node_with_prompts.get_prompts_warnings()['ignored']
|
||||
assert 'inventory' in job_node_with_prompts.get_prompts_warnings()['ignored']
|
||||
assert len(job_node_with_prompts.get_prompts_warnings()['ignored']) == 2
|
||||
|
||||
Reference in New Issue
Block a user