-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Send email notification when lease starts or ends soon
Closes: #149
- Loading branch information
Showing
1 changed file
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
""" | ||
Description: | ||
This script is designed to query and send email notifications for ESI lease events. | ||
Usage: | ||
To run this script, execute it from CLI or add it to a scheduled task (like cronjob). | ||
Ensure that the necessary environment variables (ENABLE_EMAIL, SMTP_SERVER, EMAIL_SENDER, and LEASE_WARNING_DAYS) are set. | ||
Example: | ||
$ python query_event.py | ||
""" | ||
|
||
import datetime | ||
from email.mime.multipart import MIMEMultipart | ||
from email.mime.text import MIMEText | ||
import json | ||
import os | ||
import subprocess | ||
import smtplib | ||
|
||
|
||
# Defaults to 'false' if not set. Set to 'true' to enable email notifications | ||
enable_email = os.getenv('ENABLE_EMAIL', 'false').lower() == 'true' | ||
# SMTP server address for sending emails. Default is 'localhost' | ||
smtp_server = os.getenv('SMTP_SERVER', 'localhost') | ||
# The email address that will be used as the sender in outgoing emails | ||
email_sender = os.getenv('EMAIL_SENDER') | ||
# The number of days before a lease's end when a notification email should be sent | ||
lease_warning_days = int(os.getenv('LEASE_WARNING_DAYS', 1)) | ||
|
||
|
||
def run_openstack_command(cmd): | ||
output_json = subprocess.check_output('%s --format json' % cmd, shell=True) | ||
return json.loads(output_json) | ||
|
||
def get_last_event_id(default_last_event_id=0, file_name='.esi-last-event-id'): | ||
try: | ||
with open(file_name, "r") as f: | ||
last_event_id = int(f.read()) | ||
except FileNotFoundError: | ||
last_event_id = default_last_event_id | ||
except ValueError: | ||
last_event_id = default_last_event_id | ||
return last_event_id | ||
|
||
def write_last_event_id(last_event_id, file_name='.esi-last-event-id'): | ||
with open(file_name, "w") as f: | ||
f.write(str(last_event_id)) | ||
|
||
def notify_lease(project_name, email_body): | ||
try: | ||
project = run_openstack_command('openstack project show %s' % project_name) | ||
to_email = project.get('email') | ||
if not to_email: | ||
print('No email linked to project %s. ' | ||
'Not sending email notification' % project) | ||
else: | ||
msg = MIMEMultipart() | ||
msg['From'] = email_sender | ||
msg['To'] = to_email | ||
msg['Subject'] = '[ESI]Lease notification' | ||
msg.attach(MIMEText(email_body, 'plain')) | ||
server = smtplib.SMTP(smtp_server) | ||
server.sendmail(email_sender, to_email, | ||
msg.as_string()) | ||
server.quit() | ||
print("Email sent successfully to %s" % to_email) | ||
except Exception as e: | ||
print('Email not sent: %s: %s' % | ||
(type(e).__name__, e)) | ||
|
||
def main(): | ||
last_event_id = get_last_event_id() | ||
events = run_openstack_command('openstack esi event list --last-event-id %s' % last_event_id) | ||
new_last_event_id = last_event_id | ||
for event in events: | ||
new_last_event_id = event['ID'] | ||
if event['Event Type'] == 'esi_leap.lease.fulfill.end': | ||
node_uuid = event['Resource UUID'] | ||
lease_uuid = event['Object UUID'] | ||
lease = run_openstack_command('openstack esi lease show %s' % lease_uuid) | ||
print("Lease %s with purpose %s on node %s started" % (lease_uuid, lease['purpose'], node_uuid)) | ||
if enable_email: | ||
email_body_lease_start = f"Hi {lease['project']}," \ | ||
f"\n\n" \ | ||
f"We would like to inform you that " \ | ||
f"your lease: {lease['uuid']} is fulfilled. " \ | ||
f"Start Time: {lease['start_time']}." \ | ||
f"\n\n" \ | ||
f"Thank you!" \ | ||
f"\n\n" \ | ||
f"ESI Admin Team" | ||
notify_lease(lease['project'], email_body_lease_start) | ||
write_last_event_id(new_last_event_id) | ||
|
||
# Checking for leases expire soon | ||
leases = run_openstack_command('openstack esi lease list') | ||
now = datetime.datetime.utcnow() | ||
for lease in leases: | ||
lease_end = datetime.datetime.strptime(lease["End Time"], "%Y-%m-%dT%H:%M:%S.%f") | ||
if lease_end - now <= datetime.timedelta(lease_warning_days): | ||
print('Lease %s is expiring in %s day(s)' %(lease["UUID"], lease_warning_days)) | ||
if enable_email: | ||
email_body_lease_expire = f"Hi {lease['Project']}," \ | ||
f"\n\n" \ | ||
f"We would like to inform you that" \ | ||
f" your lease: {lease['UUID']} " \ | ||
f"will expire on {lease['End Time']}." \ | ||
f" To ensure " \ | ||
f"the continuity of your data, " \ | ||
f"please take the following steps:" \ | ||
f"\n\n" \ | ||
f"1. Save any important data" \ | ||
f" associated with this resource." \ | ||
f"\n" \ | ||
f"2. If you wish to" \ | ||
f" extend your lease," \ | ||
f" please contact ESI admin team." \ | ||
f"\n\n" \ | ||
f"Thank you!" \ | ||
f"\n\n" \ | ||
f"ESI Admin Team" | ||
notify_lease(lease['Project'], email_body_lease_expire) | ||
|
||
if __name__ == "__main__": | ||
main() |