""" This script monitors execution of a given jenkins job. Arguments: --job -j Jenkins job name --server -s Jenkins server address --threshold -t threshold for maximum execution delay (in hours) Env args: JENKINS_API_TOKEN JENKINS_USER """ import argparse import datetime import os import dotenv import jenkins dotenv.load_dotenv('.env') def parse_args(args): parser = argparse.ArgumentParser(description='This script monitors execution of a given jenkins job') parser.add_argument('-j', '--job', required=True, help='Jenkins job name') parser.add_argument('-s', '--server', help='Jenkins server address. Default to https://scheduler.theorchard.io', default='https://scheduler.theorchard.io') parser.add_argument('-t', '--threshold', type=int, required=True, help='Threshold for maximum execution delay (in hours)') return vars(parser.parse_args(args)) def connect_jenkins(server): server = jenkins.Jenkins( url=server, username=os.environ['JENKINS_USER'], password=os.environ['JENKINS_API_TOKEN'], ) return server def get_last_execution(jenkins_server: jenkins.Jenkins, job_name): jenkins_server.assert_job_exists(job_name) job_info = jenkins_server.get_job_info(job_name) last_execution = job_info['lastCompletedBuild'] build_info = jenkins_server.get_build_info(job_name, last_execution['number']) return build_info def main(): parsed = parse_args(args=None) threshold_hours = parsed['threshold'] server_url = parsed['server'] jenkins_server = connect_jenkins(server_url) job_name = parsed['job'] last_execution = get_last_execution(jenkins_server, job_name) print(f'Job name {job_name}') last_execution_build_number = last_execution["number"] execution_url = f'{server_url}/view/Jobs%20Builder/job/{job_name}/{last_execution_build_number}/' print(f'Last build #{last_execution_build_number} {execution_url} ') execution_status = last_execution.get('result', 'UNKNOWN') print(f'Status {execution_status}') execution_time = last_execution['timestamp'] / 1000 started_at = datetime.datetime.fromtimestamp(execution_time) delta = datetime.datetime.now() - started_at print(f'It happened {started_at} ({delta} back)') errors = [] if delta > datetime.timedelta(hours=threshold_hours): errors.append(f'Last build #{last_execution_build_number} expired. It happened {delta} back.') if execution_status != 'SUCCESS': errors.append(f'Last build #{last_execution_build_number} status {execution_status} != SUCCESS.') if errors: print('ERRORS:') print('\n'.join(errors)) exit(1) print('OK') exit(0) if __name__ == '__main__': main()