Skip to content

Commit

Permalink
feat: Report Waffle changes to Slack webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
timmc-edx committed Oct 23, 2023
1 parent be2d92b commit 07b0e59
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions edx_arch_experiments/config_watcher/signals/receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,57 @@
Call ``connect_receivers`` to initialize.
"""

import html
import json
import logging
import urllib.request

import waffle.models
from django.conf import settings
from django.db.models import signals
from django.dispatch import receiver

log = logging.getLogger(__name__)

# .. setting_name: CONFIG_WATCHER_SLACK_WEBHOOK_URL
# .. setting_default: None
# .. setting_description: Slack webhook URL to send config change events to.
# If not configured, this functionality is disabled.
CONFIG_WATCHER_SLACK_WEBHOOK_URL = getattr(settings, 'CONFIG_WATCHER_SLACK_WEBHOOK_URL', None)


def _send_to_slack(message):
"""Send this message as plain text to the configured Slack channel."""
if not CONFIG_WATCHER_SLACK_WEBHOOK_URL:
return

# https://api.slack.com/reference/surfaces/formatting
body_data = {
'text': html.escape(message, quote=False)
}

req = urllib.request.Request(
url=CONFIG_WATCHER_SLACK_WEBHOOK_URL, data=json.dumps(body_data).encode(),
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=2) as resp:
status = resp.getcode()
if status != 200:
log.error(f"Slack rejected the config watcher message. {status=}, body={resp.read().decode('utf-8')}")

def _report_config_change(message):
log.info(message)
_send_to_slack(message)


def _report_waffle_change(model_short_name, instance, created, fields):
verb = "created" if created else "updated"
state_desc = ", ".join(f"{field}={repr(getattr(instance, field))}" for field in fields)
log.info(f"Waffle {model_short_name} {instance.name!r} was {verb}. New config: {state_desc}")
_report_config_change(f"Waffle {model_short_name} {instance.name!r} was {verb}. New config: {state_desc}")


def _report_waffle_delete(model_short_name, instance):
log.info(f"Waffle {model_short_name} {instance.name!r} was deleted")
_report_config_change(f"Waffle {model_short_name} {instance.name!r} was deleted")


_WAFFLE_MODELS_TO_OBSERVE = [
Expand Down

0 comments on commit 07b0e59

Please sign in to comment.