first commit
This commit is contained in:
Executable
+467
@@ -0,0 +1,467 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# eBdesk SiCABE — Verifikasi Phase 4 (Serving): StarRocks Shared-Data
|
||||
#
|
||||
# Gate "kontrak serving": memastikan StarRocks (FE + Compute Node) benar-benar
|
||||
# siap dipakai — termasuk saat FE/CN EXISTING (dikelola sistem lain).
|
||||
#
|
||||
# Yang diperiksa:
|
||||
# A. Kontrak service : FE LEADER + Alive, CN Alive, protokol MySQL terjangkau
|
||||
# B. Storage volume : s3_volume — ada, DEFAULT, enabled, location & endpoint S3
|
||||
# sesuai konfigurasi deploy (DESC STORAGE VOLUME)
|
||||
# C. Keamanan : sr_oidc (permitted_groups, redirect_url, issuer, audience,
|
||||
# principal_field) + sr_ldap (ldap_conn_url == LDAP_URL),
|
||||
# role sr_*, activate_all_roles_on_login, dan
|
||||
# authentication_chain yang MEMUAT sr_oidc
|
||||
# D. External catalog : iceberg_catalog (Iceberg via Nessie) + database terbaca
|
||||
# E. Antarmuka konsumen: OpenMetadata/Grafana + konsistensi antar-fase → WARN/SKIP
|
||||
#
|
||||
# Catatan desain (mengikuti §2.10 dokumen fase): hanya memverifikasi kontrak yang
|
||||
# dimiliki fase ini. Bagian E bersifat informatif karena artefaknya milik fase 6.
|
||||
#
|
||||
# ⚠️ `authentication_chain` adalah dynamic config yang HILANG saat FE restart;
|
||||
# gate ini sengaja memeriksanya sebagai FAIL karena tanpa itu login OIDC mati.
|
||||
#
|
||||
# Exit code: 0 = semua gate lolos (WARN/SKIP boleh), 1 = ada FAIL.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/verify-phase4-serving.sh
|
||||
# # menunjuk StarRocks existing:
|
||||
# STARROCKS_HOST=starrocks.corp STARROCKS_PORT=9030 \
|
||||
# STARROCKS_ROOT_PASSWORD=... ./scripts/verify-phase4-serving.sh
|
||||
# =============================================================================
|
||||
set -uo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "${SCRIPT_DIR}/lib/common.sh"
|
||||
# shellcheck source=../config/environment.defaults.sh
|
||||
source "${SCRIPT_DIR}/config/environment.defaults.sh"
|
||||
sicabe_load_env "${SCRIPT_DIR}" "$@"
|
||||
|
||||
# Config RELEVAN: mode host (--env-file) = BUNDLE host (ter-render), bukan deploy/config/ sumber.
|
||||
if [[ -n "${SICABE_BUNDLE_DIR:-}" ]]; then CONFIG_DIR="${SICABE_BUNDLE_DIR}/config"; else CONFIG_DIR="${SCRIPT_DIR}/config"; fi
|
||||
|
||||
# STARROCKS_HOST tetap = penanda EXTERNAL (nilai operator; default localhost).
|
||||
STARROCKS_HOST="${STARROCKS_HOST:-localhost}"
|
||||
STARROCKS_PORT="${STARROCKS_PORT:-${STARROCKS_FE_PORT:-12930}}"
|
||||
# Host EFEKTIF untuk koneksi: alamat host pemilik (multi-host) atau override operator.
|
||||
SR_CONNECT="$(sicabe_local_host STARROCKS_FE_HOST STARROCKS_HOST)"
|
||||
SR_USER="${STARROCKS_USER:-root}"
|
||||
SR_PW="${STARROCKS_ROOT_PASSWORD:-}"
|
||||
BUCKET="${MINIO_BUCKET_ICEBERG_DATA:-iceberg-data}"
|
||||
S3_ENDPOINT="${S3_ENDPOINT:-http://minio:9000}"
|
||||
S3_REGION="${S3_REGION:-us-east-1}"
|
||||
LDAP_URL="${LDAP_URL:-ldap://openldap:389}"
|
||||
KC_BASE="$(sicabe_local_url http KEYCLOAK_HOST "${KEYCLOAK_PORT:-12080}" KEYCLOAK_URL)"
|
||||
REALM="${SICABE_REALM:-sicabe}"
|
||||
GROUP_PROVIDER_NAME="${STARROCKS_GROUP_PROVIDER:-sr_ldap}"
|
||||
OIDC_NAME="${STARROCKS_OIDC_INTEGRATION:-sr_oidc}"
|
||||
CATALOG="${STARROCKS_ICEBERG_CATALOG:-iceberg_catalog}"
|
||||
EXPECTED_GROUPS="data-admin,data-engineer,data-analyst,data-viewer"
|
||||
|
||||
# Klien MySQL: pakai host bila ada, jika tidak fallback ke container (tanpa pull
|
||||
# mengejutkan — hanya bila image-nya sudah ada).
|
||||
SR_MYSQL_IMAGE="${SR_MYSQL_IMAGE:-mysql:8}"
|
||||
if command -v mysql >/dev/null 2>&1; then
|
||||
SR_MODE="host"
|
||||
elif docker image inspect "${SR_MYSQL_IMAGE}" >/dev/null 2>&1; then
|
||||
SR_MODE="container"
|
||||
else
|
||||
SR_MODE="none"
|
||||
fi
|
||||
|
||||
PASS_N=0
|
||||
FAIL_N=0
|
||||
WARN_N=0
|
||||
SKIP_N=0
|
||||
pass() { echo -e " ${PASS} $1"; PASS_N=$((PASS_N + 1)); }
|
||||
FAIL_MSGS=()
|
||||
fail() { echo -e " ${FAIL} $1"; FAIL_N=$((FAIL_N + 1)); FAIL_MSGS+=("$1"); }
|
||||
warn() { echo -e " ${WARN} $1"; WARN_N=$((WARN_N + 1)); }
|
||||
skip() { echo -e " ${YELLOW}[SKIP]${NC} $1"; SKIP_N=$((SKIP_N + 1)); }
|
||||
|
||||
container_running() {
|
||||
docker ps --format "{{.Names}}" 2>/dev/null | grep -q "^$1$"
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Helper: query StarRocks
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# sr_sql <sql> → tab-separated, tanpa header (untuk parsing)
|
||||
# sr_sql_vertical → format \G (label: value) untuk FE/CN
|
||||
sr_sql() {
|
||||
case "${SR_MODE}" in
|
||||
host)
|
||||
# --protocol=TCP: tanpa ini, -h localhost akan memakai unix socket, bukan port.
|
||||
MYSQL_PWD="${SR_PW}" mysql --protocol=TCP -h "${SR_CONNECT}" -P "${STARROCKS_PORT}" \
|
||||
-u "${SR_USER}" -N -B -e "$1" 2>/dev/null
|
||||
;;
|
||||
container)
|
||||
docker run --rm -i --network "${SICABE_NETWORK:-sicabe-network}" \
|
||||
-e MYSQL_PWD="${SR_PW}" "${SR_MYSQL_IMAGE}" \
|
||||
mysql --protocol=TCP -h "${SR_CONNECT}" -P "${STARROCKS_PORT}" -u "${SR_USER}" \
|
||||
-N -B -e "$1" 2>/dev/null
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
sr_sql_vertical() {
|
||||
case "${SR_MODE}" in
|
||||
host)
|
||||
MYSQL_PWD="${SR_PW}" mysql --protocol=TCP -h "${SR_CONNECT}" -P "${STARROCKS_PORT}" \
|
||||
-u "${SR_USER}" -e "$1\G" 2>/dev/null
|
||||
;;
|
||||
container)
|
||||
docker run --rm -i --network "${SICABE_NETWORK:-sicabe-network}" \
|
||||
-e MYSQL_PWD="${SR_PW}" "${SR_MYSQL_IMAGE}" \
|
||||
mysql --protocol=TCP -h "${SR_CONNECT}" -P "${STARROCKS_PORT}" -u "${SR_USER}" \
|
||||
-e "$1\G" 2>/dev/null
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# A. Kontrak service
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
check_service() {
|
||||
echo -e "${BOLD}A. Kontrak service StarRocks${NC}"
|
||||
|
||||
local external_expected=0
|
||||
[[ "${STARROCKS_HOST}" != "localhost" && "${STARROCKS_HOST}" != "127.0.0.1" ]] && external_expected=1
|
||||
|
||||
if ! sicabe_host_expects_container sicabe-starrocks-fe; then
|
||||
skip "Container sicabe-starrocks-fe di host lain (mode host) - dilewati"
|
||||
elif container_running sicabe-starrocks-fe; then
|
||||
pass "Container sicabe-starrocks-fe berjalan"
|
||||
elif [[ ${external_expected} -eq 1 ]]; then
|
||||
skip "FE dikelola eksternal (${STARROCKS_HOST}:${STARROCKS_PORT}) — lewati cek container"
|
||||
else
|
||||
fail "Container sicabe-starrocks-fe tidak berjalan"
|
||||
fi
|
||||
if ! sicabe_host_expects_container sicabe-starrocks-cn; then
|
||||
skip "Container sicabe-starrocks-cn di host lain (mode host) - dilewati"
|
||||
elif container_running sicabe-starrocks-cn; then
|
||||
pass "Container sicabe-starrocks-cn berjalan"
|
||||
elif [[ ${external_expected} -eq 1 ]]; then
|
||||
skip "Compute Node dikelola eksternal — lewati cek container"
|
||||
else
|
||||
fail "Container sicabe-starrocks-cn tidak berjalan"
|
||||
fi
|
||||
|
||||
if [[ "${SR_MODE}" == "none" ]]; then
|
||||
fail "Klien MySQL tidak tersedia (host) & image ${SR_MYSQL_IMAGE} belum ada lokal — semua cek SQL dilewati"
|
||||
return 1
|
||||
fi
|
||||
if [[ -z "${SR_PW}" ]]; then
|
||||
fail "STARROCKS_ROOT_PASSWORD kosong — tidak bisa terhubung"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$(sr_sql 'SELECT 1')" != "1" ]]; then
|
||||
fail "Tidak bisa terhubung ke StarRocks di ${STARROCKS_HOST}:${STARROCKS_PORT}"
|
||||
return 1
|
||||
fi
|
||||
pass "Protokol MySQL terjangkau (${STARROCKS_HOST}:${STARROCKS_PORT})"
|
||||
|
||||
local fe
|
||||
fe="$(sr_sql_vertical 'SHOW FRONTENDS')"
|
||||
if [[ "${fe}" == *"Alive: true"* ]]; then
|
||||
pass "FE Alive"
|
||||
else
|
||||
fail "FE tidak Alive"
|
||||
fi
|
||||
if [[ "${fe}" == *"Role: LEADER"* ]]; then
|
||||
pass "FE berperan LEADER"
|
||||
else
|
||||
warn "FE bukan LEADER (cluster multi-FE?)"
|
||||
fi
|
||||
|
||||
local cn
|
||||
cn="$(sr_sql_vertical 'SHOW COMPUTE NODES')"
|
||||
if [[ "${cn}" == *"Alive: true"* ]]; then
|
||||
pass "Compute Node Alive (shared-data)"
|
||||
else
|
||||
fail "Tidak ada Compute Node yang Alive"
|
||||
fi
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# B. Storage volume (shared-data) — inti fase ini
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
check_storage_volume() {
|
||||
echo -e "${BOLD}B. Storage volume S3 (shared-data)${NC}"
|
||||
|
||||
if ! sr_sql "SHOW STORAGE VOLUMES;" | grep -q "s3_volume"; then
|
||||
fail "Storage volume 's3_volume' tidak ada (jalankan bootstrap.sh --step 5)"
|
||||
return 1
|
||||
fi
|
||||
pass "Storage volume 's3_volume' terdaftar"
|
||||
|
||||
local desc
|
||||
desc="$(sr_sql "DESC STORAGE VOLUME s3_volume;")"
|
||||
# Kolom: Name · Type · IsDefault · Location · Params · Enabled · Comment
|
||||
local is_default location params enabled
|
||||
is_default="$(echo "${desc}" | awk -F'\t' '{print $3}')"
|
||||
location="$(echo "${desc}" | awk -F'\t' '{print $4}')"
|
||||
params="$(echo "${desc}" | awk -F'\t' '{print $5}')"
|
||||
enabled="$(echo "${desc}" | awk -F'\t' '{print $6}')"
|
||||
|
||||
if [[ "${enabled}" == "true" ]]; then
|
||||
pass "s3_volume enabled"
|
||||
else
|
||||
fail "s3_volume tidak enabled ('${enabled}')"
|
||||
fi
|
||||
if [[ "${is_default}" == "true" ]]; then
|
||||
pass "s3_volume = DEFAULT STORAGE VOLUME"
|
||||
else
|
||||
fail "s3_volume bukan default storage volume ('${is_default}')"
|
||||
fi
|
||||
if [[ "${location}" == "s3://${BUCKET}/starrocks/" ]]; then
|
||||
pass "Location → ${location}"
|
||||
else
|
||||
fail "Location '${location}' ≠ 's3://${BUCKET}/starrocks/'"
|
||||
fi
|
||||
|
||||
local ep region path_style
|
||||
ep="$(echo "${params}" | grep -oE '"aws\.s3\.endpoint":"[^"]*"' | sed 's/.*:"//; s/"//')"
|
||||
region="$(echo "${params}" | grep -oE '"aws\.s3\.region":"[^"]*"' | sed 's/.*:"//; s/"//')"
|
||||
path_style="$(echo "${params}" | grep -oE '"aws\.s3\.enable_path_style_access":"[^"]*"' | sed 's/.*:"//; s/"//')"
|
||||
if [[ "${ep}" == "${S3_ENDPOINT}" ]]; then
|
||||
pass "Params aws.s3.endpoint → ${ep}"
|
||||
else
|
||||
fail "Params aws.s3.endpoint '${ep:-tak terbaca}' ≠ S3_ENDPOINT '${S3_ENDPOINT}'"
|
||||
fi
|
||||
if [[ "${region}" == "${S3_REGION}" ]]; then
|
||||
pass "Params aws.s3.region → ${region}"
|
||||
else
|
||||
fail "Params aws.s3.region '${region:-tak terbaca}' ≠ S3_REGION '${S3_REGION}'"
|
||||
fi
|
||||
if [[ "${path_style}" == "true" ]]; then
|
||||
pass "Path-style access aktif (wajib untuk MinIO/S3 non-AWS)"
|
||||
else
|
||||
warn "Path-style access '${path_style:-tak terbaca}' — bisa gagal di MinIO"
|
||||
fi
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# C. Keamanan: OIDC + LDAP group provider + role
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
check_security() {
|
||||
echo -e "${BOLD}C. Keamanan — OIDC Keycloak + group provider LDAP${NC}"
|
||||
|
||||
local oidc
|
||||
oidc="$(sr_sql "SHOW CREATE SECURITY INTEGRATION ${OIDC_NAME};")"
|
||||
if [[ -z "${oidc}" ]]; then
|
||||
fail "Security integration '${OIDC_NAME}' tidak ada"
|
||||
else
|
||||
pass "Security integration '${OIDC_NAME}' ada"
|
||||
local pat
|
||||
for pat in "client_id\" = \"starrocks" "principal_field\" = \"preferred_username" \
|
||||
"group_provider\" = \"${GROUP_PROVIDER_NAME}\"" "required_audience\" = \"starrocks" \
|
||||
"required_issuer\" = \"${KC_BASE}/realms/${REALM}\""; do
|
||||
if [[ "${oidc}" == *"${pat}"* ]]; then
|
||||
pass " ${OIDC_NAME}: $(echo "${pat}" | sed 's/\\"//g')"
|
||||
else
|
||||
fail " ${OIDC_NAME}: tidak memuat ${pat} (cek bootstrap.sh --step 5)"
|
||||
fi
|
||||
done
|
||||
if [[ "${oidc}" == *"redirect_url\" = \"http://localhost:${STARROCKS_HTTP_PORT:-12030}/api/oauth2\""* ]]; then
|
||||
pass " ${OIDC_NAME}: redirect_url → http://localhost:${STARROCKS_HTTP_PORT:-12030}/api/oauth2"
|
||||
else
|
||||
warn " ${OIDC_NAME}: redirect_url tidak sesuai STARROCKS_HTTP_PORT (${STARROCKS_HTTP_PORT:-12030})"
|
||||
fi
|
||||
local g miss="" groups
|
||||
IFS=',' read -ra groups <<< "${EXPECTED_GROUPS}"
|
||||
for g in "${groups[@]}"; do
|
||||
[[ "${oidc}" == *"${g}"* ]] || miss+=" ${g}"
|
||||
done
|
||||
if [[ -z "${miss}" ]]; then
|
||||
pass " permitted_groups memuat 4 grup (${EXPECTED_GROUPS})"
|
||||
else
|
||||
fail " permitted_groups kehilangan:${miss}"
|
||||
fi
|
||||
fi
|
||||
|
||||
local ldap
|
||||
ldap="$(sr_sql "SHOW CREATE GROUP PROVIDER ${GROUP_PROVIDER_NAME};")"
|
||||
if [[ -z "${ldap}" ]]; then
|
||||
fail "Group provider '${GROUP_PROVIDER_NAME}' tidak ada"
|
||||
else
|
||||
pass "Group provider '${GROUP_PROVIDER_NAME}' ada"
|
||||
if [[ "${ldap}" == *"\"ldap_conn_url\" = \"${LDAP_URL}\""* ]]; then
|
||||
pass " ldap_conn_url → ${LDAP_URL}"
|
||||
else
|
||||
fail " ldap_conn_url tidak menunjuk LDAP_URL (${LDAP_URL}) — cek bootstrap.sh --step 5"
|
||||
fi
|
||||
if [[ "${ldap}" == *"\"ldap_group_identifier_attr\" = \"cn\""* ]]; then
|
||||
pass " group identifier = cn (cocok dengan grup LDAP data-*)"
|
||||
else
|
||||
fail " ldap_group_identifier_attr bukan 'cn'"
|
||||
fi
|
||||
if [[ "${ldap}" == *"***"* ]]; then
|
||||
pass " bind password tersimpan (disamarkan oleh StarRocks)"
|
||||
fi
|
||||
fi
|
||||
|
||||
local roles missing=""
|
||||
roles="$(sr_sql "SHOW ROLES;")"
|
||||
local r
|
||||
for r in sr_admin sr_engineer sr_analyst sr_viewer; do
|
||||
grep -q "^${r} " <<< "${roles}" || missing+=" ${r}"
|
||||
done
|
||||
if [[ -z "${missing}" ]]; then
|
||||
pass "Role sr_admin/sr_engineer/sr_analyst/sr_viewer ada"
|
||||
else
|
||||
fail "Role hilang:${missing}"
|
||||
fi
|
||||
|
||||
if [[ "$(sr_sql "SHOW VARIABLES LIKE 'activate_all_roles_on_login';" | awk -F'\t' '{print $2}')" == "true" ]]; then
|
||||
pass "activate_all_roles_on_login = true"
|
||||
else
|
||||
fail "activate_all_roles_on_login bukan true"
|
||||
fi
|
||||
|
||||
# ⚠️ Dynamic config — hilang saat FE restart. Tanpa ini login OIDC mati meski
|
||||
# integration-nya ada.
|
||||
local chain
|
||||
chain="$(sr_sql "ADMIN SHOW FRONTEND CONFIG LIKE 'authentication_chain';" | awk -F'\t' '{print $3}')"
|
||||
if [[ "${chain}" == *"${OIDC_NAME}"* ]]; then
|
||||
pass "authentication_chain memuat ${OIDC_NAME} (${chain})"
|
||||
else
|
||||
fail "authentication_chain = ${chain:-tak terbaca} TIDAK memuat ${OIDC_NAME} → login OIDC mati"
|
||||
warn " perbaiki: ./bootstrap.sh --step 5 (dynamic config hilang setelah FE restart)"
|
||||
fi
|
||||
|
||||
# Pemetaan role → EXTERNAL GROUP: tidak dapat diintrospeksi tanpa login OIDC.
|
||||
local app
|
||||
app="$(sr_sql "SELECT GRANTEE FROM information_schema.applicable_roles WHERE GRANTEE LIKE 'data-%';")"
|
||||
if [[ -n "${app}" ]]; then
|
||||
pass "GRANT role → EXTERNAL GROUP terlihat untuk grup: $(echo "${app}" | tr '\n' ' ')"
|
||||
else
|
||||
skip "Pemetaan role→EXTERNAL GROUP tidak terlihat (baru tampil setelah login OIDC) — diterapkan bootstrap step 5"
|
||||
fi
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# D. External catalog Iceberg via Nessie
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
check_catalog() {
|
||||
echo -e "${BOLD}D. External catalog Iceberg → Nessie${NC}"
|
||||
|
||||
if sr_sql "SHOW CATALOGS;" | grep -q "^${CATALOG}"; then
|
||||
pass "Catalog '${CATALOG}' terdaftar"
|
||||
else
|
||||
fail "Catalog '${CATALOG}' tidak ada (jalankan bootstrap.sh --step 5)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local dbs
|
||||
dbs="$(sr_sql "SHOW DATABASES FROM ${CATALOG};")"
|
||||
if [[ -z "${dbs}" ]]; then
|
||||
fail "Tidak bisa membaca database dari ${CATALOG} (Nessie tidak terjangkau?)"
|
||||
return 1
|
||||
fi
|
||||
pass "Database terbaca dari ${CATALOG}: $(echo "${dbs}" | tr '\n' ' ')"
|
||||
|
||||
# Query nyata — tabel berasal dari seed fase 5, jadi SKIP (bukan FAIL) bila belum ada.
|
||||
local t state n
|
||||
for t in bronze.orders silver.orders_silver gold.orders_gold; do
|
||||
n="$(sr_sql "SELECT count(*) FROM ${CATALOG}.${t};" 2>/dev/null | head -1)"
|
||||
if [[ "${n}" =~ ^[0-9]+$ ]]; then
|
||||
pass "SELECT count(*) FROM ${CATALOG}.${t} → ${n} baris"
|
||||
elif [[ -z "${n}" ]]; then
|
||||
skip "Tabel ${CATALOG}.${t} belum ada (di-seed fase 5)"
|
||||
else
|
||||
warn "Query ${CATALOG}.${t} → '$(echo "${n}" | cut -c1-70)'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# E. Antarmuka konsumen — milik fase 6 (WARN/SKIP)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
check_consumer_interfaces() {
|
||||
echo -e "${BOLD}E. Antarmuka konsumen & konsistensi antar-fase (informatif)${NC}"
|
||||
|
||||
# Konsistensi statis: SQL s3_volume di bootstrap harus memakai S3_* params.
|
||||
local bs="${SCRIPT_DIR}/bootstrap.sh"
|
||||
if grep -q "aws.s3.endpoint' = '\${S3_ENDPOINT" "${bs}" 2>/dev/null; then
|
||||
pass "bootstrap.sh: s3_volume memakai \${S3_ENDPOINT} (siap S3 existing)"
|
||||
else
|
||||
warn "bootstrap.sh: 'aws.s3.endpoint' tidak memakai \${S3_ENDPOINT} — sulit diarahkan ke S3 existing"
|
||||
fi
|
||||
|
||||
# permitted_groups (fase 4) ⊆ roles di ACL OPA (fase 3) — artefak lintas fase.
|
||||
local opa_roles="" g
|
||||
if [[ -f "${CONFIG_DIR}/opa/data.json" ]]; then
|
||||
opa_roles="$(grep -oE '"(data-[a-z]+)"' "${CONFIG_DIR}/opa/data.json" | tr -d '"' | sort -u | tr '\n' ' ')"
|
||||
local miss="" groups
|
||||
IFS=',' read -ra groups <<< "${EXPECTED_GROUPS}"
|
||||
for g in "${groups[@]}"; do
|
||||
[[ " ${opa_roles} " == *" ${g} "* ]] || miss+=" ${g}"
|
||||
done
|
||||
if [[ -z "${miss}" ]]; then
|
||||
pass "permitted_groups StarRocks ⊇ kunci roles di config/opa/data.json"
|
||||
else
|
||||
warn "Grup StarRocks tanpa padanan di data.json:${miss}"
|
||||
fi
|
||||
else
|
||||
skip "config/opa/data.json tidak ada — lewati konsistensi antar-fase"
|
||||
fi
|
||||
|
||||
if ! sicabe_host_expects_container sicabe-openmetadata; then
|
||||
skip "Container sicabe-openmetadata di host lain (mode host) - dilewati"
|
||||
elif container_running sicabe-openmetadata; then
|
||||
pass "OpenMetadata berjalan — konektor StarRocks diuji di gate Phase 6"
|
||||
else
|
||||
skip "OpenMetadata belum berjalan (fase 6) — lewati pemeriksaan antarmukanya"
|
||||
fi
|
||||
if ! sicabe_host_expects_container sicabe-grafana; then
|
||||
skip "Container sicabe-grafana di host lain (mode host) - dilewati"
|
||||
elif container_running sicabe-grafana; then
|
||||
pass "Grafana berjalan — datasource StarRocks diuji di gate Phase 6"
|
||||
else
|
||||
skip "Grafana belum berjalan (fase 6) — lewati pemeriksaan antarmukanya"
|
||||
fi
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Main
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
main() {
|
||||
print_section "Verifikasi Phase 4 — Kontrak Serving (StarRocks shared-data)"
|
||||
echo -e " FE : ${CYAN}${STARROCKS_HOST}:${STARROCKS_PORT}${NC} (root) · klien MySQL: ${SR_MODE}"
|
||||
echo -e " Volume : ${CYAN}s3_volume${NC} → s3://${BUCKET}/starrocks/ @ ${S3_ENDPOINT} (${S3_REGION})"
|
||||
echo -e " Catalog: ${CYAN}${CATALOG}${NC} (Iceberg via Nessie) · OIDC + ${GROUP_PROVIDER_NAME}"
|
||||
echo ""
|
||||
|
||||
check_service
|
||||
check_storage_volume
|
||||
check_security
|
||||
check_catalog
|
||||
check_consumer_interfaces
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}Ringkasan:${NC} ${GREEN}${PASS_N} PASS${NC} · ${RED}${FAIL_N} FAIL${NC} · ${YELLOW}${WARN_N} WARN${NC} · ${YELLOW}${SKIP_N} SKIP${NC}"
|
||||
if [[ ${FAIL_N} -gt 0 ]]; then
|
||||
echo ""
|
||||
echo -e "${BOLD}Yang gagal (${FAIL_N}):${NC}"
|
||||
local _i=1 _m
|
||||
for _m in "${FAIL_MSGS[@]}"; do
|
||||
echo -e " ${RED}${_i}.${NC} ${_m}"
|
||||
_i=$((_i + 1))
|
||||
done
|
||||
echo -e "${INFO} Perbaiki item di atas, lalu jalankan ulang: ./scripts/${0##*/}"
|
||||
fi
|
||||
if [[ ${FAIL_N} -eq 0 ]]; then
|
||||
echo -e "${OK} ${GREEN}Kontrak serving Phase 4 terpenuhi — aman lanjut ke fase berikutnya.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
echo -e "${ERR} Ada ${FAIL_N} gate yang gagal — perbaiki sebelum melanjutkan."
|
||||
exit 1
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user