mirror of
https://github.com/ansible/awx.git
synced 2026-05-13 04:17:36 -02:30
add AWX meta extra_vars: WFJT + schedule
This commit is contained in:
@@ -701,6 +701,17 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
|
|||||||
return self.global_instance_groups
|
return self.global_instance_groups
|
||||||
return selected_groups
|
return selected_groups
|
||||||
|
|
||||||
|
def awx_meta_vars(self):
|
||||||
|
r = super(Job, self).awx_meta_vars()
|
||||||
|
if self.project:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_project_revision'.format(name)] = self.project.scm_revision
|
||||||
|
if self.job_template:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_job_template_id'.format(name)] = self.job_template.pk
|
||||||
|
r['{}_job_template_name'.format(name)] = self.job_template.name
|
||||||
|
return r
|
||||||
|
|
||||||
'''
|
'''
|
||||||
JobNotificationMixin
|
JobNotificationMixin
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -854,15 +854,21 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
|||||||
def result_stdout_limited(self, start_line=0, end_line=None, redact_sensitive=False):
|
def result_stdout_limited(self, start_line=0, end_line=None, redact_sensitive=False):
|
||||||
return self._result_stdout_raw_limited(start_line, end_line, redact_sensitive, escape_ascii=True)
|
return self._result_stdout_raw_limited(start_line, end_line, redact_sensitive, escape_ascii=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def workflow_job_id(self):
|
||||||
|
workflow_job = self.get_workflow_job()
|
||||||
|
if workflow_job:
|
||||||
|
return workflow_job.pk
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def spawned_by_workflow(self):
|
def spawned_by_workflow(self):
|
||||||
return self.launch_type == 'workflow'
|
return self.launch_type == 'workflow'
|
||||||
|
|
||||||
@property
|
def get_workflow_job(self):
|
||||||
def workflow_job_id(self):
|
|
||||||
if self.spawned_by_workflow:
|
if self.spawned_by_workflow:
|
||||||
try:
|
try:
|
||||||
return self.unified_job_node.workflow_job.pk
|
return self.unified_job_node.workflow_job
|
||||||
except UnifiedJob.unified_job_node.RelatedObjectDoesNotExist:
|
except UnifiedJob.unified_job_node.RelatedObjectDoesNotExist:
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
@@ -1129,3 +1135,32 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
|||||||
if default_instance_group.exists():
|
if default_instance_group.exists():
|
||||||
return [default_instance_group.first()]
|
return [default_instance_group.first()]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def awx_meta_vars(self):
|
||||||
|
'''
|
||||||
|
The result of this method is used as extra_vars of a job launched
|
||||||
|
by AWX, for purposes of client playbook hooks
|
||||||
|
'''
|
||||||
|
r = {}
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_job_id'.format(name)] = self.pk
|
||||||
|
r['{}_job_launch_type'.format(name)] = self.launch_type
|
||||||
|
if self.created_by:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_user_id'.format(name)] = self.created_by.pk
|
||||||
|
r['{}_user_name'.format(name)] = self.created_by.username
|
||||||
|
else:
|
||||||
|
wj = self.get_workflow_job()
|
||||||
|
if wj:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_workflow_job_id'.format(name)] = wj.pk
|
||||||
|
r['{}_workflow_job_name'.format(name)] = wj.name
|
||||||
|
if wj.created_by:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_user_id'.format(name)] = wj.created_by.pk
|
||||||
|
r['{}_user_name'.format(name)] = wj.created_by.username
|
||||||
|
if self.schedule:
|
||||||
|
for name in ('awx', 'tower'):
|
||||||
|
r['{}_schedule_id'.format(name)] = self.schedule.pk
|
||||||
|
r['{}_schedule_name'.format(name)] = self.schedule.name
|
||||||
|
return r
|
||||||
|
|||||||
@@ -1145,31 +1145,8 @@ class RunJob(BaseTask):
|
|||||||
args.append('--start-at-task=%s' % job.start_at_task)
|
args.append('--start-at-task=%s' % job.start_at_task)
|
||||||
|
|
||||||
# Define special extra_vars for AWX, combine with job.extra_vars.
|
# Define special extra_vars for AWX, combine with job.extra_vars.
|
||||||
extra_vars = {
|
extra_vars = job.awx_meta_vars()
|
||||||
'tower_job_id': job.pk,
|
|
||||||
'tower_job_launch_type': job.launch_type,
|
|
||||||
'awx_job_id': job.pk,
|
|
||||||
'awx_job_launch_type': job.launch_type,
|
|
||||||
}
|
|
||||||
if job.project:
|
|
||||||
extra_vars.update({
|
|
||||||
'tower_project_revision': job.project.scm_revision,
|
|
||||||
'awx_project_revision': job.project.scm_revision,
|
|
||||||
})
|
|
||||||
if job.job_template:
|
|
||||||
extra_vars.update({
|
|
||||||
'tower_job_template_id': job.job_template.pk,
|
|
||||||
'tower_job_template_name': job.job_template.name,
|
|
||||||
'awx_job_template_id': job.job_template.pk,
|
|
||||||
'awx_job_template_name': job.job_template.name,
|
|
||||||
})
|
|
||||||
if job.created_by:
|
|
||||||
extra_vars.update({
|
|
||||||
'tower_user_id': job.created_by.pk,
|
|
||||||
'tower_user_name': job.created_by.username,
|
|
||||||
'awx_user_id': job.created_by.pk,
|
|
||||||
'awx_user_name': job.created_by.username,
|
|
||||||
})
|
|
||||||
if job.extra_vars_dict:
|
if job.extra_vars_dict:
|
||||||
if kwargs.get('display', False) and job.job_template:
|
if kwargs.get('display', False) and job.job_template:
|
||||||
extra_vars.update(json.loads(job.display_extra_vars()))
|
extra_vars.update(json.loads(job.display_extra_vars()))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import mock
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models import UnifiedJobTemplate, Job, JobTemplate, WorkflowJobTemplate, Project
|
from awx.main.models import UnifiedJobTemplate, Job, JobTemplate, WorkflowJobTemplate, Project, WorkflowJob, Schedule
|
||||||
from awx.main.models.ha import InstanceGroup
|
from awx.main.models.ha import InstanceGroup
|
||||||
|
|
||||||
|
|
||||||
@@ -110,3 +110,39 @@ class TestIsolatedRuns:
|
|||||||
link=success_callback,
|
link=success_callback,
|
||||||
queue='thepentagon',
|
queue='thepentagon',
|
||||||
task_id='something')
|
task_id='something')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
class TestMetaVars:
|
||||||
|
'''
|
||||||
|
Extension of unit tests with same class name
|
||||||
|
'''
|
||||||
|
|
||||||
|
def test_workflow_job_metavars(self, admin_user):
|
||||||
|
workflow_job = WorkflowJob.objects.create(
|
||||||
|
name='workflow-job',
|
||||||
|
created_by=admin_user
|
||||||
|
)
|
||||||
|
job = Job.objects.create(
|
||||||
|
name='fake-job',
|
||||||
|
launch_type='workflow'
|
||||||
|
)
|
||||||
|
workflow_job.workflow_nodes.create(job=job)
|
||||||
|
data = job.awx_meta_vars()
|
||||||
|
assert data['awx_user_name'] == admin_user.username
|
||||||
|
assert data['awx_workflow_job_id'] == workflow_job.pk
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ def job(mocker):
|
|||||||
'pk': 1, 'job_template.pk': 1, 'job_template.name': '',
|
'pk': 1, 'job_template.pk': 1, 'job_template.name': '',
|
||||||
'created_by.pk': 1, 'created_by.username': 'admin',
|
'created_by.pk': 1, 'created_by.username': 'admin',
|
||||||
'launch_type': 'manual',
|
'launch_type': 'manual',
|
||||||
|
'awx_meta_vars.return_value': {},
|
||||||
'inventory.get_script_data.return_value': {}})
|
'inventory.get_script_data.return_value': {}})
|
||||||
ret.project = mocker.MagicMock(scm_revision='asdf1234')
|
ret.project = mocker.MagicMock(scm_revision='asdf1234')
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ from awx.main.models import (
|
|||||||
UnifiedJob,
|
UnifiedJob,
|
||||||
WorkflowJob,
|
WorkflowJob,
|
||||||
WorkflowJobNode,
|
WorkflowJobNode,
|
||||||
Job
|
Job,
|
||||||
|
User,
|
||||||
|
Project,
|
||||||
|
JobTemplate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -61,3 +64,45 @@ def test_log_representation():
|
|||||||
assert job.log_format == 'job 4 (running)'
|
assert job.log_format == 'job 4 (running)'
|
||||||
assert uj.log_format == 'unified_job 4 (running)'
|
assert uj.log_format == 'unified_job 4 (running)'
|
||||||
|
|
||||||
|
|
||||||
|
class TestMetaVars:
|
||||||
|
'''
|
||||||
|
Corresponding functional test exists for cases with indirect relationships
|
||||||
|
'''
|
||||||
|
|
||||||
|
def test_job_metavars(self):
|
||||||
|
maker = User(username='joe', pk=47, id=47)
|
||||||
|
assert Job(
|
||||||
|
name='fake-job',
|
||||||
|
pk=42, id=42,
|
||||||
|
launch_type='manual',
|
||||||
|
created_by=maker
|
||||||
|
).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_id': 47,
|
||||||
|
'tower_user_id': 47
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_project_update_metavars(self):
|
||||||
|
data = Job(
|
||||||
|
name='fake-job',
|
||||||
|
pk=40, id=40,
|
||||||
|
launch_type='manual',
|
||||||
|
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'
|
||||||
|
|||||||
Reference in New Issue
Block a user