From 5b76f4b1cbf342e1ec6a8886630b71abcc7454d5 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Oct 24 2017 06:35:17 +0000 Subject: Simple freshmaker command line client to query Freshmaker REST API --- diff --git a/contrib/freshmaker-cli b/contrib/freshmaker-cli new file mode 100755 index 0000000..ed87418 --- /dev/null +++ b/contrib/freshmaker-cli @@ -0,0 +1,201 @@ +#!/usr/bin/env python + +""" freshmaker-cli - Read-only client for Freshmaker REST API + + +Example usage: + - List all the events handled by Freshmaker on redhat staging instance: + ./freshmaker-cli --redhat --stage + - List particular events based on the event id: + ./freshmaker-cli --redhat --stage 1 2 3 + - Search for events matching particular event key: + ./freshmaker-cli --redhat --stage --search-key 29110 + - Search for events which lead built particular NVR in Koji: + ./freshmaker-cli --redhat --stage --rebuilt-nvr NVR + - Search for events which upated particular NVR: + ./freshmaker-cli --redhat --stage --original-nvr NVR +""" + +from __future__ import print_function + +import textwrap +import argparse +import sys +import requests +from tabulate import tabulate + +# Disable InsecureRequestWarning +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + + +EVENT_TYPES = [ + "Module build state changed", + "Module git definition changed", + "RPM git definition changed", + "Internal Freshmaker event type", + "Container image git definition changed", + "Bodhi update added to stable", + "Koji task state changed", + "Koji RPM signed", + "Errata advisory RPMS signed" +] + + +def get_api_url(deployment, env): + API_URLS = { + "redhat": { + "prod": "https://freshmaker.host.prod.eng.bos.redhat.com", + "stage": "https://freshmaker.host.stage.eng.bos.redhat.com", + "qe": "https://freshmaker.host.qe.eng.pek2.redhat.com", + "dev": "https://freshmaker.host.dev.eng.pek2.redhat.com", + }, + "fedora": {} + } + + if deployment not in API_URLS: + return None + + envs = API_URLS[deployment] + if env not in envs: + return None + + return envs[env] + + +def get_events_from_builds(api_url, rebuilt_nvr=None, original_nvr=None): + page = 1 + ids = [] + while True: + print("Getting messages from Freshmaker, page", page) + url = '%s/api/1/builds?page=%d' % (api_url, page) + if rebuilt_nvr: + url += "&rebuilt_nvr=" + rebuilt_nvr + + r = requests.get(url, verify=False) + page += 1 + ret = r.json() + items = ret["items"] + if not items: + break + for item in items: + if item["event_id"] not in ids: + ids.append(item["event_id"]) + + return get_freshmaker_events_by_ids(api_url, ids) + + +def get_freshmaker_events(api_url, search_key=None, rebuilt_nvr=None, original_nvr=None): + if rebuilt_nvr or original_nvr: + return get_events_from_builds(api_url, rebuilt_nvr, original_nvr) + + page = 1 + events = [] + while True: + print("Getting messages from Freshmaker, page", page) + url = '%s/api/1/events?page=%d' % (api_url, page) + if search_key: + url += "&search_key=" + search_key + + r = requests.get(url, verify=False) + page += 1 + ret = r.json() + items = ret["items"] + if not items: + return events + events += items + + return events + + +def get_freshmaker_events_by_ids(api_url, ids): + events = [] + for i in ids: + print("Getting Freshmaker event id", i) + url = '%s/api/1/events/%s' % (api_url, str(i)) + + r = requests.get(url, verify=False) + ret = r.json() + events += [ret] + + return events + + +def print_events(events): + table = [["ID", "Event type", "Event key", "Number of builds"]] + for event in events: + row = [event["id"], EVENT_TYPES[event["event_type_id"]], + event["search_key"], len(event["builds"])] + table.append(row) + print(tabulate(table, headers="firstrow")) + + +def print_detailed_events(events): + for event in events: + print("Event id:", event["id"]) + + table = [["Build ID", "Task ID", "State", "Original NVR", "Rebuilt NVR", "State Reason"]] + for build in event["builds"]: + row = [build["id"], build["build_id"], build["state_name"], + build["original_nvr"], build["rebuilt_nvr"], build["state_reason"]] + table.append(row) + print(tabulate(table, headers="firstrow")) + + +parser = argparse.ArgumentParser( + description=textwrap.dedent(__doc__), + formatter_class=argparse.RawDescriptionHelpFormatter, +) +parser.add_argument( + '--stage', default=False, action='store_true', + help="Use the staging environment.") +parser.add_argument( + '--qe', default=False, action='store_true', + help="Use the qe environment.") +parser.add_argument( + '--dev', default=False, action='store_true', + help="Use the dev environment.") +parser.add_argument( + '--redhat', default=False, action='store_true', + help="Use the redhat instances.") +parser.add_argument( + 'events', metavar='event', nargs='*', + help='Event ids to be queried') +parser.add_argument( + '--search-key', default=None, + help="Search for events matching the search_key") +parser.add_argument( + '--rebuilt-nvr', default=None, + help="NVR of rebuilt artifact to search for") +parser.add_argument( + '--original-nvr', default=None, + help="NVR of original artifact to search for") +args = parser.parse_args() + +if args.redhat: + deployment = "redhat" +else: + deployment = "fedora" + +if args.stage: + env = "stage" +elif args.qe: + env = "qe" +elif args.dev: + env = "dev" +else: + env = "prod" + +api_url = get_api_url(deployment, env) +if not api_url: + print("There is no Freshmaker instance for deployment %s and env %s" %( deployment, env)) + sys.exit(1) + +if not args.events: + events = get_freshmaker_events(api_url, search_key=args.search_key, + rebuilt_nvr=args.rebuilt_nvr, + original_nvr=args.original_nvr) + print_events(events) +else: + events = get_freshmaker_events_by_ids(api_url, args.events) + print_detailed_events(events)