#!/usr/bin/env bash # Covers the current OCDP workflow: login, registry health, Harbor chart repository browsing, # chart artifact listing, optional values schema fetch, and optional nginx deployment cleanup. set -euo pipefail BASE_URL="${BASE_URL:-http://localhost:18081/api/v1}" ADMIN_USER="${ADMIN_USER:-${BOOTSTRAP_ADMIN_USER:-admin}}" ADMIN_PASS="${ADMIN_PASS:-${BOOTSTRAP_ADMIN_PASS:-}}" RUN_DEPLOY_TEST="${RUN_DEPLOY_TEST:-false}" TEST_NAMESPACE="${TEST_NAMESPACE:-ocdp-smoke}" TEST_RELEASE="${TEST_RELEASE:-ocdp-smoke-nginx}" TEST_REPOSITORY_CONTAINS="${TEST_REPOSITORY_CONTAINS:-}" json_get() { python3 -c 'import json,sys; data=json.load(sys.stdin); cur=data for part in sys.argv[1].split("."): cur = cur[int(part)] if isinstance(cur, list) else cur.get(part) print("" if cur is None else cur)' "$1" } urlencode() { python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1" } echo "==> Health" curl -fsS "${BASE_URL%/api/v1}/health" >/dev/null if [[ -z "$ADMIN_PASS" ]]; then echo "ADMIN_PASS or BOOTSTRAP_ADMIN_PASS must be set for smoke tests" >&2 exit 1 fi echo "==> Login" login_payload=$(printf '{"username":"%s","password":"%s"}' "$ADMIN_USER" "$ADMIN_PASS") login_response=$(curl -fsS -H 'Content-Type: application/json' -d "$login_payload" "$BASE_URL/auth/login") token=$(printf '%s' "$login_response" | json_get "accessToken") auth_header="Authorization: Bearer $token" echo "==> Registries" registries=$(curl -fsS -H "$auth_header" "$BASE_URL/registries") registry_id=$(printf '%s' "$registries" | json_get "0.id") test -n "$registry_id" curl -fsS -H "$auth_header" "$BASE_URL/registries/$registry_id/health" >/dev/null echo "==> Chart repositories" repos=$(curl -fsS -H "$auth_header" "$BASE_URL/registries/$registry_id/repositories?artifact_type=chart") if [[ -n "$TEST_REPOSITORY_CONTAINS" ]]; then repo_name=$(printf '%s' "$repos" | python3 -c 'import json,os,sys needle=os.environ["TEST_REPOSITORY_CONTAINS"].lower() for repo in json.load(sys.stdin).get("repositories", []): if needle in repo.lower(): print(repo) break') else repo_name=$(printf '%s' "$repos" | json_get "repositories.0") fi test -n "$repo_name" encoded_repo=$(urlencode "$repo_name") echo "==> Chart artifacts" artifacts=$(curl -fsS -H "$auth_header" "$BASE_URL/registries/$registry_id/repositories/$encoded_repo/artifacts?media_type=chart") tag=$(printf '%s' "$artifacts" | json_get "0.tag") test -n "$tag" encoded_tag=$(urlencode "$tag") curl -fsS -H "$auth_header" "$BASE_URL/registries/$registry_id/repositories/$encoded_repo/artifacts/$encoded_tag/values-schema" >/dev/null || true if [[ "$RUN_DEPLOY_TEST" != "true" ]]; then echo "==> Smoke passed without deployment. Set RUN_DEPLOY_TEST=true to create and cleanup a release." exit 0 fi echo "==> Clusters" clusters=$(curl -fsS -H "$auth_header" "$BASE_URL/clusters") cluster_id=$(printf '%s' "$clusters" | json_get "0.id") test -n "$cluster_id" echo "==> Deploy test release" deploy_payload=$(TEST_RELEASE="$TEST_RELEASE" TEST_NAMESPACE="$TEST_NAMESPACE" REGISTRY_ID="$registry_id" REPOSITORY="$repo_name" TAG="$tag" python3 -c 'import json, os print(json.dumps({ "name": os.environ["TEST_RELEASE"], "namespace": os.environ["TEST_NAMESPACE"], "registryId": os.environ["REGISTRY_ID"], "repository": os.environ["REPOSITORY"], "tag": os.environ["TAG"], "valuesYaml": "replicaCount: 1\n", }))') instance=$(curl -fsS -H "$auth_header" -H 'Content-Type: application/json' -d "$deploy_payload" "$BASE_URL/clusters/$cluster_id/instances") instance_id=$(printf '%s' "$instance" | json_get "id") test -n "$instance_id" echo "==> Poll instance status" for _ in $(seq 1 60); do current=$(curl -fsS -H "$auth_header" "$BASE_URL/clusters/$cluster_id/instances/$instance_id") status=$(printf '%s' "$current" | json_get "status") echo "status=$status" [[ "$status" == "deployed" ]] && break [[ "$status" == "failed" ]] && { printf '%s\n' "$current"; exit 1; } sleep 5 done echo "==> Cleanup" curl -fsS -X DELETE -H "$auth_header" "$BASE_URL/clusters/$cluster_id/instances/$instance_id" >/dev/null || true echo "==> Deploy smoke completed"