mirror of
https://github.com/ansible/awx.git
synced 2026-02-24 06:26:00 -03:30
Adding awx_ as well as tower_ variable names for webhooks (#11925)
Adding utility to ease testing webhooks from command line Modifying all variables to use a constants list of variable names
This commit is contained in:
@@ -16,7 +16,7 @@ from awx.api import serializers
|
||||
from awx.api.generics import APIView, GenericAPIView
|
||||
from awx.api.permissions import WebhookKeyPermission
|
||||
from awx.main.models import Job, JobTemplate, WorkflowJob, WorkflowJobTemplate
|
||||
|
||||
from awx.main.constants import JOB_VARIABLE_PREFIXES
|
||||
|
||||
logger = logging.getLogger('awx.api.views.webhooks')
|
||||
|
||||
@@ -136,15 +136,16 @@ class WebhookReceiverBase(APIView):
|
||||
'webhook_credential': obj.webhook_credential,
|
||||
'webhook_guid': event_guid,
|
||||
},
|
||||
'extra_vars': {
|
||||
'tower_webhook_event_type': event_type,
|
||||
'tower_webhook_event_guid': event_guid,
|
||||
'tower_webhook_event_ref': event_ref,
|
||||
'tower_webhook_status_api': status_api,
|
||||
'tower_webhook_payload': request.data,
|
||||
},
|
||||
'extra_vars': {},
|
||||
}
|
||||
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
kwargs['extra_vars']['{}_webhook_event_type'.format(name)] = event_type
|
||||
kwargs['extra_vars']['{}_webhook_event_guid'.format(name)] = event_guid
|
||||
kwargs['extra_vars']['{}_webhook_event_ref'.format(name)] = event_ref
|
||||
kwargs['extra_vars']['{}_webhook_status_api'.format(name)] = status_api
|
||||
kwargs['extra_vars']['{}_webhook_payload'.format(name)] = request.data
|
||||
|
||||
new_job = obj.create_unified_job(**kwargs)
|
||||
new_job.signal_start()
|
||||
|
||||
|
||||
@@ -95,3 +95,8 @@ CONTAINER_VOLUMES_MOUNT_TYPES = ['z', 'O', 'ro', 'rw']
|
||||
MAX_ISOLATED_PATH_COLON_DELIMITER = 2
|
||||
|
||||
SURVEY_TYPE_MAPPING = {'text': str, 'textarea': str, 'password': str, 'multiplechoice': str, 'multiselect': str, 'integer': int, 'float': (float, int)}
|
||||
|
||||
JOB_VARIABLE_PREFIXES = [
|
||||
'awx',
|
||||
'tower',
|
||||
]
|
||||
|
||||
@@ -55,6 +55,7 @@ from awx.main.models.mixins import (
|
||||
WebhookMixin,
|
||||
WebhookTemplateMixin,
|
||||
)
|
||||
from awx.main.constants import JOB_VARIABLE_PREFIXES
|
||||
|
||||
|
||||
logger = logging.getLogger('awx.main.models.jobs')
|
||||
@@ -770,14 +771,14 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
|
||||
def awx_meta_vars(self):
|
||||
r = super(Job, self).awx_meta_vars()
|
||||
if self.project:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_project_revision'.format(name)] = self.project.scm_revision
|
||||
r['{}_project_scm_branch'.format(name)] = self.project.scm_branch
|
||||
if self.scm_branch:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_job_scm_branch'.format(name)] = self.scm_branch
|
||||
if self.job_template:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_job_template_id'.format(name)] = self.job_template.pk
|
||||
r['{}_job_template_name'.format(name)] = self.job_template.name
|
||||
return r
|
||||
|
||||
@@ -583,7 +583,7 @@ class WebhookMixin(models.Model):
|
||||
if not self.webhook_credential:
|
||||
return
|
||||
|
||||
status_api = self.extra_vars_dict.get('tower_webhook_status_api')
|
||||
status_api = self.extra_vars_dict.get('awx_webhook_status_api')
|
||||
if not status_api:
|
||||
logger.debug("Webhook event did not have a status API endpoint associated, skipping.")
|
||||
return
|
||||
|
||||
@@ -51,7 +51,7 @@ from awx.main.utils.common import (
|
||||
)
|
||||
from awx.main.utils.encryption import encrypt_dict, decrypt_field
|
||||
from awx.main.utils import polymorphic
|
||||
from awx.main.constants import ACTIVE_STATES, CAN_CANCEL
|
||||
from awx.main.constants import ACTIVE_STATES, CAN_CANCEL, JOB_VARIABLE_PREFIXES
|
||||
from awx.main.redact import UriCleaner, REPLACE_STR
|
||||
from awx.main.consumers import emit_channel_notification
|
||||
from awx.main.fields import AskForField, OrderedManyToManyField
|
||||
@@ -1450,7 +1450,7 @@ class UnifiedJob(
|
||||
by AWX, for purposes of client playbook hooks
|
||||
"""
|
||||
r = {}
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_job_id'.format(name)] = self.pk
|
||||
r['{}_job_launch_type'.format(name)] = self.launch_type
|
||||
|
||||
@@ -1459,7 +1459,7 @@ class UnifiedJob(
|
||||
wj = self.get_workflow_job()
|
||||
if wj:
|
||||
schedule = getattr_dne(wj, 'schedule')
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_workflow_job_id'.format(name)] = wj.pk
|
||||
r['{}_workflow_job_name'.format(name)] = wj.name
|
||||
r['{}_workflow_job_launch_type'.format(name)] = wj.launch_type
|
||||
@@ -1470,12 +1470,12 @@ class UnifiedJob(
|
||||
if not created_by:
|
||||
schedule = getattr_dne(self, 'schedule')
|
||||
if schedule:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_schedule_id'.format(name)] = schedule.pk
|
||||
r['{}_schedule_name'.format(name)] = schedule.name
|
||||
|
||||
if created_by:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_user_id'.format(name)] = created_by.pk
|
||||
r['{}_user_name'.format(name)] = created_by.username
|
||||
r['{}_user_email'.format(name)] = created_by.email
|
||||
@@ -1484,7 +1484,7 @@ class UnifiedJob(
|
||||
|
||||
inventory = getattr_dne(self, 'inventory')
|
||||
if inventory:
|
||||
for name in ('awx', 'tower'):
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_inventory_id'.format(name)] = inventory.pk
|
||||
r['{}_inventory_name'.format(name)] = inventory.name
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.contrib.contenttypes.models import ContentType
|
||||
# AWX
|
||||
from awx.main.models import UnifiedJobTemplate, Job, JobTemplate, WorkflowJobTemplate, WorkflowApprovalTemplate, Project, WorkflowJob, Schedule, Credential
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.constants import JOB_VARIABLE_PREFIXES
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -125,17 +126,19 @@ class TestMetaVars:
|
||||
|
||||
workflow_job.workflow_nodes.create(job=job)
|
||||
data = job.awx_meta_vars()
|
||||
assert data['awx_user_id'] == admin_user.id
|
||||
assert data['awx_user_name'] == admin_user.username
|
||||
assert data['awx_workflow_job_id'] == workflow_job.pk
|
||||
assert data['awx_workflow_job_launch_type'] == workflow_job.launch_type
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
assert data['{}_user_id'.format(name)] == admin_user.id
|
||||
assert data['{}_user_name'.format(name)] == admin_user.username
|
||||
assert data['{}_workflow_job_id'.format(name)] == workflow_job.pk
|
||||
assert data['{}_workflow_job_launch_type'.format(name)] == workflow_job.launch_type
|
||||
|
||||
def test_scheduled_job_metavars(self, job_template, admin_user):
|
||||
schedule = Schedule.objects.create(name='job-schedule', rrule='DTSTART:20171129T155939z\nFREQ=MONTHLY', unified_job_template=job_template)
|
||||
job = Job.objects.create(name='fake-job', launch_type='workflow', schedule=schedule, job_template=job_template)
|
||||
data = job.awx_meta_vars()
|
||||
assert data['awx_schedule_id'] == schedule.pk
|
||||
assert 'awx_user_name' not in data
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
assert data['{}_schedule_id'.format(name)] == schedule.pk
|
||||
assert '{}_user_name'.format(name) not in data
|
||||
|
||||
def test_scheduled_workflow_job_node_metavars(self, workflow_job_template):
|
||||
schedule = Schedule.objects.create(name='job-schedule', rrule='DTSTART:20171129T155939z\nFREQ=MONTHLY', unified_job_template=workflow_job_template)
|
||||
@@ -144,22 +147,16 @@ class TestMetaVars:
|
||||
|
||||
job = Job.objects.create(launch_type='workflow')
|
||||
workflow_job.workflow_nodes.create(job=job)
|
||||
assert job.awx_meta_vars() == {
|
||||
'awx_job_id': job.id,
|
||||
'tower_job_id': job.id,
|
||||
'awx_job_launch_type': 'workflow',
|
||||
'tower_job_launch_type': 'workflow',
|
||||
'awx_workflow_job_name': 'workflow-job',
|
||||
'tower_workflow_job_name': 'workflow-job',
|
||||
'awx_workflow_job_id': workflow_job.id,
|
||||
'tower_workflow_job_id': workflow_job.id,
|
||||
'awx_workflow_job_launch_type': workflow_job.launch_type,
|
||||
'tower_workflow_job_launch_type': workflow_job.launch_type,
|
||||
'awx_parent_job_schedule_id': schedule.id,
|
||||
'tower_parent_job_schedule_id': schedule.id,
|
||||
'awx_parent_job_schedule_name': 'job-schedule',
|
||||
'tower_parent_job_schedule_name': 'job-schedule',
|
||||
}
|
||||
result_hash = {}
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
result_hash['{}_job_id'.format(name)] = job.id
|
||||
result_hash['{}_job_launch_type'.format(name)] = 'workflow'
|
||||
result_hash['{}_workflow_job_name'.format(name)] = 'workflow-job'
|
||||
result_hash['{}_workflow_job_id'.format(name)] = workflow_job.id
|
||||
result_hash['{}_workflow_job_launch_type'.format(name)] = workflow_job.launch_type
|
||||
result_hash['{}_parent_job_schedule_id'.format(name)] = schedule.id
|
||||
result_hash['{}_parent_job_schedule_name'.format(name)] = 'job-schedule'
|
||||
assert job.awx_meta_vars() == result_hash
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -2,6 +2,7 @@ import pytest
|
||||
from unittest import mock
|
||||
|
||||
from awx.main.models import UnifiedJob, UnifiedJobTemplate, WorkflowJob, WorkflowJobNode, WorkflowApprovalTemplate, Job, User, Project, JobTemplate, Inventory
|
||||
from awx.main.constants import JOB_VARIABLE_PREFIXES
|
||||
|
||||
|
||||
def test_incorrectly_formatted_variables():
|
||||
@@ -83,26 +84,18 @@ class TestMetaVars:
|
||||
def test_job_metavars(self):
|
||||
maker = User(username='joe', pk=47, id=47)
|
||||
inv = Inventory(name='example-inv', id=45)
|
||||
assert Job(name='fake-job', pk=42, id=42, launch_type='manual', created_by=maker, inventory=inv).awx_meta_vars() == {
|
||||
'tower_job_id': 42,
|
||||
'awx_job_id': 42,
|
||||
'tower_job_launch_type': 'manual',
|
||||
'awx_job_launch_type': 'manual',
|
||||
'awx_user_name': 'joe',
|
||||
'tower_user_name': 'joe',
|
||||
'awx_user_email': '',
|
||||
'tower_user_email': '',
|
||||
'awx_user_first_name': '',
|
||||
'tower_user_first_name': '',
|
||||
'awx_user_last_name': '',
|
||||
'tower_user_last_name': '',
|
||||
'awx_user_id': 47,
|
||||
'tower_user_id': 47,
|
||||
'tower_inventory_id': 45,
|
||||
'awx_inventory_id': 45,
|
||||
'tower_inventory_name': 'example-inv',
|
||||
'awx_inventory_name': 'example-inv',
|
||||
}
|
||||
result_hash = {}
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
result_hash['{}_job_id'.format(name)] = 42
|
||||
result_hash['{}_job_launch_type'.format(name)] = 'manual'
|
||||
result_hash['{}_user_name'.format(name)] = 'joe'
|
||||
result_hash['{}_user_email'.format(name)] = ''
|
||||
result_hash['{}_user_first_name'.format(name)] = ''
|
||||
result_hash['{}_user_last_name'.format(name)] = ''
|
||||
result_hash['{}_user_id'.format(name)] = 47
|
||||
result_hash['{}_inventory_id'.format(name)] = 45
|
||||
result_hash['{}_inventory_name'.format(name)] = 'example-inv'
|
||||
assert Job(name='fake-job', pk=42, id=42, launch_type='manual', created_by=maker, inventory=inv).awx_meta_vars() == result_hash
|
||||
|
||||
def test_project_update_metavars(self):
|
||||
data = Job(
|
||||
@@ -113,7 +106,8 @@ class TestMetaVars:
|
||||
project=Project(name='jobs-sync', scm_revision='12345444'),
|
||||
job_template=JobTemplate(name='jobs-jt', id=92, pk=92),
|
||||
).awx_meta_vars()
|
||||
assert data['awx_project_revision'] == '12345444'
|
||||
assert 'tower_job_template_id' in data
|
||||
assert data['tower_job_template_id'] == 92
|
||||
assert data['tower_job_template_name'] == 'jobs-jt'
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
assert data['{}_project_revision'.format(name)] == '12345444'
|
||||
assert '{}_job_template_id'.format(name) in data
|
||||
assert data['{}_job_template_id'.format(name)] == 92
|
||||
assert data['{}_job_template_name'.format(name)] == 'jobs-jt'
|
||||
|
||||
@@ -39,6 +39,7 @@ from awx.main.utils.safe_yaml import SafeLoader
|
||||
from awx.main.utils.execution_environments import CONTAINER_ROOT, to_host_path
|
||||
|
||||
from awx.main.utils.licensing import Licenser
|
||||
from awx.main.constants import JOB_VARIABLE_PREFIXES
|
||||
|
||||
|
||||
class TestJobExecution(object):
|
||||
@@ -363,32 +364,14 @@ class TestExtraVarSanitation(TestJobExecution):
|
||||
extra_vars = yaml.load(fd, Loader=SafeLoader)
|
||||
|
||||
# ensure that strings are marked as unsafe
|
||||
for unsafe in [
|
||||
'awx_job_template_name',
|
||||
'tower_job_template_name',
|
||||
'awx_user_name',
|
||||
'tower_job_launch_type',
|
||||
'awx_project_revision',
|
||||
'tower_project_revision',
|
||||
'tower_user_name',
|
||||
'awx_job_launch_type',
|
||||
'awx_inventory_name',
|
||||
'tower_inventory_name',
|
||||
]:
|
||||
assert hasattr(extra_vars[unsafe], '__UNSAFE__')
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
for variable_name in ['_job_template_name', '_user_name', '_job_launch_type', '_project_revision', '_inventory_name']:
|
||||
assert hasattr(extra_vars['{}{}'.format(name, variable_name)], '__UNSAFE__')
|
||||
|
||||
# ensure that non-strings are marked as safe
|
||||
for safe in [
|
||||
'awx_job_template_id',
|
||||
'awx_job_id',
|
||||
'awx_user_id',
|
||||
'tower_user_id',
|
||||
'tower_job_template_id',
|
||||
'tower_job_id',
|
||||
'awx_inventory_id',
|
||||
'tower_inventory_id',
|
||||
]:
|
||||
assert not hasattr(extra_vars[safe], '__UNSAFE__')
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
for variable_name in ['_job_template_id', '_job_id', '_user_id', '_inventory_id']:
|
||||
assert not hasattr(extra_vars['{}{}'.format(name, variable_name)], '__UNSAFE__')
|
||||
|
||||
def test_launchtime_vars_unsafe(self, job, private_data_dir, mock_me):
|
||||
job.extra_vars = json.dumps({'msg': self.UNSAFE})
|
||||
@@ -552,10 +535,9 @@ class TestGenericRun:
|
||||
call_args, _ = task._write_extra_vars_file.call_args_list[0]
|
||||
|
||||
private_data_dir, extra_vars, safe_dict = call_args
|
||||
assert extra_vars['tower_user_id'] == 123
|
||||
assert extra_vars['tower_user_name'] == "angry-spud"
|
||||
assert extra_vars['awx_user_id'] == 123
|
||||
assert extra_vars['awx_user_name'] == "angry-spud"
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
assert extra_vars['{}_user_id'.format(name)] == 123
|
||||
assert extra_vars['{}_user_name'.format(name)] == "angry-spud"
|
||||
|
||||
def test_survey_extra_vars(self, mock_me):
|
||||
job = Job()
|
||||
@@ -640,10 +622,9 @@ class TestAdhocRun(TestJobExecution):
|
||||
call_args, _ = task._write_extra_vars_file.call_args_list[0]
|
||||
|
||||
private_data_dir, extra_vars = call_args
|
||||
assert extra_vars['tower_user_id'] == 123
|
||||
assert extra_vars['tower_user_name'] == "angry-spud"
|
||||
assert extra_vars['awx_user_id'] == 123
|
||||
assert extra_vars['awx_user_name'] == "angry-spud"
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
assert extra_vars['{}_user_id'.format(name)] == 123
|
||||
assert extra_vars['{}_user_name'.format(name)] == "angry-spud"
|
||||
|
||||
|
||||
class TestJobCredentials(TestJobExecution):
|
||||
|
||||
Reference in New Issue
Block a user