mirror of
https://github.com/ansible/awx.git
synced 2026-03-13 15:09:32 -02:30
AC-504 Capture role when available for job events.
This commit is contained in:
@@ -1328,7 +1328,7 @@ class JobEventSerializer(BaseSerializer):
|
||||
model = JobEvent
|
||||
fields = ('*', '-name', '-description', 'job', 'event',
|
||||
'event_display', 'event_data', 'event_level', 'failed',
|
||||
'changed', 'host', 'parent', 'play', 'task')
|
||||
'changed', 'host', 'parent', 'play', 'task', 'role')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(JobEventSerializer, self).get_related(obj)
|
||||
|
||||
@@ -512,7 +512,7 @@ class JobEvent(CreatedModifiedModel):
|
||||
return reverse('api:job_event_detail', args=(self.pk,))
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s @ %s' % (self.get_event_display(), self.created.isoformat())
|
||||
return u'%s @ %s' % (self.get_event_display2(), self.created.isoformat())
|
||||
|
||||
@property
|
||||
def event_level(self):
|
||||
@@ -521,11 +521,14 @@ class JobEvent(CreatedModifiedModel):
|
||||
def get_event_display2(self):
|
||||
msg = self.get_event_display()
|
||||
if self.event == 'playbook_on_play_start':
|
||||
if self.play is not None:
|
||||
if self.play:
|
||||
msg = "%s (%s)" % (msg, self.play)
|
||||
elif self.event == 'playbook_on_task_start':
|
||||
if self.task is not None:
|
||||
msg = "%s (%s)" % (msg, self.task)
|
||||
if self.task:
|
||||
if self.role:
|
||||
msg = '%s (%s | %s)' % (msg, self.role, self.task)
|
||||
else:
|
||||
msg = "%s (%s)" % (msg, self.task)
|
||||
|
||||
# Change display for runner events trigged by async polling. Some of
|
||||
# these events may not show in most cases, due to filterting them out
|
||||
@@ -637,6 +640,9 @@ class JobEvent(CreatedModifiedModel):
|
||||
self.task = self.event_data.get('task', '').strip()
|
||||
if 'task' not in update_fields:
|
||||
update_fields.append('task')
|
||||
self.role = self.event_data.get('role', '').strip()
|
||||
if 'role' not in update_fields:
|
||||
update_fields.append('role')
|
||||
# Only update job event hierarchy and related models during post
|
||||
# processing (after running job).
|
||||
post_process = kwargs.pop('post_process', False)
|
||||
|
||||
@@ -126,7 +126,7 @@ class BaseTestMixin(object):
|
||||
return results
|
||||
|
||||
def make_project(self, name, description='', created_by=None,
|
||||
playbook_content=''):
|
||||
playbook_content='', role_playbooks=None):
|
||||
if not os.path.exists(settings.PROJECTS_ROOT):
|
||||
os.makedirs(settings.PROJECTS_ROOT)
|
||||
# Create temp project directory.
|
||||
@@ -139,13 +139,24 @@ class BaseTestMixin(object):
|
||||
test_playbook_file = os.fdopen(handle, 'w')
|
||||
test_playbook_file.write(playbook_content)
|
||||
test_playbook_file.close()
|
||||
# Role playbooks are specified as a dict of role name and the
|
||||
# content of tasks/main.yml playbook.
|
||||
role_playbooks = role_playbooks or {}
|
||||
for role_name, role_playbook_content in role_playbooks.items():
|
||||
role_tasks_dir = os.path.join(project_dir, 'roles', role_name, 'tasks')
|
||||
if not os.path.exists(role_tasks_dir):
|
||||
os.makedirs(role_tasks_dir)
|
||||
role_tasks_playbook_path = os.path.join(role_tasks_dir, 'main.yml')
|
||||
with open(role_tasks_playbook_path, 'w') as f:
|
||||
f.write(role_playbook_content)
|
||||
return Project.objects.create(
|
||||
name=name, description=description,
|
||||
local_path=os.path.basename(project_dir), created_by=created_by,
|
||||
#scm_type='git', default_playbook='foo.yml',
|
||||
)
|
||||
|
||||
def make_projects(self, created_by, count=1, playbook_content=''):
|
||||
def make_projects(self, created_by, count=1, playbook_content='',
|
||||
role_playbooks=None):
|
||||
results = []
|
||||
for x in range(0, count):
|
||||
self.object_ctr = self.object_ctr + 1
|
||||
@@ -154,6 +165,7 @@ class BaseTestMixin(object):
|
||||
description="proj%s" % x,
|
||||
created_by=created_by,
|
||||
playbook_content=playbook_content,
|
||||
role_playbooks=role_playbooks,
|
||||
))
|
||||
return results
|
||||
|
||||
|
||||
@@ -88,6 +88,26 @@ TEST_ASYNC_NOWAIT_PLAYBOOK = '''
|
||||
poll: 0
|
||||
'''
|
||||
|
||||
TEST_PLAYBOOK_WITH_ROLES = '''
|
||||
- hosts: test-group
|
||||
gather_facts: false
|
||||
roles:
|
||||
- some_stuff
|
||||
- more_stuff
|
||||
- {role: stuff, tags: stuff}
|
||||
'''
|
||||
|
||||
TEST_ROLE_PLAYBOOK = '''
|
||||
- name: some task in a role
|
||||
command: test 1 = 1
|
||||
'''
|
||||
|
||||
TEST_ROLE_PLAYBOOKS = {
|
||||
'some_stuff': TEST_ROLE_PLAYBOOK,
|
||||
'more_stuff': TEST_ROLE_PLAYBOOK,
|
||||
'stuff': TEST_ROLE_PLAYBOOK,
|
||||
}
|
||||
|
||||
TEST_VAULT_PLAYBOOK = '''$ANSIBLE_VAULT;1.1;AES256
|
||||
35623233333035633365383330323835353564346534363762366465316263363463396162656432
|
||||
6562643539396330616265616532656466353639303338650a313466333663646431646663333739
|
||||
@@ -230,8 +250,9 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.cloud_credential = Credential.objects.create(**opts)
|
||||
return self.cloud_credential
|
||||
|
||||
def create_test_project(self, playbook_content):
|
||||
self.project = self.make_projects(self.normal_django_user, 1, playbook_content)[0]
|
||||
def create_test_project(self, playbook_content, role_playbooks=None):
|
||||
self.project = self.make_projects(self.normal_django_user, 1,
|
||||
playbook_content, role_playbooks)[0]
|
||||
self.organization.projects.add(self.project)
|
||||
|
||||
def create_test_job_template(self, **kwargs):
|
||||
@@ -299,7 +320,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
|
||||
def check_job_events(self, job, runner_status='ok', plays=1, tasks=1,
|
||||
async=False, async_timeout=False, async_nowait=False,
|
||||
check_ignore_errors=False):
|
||||
check_ignore_errors=False, has_roles=False):
|
||||
job_events = job.job_events.all()
|
||||
if False and async:
|
||||
print
|
||||
@@ -323,6 +344,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertFalse(evt.play, evt)
|
||||
self.assertFalse(evt.task, evt)
|
||||
self.assertFalse(evt.role, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
if not async:
|
||||
self.assertEqual(evt.changed, should_be_changed)
|
||||
@@ -335,6 +357,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertFalse(evt.task, evt)
|
||||
self.assertFalse(evt.role, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
if not async:
|
||||
self.assertEqual(evt.changed, should_be_changed)
|
||||
@@ -347,6 +370,10 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertTrue(evt.task, evt)
|
||||
if has_roles:
|
||||
self.assertTrue(evt.role, evt)
|
||||
else:
|
||||
self.assertFalse(evt.role, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
if not async:
|
||||
self.assertEqual(evt.changed, should_be_changed)
|
||||
@@ -367,6 +394,10 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertEqual(evt.host, self.host)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertTrue(evt.task, evt)
|
||||
if has_roles:
|
||||
self.assertTrue(evt.role, evt)
|
||||
else:
|
||||
self.assertFalse(evt.role, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
if not async:
|
||||
self.assertEqual(evt.changed, should_be_changed)
|
||||
@@ -1049,3 +1080,14 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertEqual(job.unreachable_hosts.count(), 0)
|
||||
self.assertEqual(job.skipped_hosts.count(), 0)
|
||||
self.assertEqual(job.processed_hosts.count(), 1)
|
||||
|
||||
def test_run_job_with_roles(self):
|
||||
self.create_test_project(TEST_PLAYBOOK_WITH_ROLES, TEST_ROLE_PLAYBOOKS)
|
||||
job_template = self.create_test_job_template()
|
||||
job = self.create_test_job(job_template=job_template)
|
||||
self.assertEqual(job.status, 'new')
|
||||
self.assertFalse(job.passwords_needed_to_start)
|
||||
self.assertTrue(job.signal_start())
|
||||
job = Job.objects.get(pk=job.pk)
|
||||
self.check_job_result(job, 'successful')
|
||||
self.check_job_events(job, 'ok', 1, 3, has_roles=True)
|
||||
|
||||
@@ -167,12 +167,17 @@ class CallbackModule(object):
|
||||
response.raise_for_status()
|
||||
|
||||
def _log_event(self, event, **event_data):
|
||||
play = getattr(getattr(self, 'play', None), 'name', '')
|
||||
if play and event not in self.EVENTS_WITHOUT_PLAY:
|
||||
event_data['play'] = play
|
||||
task = getattr(getattr(self, 'task', None), 'name', '')
|
||||
if task and event not in self.EVENTS_WITHOUT_TASK:
|
||||
event_data['task'] = task
|
||||
play = getattr(self, 'play', None)
|
||||
play_name = getattr(play, 'name', '')
|
||||
if play_name and event not in self.EVENTS_WITHOUT_PLAY:
|
||||
event_data['play'] = play_name
|
||||
task = getattr(self, 'task', None)
|
||||
task_name = getattr(task, 'name', '')
|
||||
role_name = getattr(task, 'role_name', '')
|
||||
if task_name and event not in self.EVENTS_WITHOUT_TASK:
|
||||
event_data['task'] = task_name
|
||||
if role_name and event not in self.EVENTS_WITHOUT_TASK:
|
||||
event_data['role'] = role_name
|
||||
if self.callback_consumer_port:
|
||||
self._post_job_event_queue_msg(event, event_data)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user