Add a periodic administrative notification

This commit is contained in:
Matthew Jones
2016-02-23 10:59:08 -05:00
parent ab3669efa9
commit 4928badd3f
3 changed files with 39 additions and 6 deletions

View File

@@ -21,13 +21,11 @@ class WebhookBackend(TowerBaseEmailBackend):
super(WebhookBackend, self).__init__(fail_silently=fail_silently) super(WebhookBackend, self).__init__(fail_silently=fail_silently)
def format_body(self, body): def format_body(self, body):
logger.error("Generating body from {}".format(str(body)))
return body return body
def send_messages(self, messages): def send_messages(self, messages):
sent_messages = 0 sent_messages = 0
for m in messages: for m in messages:
logger.error("BODY: " + str(m.body))
r = requests.post("{}".format(m.recipients()[0]), r = requests.post("{}".format(m.recipients()[0]),
data=json.dumps(m.body), data=json.dumps(m.body),
headers=self.headers) headers=self.headers)

View File

@@ -39,6 +39,8 @@ from celery import Task, task
from django.conf import settings from django.conf import settings
from django.db import transaction, DatabaseError from django.db import transaction, DatabaseError
from django.utils.timezone import now from django.utils.timezone import now
from django.core.mail import send_mail
from django.contrib.auth.models import User
# AWX # AWX
from awx.lib.metrics import task_timer from awx.lib.metrics import task_timer
@@ -46,6 +48,7 @@ from awx.main.constants import CLOUD_PROVIDERS
from awx.main.models import * # noqa from awx.main.models import * # noqa
from awx.main.queue import FifoQueue from awx.main.queue import FifoQueue
from awx.main.conf import tower_settings from awx.main.conf import tower_settings
from awx.main.task_engine import TaskSerializer, TASK_TIMEOUT_INTERVAL
from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url, from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url,
ignore_inventory_computed_fields, emit_websocket_notification, ignore_inventory_computed_fields, emit_websocket_notification,
check_proot_installed, build_proot_temp_dir, wrap_args_with_proot) check_proot_installed, build_proot_temp_dir, wrap_args_with_proot)
@@ -53,7 +56,7 @@ from awx.fact.utils.connection import test_mongo_connection
__all__ = ['RunJob', 'RunSystemJob', 'RunProjectUpdate', 'RunInventoryUpdate', __all__ = ['RunJob', 'RunSystemJob', 'RunProjectUpdate', 'RunInventoryUpdate',
'RunAdHocCommand', 'handle_work_error', 'handle_work_success', 'RunAdHocCommand', 'handle_work_error', 'handle_work_success',
'update_inventory_computed_fields', 'send_notifications'] 'update_inventory_computed_fields', 'send_notifications', 'run_administrative_checks']
HIDDEN_PASSWORD = '**********' HIDDEN_PASSWORD = '**********'
@@ -69,6 +72,8 @@ logger = logging.getLogger('awx.main.tasks')
def send_notifications(notification_list, job_id=None): def send_notifications(notification_list, job_id=None):
if not isinstance(notification_list, list): if not isinstance(notification_list, list):
raise TypeError("notification_list should be of type list") raise TypeError("notification_list should be of type list")
if job_id is not None:
job_actual = UnifiedJob.objects.get(id=job_id)
for notification_id in notification_list: for notification_id in notification_list:
notification = Notification.objects.get(id=notification_id) notification = Notification.objects.get(id=notification_id)
try: try:
@@ -82,8 +87,26 @@ def send_notifications(notification_list, job_id=None):
finally: finally:
notification.save() notification.save()
if job_id is not None: if job_id is not None:
j = UnifiedJob.objects.get(id=job_id) job_actual.notifications.add(notification)
j.notifications.add(notification)
@task(bind=True)
def run_administrative_checks(self):
if not tower_settings.TOWER_ADMIN_ALERTS:
return
reader = TaskSerializer()
validation_info = reader.from_database()
used_percentage = validation_info.get('current_instances',0) / validation_info.get('instance_count', 100)
tower_admin_emails = User.objects.filter(is_superuser=True).values_list('email', flat=True)
if (used_percentage * 100) > 90:
send_mail("Ansible Tower host usage over 90%",
"Ansible Tower host usage over 90%",
tower_admin_emails,
fail_silently=True)
if validation_info.get('time_remaining', 0) < TASK_TIMEOUT_INTERVAL:
send_mail("Ansible Tower license will expire soon",
"Ansible Tower license will expire soon",
tower_admin_emails,
fail_silently=True)
@task() @task()
def bulk_inventory_element_delete(inventory, hosts=[], groups=[]): def bulk_inventory_element_delete(inventory, hosts=[], groups=[]):
@@ -155,7 +178,6 @@ def notify_task_runner(metadata_dict):
queue = FifoQueue('tower_task_manager') queue = FifoQueue('tower_task_manager')
queue.push(metadata_dict) queue.push(metadata_dict)
@task() @task()
def mongodb_control(cmd): def mongodb_control(cmd):
# Sanity check: Do not send arbitrary commands. # Sanity check: Do not send arbitrary commands.

View File

@@ -341,6 +341,10 @@ CELERYBEAT_SCHEDULE = {
'task': 'awx.main.tasks.tower_periodic_scheduler', 'task': 'awx.main.tasks.tower_periodic_scheduler',
'schedule': timedelta(seconds=30) 'schedule': timedelta(seconds=30)
}, },
'admin_checks': {
'task': 'awx.main.tasks.run_administrative_checks',
'schedule': timedelta(days=30)
},
} }
# Social Auth configuration. # Social Auth configuration.
@@ -679,6 +683,8 @@ FACT_CACHE_PORT = 6564
ORG_ADMINS_CAN_SEE_ALL_USERS = True ORG_ADMINS_CAN_SEE_ALL_USERS = True
TOWER_ADMIN_ALERTS = True
TOWER_SETTINGS_MANIFEST = { TOWER_SETTINGS_MANIFEST = {
"SCHEDULE_MAX_JOBS": { "SCHEDULE_MAX_JOBS": {
"name": "Maximum Scheduled Jobs", "name": "Maximum Scheduled Jobs",
@@ -806,6 +812,13 @@ TOWER_SETTINGS_MANIFEST = {
"type": "bool", "type": "bool",
"category": "system", "category": "system",
}, },
"TOWER_ADMIN_ALERTS": {
"name": "Enable Tower Administrator Alerts",
"description": "Allow Tower to email Admin users for system events that may require attention",
"default": TOWER_ADMIN_ALERTS,
"type": "bool",
"category": "system",
},
"LICENSE": { "LICENSE": {
"name": "Tower License", "name": "Tower License",
"description": "Controls what features and functionality is enabled in Tower.", "description": "Controls what features and functionality is enabled in Tower.",