68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
"""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)
|