"""Discover instances, save one address, and compare cached/fresh requests.""" import argparse import json from pathlib import Path import sys import time from urllib.request import urlopen BASE = "http://consul:8500" CACHE = Path("/work/consul-address.json") def get(url): with urlopen(url, timeout=2) as response: return json.load(response) def discover(): rows = get(BASE + "/v1/health/service/orders?passing=true") return sorted([{"id": r["Service"]["ID"], "address": r["Service"]["Address"], "port": r["Service"]["Port"]} for r in rows], key=lambda r: r["id"]) def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("action", choices=["list", "save", "cached", "fresh", "wait"]) parser.add_argument("--ids", default="app-a,app-b", help="Expected passing IDs for wait") args = parser.parse_args() if args.action == "wait": expected = sorted(args.ids.split(",")) deadline = time.monotonic() + 30 while time.monotonic() < deadline: try: rows = discover() if [r["id"] for r in rows] == expected: print(json.dumps(rows, indent=2)) return except OSError: pass time.sleep(0.5) raise RuntimeError("Passing instances did not reach " + str(expected)) if args.action == "list": print(json.dumps(discover(), indent=2)) return if args.action == "cached": endpoint = json.loads(CACHE.read_text()) else: rows = discover() if not rows: raise RuntimeError("No passing instances") endpoint = rows[0] if args.action == "save": CACHE.parent.mkdir(parents=True, exist_ok=True) CACHE.write_text(json.dumps(endpoint), encoding="utf-8") print("SAVED", endpoint) return url = f"http://{endpoint['address']}:{endpoint['port']}/" print(("CACHED" if args.action == "cached" else "FRESH"), endpoint["id"], url, flush=True) print(json.dumps(get(url), indent=2)) if __name__ == "__main__": try: main() except (OSError, ValueError, RuntimeError) as error: print("REQUEST FAILED:", error, file=sys.stderr) sys.exit(1)