Merge branch 'devel' of github.com:ansible/ansible-tower into rbac

This commit is contained in:
Akita Noek
2016-03-09 12:04:05 -05:00
41 changed files with 998 additions and 264 deletions
@@ -67,7 +67,7 @@ class FactCacheReceiver(object):
self.timestamp = datetime.fromtimestamp(date_key, None)
# Update existing Fact entry
fact_obj = Fact.objects.filter(host__id=host_obj.id, module=module_name, timestamp=self.timestamp)
fact_obj = Fact.objects.filter(host__id=host_obj.id, module=module_name, timestamp=self.timestamp)
if fact_obj:
fact_obj.facts = facts
fact_obj.save()
+115
View File
@@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.utils.timezone import now
from awx.api.license import feature_enabled
def create_system_job_templates(apps, schema_editor):
'''
Create default system job templates if not present. Create default schedules
only if new system job templates were created (i.e. new database).
'''
SystemJobTemplate = apps.get_model('main', 'SystemJobTemplate')
ContentType = apps.get_model('contenttypes', 'ContentType')
sjt_ct = ContentType.objects.get_for_model(SystemJobTemplate)
now_dt = now()
now_str = now_dt.strftime('%Y%m%dT%H%M%SZ')
sjt, created = SystemJobTemplate.objects.get_or_create(
job_type='cleanup_jobs',
defaults=dict(
name='Cleanup Job Details',
description='Remove job history older than X days',
created=now_dt,
modified=now_dt,
polymorphic_ctype=sjt_ct,
),
)
if created:
sjt.schedules.create(
name='Cleanup Job Schedule',
rrule='DTSTART:%s RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU' % now_str,
description='Automatically Generated Schedule',
enabled=True,
extra_data={'days': '120'},
created=now_dt,
modified=now_dt,
)
sjt, created = SystemJobTemplate.objects.get_or_create(
job_type='cleanup_deleted',
defaults=dict(
name='Cleanup Deleted Data',
description='Remove deleted object history older than X days',
created=now_dt,
modified=now_dt,
polymorphic_ctype=sjt_ct,
),
)
if created:
sjt.schedules.create(
name='Cleanup Deleted Data Schedule',
rrule='DTSTART:%s RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO' % now_str,
description='Automatically Generated Schedule',
enabled=True,
extra_data={'days': '30'},
created=now_dt,
modified=now_dt,
)
sjt, created = SystemJobTemplate.objects.get_or_create(
job_type='cleanup_activitystream',
defaults=dict(
name='Cleanup Activity Stream',
description='Remove activity stream history older than X days',
created=now_dt,
modified=now_dt,
polymorphic_ctype=sjt_ct,
),
)
if created:
sjt.schedules.create(
name='Cleanup Activity Schedule',
rrule='DTSTART:%s RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU' % now_str,
description='Automatically Generated Schedule',
enabled=True,
extra_data={'days': '355'},
created=now_dt,
modified=now_dt,
)
sjt, created = SystemJobTemplate.objects.get_or_create(
job_type='cleanup_facts',
defaults=dict(
name='Cleanup Fact Details',
description='Remove system tracking history',
created=now_dt,
modified=now_dt,
polymorphic_ctype=sjt_ct,
),
)
if created and feature_enabled('system_tracking', bypass_database=True):
sjt.schedules.create(
name='Cleanup Fact Schedule',
rrule='DTSTART:%s RRULE:FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1' % now_str,
description='Automatically Generated Schedule',
enabled=True,
extra_data={'older_than': '120d', 'granularity': '1w'},
created=now_dt,
modified=now_dt,
)
class Migration(migrations.Migration):
dependencies = [
('main', '0004_v300_changes'),
]
operations = [
migrations.RunPython(create_system_job_templates, migrations.RunPython.noop),
]
+2 -1
View File
@@ -233,7 +233,8 @@ def handle_work_success(self, result, task_actual):
task_actual['id'],
instance_name,
notification_body['url'])
send_notifications.delay([n.generate_notification(notification_subject, notification_body)
notification_body['friendly_name'] = friendly_name
send_notifications.delay([n.generate_notification(notification_subject, notification_body).id
for n in set(notifiers.get('success', []) + notifiers.get('any', []))],
job_id=task_actual['id'])
+3
View File
@@ -11,6 +11,7 @@ import shutil
import sys
import tempfile
import time
import urllib
from multiprocessing import Process
from subprocess import Popen
import re
@@ -463,6 +464,8 @@ class BaseTestMixin(QueueTestMixin, MockCommonlySlowTestMixin):
response = method(url, json.dumps(data), 'application/json')
elif data_type == 'yaml':
response = method(url, yaml.safe_dump(data), 'application/yaml')
elif data_type == 'form':
response = method(url, urllib.urlencode(data), 'application/x-www-form-urlencoded')
else:
self.fail('Unsupported data_type %s' % data_type)
else:
+23 -8
View File
@@ -803,6 +803,21 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
self.assertEqual(job.hosts.count(), 1)
self.assertEqual(job.hosts.all()[0], host)
# Create the job itself using URL-encoded form data instead of JSON.
result = self.post(url, data, expect=202, remote_addr=host_ip, data_type='form')
# Establish that we got back what we expect, and made the changes
# that we expect.
self.assertTrue('Location' in result.response, result.response)
self.assertEqual(jobs_qs.count(), 2)
job = jobs_qs[0]
self.assertEqual(urlparse.urlsplit(result.response['Location']).path,
job.get_absolute_url())
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name)
self.assertEqual(job.hosts.count(), 1)
self.assertEqual(job.hosts.all()[0], host)
# Run the callback job again with extra vars and verify their presence
data.update(dict(extra_vars=dict(key="value")))
result = self.post(url, data, expect=202, remote_addr=host_ip)
@@ -853,9 +868,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
if host_ip:
break
self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 2)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 3)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 4)
job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name)
@@ -878,9 +893,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
if host_ip:
break
self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 3)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 4)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 5)
job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name)
@@ -892,9 +907,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
host_qs = host_qs.filter(variables__icontains='ansible_ssh_host')
host = host_qs[0]
host_ip = host.variables_dict['ansible_ssh_host']
self.assertEqual(jobs_qs.count(), 4)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 5)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 6)
job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name)
@@ -926,9 +941,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
host_ip = list(ips)[0]
break
self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 5)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 6)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 7)
job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, ':&'.join([job_template.limit, host.name]))