diff --git a/bin/query_events.py b/bin/query_events.py new file mode 100755 index 00000000..d9009e1e --- /dev/null +++ b/bin/query_events.py @@ -0,0 +1,108 @@ +import datetime +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +import json +import os +import subprocess +import smtplib + +enable_email = os.getenv('ENABLE_EMAIL', 'false').lower() == 'true' +smtp_server = os.getenv('SMTP_SERVER', 'localhost') +email_sender = os.getenv('EMAIL_SENDER') +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()