Files
sicabe-core/deploy/scripts/seed-starrocks.sh
T
2026-10-11 15:09:43 +07:00

176 lines
7.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# eBdesk SiCABE — Seed StarRocks: External Catalog (Nessie) + Native Shared Tables
# =============================================================================
# Idempoten:
# 1. Pastikan external catalog 'iceberg_catalog' → Nessie (query Iceberg).
# 2. Buat database native 'sicabe' di default_catalog.
# 3. Buat tabel native shared-data 'sicabe.orders' + 'sicabe.products'
# (otomatis CLOUD_NATIVE via default storage volume 's3_volume' → MinIO).
# 4. Seed data contoh (hanya bila kosong).
# 5. GRANT object privileges ke role (RBAC internal — tanpa ini user OIDC
# bisa login tapi tabel tidak terlihat).
#
# Pemakaian:
# cd deploy
# set -a; source config/environment.defaults.sh; source .env; set +a
# ./scripts/seed-starrocks.sh
#
# Env (opsional):
# STARROCKS_FE_CONTAINER (sicabe-starrocks-fe), STARROCKS_ROOT_PASSWORD,
# SEED_DB (sicabe)
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${SCRIPT_DIR}"
source "${SCRIPT_DIR}/lib/common.sh"
source "${SCRIPT_DIR}/config/environment.defaults.sh"
sicabe_load_env "${SCRIPT_DIR}" "$@"
SR_CONTAINER="${STARROCKS_FE_CONTAINER:-sicabe-starrocks-fe}"
SR_PASSWORD="${STARROCKS_ROOT_PASSWORD:?set STARROCKS_ROOT_PASSWORD}"
SEED_DB="${SEED_DB:-sicabe}"
# Multi-host: StarRocks FE ada di host `compute`; `docker exec` bersifat lokal.
sicabe_require_local_container "${SR_CONTAINER}" "StarRocks FE" "compute" || exit $?
# Jalankan SQL via mysql client di dalam container FE (selalu tersedia di image).
sr_sql() {
docker exec "${SR_CONTAINER}" mysql -h 127.0.0.1 -P 9030 -u root -p"${SR_PASSWORD}" -N -e "$1" 2>/dev/null
}
# ─── 1. External catalog Nessie (idempoten) ─────────────────────────────────
ensure_external_catalog() {
echo -e "${INFO} [1/5] Pastikan external catalog 'iceberg_catalog' → Nessie..."
if sr_sql "SHOW CATALOGS;" | grep -q "iceberg_catalog"; then
echo -e "${OK} Catalog 'iceberg_catalog' sudah ada."
return 0
fi
sr_sql "CREATE EXTERNAL CATALOG iceberg_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.catalog.uri' = '${NESSIE_URL:-http://nessie:19120}/iceberg/',
'iceberg.catalog.warehouse' = '${ICEBERG_WAREHOUSE:-warehouse}',
'iceberg.catalog.rest.nested-namespace-enabled' = 'true',
'aws.s3.endpoint' = '${S3_ENDPOINT:-http://minio:9000}',
'aws.s3.access_key' = '${S3_ACCESS_KEY:-${MINIO_ROOT_USER:-minioadmin}}',
'aws.s3.secret_key' = '${S3_SECRET_KEY:-${MINIO_ROOT_PASSWORD}}',
'aws.s3.enable_path_style_access' = 'true',
'aws.s3.region' = '${S3_REGION:-us-east-1}'
);" && echo -e "${OK} Catalog 'iceberg_catalog' dibuat."
}
# ─── 2. Database native ─────────────────────────────────────────────────────
ensure_native_db() {
echo -e "${INFO} [2/5] Database native '${SEED_DB}'..."
sr_sql "CREATE DATABASE IF NOT EXISTS ${SEED_DB};" \
&& echo -e "${OK} Database '${SEED_DB}' siap."
}
# ─── 3. Tabel native shared-data (→ MinIO via default storage volume) ───────
ensure_native_tables() {
echo -e "${INFO} [3/5] Tabel native shared-data (→ MinIO via 's3_volume')..."
sr_sql "CREATE TABLE IF NOT EXISTS ${SEED_DB}.orders (
id INT NOT NULL,
item VARCHAR(50),
customer VARCHAR(50),
qty INT,
price DECIMAL(10,2),
ts DATETIME
) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES (\"replication_num\" = \"1\");" \
&& echo -e "${OK} Tabel '${SEED_DB}.orders' siap."
sr_sql "CREATE TABLE IF NOT EXISTS ${SEED_DB}.products (
id INT NOT NULL,
name VARCHAR(50),
category VARCHAR(50),
price DECIMAL(10,2)
) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES (\"replication_num\" = \"1\");" \
&& echo -e "${OK} Tabel '${SEED_DB}.products' siap."
}
# ─── 4. Seed data (hanya bila kosong) ───────────────────────────────────────
seed_rows() {
echo -e "${INFO} [4/5] Seed data contoh (bila kosong)..."
local cnt
cnt=$(sr_sql "SELECT count(*) FROM ${SEED_DB}.orders;" || true); cnt="${cnt:-0}"
if [[ "${cnt}" -gt 0 ]]; then
echo -e "${OK} '${SEED_DB}.orders' sudah berisi ${cnt} baris (skip)."
else
sr_sql "INSERT INTO ${SEED_DB}.orders VALUES
(1,'laptop','alice',2,1500.00,'2026-09-01 09:00:00'),
(2,'monitor','budi',1,300.50,'2026-09-02 10:30:00'),
(3,'keyboard','citra',3,75.25,'2026-09-03 11:00:00');" \
&& echo -e "${OK} 3 baris → '${SEED_DB}.orders'."
fi
local pcnt
pcnt=$(sr_sql "SELECT count(*) FROM ${SEED_DB}.products;" || true); pcnt="${pcnt:-0}"
if [[ "${pcnt}" -gt 0 ]]; then
echo -e "${OK} '${SEED_DB}.products' sudah berisi ${pcnt} baris (skip)."
else
sr_sql "INSERT INTO ${SEED_DB}.products VALUES
(1,'laptop','elektronik',1500.00),
(2,'monitor','elektronik',300.50),
(3,'keyboard','aksesoris',75.25),
(4,'kursi','furnitur',450.00);" \
&& echo -e "${OK} 4 baris → '${SEED_DB}.products'."
fi
}
# ─── 5. GRANT object privileges ke role (RBAC internal) ─────────────────────
# Role di-map dari grup eksternal (bootstrap Step 5: GRANT role TO EXTERNAL
# GROUP). Tanpa object privilege, user OIDC bisa login tapi tidak melihat tabel.
grant_roles() {
echo -e "${INFO} [5/5] GRANT object privileges ke role (RBAC internal)..."
local role
for role in sr_admin sr_engineer sr_analyst sr_viewer; do
sr_sql "CREATE ROLE ${role};" >/dev/null 2>&1 || true
done
sr_sql "GRANT SELECT ON ALL TABLES IN DATABASE ${SEED_DB} TO ROLE sr_analyst;" >/dev/null 2>&1 \
&& echo -e "${OK} sr_analyst: SELECT ${SEED_DB}.*"
sr_sql "GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN DATABASE ${SEED_DB} TO ROLE sr_engineer;" >/dev/null 2>&1 \
&& echo -e "${OK} sr_engineer: RW ${SEED_DB}.*"
sr_sql "GRANT SELECT,INSERT,UPDATE,DELETE,ALTER,DROP ON ALL TABLES IN ALL DATABASES TO ROLE sr_admin;" >/dev/null 2>&1 \
&& echo -e "${OK} sr_admin: ALL (semua database)"
echo -e "${INFO} sr_viewer: tanpa grant (fail-closed)"
}
# ─── Verifikasi ─────────────────────────────────────────────────────────────
verify() {
echo -e "${INFO} Verifikasi:"
echo " Catalogs:"
sr_sql "SHOW CATALOGS;" | sed 's/^/ /'
echo " Native tables (default_catalog.${SEED_DB}):"
sr_sql "SHOW TABLES FROM ${SEED_DB};" | sed 's/^/ /'
echo " ${SEED_DB}.orders:"
sr_sql "SELECT id,item,customer,qty,price FROM ${SEED_DB}.orders ORDER BY id;" | sed 's/^/ /'
echo " External (Nessie) iceberg_catalog.bronze.orders:"
sr_sql "SELECT id,komoditas,harga_per_kg FROM iceberg_catalog.bronze.orders ORDER BY id;" | sed 's/^/ /'
}
# ─── MAIN ───────────────────────────────────────────────────────────────────
main() {
echo -e "${BOLD}${BLUE}═══ Seed StarRocks — catalog Nessie + tabel native shared (${SEED_DB}) ═══${NC}"
if ! docker ps --format '{{.Names}}' | grep -q "^${SR_CONTAINER}$"; then
echo -e "${ERR} Container '${SR_CONTAINER}' tidak running."
exit 1
fi
ensure_external_catalog
ensure_native_db
ensure_native_tables
seed_rows
grant_roles
verify
echo -e "${OK} ${GREEN}Seed StarRocks selesai.${NC}"
}
main "$@"