import json import os import sys import time import urllib.parse from proof_client import ( APPLICATION_ID, auth0_token, cluster_identity, cluster_query, request, request_json, ) GLOBAL_SERVER = "http://globalserver:8080" VM_INSERT = "http://vminsert-cp9-metrics:8480" VM_SELECT = "http://vmselect-cp9-metrics:8481" REGION = os.environ["CP9_TARGET_REGION"] BIZ_TYPE = os.environ["CP9_SESSION_NAME"] EXPECTED_DNS_NAME = os.environ["CP9_EXPECTED_DNS_NAME"] EXPECTED_ENDPOINT_SERVICE = os.environ["CP9_EXPECTED_ENDPOINT_SERVICE"] METRIC = "cp9_o11y_platform_mapping_ready" def clusters(token): _, response = request_json( "GET", f"{GLOBAL_SERVER}/api/v1/clusters/?{cluster_query(REGION, BIZ_TYPE)}", bearer=token, ) result = response.get("data", {}).get("clusters") if not isinstance(result, list): raise RuntimeError("GS cluster list response did not contain data.clusters") return result def delete_cluster(token, cluster_id): request_json( "DELETE", f"{GLOBAL_SERVER}/api/v1/clusters/{urllib.parse.quote(cluster_id)}" f"?{cluster_query(REGION, BIZ_TYPE)}", bearer=token, expected=(200, 202), ) def wait_for_zero(token): for _ in range(60): if not clusters(token): return time.sleep(2) raise RuntimeError("owned GS cluster remained after delete") def cleanup_owned(token): existing = clusters(token) for cluster in existing: cluster_id = cluster.get("id") if not isinstance(cluster_id, str) or not cluster_id: raise RuntimeError("owned GS cluster list entry had no id") delete_cluster(token, cluster_id) if existing: wait_for_zero(token) def create_cluster(token): _, response = request_json( "POST", f"{GLOBAL_SERVER}/api/v1/clusters/", bearer=token, json_body={ **cluster_identity(REGION, BIZ_TYPE), "shareMode": "shared", "category": ["metrics"], }, expected=(200, 202), ) cluster_id = response.get("data", {}).get("id") if not isinstance(cluster_id, str) or not cluster_id: raise RuntimeError("GS create response did not contain data.id") return cluster_id def wait_for_active(token, cluster_id): query = cluster_query(REGION, BIZ_TYPE) detail_url = ( f"{GLOBAL_SERVER}/api/v1/clusters/{urllib.parse.quote(cluster_id)}?{query}" ) for _ in range(90): _, response = request_json("GET", detail_url, bearer=token) detail = response.get("data", {}) if str(detail.get("status", "")).upper() == "ACTIVE": monitor = detail.get("monitorInfo", {}) account_id = monitor.get("vmAccountID") project_id = monitor.get("vmProjectID") dns_name = monitor.get("dnsName") endpoint_service = monitor.get("endpointServiceName") if ( all(isinstance(value, str) and value for value in (account_id, project_id)) and dns_name == EXPECTED_DNS_NAME and endpoint_service == EXPECTED_ENDPOINT_SERVICE ): return detail, account_id, project_id, dns_name, endpoint_service time.sleep(2) raise RuntimeError( "GS cluster did not become ACTIVE with expected mapping and endpoint" ) def prove_metric(account_id, project_id): timestamp_ms = int(time.time() * 1000) line = ( f'{METRIC}{{contract="gs-rs-released",application="{APPLICATION_ID}"}} ' f"1 {timestamp_ms}" ).encode() insert_url = ( f"{VM_INSERT}/insert/{urllib.parse.quote(account_id)}:" f"{urllib.parse.quote(project_id)}/prometheus/api/v1/import/prometheus" ) request("POST", insert_url, body=line, expected=(200, 204)) query = urllib.parse.urlencode({"query": METRIC, "nocache": "1"}) select_url = ( f"{VM_SELECT}/select/{urllib.parse.quote(account_id)}:" f"{urllib.parse.quote(project_id)}/prometheus/api/v1/query?{query}" ) for _ in range(30): _, response = request_json("GET", select_url) result = response.get("data", {}).get("result", []) if any(item.get("metric", {}).get("__name__") == METRIC for item in result): return time.sleep(2) raise RuntimeError("VictoriaMetrics did not return the mapped readiness metric") def main(): _, token = auth0_token() cluster_id = None handed_off = False try: cleanup_owned(token) cluster_id = create_cluster(token) detail, account_id, project_id, dns_name, endpoint_service = wait_for_active( token, cluster_id ) listed = clusters(token) if not any(cluster.get("id") == cluster_id for cluster in listed): raise RuntimeError("created GS cluster was absent from list") prove_metric(account_id, project_id) handed_off = True print( json.dumps( { "status": "passed", "cluster_id": cluster_id, "cluster_status": str(detail.get("status", "")).upper(), "region": REGION, "vm_account_id": account_id, "vm_project_id": project_id, "dns_name": dns_name, "endpoint_service_name": endpoint_service, "metric": METRIC, "active_clusters_before_gateway": len(listed), "cleanup_pending": True, }, sort_keys=True, ) ) finally: if cluster_id is not None and not handed_off: try: delete_cluster(token, cluster_id) wait_for_zero(token) except Exception as cleanup_error: print( f"contract tracer cleanup failed: {cleanup_error}", file=sys.stderr, ) if __name__ == "__main__": main()