#!/usr/bin/env bash
# smoke-test.sh -- Omega Cloud environment health check (yours to run; read-only).
#
# What: proves your automation credential and environment work end to end:
# 1. issue a token (authentication)
# 2. list the service catalog (endpoint discovery)
# 3. read your quota/limits envelope (capacity visibility)
# These are rows A1/A4/A5 of the Acceptance Checklist and the first
# triage steps of the CI/Automation Integration Guide.
# Why: authentication and quota explain most sudden pipeline breakage --
# run this first whenever automation against your environment fails,
# and as the opening stage of every pipeline.
# Safety: READ-ONLY. This script creates, changes, and deletes nothing.
#
# Auth: your normal OpenStack client environment -- either OS_CLOUD (from a
# clouds.yaml) or the OS_* variables from the CI/Automation Integration
# Guide. No arguments needed.
# Exit: 0 all checks passed | 1 a check failed | 2 environment not set up.
set -uo pipefail
command -v openstack >/dev/null 2>&1 || {
echo "SETUP: the 'openstack' client is not installed (pip install python-openstackclient)"; exit 2; }
command -v python3 >/dev/null 2>&1 || { echo "SETUP: python3 is required"; exit 2; }
if [ -z "${OS_CLOUD:-}" ] && [ -z "${OS_AUTH_URL:-}" ]; then
echo "SETUP: no OpenStack environment found."
echo " Either: export OS_CLOUD=<your cloud name from clouds.yaml>"
echo " Or: export the OS_* variables from the CI/Automation Integration Guide."
exit 2
fi
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT
OS_ERR="$WORK/stderr.txt"
FAILED=0
# Structured captures take stdout ONLY; stderr goes to a file so client
# warnings and notices can never corrupt the parsed output.
cap() { # cap <var> <openstack args...>
local __v="$1"; shift
local out rc
out=$(openstack "$@" </dev/null 2>"$OS_ERR"); rc=$?
printf -v "$__v" '%s' "$out"
return "$rc"
}
oerr() { head -1 "$OS_ERR" 2>/dev/null || true; }
echo "=== Omega Cloud smoke test ($(date -u +%Y-%m-%dT%H:%M:%SZ)) ==="
# ---- 1/3 authentication --------------------------------------------------
if cap TOK token issue -f json; then
PROJECT_ID=$(printf '%s' "$TOK" | python3 -c '
import json,sys
try: print(json.load(sys.stdin).get("project_id",""))
except Exception: pass')
if [ -n "$PROJECT_ID" ]; then
echo " [PASS] 1/3 token issued, scoped to your project ($PROJECT_ID)"
else
echo " [FAIL] 1/3 token issue returned output the client could not parse"
[ -s "$OS_ERR" ] && echo " client said: $(oerr)"
FAILED=1
fi
else
echo " [FAIL] 1/3 authentication failed"
echo " client said: $(oerr)"
echo " Most common causes (check in this order):"
echo " - the application credential was revoked or has expired"
echo " (whoever rotates credentials on your side will know)"
echo " - the CA bundle is missing from this environment"
echo " (OS_CACERT, or 'cacert' in clouds.yaml -- do not disable"
echo " certificate verification instead)"
echo " - the credential id/secret were not injected into this job"
FAILED=1
fi
# ---- 2/3 endpoint discovery ----------------------------------------------
if [ "$FAILED" -eq 0 ]; then
if cap CAT catalog list -f json; then
SUMMARY=$(printf '%s' "$CAT" | python3 -c '
import json,sys
try: rows=json.load(sys.stdin)
except Exception: sys.exit(1)
types=sorted({r.get("Type","?") for r in rows})
print("%d services: %s" % (len(rows), ", ".join(types)))') || SUMMARY=""
if [ -n "$SUMMARY" ]; then
echo " [PASS] 2/3 service catalog visible ($SUMMARY)"
else
echo " [FAIL] 2/3 catalog list returned unparseable output: $(oerr)"
FAILED=1
fi
else
echo " [FAIL] 2/3 catalog list failed: $(oerr)"
FAILED=1
fi
else
echo " [SKIP] 2/3 catalog list (blocked: authentication failed)"
fi
# ---- 3/3 quota envelope ---------------------------------------------------
if [ "$FAILED" -eq 0 ]; then
if cap LIM limits show --absolute -f json; then
USAGE=$(printf '%s' "$LIM" | python3 -c '
import json,sys
try: d={r.get("Name"): r.get("Value") for r in json.load(sys.stdin)}
except Exception: sys.exit(1)
def g(k): return d.get(k, "?")
print("instances %s/%s, cores %s/%s, ram %s/%s MB" % (
g("totalInstancesUsed"), g("maxTotalInstances"),
g("totalCoresUsed"), g("maxTotalCores"),
g("totalRAMUsed"), g("maxTotalRAMSize")))') || USAGE=""
if [ -n "$USAGE" ]; then
echo " [PASS] 3/3 quota envelope visible (used/limit: $USAGE)"
echo " Quota-exceeded errors in pipelines are actionable, not"
echo " retryable: clean up leaked resources or request a raise."
else
echo " [FAIL] 3/3 limits show returned unparseable output: $(oerr)"
FAILED=1
fi
else
echo " [FAIL] 3/3 limits show failed: $(oerr)"
FAILED=1
fi
else
echo " [SKIP] 3/3 limits show (blocked by an earlier failure)"
fi
echo
if [ "$FAILED" -eq 0 ]; then
echo "RESULT: SMOKE TEST PASS (authentication, catalog, quota all healthy)"
exit 0
fi
echo "RESULT: SMOKE TEST FAIL"
echo " Reminders from the integration guide:"
echo " - A permission error on identity, quota, or cluster operations is the"
echo " platform working as designed, not an outage."
echo " - Anything that looks like a platform fault: send the EXACT command"
echo " and the EXACT error text to your account contact. Verbatim errors"
echo " get fast answers; paraphrased ones do not."
exit 1