New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write a script to send emails before koji cert expirations #146
Comments
you need to validate that only the last request is used per user, otherwise there would be unnecessary noise if a user requests two certs within 6 months. |
How about something like this that we can keep in puppet/ansible and run as a weekly cronjob. """ Send emails to Fedora users whose koji certs are about to expire.
We first get a list of Fedora users in the cla_done group. Then we query
datagrepper for the history of when each user last changed their cert. If that
event occurred inside a window (between 5.75 months ago and 6 months ago), then
send them an email letting them know their cert is about to expire.
Requires: python-arrow python-fedora python-requests fedmsg
License: LGPLv2+
Authors: Ralph Bean <rbean@redhat.com>
"""
import arrow
import datetime
import email
import fedmsg
import fedora.client.fas2
import getpass
import smtplib
import requests
# This is a flag used to turn of email to the actual users
DEVELOPMENT = True
datagrepper_url = 'https://apps.fedoraproject.org/datagrepper/raw'
mail_server = 'bastion.fedoraproject.org'
message_template = """{human_name}/{username}:
This is an automated email sent to inform you that your Fedora Project Koji
certificate is about to expire. Koji certificates are valid for 6 months and
our records indicate that you last recreated yours about {change_human}
on {change_date}.
Please run the following command to regenerate your certificate:
$ /usr/bin/fedora-cert -n
For more information, see the following wiki page:
https://fedoraproject.org/wiki/Using_the_Koji_build_system#Fedora_Certificates
"""
# We want to alert users if their cert is going to expire this week.
now = arrow.utcnow()
six_months = 1.57785e7
one_week = 604800
window_delta = one_week
window_max = six_months
window_min = window_max - window_delta
def cert_changes(user):
""" Generator that returns all the koji cert changes for a user.
>>> user = 'ralph'
>>> for change in cert_changes(user):
... print change.humanize(), "on", change.format('YYYY-MM-DD')
21 hours ago on 2014-04-08
2 months ago on 2014-02-09
8 months ago on 2013-08-12
"""
def get_page(page):
params = dict(
rows_per_page=100,
topic='org.fedoraproject.prod.fas.user.update',
user=user,
page=page,
)
return requests.get(datagrepper_url, params=params).json()
data = get_page(1)
pages = data['pages']
for page in range(1, pages + 1):
data = get_page(page)
for message in data['raw_messages']:
if 'certificate' in message['msg']['fields']:
yield arrow.get(message['timestamp'])
def test_cert_changes():
""" Just messing around... """
for user in ['kevin', 'ralph', 'lmacken', 'pingou']:
for change in cert_changes(user):
print user, change.humanize(), "on", change.format('YYYY-MM-DD')
def fedora_users(credentials):
return fedora.client.fas2.AccountSystem(
username=credentials['username'],
password=credentials['password'],
).people_by_groupname('cla_done')
def total_seconds(td):
""" Take a datetime.timedelta object and return the total seconds.
td.total_seconds() exists in the python 2.7 stdlib, but not in python 2.6.
"""
return td.days * 24 * 60 * 60 + td.seconds + td.microseconds / 1000000.0
def to_address(user):
if DEVELOPMENT:
return 'ralph@fedoraproject.org'
else:
return user['email']
def send_email(user, last_change):
print "send an email to %r since they last changed on %r" % (
user, last_change.format('YYYY-MM-DD'))
message = email.Message.Message()
message.add_header('To', to_address(user))
message.add_header('From', 'admin@fedoraproject.org')
subject = 'Your Koji certificate expires within a week'
message.add_header('Subject', subject)
content = message_template.format(
change_human=last_change.humanize(),
change_date=last_change.format('YYYY-MM-DD'),
**user
)
message.set_payload(content)
server = smtplib.SMTP(mail_server)
server.sendmail(
fromaddress.encode('utf-8'),
[to_address(user).encode('utf-8')],
message.as_string().encode('utf-8'),
)
server.quit()
def main(credentials):
print "* Querying FAS for a list of users"
users = fedora_users(credentials)
print "* Found %r people" % len(users)
for user in users:
#print "* Querying datagrepper for %r." % user['username'],
changes = cert_changes(user['username'])
try:
latest = changes.next()
except StopIteration:
# Then the user has no changes in the fedmsg history.
#print "No record of %r changing a cert." % user['username']
continue
print user['username'], "changed", latest.humanize(),
print "on", latest.format('YYYY-MM-DD')
delta = total_seconds(now - latest)
if delta >= window_min and delta <= window_max:
send_email(user, latest)
if __name__ == '__main__':
# Load credentials from /etc/fedmsg.d/
config = fedmsg.config.load_config()
if 'fas_credentials' not in config:
print "No 'fas_credentials' found in `fedmsg-config`..."
username = raw_input("Enter your fas username: ")
password = getpass.getpass("Enter your fas password: ")
config['fas_credentials'] = dict(username=username, password=password)
main(config['fas_credentials']) |
There seems to be an |
Thanks! I fixed the I'm pretty sure the utf-8 encoding works. I took the code from some code I was working on this winter over here. |
|
Is fedora-cert -n documented on the wiki? If so, where? |
Good point, it doesn't seem to be very well documented, the only place I found it is at: http://fedoraproject.org/wiki/Package_update_HOWTO#Build_a_package_for_Rawhide |
Ah found a couple more:
But not in the main pages apparently Sorry, had to finish the exercise :-) |
This can query datanommer for "who got a new cert 6months - 1 week ago".
This depends on #145 being in place first.
The text was updated successfully, but these errors were encountered: