feat: send_apikey_usage_emails_task() (#7486)
* feat: send_apikey_usage_emails_task * chore: update test to use task instead of cmd * chore: add PeriodicTask * chore: remove old command + empty management dir * chore: remove now-empty bin/weekly * refactor: only consider keys that might have events --------- Co-authored-by: Robert Sparks <rjsparks@nostrum.com>
This commit is contained in:
parent
020bdeb058
commit
2ccc230ce7
22
bin/weekly
22
bin/weekly
|
@ -1,22 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Weekly datatracker jobs.
|
||||
#
|
||||
# This script is expected to be triggered by cron from
|
||||
# /etc/cron.d/datatracker
|
||||
export LANG=en_US.UTF-8
|
||||
export PYTHONIOENCODING=utf-8
|
||||
|
||||
DTDIR=/a/www/ietf-datatracker/web
|
||||
cd $DTDIR/
|
||||
|
||||
# Set up the virtual environment
|
||||
source $DTDIR/env/bin/activate
|
||||
|
||||
logger -p user.info -t cron "Running $DTDIR/bin/weekly"
|
||||
|
||||
|
||||
# Send out weekly summaries of apikey usage
|
||||
|
||||
$DTDIR/ietf/manage.py send_apikey_usage_emails
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
# Copyright The IETF Trust 2017-2020, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.person.models import PersonalApiKey, PersonApiKeyEvent
|
||||
from ietf.utils.mail import send_mail
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
Send out emails to all persons who have personal API keys about usage.
|
||||
|
||||
Usage is show over the given period, where the default period is 7 days.
|
||||
"""
|
||||
|
||||
help = dedent(__doc__).strip()
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('-d', '--days', dest='days', type=int, default=7,
|
||||
help='The period over which to show usage.')
|
||||
|
||||
def handle(self, *filenames, **options):
|
||||
"""
|
||||
"""
|
||||
|
||||
self.verbosity = int(options.get('verbosity'))
|
||||
days = options.get('days')
|
||||
|
||||
keys = PersonalApiKey.objects.filter(valid=True)
|
||||
for key in keys:
|
||||
earliest = timezone.now() - datetime.timedelta(days=days)
|
||||
events = PersonApiKeyEvent.objects.filter(key=key, time__gt=earliest)
|
||||
count = events.count()
|
||||
events = events[:32]
|
||||
if count:
|
||||
key_name = key.hash()[:8]
|
||||
subject = "API key usage for key '%s' for the last %s days" %(key_name, days)
|
||||
to = key.person.email_address()
|
||||
frm = settings.DEFAULT_FROM_EMAIL
|
||||
send_mail(None, to, frm, subject, 'utils/apikey_usage_report.txt', {'person':key.person,
|
||||
'days':days, 'key':key, 'key_name':key_name, 'count':count, 'events':events, } )
|
||||
|
|
@ -41,6 +41,7 @@ from ietf.meeting.factories import MeetingFactory
|
|||
from ietf.nomcom.factories import NomComFactory
|
||||
from ietf.person.factories import PersonFactory, EmailFactory, UserFactory, PersonalApiKeyFactory
|
||||
from ietf.person.models import Person, Email, PersonalApiKey
|
||||
from ietf.person.tasks import send_apikey_usage_emails_task
|
||||
from ietf.review.factories import ReviewRequestFactory, ReviewAssignmentFactory
|
||||
from ietf.review.models import ReviewWish, UnavailablePeriod
|
||||
from ietf.stats.models import MeetingRegistration
|
||||
|
@ -853,9 +854,6 @@ class IetfAuthTests(TestCase):
|
|||
key2.delete()
|
||||
|
||||
def test_send_apikey_report(self):
|
||||
from ietf.ietfauth.management.commands.send_apikey_usage_emails import Command
|
||||
from ietf.utils.mail import outbox, empty_outbox
|
||||
|
||||
person = RoleFactory(name_id='secr', group__acronym='secretariat').person
|
||||
|
||||
url = urlreverse('ietf.ietfauth.views.apikey_create')
|
||||
|
@ -880,9 +878,8 @@ class IetfAuthTests(TestCase):
|
|||
date = str(date_today())
|
||||
|
||||
empty_outbox()
|
||||
cmd = Command()
|
||||
cmd.handle(verbosity=0, days=7)
|
||||
|
||||
send_apikey_usage_emails_task(days=7)
|
||||
|
||||
self.assertEqual(len(outbox), len(endpoints))
|
||||
for mail in outbox:
|
||||
body = get_payload_text(mail)
|
||||
|
|
|
@ -5,12 +5,51 @@
|
|||
import datetime
|
||||
|
||||
from celery import shared_task
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from ietf.utils import log
|
||||
from .models import PersonApiKeyEvent
|
||||
from ietf.utils.mail import send_mail
|
||||
from .models import PersonalApiKey, PersonApiKeyEvent
|
||||
|
||||
|
||||
@shared_task
|
||||
def send_apikey_usage_emails_task(days):
|
||||
"""Send usage emails to Persons who have API keys"""
|
||||
earliest = timezone.now() - datetime.timedelta(days=days)
|
||||
keys = PersonalApiKey.objects.filter(
|
||||
valid=True,
|
||||
personapikeyevent__time__gt=earliest,
|
||||
).distinct()
|
||||
for key in keys:
|
||||
events = PersonApiKeyEvent.objects.filter(key=key, time__gt=earliest)
|
||||
count = events.count()
|
||||
events = events[:32]
|
||||
if count:
|
||||
key_name = key.hash()[:8]
|
||||
subject = "API key usage for key '%s' for the last %s days" % (
|
||||
key_name,
|
||||
days,
|
||||
)
|
||||
to = key.person.email_address()
|
||||
frm = settings.DEFAULT_FROM_EMAIL
|
||||
send_mail(
|
||||
None,
|
||||
to,
|
||||
frm,
|
||||
subject,
|
||||
"utils/apikey_usage_report.txt",
|
||||
{
|
||||
"person": key.person,
|
||||
"days": days,
|
||||
"key": key,
|
||||
"key_name": key_name,
|
||||
"count": count,
|
||||
"events": events,
|
||||
},
|
||||
)
|
||||
|
||||
@shared_task
|
||||
def purge_personal_api_key_events_task(keep_days):
|
||||
keep_since = timezone.now() - datetime.timedelta(days=keep_days)
|
||||
|
|
|
@ -241,6 +241,17 @@ class Command(BaseCommand):
|
|||
),
|
||||
)
|
||||
|
||||
PeriodicTask.objects.get_or_create(
|
||||
name="Send personal API key usage emails",
|
||||
task="ietf.person.tasks.send_apikey_usage_emails_task",
|
||||
kwargs=json.dumps(dict(days=7)),
|
||||
defaults=dict(
|
||||
enabled=False,
|
||||
crontab=self.crontabs["weekly"],
|
||||
description="Send personal API key usage summary emails for the past week",
|
||||
),
|
||||
)
|
||||
|
||||
PeriodicTask.objects.get_or_create(
|
||||
name="Purge old personal API key events",
|
||||
task="ietf.person.tasks.purge_personal_api_key_events_task",
|
||||
|
|
Loading…
Reference in a new issue