Files

238 lines
8.6 KiB
Makefile

set fallback := true
export CUBE_NAMESPACE := env("CUBE_NAMESPACE", "cube")
export CUBESTORE_CHART_VERSION := env("CUBESTORE_CHART_VERSION", "1.1.0")
export CUBE_CHART_VERSION := env("CUBE_CHART_VERSION", "3.2.0")
export KEYCLOAK_REALM := env("KEYCLOAK_REALM", "buunstack")
export KEYCLOAK_HOST := env("KEYCLOAK_HOST", "")
export CUBE_OIDC_CLIENT_ID := env("CUBE_OIDC_CLIENT_ID", "cube-cli")
export CUBE_OIDC_CALLBACK_PORT := env("CUBE_OIDC_CALLBACK_PORT", "9876")
export CUBE_STORAGE_SIZE := env("CUBE_STORAGE_SIZE", "1Gi")
export K8S_VAULT_NAMESPACE := env("K8S_VAULT_NAMESPACE", "vault")
export EXTERNAL_SECRETS_NAMESPACE := env("EXTERNAL_SECRETS_NAMESPACE", "external-secrets")
[private]
default:
@just --list --unsorted --list-submodules
# Create Cube namespace
create-namespace:
@kubectl get namespace ${CUBE_NAMESPACE} &>/dev/null || \
kubectl create namespace ${CUBE_NAMESPACE}
# Delete Cube namespace
delete-namespace:
@kubectl delete namespace ${CUBE_NAMESPACE} --ignore-not-found
# Install Cube.dev and Cubestore
install:
#!/bin/bash
set -euo pipefail
just add-helm-repo
just create-credentials
just create-database
just install-cubestore
just install-cube
echo "Cube.dev and Cubestore installed successfully"
echo "Access Cube Playground: http://localhost:4000 (after port-forward)"
echo "Run: just cube::port-forward"
# Add Helm repository
add-helm-repo:
@echo "Adding gadsme Helm repository..."
helm repo add gadsme https://gadsme.github.io/charts
helm repo update
# Install Cubestore cluster
install-cubestore:
@echo "Installing Cubestore cluster..."
just create-namespace
helm upgrade --install cubestore gadsme/cubestore --namespace ${CUBE_NAMESPACE} \
--version ${CUBESTORE_CHART_VERSION} --values cubestore-values.yaml --wait --timeout=5m
# Install Cube.dev
install-cube:
#!/bin/bash
set -euo pipefail
echo "Installing Cube.dev..."
export CUBE_HOST=${CUBE_HOST:-}
while [ -z "${CUBE_HOST}" ]; do
CUBE_HOST=$(
gum input --prompt="Cube host (FQDN): " --width=100 \
--placeholder="e.g., cube.example.com" \
)
done
gomplate -f cube-values.gomplate.yaml -o cube-values.yaml
helm upgrade --install cube gadsme/cube --namespace ${CUBE_NAMESPACE} \
--version ${CUBE_CHART_VERSION} --values cube-values.yaml --wait --timeout=5m
# Create Cube database and user
create-database:
#!/bin/bash
set -euo pipefail
echo "Creating Cube database and user..."
password=$(just utils::random-password)
# Create database if not exists
if ! just postgres::db-exists cube &>/dev/null; then
just postgres::create-db cube
else
echo "Database cube already exists"
fi
# Handle existing user - update password instead of recreating
if just postgres::user-exists cube &>/dev/null; then
echo "User cube already exists, updating password..."
just postgres::change-password cube "${password}"
else
# Create new user
echo "Creating new user cube..."
just postgres::create-user cube "${password}"
just postgres::grant cube cube
fi
just create-namespace
if helm status external-secrets -n ${EXTERNAL_SECRETS_NAMESPACE} &>/dev/null; then
echo "External Secrets Operator detected. Creating ExternalSecret..."
just vault::put postgres/cube password="${password}"
kubectl delete secret postgres-cube-secret -n ${CUBE_NAMESPACE} --ignore-not-found
kubectl delete externalsecret postgres-cube-external-secret -n ${CUBE_NAMESPACE} \
--ignore-not-found
gomplate -f postgres-cube-external-secret.gomplate.yaml | kubectl apply -f -
echo "Waiting for ExternalSecret to sync..."
kubectl wait --for=condition=Ready externalsecret/postgres-cube-external-secret \
-n ${CUBE_NAMESPACE} --timeout=60s
else
echo "External Secrets Operator not found. Creating secret directly..."
kubectl delete secret postgres-cube-secret -n ${CUBE_NAMESPACE} --ignore-not-found
kubectl create secret generic postgres-cube-secret -n ${CUBE_NAMESPACE} \
--from-literal=password="${password}"
if helm status vault -n ${K8S_VAULT_NAMESPACE} &>/dev/null; then
just vault::put postgres/cube password="${password}"
fi
fi
echo "Cube database and user created successfully"
# Create Cube API secret
create-credentials:
#!/bin/bash
set -euo pipefail
api_secret=$(just utils::random-password)
just create-namespace
if helm status external-secrets -n ${EXTERNAL_SECRETS_NAMESPACE} &>/dev/null; then
echo "External Secrets Operator detected. Creating ExternalSecret..."
just put-api-secret-to-vault "${api_secret}"
kubectl delete secret cube-api-secret -n ${CUBE_NAMESPACE} --ignore-not-found
kubectl delete externalsecret cube-api-external-secret -n ${CUBE_NAMESPACE} \
--ignore-not-found
gomplate -f cube-api-external-secret.gomplate.yaml | kubectl apply -f -
echo "Waiting for ExternalSecret to sync..."
kubectl wait --for=condition=Ready externalsecret/cube-api-external-secret \
-n ${CUBE_NAMESPACE} --timeout=60s
else
echo "External Secrets Operator not found. Creating secret directly..."
if kubectl get secret cube-api-secret -n ${CUBE_NAMESPACE} &>/dev/null; then
kubectl delete --ignore-not-found secret cube-api-secret -n ${CUBE_NAMESPACE}
fi
kubectl create secret generic cube-api-secret -n ${CUBE_NAMESPACE} \
--from-literal=api-secret="${api_secret}"
if helm status vault -n ${K8S_VAULT_NAMESPACE} &>/dev/null; then
just put-api-secret-to-vault "${api_secret}"
fi
fi
# Delete Cube API secret
delete-credentials:
@kubectl delete secret cube-api-secret -n ${CUBE_NAMESPACE} --ignore-not-found
@kubectl delete externalsecret cube-api-secret -n ${CUBE_NAMESPACE} --ignore-not-found
# Create Keycloak client for Cube
create-keycloak-client:
@just keycloak::create-client realm=${KEYCLOAK_REALM} client_id=${CUBE_OIDC_CLIENT_ID} \
redirect_url="http://localhost:${CUBE_OIDC_CALLBACK_PORT}/callback"
# Get JWT token using oauth2c
get-token:
#!/bin/bash
set -euo pipefail
TOKEN=$(oauth2c \
--issuer-url "https://${KEYCLOAK_HOST}/realms/${KEYCLOAK_REALM}" \
--client-id ${CUBE_OIDC_CLIENT_ID} \
--redirect-url "http://localhost:${CUBE_OIDC_CALLBACK_PORT}/callback" \
--scopes "openid profile email" \
--response-types code \
--grant-type authorization_code \
--auth-method none \
--browser-timeout 300s \
--silent 2>/dev/null | jq -r '.access_token')
echo "${TOKEN}"
# Show JWT token for Playground
show-token:
@echo "JWT Token for Cube Playground:"
@echo "Copy this token to Playground > Add Security Context > Token tab:"
@echo
@just cube::get-token
# Uninstall Cube.dev
uninstall-cube:
@echo "Deleting Cube.dev..."
helm uninstall cube -n ${CUBE_NAMESPACE} --ignore-not-found
# Uninstall Cubestore
uninstall-cubestore:
@echo "Deleting Cubestore..."
helm uninstall cubestore -n ${CUBE_NAMESPACE} --ignore-not-found
# Uninstall everything
uninstall: uninstall-cube uninstall-cubestore delete-credentials delete-namespace
# Test connection to Cube API
test-api:
#!/bin/bash
set -euo pipefail
echo "Testing Cube API connection..."
TOKEN=$(just cube::get-token)
if [ -n "${CUBE_HOST}" ]; then
API_URL="https://${CUBE_HOST}/cubejs-api/v1/meta"
echo "Testing via Ingress: ${API_URL}"
else
API_URL="http://localhost:4000/cubejs-api/v1/meta"
echo "Testing via port-forward: ${API_URL}"
fi
curl -s -H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
"${API_URL}" || echo "API test failed - check connection method"
# Show configuration
config:
@echo "Cube Configuration:"
@echo "Namespace: ${CUBE_NAMESPACE}"
@echo "Cube Host: ${CUBE_HOST}"
@echo "Keycloak Host: ${KEYCLOAK_HOST}"
@echo "Keycloak Realm: ${KEYCLOAK_REALM}"
@echo "Cube OIDC Client ID: ${CUBE_OIDC_CLIENT_ID}"
@echo "OIDC Callback Port: ${CUBE_OIDC_CALLBACK_PORT}"
@echo "Storage Size: ${CUBE_STORAGE_SIZE}"
# Put API secret to Vault
put-api-secret-to-vault secret:
@just vault::put cube/api api-secret={{ secret }}
@echo "API secret stored in Vault under 'cube/api'."
# Delete API secret from Vault
delete-api-secret-from-vault:
@just vault::delete cube/api
@echo "API secret deleted from Vault."