diff --git a/.gitignore b/.gitignore index 925ac58..15b14c4 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ htmlcov/ /workstation/Prole/Saved/ /workstation/Prole/DerivedDataCache/ /workstation/Prole/Build/ +/ssh-keys/ diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/env.sh b/MagicMock/mock.Entry().get().strip()/4411745888/env.sh deleted file mode 100755 index 430df05..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/env.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Prole environment configuration -# This file is generated by the installer. Source it in new shells, or execute as a wrapper: -# "$PROLE_HOME/env.sh" [args…] -# shellcheck shell=bash -export PROLE_HOME="" -export PROLE_CONF="" -export PROLE_DATA="" -export PROLE_LOGS="" -export PROLE_SERVICE="" - -# Ensure PATH works for GUI-launched shells (Docker, Ollama, etc.) -_prole_add_path() { case ":${PATH}:" in *":$1:"*) ;; *) PATH="$1:${PATH:-}" ;; esac; } -_prole_add_path "$PROLE_HOME/bin" -_prole_add_path "/opt/homebrew/bin" -_prole_add_path "/usr/local/bin" -_prole_add_path "/usr/bin" -_prole_add_path "/bin" -_prole_add_path "/usr/sbin" -_prole_add_path "/sbin" -export PATH - -# Add custom paths below if needed (examples): -# _prole_add_path "/Applications/Ollama.app/Contents/MacOS" - -# If executed with arguments, run them under this environment -if [ "$#" -gt 0 ]; then - exec "$@" -fi diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/hosts.txt b/MagicMock/mock.Entry().get().strip()/4411745888/hosts.txt deleted file mode 100644 index 4e73115..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/hosts.txt +++ /dev/null @@ -1,15 +0,0 @@ -myrddin.prole.org 10.0.0.3 -raspberry.prole.org 10.0.0.4 -pi.prole.org 10.0.0.5 -synology.prole.org 10.0.0.203 -morgoth.prole.org 10.0.0.204 -zinfandel.prole.org 10.0.0.205 -aventage.prole.org 10.0.0.206 -retropie.prole.org 10.0.0.207 -fairyland.prole.org 10.0.0.208 -k8s.prole.org zinfandel.prole.org -mc.prole.org 73.15.20.166 -morana.prole.org 10.0.0.66 -ollama.prole.org 73.15.20.166 -svc.prole.org 73.15.20.166 -www.prole.org ghs.googlehosted.com \ No newline at end of file diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/init_cloudnative_pg.sh b/MagicMock/mock.Entry().get().strip()/4411745888/init_cloudnative_pg.sh deleted file mode 100755 index 6708415..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/init_cloudnative_pg.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_cloudnative_pg.sh -# Purpose: -# - Distribute administrator ed25519 key pair to CloudNative‑PG as a Kubernetes Secret for cert auth -# - Configure Kerberos (GSSAPI) using external Kerberos KDC -# - Patch CNPG cluster to enable TLS and GSSAPI where possible -# -# Usage: -# ./init_cloudnative_pg.sh start|stop|status|restart -# ./init_cloudnative_pg.sh initialize # create/update k8s secrets/configs and patch CNPG -# ./init_cloudnative_pg.sh update|reload # re-apply/patch -# -# Requirements: -# - init_openbao.sh has been run (OpenBao running in k8s) -# - $PROLE_HOME/env.sh or $HOME/.prole/env.sh defining PROLE_SERVICE - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Load env without leaking our positional args to the env script (some env.sh may `exec "$@"`). -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -else - echo "ERROR: Missing env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env." >&2 - exit 1 -fi - -ACTION=${1:-} -CNPG_CLUSTER_NAME=${2:-${CNPG_CLUSTER_NAME:-prole-db}} -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -REALM=${REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-prole.org} -KRB5_KDC=${KRB5_KDC:-} -KRB5_ADMIN=${KRB5_ADMIN:-} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -SECRETS_DIR="$PROLE_SERVICE/secrets" -ADMIN_PRIV="$SECRETS_DIR/admin_ed25519.key" -ADMIN_PUB="$SECRETS_DIR/admin_ed25519.pub" -OPENBAO_TOKEN_FILE="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64 jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -# Resolve OpenBao URL: prefer explicit env, then localhost port-forward, then cluster DNS -bao_service_url() { - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - echo "$PROLE_OPENBAO_URL" - return 0 - fi - # Prefer standard local port-forward managed by etc/init_port_forwards.sh - if curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - echo "http://127.0.0.1:18200" - return 0 - fi - echo "http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" -} - -fetch_admin_keys_and_db_pass_from_bao_or_local() { - local token url - if [[ -f "$OPENBAO_TOKEN_FILE" ]]; then - token=$(cat "$OPENBAO_TOKEN_FILE") - else - token="" - fi - url=$(bao_service_url) - if [[ -n "$token" ]]; then - echo "Attempting to read admin key pair from OpenBao kv/prole/admin ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -e '.data.data' >/dev/null 2>&1; then - local priv_b64 pub_b64 - priv_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_private_key_b64') - pub_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_public_key_b64') - printf "%s" "$priv_b64" | base64 -d >"$ADMIN_PRIV" - printf "%s" "$pub_b64" | base64 -d >"$ADMIN_PUB" - chmod 0600 "$ADMIN_PRIV" - fi - - echo "Attempting to read database password from OpenBao kv/prole/db ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -e '.data.data' >/dev/null 2>&1; then - local db_pass - db_pass=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -r '.data.data.password') - if [[ -n "$db_pass" ]]; then - echo "Updating database user secret 'prole-db-user' from OpenBao ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username=prole \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - - echo "Updating database superuser secret 'prole-db-superuser' from OpenBao ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - fi - fi - fi - - if [[ -f "$ADMIN_PRIV" && -f "$ADMIN_PUB" ]]; then - echo "Using local admin key pair at $SECRETS_DIR" - return 0 - fi - echo "ERROR: Could not obtain admin key pair from OpenBao and no local files found." >&2 - exit 1 -} - -apply_cnpg_admin_secret() { - echo "Creating/updating Secret cnpg-admin-key ..." - kubectl create secret generic cnpg-admin-key -n "$NAMESPACE" \ - --from-file=admin.key="$ADMIN_PRIV" \ - --from-file=admin.pub="$ADMIN_PUB" \ - --dry-run=client -o yaml | kubectl apply -f - -} - -ensure_krb5_conf_configmap() { - echo "Creating/updating ConfigMap prole-krb5-conf ..." - - local kdc_val admin_val - if [[ -n "$KRB5_KDC" ]]; then - kdc_val="$KRB5_KDC" - admin_val=${KRB5_ADMIN:-$(echo "$KRB5_KDC" | cut -d, -f1)} - else - kdc_val="kdc.$DOMAIN" - admin_val="kdc.$DOMAIN" - fi - - local TMP - TMP=$(mktemp) - cat >"$TMP" </dev/null 2>&1; then - echo "CA secret $ca_secret_name already exists; skipping generation." - return 0 - fi - echo "Generating self-signed CA (RSA 4096) for CNPG ..." - local TMPD - TMPD=$(mktemp -d) - openssl genrsa -out "$TMPD/ca.key" 4096 - openssl req -x509 -new -key "$TMPD/ca.key" -out "$TMPD/ca.crt" -days 3650 -subj "/CN=Prole CNPG CA" - kubectl -n "$NAMESPACE" create secret generic "$ca_secret_name" \ - --from-file=ca.crt="$TMPD/ca.crt" \ - --from-file=ca.key="$TMPD/ca.key" \ - --dry-run=client -o yaml | kubectl apply -f - - rm -rf "$TMPD" -} - -patch_cnpg_cluster_for_auth() { - echo "Patching CNPG Cluster $CNPG_CLUSTER_NAME to enable GSSAPI and fix config (best-effort) ..." - # Best-effort patch; schema may vary with CNPG version. - # We remove krb_srvname as it is unrecognized in some PG 17 builds. - # We revert certificates to default to avoid operator TLS issues. - kubectl -n "$NAMESPACE" patch cluster "$CNPG_CLUSTER_NAME" --type merge -p "{ - \"spec\": { - \"postgresql\": { - \"parameters\": {\"krb_srvname\": null}, - \"pg_hba\": [ - \"local all postgres trust\", - \"host all postgres all scram-sha-256\", - \"host all all all gss include_realm=1 krb_realm=$REALM\", - \"host all all all scram-sha-256\" - ] - }, - \"certificates\": { - \"serverCASecret\": null, - \"clientCASecret\": null - } - } - }" >/dev/null || echo "Note: patch may need adjustment for your CNPG version." -} - -initialize() { - ensure_tools - - # Ensure port-forward is running for OpenBao (dependency) - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - fetch_admin_keys_and_db_pass_from_bao_or_local - apply_cnpg_admin_secret - ensure_krb5_conf_configmap - # generate_tls_if_missing - patch_cnpg_cluster_for_auth - - # Ensure port-forward is running for Postgres (local access) - echo "Ensuring port-forward for Postgres is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart postgres - - echo "Initialization complete for CNPG + Kerberos + cert artifacts." -} - -update_reload() { - initialize -} - -case "$ACTION" in - recreate) - ensure_tools - "$0" delete "$CNPG_CLUSTER_NAME" - "$0" create "$CNPG_CLUSTER_NAME" - ;; - create) - ensure_tools - echo "Installing CloudNative-PG operator ..." - kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml - - echo "Creating CloudNative-PG cluster and resources for '$CNPG_CLUSTER_NAME' ..." - - kubectl apply -k "$SCRIPT_DIR/../k8s/prole" - - # Ensure prole-index-html exists for prole deployment readiness probe - if ! kubectl get configmap prole-index-html -n prole >/dev/null 2>&1; then - echo "Creating prole-index-html configmap..." - printf "

Prole

" > /tmp/index.html - kubectl create configmap prole-index-html --from-file=/tmp/index.html -n prole - rm /tmp/index.html - fi - - # Ensure prole-nginx-tls exists (self-signed for dev) - if ! kubectl get secret prole-nginx-tls -n prole >/dev/null 2>&1; then - echo "Generating self-signed prole-nginx-tls for development..." - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /tmp/nginx-tls.key -out /tmp/nginx-tls.crt \ - -subj "/CN=prole.org" >/dev/null 2>&1 - kubectl create secret tls prole-nginx-tls --key /tmp/nginx-tls.key --cert /tmp/nginx-tls.crt -n prole - rm /tmp/nginx-tls.key /tmp/nginx-tls.crt - fi - - echo "Initializing and patching cluster ..." - initialize - ;; - delete) - ensure_tools - echo "Deleting all resources for '$CNPG_CLUSTER_NAME' ..." - kubectl delete -k "$SCRIPT_DIR/../k8s/prole" --ignore-not-found - ;; - start) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Starting CloudNative-PG cluster from $CNPG_MANIFEST in namespace $NAMESPACE..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - ;; - stop) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Stopping CloudNative-PG cluster using $CNPG_MANIFEST ..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found - ;; - status) - ensure_tools - echo "--- CloudNative-PG Cluster Status ($CNPG_CLUSTER_NAME) ---" - if kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" - echo "" - echo "CNPG Plugin Status:" - if kubectl cnpg version >/dev/null 2>&1; then - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - else - echo "Note: 'kubectl cnpg' plugin not found; skipping detailed status." - fi - else - echo "Cluster '$CNPG_CLUSTER_NAME' not found in namespace '$NAMESPACE'." - fi - ;; - restart) - ensure_tools - "$0" stop - "$0" start - ;; - initialize) - initialize - ;; - update|reload) - update_reload - ;; - *) - echo "Usage: $0 {create|delete|recreate|start|stop|status|restart|initialize|update|reload} [dbname]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/init_k8s.sh b/MagicMock/mock.Entry().get().strip()/4411745888/init_k8s.sh deleted file mode 100755 index 35f14aa..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/init_k8s.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# etc/init_k8s.sh -# Purpose: Manage k3d/k8s environment - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -# Default values -VERBOSE=false -ENVIRONMENT="prod" -HOST="" -CLUSTER_NAME_DEFAULT="prole-dev-cluster" -CLUSTER_PORT_DEFAULT="6443" - -usage() { - cat </dev/null || { echo "ERROR: Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - if ! docker info >/dev/null 2>&1; then - echo "ERROR: Docker is not running." >&2 - exit 1 - fi -} - -initialize() { - ensure_tools - ensure_docker - - if [[ "$ENVIRONMENT" == "dev" ]]; then - if [[ -z "$CLUSTER_NAME" ]]; then - if [[ -t 0 ]]; then - read -p "Enter k3d cluster name [$CLUSTER_NAME_DEFAULT]: " CLUSTER_NAME - CLUSTER_NAME=${CLUSTER_NAME:-$CLUSTER_NAME_DEFAULT} - else - CLUSTER_NAME=$CLUSTER_NAME_DEFAULT - fi - fi - - if k3d cluster list "$CLUSTER_NAME" >/dev/null 2>&1; then - log "Cluster '$CLUSTER_NAME' already exists." - else - log "Creating k3d cluster '$CLUSTER_NAME'..." - k3d cluster create "$CLUSTER_NAME" -p "0.0.0.0:$CLUSTER_PORT_DEFAULT:6443@server:0" - fi - else - if [[ -n "$HOST" ]]; then - log "Environment is $ENVIRONMENT. Host is $HOST." - log "TODO: Fetch kubeconfig from $HOST (placeholder)." - else - log "Environment is $ENVIRONMENT. Use -h|--host to specify the remote cluster host." - fi - fi -} - -status() { - ensure_tools - log "Checking Docker status..." - if docker info >/dev/null 2>&1; then - echo "Docker is running." - else - echo "Docker is NOT running." - fi - - log "Listing k3d clusters..." - k3d cluster list -} - -get_cluster_name() { - # If a name was provided or exists in env, use it. - # Otherwise, if there is only one cluster, use it. - # Finally, use default. - if [[ -n "${CLUSTER_NAME:-}" ]]; then - echo "$CLUSTER_NAME" - return - fi - - local clusters - clusters=$(k3d cluster list --no-headers | awk '{print $1}') - local count - count=$(echo "$clusters" | grep -c . || true) - - if [[ "$count" -eq 1 ]]; then - echo "$clusters" - else - echo "$CLUSTER_NAME_DEFAULT" - fi -} - -case "$ACTION" in - initialize) - initialize - ;; - status) - status - ;; - start) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Starting k3d cluster '$CLUSTER_NAME'..." - k3d cluster start "$CLUSTER_NAME" - ;; - stop) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Stopping k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - ;; - restart) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Restarting k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - k3d cluster start "$CLUSTER_NAME" - ;; - *) - usage - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/init_openbao.sh b/MagicMock/mock.Entry().get().strip()/4411745888/init_openbao.sh deleted file mode 100755 index 3e59151..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/init_openbao.sh +++ /dev/null @@ -1,490 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_openbao.sh -# Purpose: -# - Deploy OpenBao to Kubernetes (dev mode) and store admin ed25519 key pair -# Generate and apply a Kerberos krb5.conf ConfigMap for an external realm -# - Local Docker helpers for OpenBao (optional) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi - -ACTION=${1:-} - -# Defaults -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -OPENBAO_MANIFEST_DIR="$SCRIPT_DIR/../k8s/openbao" - -# Kerberos realm defaults -KRB5_REALM=${KRB5_REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-$(echo "$KRB5_REALM" | tr 'A-Z' 'a-z')} -KRB5_KDC=${KRB5_KDC:-kdc.$DOMAIN} -KRB5_ADMIN=${KRB5_ADMIN:-} - -# Secrets and token locations -SECRETS_DIR="$PROLE_SERVICE/secrets" -mkdir -p "$SECRETS_DIR" -admin_key_priv="$SECRETS_DIR/admin_ed25519.key" -admin_key_pub="$SECRETS_DIR/admin_ed25519.pub" -root_token_file="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - command -v docker >/dev/null || { echo "Missing required tool: docker" >&2; exit 1; } -} - -ensure_admin_keypair() { - # Ensure admin ed25519 keypair exists and a root token is available - mkdir -p "$SECRETS_DIR" - if [[ ! -f "$admin_key_priv" || ! -f "$admin_key_pub" ]]; then - echo "Generating admin ed25519 keypair in $SECRETS_DIR ..." - openssl genpkey -algorithm ED25519 -out "$admin_key_priv" - openssl pkey -in "$admin_key_priv" -pubout -out "$admin_key_pub" - chmod 0600 "$admin_key_priv" - fi - # Ensure a root token exists for OpenBao dev server interactions - if [[ ! -f "$root_token_file" || ! -s "$root_token_file" ]]; then - openssl rand -hex 24 >"$root_token_file" - chmod 0600 "$root_token_file" - fi -} - -generate_openbao_manifests() { - mkdir -p "$OPENBAO_MANIFEST_DIR" - # Only create a simple deployment if none exists; otherwise respect current file - local deploy="$OPENBAO_MANIFEST_DIR/deployment.yaml" - if [[ ! -f "$deploy" ]]; then - cat >"$deploy" <"$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" </dev/null 2>&1; then - kubectl rollout status statefulset/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - else - kubectl rollout status deploy/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - fi -} - -init_openbao_kv_and_store_admin_key() { - local token - token=$(cat "$root_token_file") - # Enable kv (if not already) and write keys - local svc="http://127.0.0.1:18200" - echo "Configuring KV at $svc ..." - - # Check if kv/ is already mounted - if curl -sS -H "X-Vault-Token: $token" "$svc/v1/sys/mounts" | grep -q '"kv/":'; then - echo "KV path 'kv/' is already enabled." - else - curl -sS -H "X-Vault-Token: $token" -X POST "$svc/v1/sys/mounts/kv" \ - -d '{"type":"kv","options":{"version":"2"}}' >/dev/null 2>&1 || true - fi - - local priv pub - priv=$(base64 <"$admin_key_priv" | tr -d '\n') - pub=$(base64 <"$admin_key_pub" | tr -d '\n') - - # Check if admin key already exists and matches - local existing_data - existing_data=$(curl -sS -H "X-Vault-Token: $token" "$svc/v1/kv/data/prole/admin" 2>/dev/null || true) - if [[ -n "$existing_data" ]]; then - local ex_priv ex_pub - ex_priv=$(echo "$existing_data" | grep -o '"admin_private_key_b64":"[^"]*' | cut -d'"' -f4 || true) - ex_pub=$(echo "$existing_data" | grep -o '"admin_public_key_b64":"[^"]*' | cut -d'"' -f4 || true) - - if [[ "$ex_priv" == "$priv" && "$ex_pub" == "$pub" ]]; then - echo "Admin key pair in OpenBao kv/prole/admin is already up to date." - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - - # Store User SSH keys if they exist - local user_key_priv="$HOME/.ssh/id_prole_ed25519" - local user_key_pub="$HOME/.ssh/id_prole_ed25519.pub" - if [[ -f "$user_key_priv" && -f "$user_key_pub" ]]; then - local u_priv u_pub - u_priv=$(base64 <"$user_key_priv" | tr -d '\n') - u_pub=$(base64 <"$user_key_pub" | tr -d '\n') - local username=${PROLE_DB_USER:-"prole"} - - echo "Writing user SSH keys for '$username' to kv/prole/user ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/user" \ - -d "{\"data\":{\"username\":\"$username\",\"private_key_b64\":\"$u_priv\",\"public_key_b64\":\"$u_pub\"}}" >/dev/null - echo "Stored user SSH keys in OpenBao kv/prole/user." - fi - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Writing database user password for '$username' to kv/prole/db ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/db" \ - -d "{\"data\":{\"username\":\"$username\",\"password\":\"$db_pass\"}}" >/dev/null - echo "Stored database password in OpenBao kv/prole/db." - fi -} - -# Removed: prompt_admin_password_and_apply_secret (no AD admin secret required) - -docker_start() { - echo "Starting local Docker container for OpenBao ..." - ensure_docker - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - # OpenBao dev - local token - token=$(cat "$root_token_file" 2>/dev/null || true) - if [[ -z "$token" ]]; then - token=$(openssl rand -hex 24) - printf "%s" "$token" >"$root_token_file" - chmod 0600 "$root_token_file" - fi - docker run -d --name "$OPENBAO_NAME" -p 18200:8200 \ - "$OPENBAO_IMAGE" server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id="$token" - echo "Docker container started: $OPENBAO_NAME" -} - -docker_stop() { - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - echo "Stopped OpenBao container if it was running." -} - -docker_restart() { - docker_stop - docker_start -} - -# status command implementation wrapped in a function to avoid top-level 'local' -cmd_status() { - echo "--- init_primary_domain status ---" - echo "Namespace: $NAMESPACE" - echo "OpenBao name: $OPENBAO_NAME" - echo "Manifest dir: $OPENBAO_MANIFEST_DIR" - - # Files/manifests present - local ok=0 - if [[ -f "$OPENBAO_MANIFEST_DIR/deployment.yaml" ]]; then - echo "[OK] OpenBao deployment manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/deployment.yaml" - ok=1 - fi - if [[ -f "$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" ]]; then - echo "[OK] Kerberos ConfigMap manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" - ok=1 - fi - - # K8s resources - if kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" >/dev/null 2>&1; then - local ready desired - ready=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao StatefulSet running ($ready/$desired ready)" - else - echo "[WARN] OpenBao StatefulSet not fully ready ($ready/$desired)" - ok=1 - fi - elif kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" >/dev/null 2>&1; then - # Get readiness - local ready desired - ready=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao Deployment running ($ready/$desired ready)" - else - echo "[WARN] OpenBao Deployment not fully ready ($ready/$desired)" - ok=1 - fi - else - echo "[MISSING] OpenBao Deployment or StatefulSet '$OPENBAO_NAME' in namespace '$NAMESPACE'" - ok=1 - fi - - if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then - echo "[OK] Kerberos ConfigMap 'prole-krb5-conf' present" - else - echo "[MISSING] Kerberos ConfigMap 'prole-krb5-conf' in namespace '$NAMESPACE'" - ok=1 - fi - - # Docker (optional local mode) - if command -v docker >/dev/null 2>&1; then - if docker ps --format '{{.Names}}' | grep -Fxq "$OPENBAO_NAME"; then - echo "[OK] Docker container '$OPENBAO_NAME' is running" - else - # Not necessarily an error; we primarily use k8s - echo "[INFO] Docker container '$OPENBAO_NAME' not running (k8s mode may be in use)" - fi - fi - - # Secrets and tokens - if [[ -f "$admin_key_priv" && -f "$admin_key_pub" ]]; then - echo "[OK] Admin ed25519 keypair present in $SECRETS_DIR" - else - echo "[MISSING] Admin keypair files in $SECRETS_DIR" - ok=1 - fi - if [[ -s "$root_token_file" ]]; then - echo "[OK] OpenBao root token file present" - else - echo "[MISSING] OpenBao root token file ($root_token_file)" - ok=1 - fi - - # OpenBao reachability and token validity (best-effort) - # Prefer explicit override, then localhost port-forward, then cluster DNS - local svc_url - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - svc_url="$PROLE_OPENBAO_URL" - elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - svc_url="http://127.0.0.1:18200" - else - svc_url="http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" - fi - if curl -sS "$svc_url/v1/sys/health" >/dev/null 2>&1; then - echo "[OK] OpenBao service reachable" - if [[ -s "$root_token_file" ]]; then - local code - code=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Vault-Token: $(cat "$root_token_file")" "$svc_url/v1/sys/mounts" || echo "000") - if [[ "$code" == "200" ]]; then - echo "[OK] OpenBao root token authenticates" - else - echo "[WARN] OpenBao root token did not authenticate (HTTP $code)" - ok=1 - fi - fi - else - echo "[WARN] OpenBao service not reachable at $svc_url" - ok=1 - fi - - # Service certificate existence (CNPG TLS) - local CNPG_CLUSTER_NAME - CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} - if kubectl -n "$NAMESPACE" get secret "${CNPG_CLUSTER_NAME}-tls" >/dev/null 2>&1; then - echo "[OK] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' exists" - else - echo "[INFO] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' not found" - fi - - echo "-------------------------------------" - if [[ $ok -eq 0 ]]; then - echo "Status: OK" - return 0 - else - echo "Status: Issues detected" - return 1 - fi -} - -case "$ACTION" in - start) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_start - ;; - status) - ensure_tools - cmd_status - ;; - stop) - ensure_docker - docker_stop - ;; - restart) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_restart - ;; - initialize) - ensure_tools - # Read password from stdin if provided - db_pass="" - if [[ ! -t 0 ]]; then - read -r db_pass - fi - - ensure_admin_keypair - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Creating database user secret 'prole-db-user' for '$username' ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username="$username" \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - - echo "Creating database superuser secret 'prole-db-superuser' ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - fi - - wait_for_openbao - - # Ensure port-forward is running for OpenBao - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - if ! curl -sS http://127.0.0.1:18200/v1/sys/health >/dev/null 2>&1; then - echo "ERROR: OpenBao not reachable at http://127.0.0.1:18200." >&2 - echo "Please start port-forwards: $SCRIPT_DIR/init_port_forwards.sh start openbao" >&2 - exit 1 - fi - init_openbao_kv_and_store_admin_key - echo "Initialization complete. Manifests in: $OPENBAO_MANIFEST_DIR" - ;; - update|reload) - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - echo "Re-applied manifests." - ;; - *) - echo "Usage: $0 {start|stop|status|restart|initialize|update|reload}" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/init_port_forwards.sh b/MagicMock/mock.Entry().get().strip()/4411745888/init_port_forwards.sh deleted file mode 100755 index 9ebea5c..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/init_port_forwards.sh +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env bash -set -u - -# init_port_forwards.sh -# Portable-ish (macOS, Ubuntu, Raspberry Pi OS, Alpine) bash init-style script -# Manages kubectl port-forward daemons defined in an XML file. - -PROG="init_port_forwards" -PROLE_HOME="${PROLE_HOME:-/Users/chrisfu/dev/prole}" -VERBOSE=0 -CONFIG_FILE="$PROLE_HOME/conf/port-mappings.properties" - -usage() { - cat < [component] - -Options: - -c, --config-file=FILE Path to local-ports.properties (XML) - -v, --verbose Verbose output - -Examples: - $PROG -c ./port-mappings.properties start - $PROG stop openbao - $PROG --verbose status -EOF -} - -TARGET_ID="" - -log() { printf '%s\n' "$*"; } -vlog() { [ "$VERBOSE" -eq 1 ] && printf '[verbose] %s\n' "$*" || true; } -err() { printf '[error] %s\n' "$*" >&2; } - -have() { command -v "$1" >/dev/null 2>&1; } - -# Choose a writable state dir for pid/log files: -# - Prefer XDG_RUNTIME_DIR if set and writable -# - Else /var/run if writable (rare without root) -# - Else ~/.local/state -# - Else /tmp -state_dir() { - if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -w "${XDG_RUNTIME_DIR:-}" ]; then - printf '%s/%s' "$XDG_RUNTIME_DIR" "$PROG" - return - fi - if [ -d "/var/run" ] && [ -w "/var/run" ]; then - printf '/var/run/%s' "$PROG" - return - fi - if [ -n "${HOME:-}" ]; then - mkdir -p "$HOME/.local/state" >/dev/null 2>&1 || true - if [ -d "$HOME/.local/state" ] && [ -w "$HOME/.local/state" ]; then - printf '%s/.local/state/%s' "$HOME" "$PROG" - return - fi - fi - printf '/tmp/%s' "$PROG" -} - -STATE_DIR="$(state_dir)" -PID_DIR="$STATE_DIR/pids" -LOG_DIR="$STATE_DIR/logs" - -ensure_dirs() { - mkdir -p "$PID_DIR" "$LOG_DIR" 2>/dev/null || true - if [ ! -d "$PID_DIR" ] || [ ! -d "$LOG_DIR" ]; then - err "Unable to create state directories under: $STATE_DIR" - exit 1 - fi -} - -# Use kubectl for actions; kubecolor is used only for prettier status output. -KUBECTL="kubectl" -detect_kubectl() { - if have kubectl; then - KUBECTL="kubectl" - else - err "kubectl not found in PATH" - exit 1 - fi -} - -# Basic environment validation -validate_env() { - detect_kubectl - ensure_dirs - - if ! "$KUBECTL" version --client >/dev/null 2>&1; then - err "kubectl seems broken or not executable" - exit 1 - fi - - # Can we reach the cluster? - if ! "$KUBECTL" cluster-info >/dev/null 2>&1; then - err "kubectl cannot reach a cluster (check KUBECONFIG/context)" - err "Try: kubectl config get-contexts && kubectl config use-context " - exit 1 - fi -} - -# ---- Preflight: Docker + k3d awareness ---- -# Return 0 when Docker CLI can talk to a running daemon. -docker_is_running() { - if ! have docker; then - return 1 - fi - docker info >/dev/null 2>&1 -} - -# Hard-fail with clean guidance when Docker is not up (used for start/restart). -ensure_docker_running() { - if docker_is_running; then - return 0 - fi - if ! have docker; then - err "Docker CLI not found. Please install Docker Desktop or docker CLI." - else - err "Docker is not running. Start Docker Desktop and wait until it is ready." - fi - err "Tip (macOS): open -a Docker" - err "Then re-run: $PROG start" - exit 3 -} - -# Detect k3d cluster name from env or current kubectl context. -# - If K3D_CLUSTER is set, use it. -# - Else, if current-context starts with 'k3d-', strip prefix to get name. -detect_k3d_context() { - if [ -n "${K3D_CLUSTER:-}" ]; then - printf '%s' "$K3D_CLUSTER" - return 0 - fi - local ctx - ctx="$($KUBECTL config current-context 2>/dev/null || echo)" - case "$ctx" in - k3d-*) printf '%s' "${ctx#k3d-}"; return 0 ;; - *) return 1 ;; - esac -} - -# Return 0 if the given k3d cluster exists and is running. -k3d_cluster_is_running() { - local name="$1" - have k3d || return 1 - # Use json output when available; fall back to grep otherwise - if k3d cluster list -o json >/dev/null 2>&1; then - k3d cluster list -o json 2>/dev/null | grep -q '"name"\s*:\s*"'"$name"'"' && \ - k3d cluster list -o json 2>/dev/null | sed -n 's/.*"name"\s*:\s*"\([^"]\+\)".*"serversRunning"\s*:\s*\([0-9]\+\).*/\1 \2/p' | awk -v n="$name" '$1==n {exit ($2>0)?0:1}' - return $? - else - k3d cluster list 2>/dev/null | grep -E "^$name\s" | grep -q running - return $? - fi -} - -# If current context indicates k3d, ensure the cluster is up; otherwise no-op. -ensure_k3d_ready_if_applicable() { - local k3d_name - if ! k3d_name="$(detect_k3d_context)"; then - return 0 - fi - if ! have k3d; then - err "k3d is not installed but kubectl context suggests k3d (context=$("$KUBECTL" config current-context))." - err "Install k3d: brew install k3d (macOS)" - err "Or switch context: kubectl config use-context " - exit 4 - fi - if ! k3d_cluster_is_running "$k3d_name"; then - err "k3d cluster '$k3d_name' is not running." - err "Start it: k3d cluster start $k3d_name" - err "Then re-run: $PROG start" - exit 4 - fi -} - -pid_file_for() { printf '%s/%s.pid' "$PID_DIR" "$1"; } -log_file_for() { printf '%s/%s.log' "$LOG_DIR" "$1"; } - -is_pid_running() { - # Return 0 if pid exists and running, else 1 - # kill -0 is portable. - local pid="$1" - [ -n "$pid" ] && kill -0 "$pid" >/dev/null 2>&1 -} - -read_pid() { - local pf="$1" - [ -f "$pf" ] || return 1 - # shellcheck disable=SC2162 - read pid <"$pf" || return 1 - printf '%s' "$pid" -} - -write_pid() { - local pf="$1" pid="$2" - printf '%s\n' "$pid" >"$pf" -} - -remove_pidfile() { - local pf="$1" - rm -f "$pf" >/dev/null 2>&1 || true -} - -# ---- XML parsing (simple attribute extraction) ---- -# We parse lines containing: -# Attributes must use double quotes in the XML (as in the sample). -get_attr() { - # $1 = line, $2 = attribute name - # outputs value or empty - printf '%s\n' "$1" | sed -n "s/.*$2=\"\([^\"]*\)\".*/\1/p" -} - -foreach_mapping() { - # Calls a provided function with mapping fields: - # callback id ns target address hostPort servicePort protocol description - local callback="$1" - [ -f "$CONFIG_FILE" ] || { err "Config file not found: $CONFIG_FILE"; exit 1; } - - # Support both single-line and multi-line self-closing mapping tags, e.g.: - # OR lines spanning multiple lines until "/>". - local in_mapping=0 in_comment=0 buffer="" line - while IFS= read -r line; do - # Handle XML comments: skip anything between - if [ $in_comment -eq 1 ]; then - case "$line" in - *"-->"*) in_comment=0; continue ;; - *) continue ;; - esac - fi - case "$line" in - *""*) - # single-line comment; skip line - continue - ;; - *) - in_comment=1 - continue - ;; - esac - ;; - esac - if [ $in_mapping -eq 0 ]; then - case "$line" in - *"' - buffer="$buffer $line" - fi - - if [ $in_mapping -eq 1 ] && printf '%s' "$line" | grep -q "/>"; then - # Normalize whitespace to make attribute extraction robust - local merged - merged=$(printf '%s\n' "$buffer" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g') - - local id ns target address hostPort servicePort protocol description - id="$(get_attr "$merged" "id")" - ns="$(get_attr "$merged" "namespace")" - target="$(get_attr "$merged" "target")" - address="$(get_attr "$merged" "address")" - hostPort="$(get_attr "$merged" "hostPort")" - servicePort="$(get_attr "$merged" "servicePort")" - protocol="$(get_attr "$merged" "protocol")" - description="$(get_attr "$merged" "description")" - - # Basic validation - if [ -z "$id" ] || [ -z "$ns" ] || [ -z "$target" ] || [ -z "$hostPort" ] || [ -z "$servicePort" ]; then - err "Invalid mapping (missing required attributes): $merged" - exit 1 - fi - - # Filter by TARGET_ID if set - if [ -n "$TARGET_ID" ] && [ "$id" != "$TARGET_ID" ]; then - in_mapping=0 - buffer="" - continue - fi - - if [ -z "$address" ]; then address="127.0.0.1"; fi - if [ -z "$protocol" ]; then protocol="TCP"; fi - - vlog "mapping: id=$id ns=$ns target=$target address=$address hostPort=$hostPort servicePort=$servicePort protocol=$protocol" - "$callback" "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - # Reset accumulator - in_mapping=0 - buffer="" - fi - done <"$CONFIG_FILE" -} - -build_port_forward_cmd() { - # echo a command string - local ns="$1" target="$2" address="$3" hostPort="$4" servicePort="$5" - # kubectl port-forward -n --address : - printf '%s port-forward -n %s --address %s %s %s:%s' \ - "$KUBECTL" "$ns" "$address" "$target" "$hostPort" "$servicePort" -} - -start_port_forward() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile logfile cmd pid - - # Aggressively stop existing processes before starting to avoid port conflicts - stop_port_forward "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - pidfile="$(pid_file_for "$id")" - logfile="$(log_file_for "$id")" - cmd="$(build_port_forward_cmd "$ns" "$target" "$address" "$hostPort" "$servicePort")" - - log "Starting: $id $address:$hostPort -> $target:$servicePort ($ns) ${description:-}" - vlog "Command: $cmd" - - # Start in background, keep output in log. - # nohup is available on macOS/Linux; redirect stdin from /dev/null to detach. - nohup sh -c "$cmd" >>"$logfile" 2>&1 /dev/null 2>&1 || true - - # wait a moment, then SIGKILL if needed - local i - for i in 1 2 3 4 5; do - if ! is_pid_running "$pid"; then break; fi - sleep 0.2 - done - if is_pid_running "$pid"; then - err "$id did not stop gracefully; sending SIGKILL" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - else - if [ -f "$pidfile" ]; then - vlog "$id stale pidfile (pid=$pid not running)" - fi - fi - remove_pidfile "$pidfile" - - # Aggressively remove any other matching kubectl port-forward processes - # Search for processes that match: kubectl port-forward -n ... : - local extra_pids - extra_pids=$(ps -ef | grep "port-forward" | grep "\-n" | grep "$ns" | grep "$target" | grep "$hostPort:$servicePort" | grep -v grep | awk '{print $2}') - - for epid in $extra_pids; do - if [ "$epid" != "$pid" ]; then - log "Cleaning up orphan process for $id (pid=$epid)" - kill -9 "$epid" >/dev/null 2>&1 || true - fi - done -} - -status_one() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile pid - - pidfile="$(pid_file_for "$id")" - pid="" - if [ -f "$pidfile" ]; then - pid="$(read_pid "$pidfile" || true)" - fi - - if [ -n "${pid:-}" ] && is_pid_running "$pid"; then - printf 'RUNNING %-12s pid=%-7s %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$pid" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - # ps details (portable flags vary; use a conservative format) - ps -p "$pid" -o pid=,ppid=,etime=,command= 2>/dev/null | sed 's/^/ /' || true - else - printf 'STOPPED %-12s (no live pid) %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - fi -} - -do_start() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping start_port_forward -} - -do_stop() { - # stop doesn't require cluster access, but it does need state dirs - ensure_dirs - foreach_mapping stop_port_forward -} - -do_restart() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping stop_port_forward - foreach_mapping start_port_forward -} - -do_status() { - validate_env - # Non-fatal awareness messages - if docker_is_running; then - log "[OK] Docker daemon is running" - else - if have docker; then - log "[WARN] Docker is not running" - else - log "[WARN] Docker CLI not found" - fi - fi - - local _k3d_name - if _k3d_name="$(detect_k3d_context)"; then - if have k3d; then - if k3d_cluster_is_running "$_k3d_name"; then - log "[OK] k3d cluster '$_k3d_name' is running" - else - log "[WARN] k3d cluster '$_k3d_name' is not running" - fi - else - log "[WARN] k3d not installed but context suggests k3d (cluster='$_k3d_name')" - fi - fi - - log "== Context / Cluster ==" - "$KUBECTL" config current-context 2>/dev/null | sed 's/^/ context: /' || true - "$KUBECTL" cluster-info 2>/dev/null | sed 's/^/ /' || true - log "" - - log "== Port-forward processes ==" - foreach_mapping status_one - log "" - - log "== Quick k3d awareness checks (best-effort) ==" - # If user is on k3d, current-context often includes k3d-... but not guaranteed. - # Show nodes + a few namespaces/services related to mappings (best effort). - "$KUBECTL" get nodes -o wide 2>/dev/null | sed 's/^/ /' || true - log "" - "$KUBECTL" get ns 2>/dev/null | sed 's/^/ /' || true - log "" - - # For each mapping, try to show target existence - log "== Target existence (best-effort) ==" - _target_check() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - # kubectl get -n - # If target is like "svc/name", "deploy/name", etc. - if "$KUBECTL" get -n "$ns" "$target" >/dev/null 2>&1; then - printf 'OK %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - else - printf 'MISSING %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - fi - } - foreach_mapping _target_check -} - -# ---- arg parsing ---- -ACTION="" - -while [ $# -gt 0 ]; do - case "$1" in - start|stop|restart|status) - if [ -z "$ACTION" ]; then - ACTION="$1" - else - TARGET_ID="$1" - fi - shift - ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - -c) - shift - [ $# -gt 0 ] || { err "-c requires a file path"; usage; exit 2; } - CONFIG_FILE="$1" - shift - ;; - --config-file=*) - CONFIG_FILE="${1#*=}" - shift - ;; - -h|--help) - usage - exit 0 - ;; - *) - if [ -z "$ACTION" ]; then - err "Unknown arg: $1" - usage - exit 2 - fi - TARGET_ID="$1" - shift - ;; - esac -done - -[ -n "$ACTION" ] || { usage; exit 2; } - -case "$ACTION" in - start) do_start ;; - stop) do_stop ;; - restart) do_restart ;; - status) do_status ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4411745888/init_prole-db.sh b/MagicMock/mock.Entry().get().strip()/4411745888/init_prole-db.sh deleted file mode 100755 index b87de05..0000000 --- a/MagicMock/mock.Entry().get().strip()/4411745888/init_prole-db.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_prole-db.sh -# Purpose: -# - Manage prole-db CloudNative-PG cluster operations (deploy, start, stop, etc.) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -ACTION=${1:-} -VERSION=${2:-latest} - -# Load env -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - source "$HOME/.prole/env.sh" -fi - -CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} -NAMESPACE=${NAMESPACE:-prole} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -ensure_tools() { - for t in kubectl jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -get_latest_image() { - local version_file="$SCRIPT_DIR/../conf/postgresql/.version" - if [[ -f "$version_file" ]]; then - echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" - else - echo "prole-db:17.7-033" - fi -} - -start() { - ensure_tools - echo "Checking dependencies..." - - # 1. k3d is running - if ! command -v k3d >/dev/null || ! k3d cluster list >/dev/null 2>&1; then - echo "ERROR: k3d is not running or not installed." >&2 - exit 1 - fi - - # 2. cnpg operator is loaded - if ! kubectl get deployment -n cnpg-system cnpg-controller-manager >/dev/null 2>&1; then - echo "ERROR: CloudNative-PG operator is not loaded." >&2 - exit 1 - fi - - # 3. openbao is configured - if ! kubectl get statefulset openbao -n "$NAMESPACE" >/dev/null 2>&1 && ! kubectl get deployment openbao -n "$NAMESPACE" >/dev/null 2>&1; then - echo "ERROR: OpenBao is not deployed." >&2 - exit 1 - fi - - # Compare latest image with deployed - local latest_image - latest_image=$(get_latest_image) - - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - - if [[ "$current_image" != "$latest_image" ]]; then - echo "Updating cluster image from '$current_image' to '$latest_image'..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$latest_image\"}}" - # Force a rollout to ensure the new image is pulled even if it was just a tag update (though we use unique tags) - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - else - echo "Cluster is already using the latest image: $latest_image" - fi - - echo "Starting prole-db cluster (ensuring manifest is applied)..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" -} - -stop() { - ensure_tools - echo "Stopping prole-db cluster $CNPG_CLUSTER_NAME..." - - # Identify instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - if [[ -z "$instances" ]]; then - echo "No instances found for cluster $CNPG_CLUSTER_NAME." - return - fi - - # Determine replicas and primary - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - - echo "Primary: $primary" - - # Shutdown replicas first - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Shutting down replica $pod..." - kubectl exec -n "$NAMESPACE" "$pod" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - done - - # Shutdown primary last - if [[ -n "$primary" ]]; then - echo "Shutting down primary $primary..." - kubectl exec -n "$NAMESPACE" "$primary" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - - echo "Deleting cluster resource..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found -} - -restart() { - ensure_tools - echo "Restarting prole-db cluster..." - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -deploy() { - ensure_tools - local image - if [[ "$VERSION" == "latest" ]]; then - image=$(get_latest_image) - else - image="prole-db:$VERSION" - fi - - echo "Deploying $image to cluster $CNPG_CLUSTER_NAME..." - - # If cluster doesn't exist, use init_cloudnative_pg.sh create first - if ! kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then - echo "Cluster not found. Running init_cloudnative_pg.sh create..." - bash "$SCRIPT_DIR/init_cloudnative_pg.sh" create - fi - - # Ensure image is updated if manifest has an older version - # First, apply the manifest to ensure the cluster exists/is updated - echo "Applying manifest $CNPG_MANIFEST..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - - # Then force the specific image version via patch if different - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - if [[ "$current_image" != "$image" ]]; then - echo "Patching cluster to use image '$image' (was '$current_image')..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$image\"}}" - # Force a rollout - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - fi -} - -rollback() { - ensure_tools - echo "Rollback: Updating to previous image (manually specified version or fallback)..." - if [[ "$VERSION" == "latest" ]]; then - echo "Please specify a version to rollback to. Usage: $0 rollback " - exit 1 - fi - deploy -} - -backup() { - echo "Backup - tbd, when we configure s3 or other block store" -} - -reset() { - ensure_tools - echo "Resetting prole-db cluster..." - echo "Removing cnpg instances and pods..." - kubectl delete cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --ignore-not-found - - # Wait for deletion - kubectl wait --for=delete cluster/"$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --timeout=60s || true - - echo "Reinstantiating..." - deploy -} - -case "$ACTION" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - deploy) - deploy - ;; - rollback) - rollback - ;; - backup) - backup - ;; - reset) - reset - ;; - *) - echo "Usage: $0 {start|stop|restart|deploy|rollback|backup|reset} [version]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/env.sh b/MagicMock/mock.Entry().get().strip()/4413171632/env.sh deleted file mode 100755 index 5b7b968..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/env.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Prole environment configuration -# This file is generated by the installer. Source it in new shells, or execute as a wrapper: -# "$PROLE_HOME/env.sh" [args…] -# shellcheck shell=bash -export PROLE_HOME="" -export PROLE_CONF="" -export PROLE_DATA="" -export PROLE_LOGS="" -export PROLE_SERVICE="" - -# Ensure PATH works for GUI-launched shells (Docker, Ollama, etc.) -_prole_add_path() { case ":${PATH}:" in *":$1:"*) ;; *) PATH="$1:${PATH:-}" ;; esac; } -_prole_add_path "$PROLE_HOME/bin" -_prole_add_path "/opt/homebrew/bin" -_prole_add_path "/usr/local/bin" -_prole_add_path "/usr/bin" -_prole_add_path "/bin" -_prole_add_path "/usr/sbin" -_prole_add_path "/sbin" -export PATH - -# Add custom paths below if needed (examples): -# _prole_add_path "/Applications/Ollama.app/Contents/MacOS" - -# If executed with arguments, run them under this environment -if [ "$#" -gt 0 ]; then - exec "$@" -fi diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/hosts.txt b/MagicMock/mock.Entry().get().strip()/4413171632/hosts.txt deleted file mode 100644 index 4e73115..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/hosts.txt +++ /dev/null @@ -1,15 +0,0 @@ -myrddin.prole.org 10.0.0.3 -raspberry.prole.org 10.0.0.4 -pi.prole.org 10.0.0.5 -synology.prole.org 10.0.0.203 -morgoth.prole.org 10.0.0.204 -zinfandel.prole.org 10.0.0.205 -aventage.prole.org 10.0.0.206 -retropie.prole.org 10.0.0.207 -fairyland.prole.org 10.0.0.208 -k8s.prole.org zinfandel.prole.org -mc.prole.org 73.15.20.166 -morana.prole.org 10.0.0.66 -ollama.prole.org 73.15.20.166 -svc.prole.org 73.15.20.166 -www.prole.org ghs.googlehosted.com \ No newline at end of file diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/init_cloudnative_pg.sh b/MagicMock/mock.Entry().get().strip()/4413171632/init_cloudnative_pg.sh deleted file mode 100755 index 6708415..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/init_cloudnative_pg.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_cloudnative_pg.sh -# Purpose: -# - Distribute administrator ed25519 key pair to CloudNative‑PG as a Kubernetes Secret for cert auth -# - Configure Kerberos (GSSAPI) using external Kerberos KDC -# - Patch CNPG cluster to enable TLS and GSSAPI where possible -# -# Usage: -# ./init_cloudnative_pg.sh start|stop|status|restart -# ./init_cloudnative_pg.sh initialize # create/update k8s secrets/configs and patch CNPG -# ./init_cloudnative_pg.sh update|reload # re-apply/patch -# -# Requirements: -# - init_openbao.sh has been run (OpenBao running in k8s) -# - $PROLE_HOME/env.sh or $HOME/.prole/env.sh defining PROLE_SERVICE - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Load env without leaking our positional args to the env script (some env.sh may `exec "$@"`). -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -else - echo "ERROR: Missing env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env." >&2 - exit 1 -fi - -ACTION=${1:-} -CNPG_CLUSTER_NAME=${2:-${CNPG_CLUSTER_NAME:-prole-db}} -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -REALM=${REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-prole.org} -KRB5_KDC=${KRB5_KDC:-} -KRB5_ADMIN=${KRB5_ADMIN:-} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -SECRETS_DIR="$PROLE_SERVICE/secrets" -ADMIN_PRIV="$SECRETS_DIR/admin_ed25519.key" -ADMIN_PUB="$SECRETS_DIR/admin_ed25519.pub" -OPENBAO_TOKEN_FILE="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64 jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -# Resolve OpenBao URL: prefer explicit env, then localhost port-forward, then cluster DNS -bao_service_url() { - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - echo "$PROLE_OPENBAO_URL" - return 0 - fi - # Prefer standard local port-forward managed by etc/init_port_forwards.sh - if curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - echo "http://127.0.0.1:18200" - return 0 - fi - echo "http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" -} - -fetch_admin_keys_and_db_pass_from_bao_or_local() { - local token url - if [[ -f "$OPENBAO_TOKEN_FILE" ]]; then - token=$(cat "$OPENBAO_TOKEN_FILE") - else - token="" - fi - url=$(bao_service_url) - if [[ -n "$token" ]]; then - echo "Attempting to read admin key pair from OpenBao kv/prole/admin ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -e '.data.data' >/dev/null 2>&1; then - local priv_b64 pub_b64 - priv_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_private_key_b64') - pub_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_public_key_b64') - printf "%s" "$priv_b64" | base64 -d >"$ADMIN_PRIV" - printf "%s" "$pub_b64" | base64 -d >"$ADMIN_PUB" - chmod 0600 "$ADMIN_PRIV" - fi - - echo "Attempting to read database password from OpenBao kv/prole/db ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -e '.data.data' >/dev/null 2>&1; then - local db_pass - db_pass=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -r '.data.data.password') - if [[ -n "$db_pass" ]]; then - echo "Updating database user secret 'prole-db-user' from OpenBao ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username=prole \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - - echo "Updating database superuser secret 'prole-db-superuser' from OpenBao ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - fi - fi - fi - - if [[ -f "$ADMIN_PRIV" && -f "$ADMIN_PUB" ]]; then - echo "Using local admin key pair at $SECRETS_DIR" - return 0 - fi - echo "ERROR: Could not obtain admin key pair from OpenBao and no local files found." >&2 - exit 1 -} - -apply_cnpg_admin_secret() { - echo "Creating/updating Secret cnpg-admin-key ..." - kubectl create secret generic cnpg-admin-key -n "$NAMESPACE" \ - --from-file=admin.key="$ADMIN_PRIV" \ - --from-file=admin.pub="$ADMIN_PUB" \ - --dry-run=client -o yaml | kubectl apply -f - -} - -ensure_krb5_conf_configmap() { - echo "Creating/updating ConfigMap prole-krb5-conf ..." - - local kdc_val admin_val - if [[ -n "$KRB5_KDC" ]]; then - kdc_val="$KRB5_KDC" - admin_val=${KRB5_ADMIN:-$(echo "$KRB5_KDC" | cut -d, -f1)} - else - kdc_val="kdc.$DOMAIN" - admin_val="kdc.$DOMAIN" - fi - - local TMP - TMP=$(mktemp) - cat >"$TMP" </dev/null 2>&1; then - echo "CA secret $ca_secret_name already exists; skipping generation." - return 0 - fi - echo "Generating self-signed CA (RSA 4096) for CNPG ..." - local TMPD - TMPD=$(mktemp -d) - openssl genrsa -out "$TMPD/ca.key" 4096 - openssl req -x509 -new -key "$TMPD/ca.key" -out "$TMPD/ca.crt" -days 3650 -subj "/CN=Prole CNPG CA" - kubectl -n "$NAMESPACE" create secret generic "$ca_secret_name" \ - --from-file=ca.crt="$TMPD/ca.crt" \ - --from-file=ca.key="$TMPD/ca.key" \ - --dry-run=client -o yaml | kubectl apply -f - - rm -rf "$TMPD" -} - -patch_cnpg_cluster_for_auth() { - echo "Patching CNPG Cluster $CNPG_CLUSTER_NAME to enable GSSAPI and fix config (best-effort) ..." - # Best-effort patch; schema may vary with CNPG version. - # We remove krb_srvname as it is unrecognized in some PG 17 builds. - # We revert certificates to default to avoid operator TLS issues. - kubectl -n "$NAMESPACE" patch cluster "$CNPG_CLUSTER_NAME" --type merge -p "{ - \"spec\": { - \"postgresql\": { - \"parameters\": {\"krb_srvname\": null}, - \"pg_hba\": [ - \"local all postgres trust\", - \"host all postgres all scram-sha-256\", - \"host all all all gss include_realm=1 krb_realm=$REALM\", - \"host all all all scram-sha-256\" - ] - }, - \"certificates\": { - \"serverCASecret\": null, - \"clientCASecret\": null - } - } - }" >/dev/null || echo "Note: patch may need adjustment for your CNPG version." -} - -initialize() { - ensure_tools - - # Ensure port-forward is running for OpenBao (dependency) - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - fetch_admin_keys_and_db_pass_from_bao_or_local - apply_cnpg_admin_secret - ensure_krb5_conf_configmap - # generate_tls_if_missing - patch_cnpg_cluster_for_auth - - # Ensure port-forward is running for Postgres (local access) - echo "Ensuring port-forward for Postgres is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart postgres - - echo "Initialization complete for CNPG + Kerberos + cert artifacts." -} - -update_reload() { - initialize -} - -case "$ACTION" in - recreate) - ensure_tools - "$0" delete "$CNPG_CLUSTER_NAME" - "$0" create "$CNPG_CLUSTER_NAME" - ;; - create) - ensure_tools - echo "Installing CloudNative-PG operator ..." - kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml - - echo "Creating CloudNative-PG cluster and resources for '$CNPG_CLUSTER_NAME' ..." - - kubectl apply -k "$SCRIPT_DIR/../k8s/prole" - - # Ensure prole-index-html exists for prole deployment readiness probe - if ! kubectl get configmap prole-index-html -n prole >/dev/null 2>&1; then - echo "Creating prole-index-html configmap..." - printf "

Prole

" > /tmp/index.html - kubectl create configmap prole-index-html --from-file=/tmp/index.html -n prole - rm /tmp/index.html - fi - - # Ensure prole-nginx-tls exists (self-signed for dev) - if ! kubectl get secret prole-nginx-tls -n prole >/dev/null 2>&1; then - echo "Generating self-signed prole-nginx-tls for development..." - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /tmp/nginx-tls.key -out /tmp/nginx-tls.crt \ - -subj "/CN=prole.org" >/dev/null 2>&1 - kubectl create secret tls prole-nginx-tls --key /tmp/nginx-tls.key --cert /tmp/nginx-tls.crt -n prole - rm /tmp/nginx-tls.key /tmp/nginx-tls.crt - fi - - echo "Initializing and patching cluster ..." - initialize - ;; - delete) - ensure_tools - echo "Deleting all resources for '$CNPG_CLUSTER_NAME' ..." - kubectl delete -k "$SCRIPT_DIR/../k8s/prole" --ignore-not-found - ;; - start) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Starting CloudNative-PG cluster from $CNPG_MANIFEST in namespace $NAMESPACE..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - ;; - stop) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Stopping CloudNative-PG cluster using $CNPG_MANIFEST ..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found - ;; - status) - ensure_tools - echo "--- CloudNative-PG Cluster Status ($CNPG_CLUSTER_NAME) ---" - if kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" - echo "" - echo "CNPG Plugin Status:" - if kubectl cnpg version >/dev/null 2>&1; then - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - else - echo "Note: 'kubectl cnpg' plugin not found; skipping detailed status." - fi - else - echo "Cluster '$CNPG_CLUSTER_NAME' not found in namespace '$NAMESPACE'." - fi - ;; - restart) - ensure_tools - "$0" stop - "$0" start - ;; - initialize) - initialize - ;; - update|reload) - update_reload - ;; - *) - echo "Usage: $0 {create|delete|recreate|start|stop|status|restart|initialize|update|reload} [dbname]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/init_k8s.sh b/MagicMock/mock.Entry().get().strip()/4413171632/init_k8s.sh deleted file mode 100755 index 35f14aa..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/init_k8s.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# etc/init_k8s.sh -# Purpose: Manage k3d/k8s environment - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -# Default values -VERBOSE=false -ENVIRONMENT="prod" -HOST="" -CLUSTER_NAME_DEFAULT="prole-dev-cluster" -CLUSTER_PORT_DEFAULT="6443" - -usage() { - cat </dev/null || { echo "ERROR: Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - if ! docker info >/dev/null 2>&1; then - echo "ERROR: Docker is not running." >&2 - exit 1 - fi -} - -initialize() { - ensure_tools - ensure_docker - - if [[ "$ENVIRONMENT" == "dev" ]]; then - if [[ -z "$CLUSTER_NAME" ]]; then - if [[ -t 0 ]]; then - read -p "Enter k3d cluster name [$CLUSTER_NAME_DEFAULT]: " CLUSTER_NAME - CLUSTER_NAME=${CLUSTER_NAME:-$CLUSTER_NAME_DEFAULT} - else - CLUSTER_NAME=$CLUSTER_NAME_DEFAULT - fi - fi - - if k3d cluster list "$CLUSTER_NAME" >/dev/null 2>&1; then - log "Cluster '$CLUSTER_NAME' already exists." - else - log "Creating k3d cluster '$CLUSTER_NAME'..." - k3d cluster create "$CLUSTER_NAME" -p "0.0.0.0:$CLUSTER_PORT_DEFAULT:6443@server:0" - fi - else - if [[ -n "$HOST" ]]; then - log "Environment is $ENVIRONMENT. Host is $HOST." - log "TODO: Fetch kubeconfig from $HOST (placeholder)." - else - log "Environment is $ENVIRONMENT. Use -h|--host to specify the remote cluster host." - fi - fi -} - -status() { - ensure_tools - log "Checking Docker status..." - if docker info >/dev/null 2>&1; then - echo "Docker is running." - else - echo "Docker is NOT running." - fi - - log "Listing k3d clusters..." - k3d cluster list -} - -get_cluster_name() { - # If a name was provided or exists in env, use it. - # Otherwise, if there is only one cluster, use it. - # Finally, use default. - if [[ -n "${CLUSTER_NAME:-}" ]]; then - echo "$CLUSTER_NAME" - return - fi - - local clusters - clusters=$(k3d cluster list --no-headers | awk '{print $1}') - local count - count=$(echo "$clusters" | grep -c . || true) - - if [[ "$count" -eq 1 ]]; then - echo "$clusters" - else - echo "$CLUSTER_NAME_DEFAULT" - fi -} - -case "$ACTION" in - initialize) - initialize - ;; - status) - status - ;; - start) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Starting k3d cluster '$CLUSTER_NAME'..." - k3d cluster start "$CLUSTER_NAME" - ;; - stop) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Stopping k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - ;; - restart) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Restarting k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - k3d cluster start "$CLUSTER_NAME" - ;; - *) - usage - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/init_openbao.sh b/MagicMock/mock.Entry().get().strip()/4413171632/init_openbao.sh deleted file mode 100755 index 3e59151..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/init_openbao.sh +++ /dev/null @@ -1,490 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_openbao.sh -# Purpose: -# - Deploy OpenBao to Kubernetes (dev mode) and store admin ed25519 key pair -# Generate and apply a Kerberos krb5.conf ConfigMap for an external realm -# - Local Docker helpers for OpenBao (optional) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi - -ACTION=${1:-} - -# Defaults -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -OPENBAO_MANIFEST_DIR="$SCRIPT_DIR/../k8s/openbao" - -# Kerberos realm defaults -KRB5_REALM=${KRB5_REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-$(echo "$KRB5_REALM" | tr 'A-Z' 'a-z')} -KRB5_KDC=${KRB5_KDC:-kdc.$DOMAIN} -KRB5_ADMIN=${KRB5_ADMIN:-} - -# Secrets and token locations -SECRETS_DIR="$PROLE_SERVICE/secrets" -mkdir -p "$SECRETS_DIR" -admin_key_priv="$SECRETS_DIR/admin_ed25519.key" -admin_key_pub="$SECRETS_DIR/admin_ed25519.pub" -root_token_file="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - command -v docker >/dev/null || { echo "Missing required tool: docker" >&2; exit 1; } -} - -ensure_admin_keypair() { - # Ensure admin ed25519 keypair exists and a root token is available - mkdir -p "$SECRETS_DIR" - if [[ ! -f "$admin_key_priv" || ! -f "$admin_key_pub" ]]; then - echo "Generating admin ed25519 keypair in $SECRETS_DIR ..." - openssl genpkey -algorithm ED25519 -out "$admin_key_priv" - openssl pkey -in "$admin_key_priv" -pubout -out "$admin_key_pub" - chmod 0600 "$admin_key_priv" - fi - # Ensure a root token exists for OpenBao dev server interactions - if [[ ! -f "$root_token_file" || ! -s "$root_token_file" ]]; then - openssl rand -hex 24 >"$root_token_file" - chmod 0600 "$root_token_file" - fi -} - -generate_openbao_manifests() { - mkdir -p "$OPENBAO_MANIFEST_DIR" - # Only create a simple deployment if none exists; otherwise respect current file - local deploy="$OPENBAO_MANIFEST_DIR/deployment.yaml" - if [[ ! -f "$deploy" ]]; then - cat >"$deploy" <"$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" </dev/null 2>&1; then - kubectl rollout status statefulset/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - else - kubectl rollout status deploy/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - fi -} - -init_openbao_kv_and_store_admin_key() { - local token - token=$(cat "$root_token_file") - # Enable kv (if not already) and write keys - local svc="http://127.0.0.1:18200" - echo "Configuring KV at $svc ..." - - # Check if kv/ is already mounted - if curl -sS -H "X-Vault-Token: $token" "$svc/v1/sys/mounts" | grep -q '"kv/":'; then - echo "KV path 'kv/' is already enabled." - else - curl -sS -H "X-Vault-Token: $token" -X POST "$svc/v1/sys/mounts/kv" \ - -d '{"type":"kv","options":{"version":"2"}}' >/dev/null 2>&1 || true - fi - - local priv pub - priv=$(base64 <"$admin_key_priv" | tr -d '\n') - pub=$(base64 <"$admin_key_pub" | tr -d '\n') - - # Check if admin key already exists and matches - local existing_data - existing_data=$(curl -sS -H "X-Vault-Token: $token" "$svc/v1/kv/data/prole/admin" 2>/dev/null || true) - if [[ -n "$existing_data" ]]; then - local ex_priv ex_pub - ex_priv=$(echo "$existing_data" | grep -o '"admin_private_key_b64":"[^"]*' | cut -d'"' -f4 || true) - ex_pub=$(echo "$existing_data" | grep -o '"admin_public_key_b64":"[^"]*' | cut -d'"' -f4 || true) - - if [[ "$ex_priv" == "$priv" && "$ex_pub" == "$pub" ]]; then - echo "Admin key pair in OpenBao kv/prole/admin is already up to date." - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - - # Store User SSH keys if they exist - local user_key_priv="$HOME/.ssh/id_prole_ed25519" - local user_key_pub="$HOME/.ssh/id_prole_ed25519.pub" - if [[ -f "$user_key_priv" && -f "$user_key_pub" ]]; then - local u_priv u_pub - u_priv=$(base64 <"$user_key_priv" | tr -d '\n') - u_pub=$(base64 <"$user_key_pub" | tr -d '\n') - local username=${PROLE_DB_USER:-"prole"} - - echo "Writing user SSH keys for '$username' to kv/prole/user ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/user" \ - -d "{\"data\":{\"username\":\"$username\",\"private_key_b64\":\"$u_priv\",\"public_key_b64\":\"$u_pub\"}}" >/dev/null - echo "Stored user SSH keys in OpenBao kv/prole/user." - fi - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Writing database user password for '$username' to kv/prole/db ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/db" \ - -d "{\"data\":{\"username\":\"$username\",\"password\":\"$db_pass\"}}" >/dev/null - echo "Stored database password in OpenBao kv/prole/db." - fi -} - -# Removed: prompt_admin_password_and_apply_secret (no AD admin secret required) - -docker_start() { - echo "Starting local Docker container for OpenBao ..." - ensure_docker - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - # OpenBao dev - local token - token=$(cat "$root_token_file" 2>/dev/null || true) - if [[ -z "$token" ]]; then - token=$(openssl rand -hex 24) - printf "%s" "$token" >"$root_token_file" - chmod 0600 "$root_token_file" - fi - docker run -d --name "$OPENBAO_NAME" -p 18200:8200 \ - "$OPENBAO_IMAGE" server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id="$token" - echo "Docker container started: $OPENBAO_NAME" -} - -docker_stop() { - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - echo "Stopped OpenBao container if it was running." -} - -docker_restart() { - docker_stop - docker_start -} - -# status command implementation wrapped in a function to avoid top-level 'local' -cmd_status() { - echo "--- init_primary_domain status ---" - echo "Namespace: $NAMESPACE" - echo "OpenBao name: $OPENBAO_NAME" - echo "Manifest dir: $OPENBAO_MANIFEST_DIR" - - # Files/manifests present - local ok=0 - if [[ -f "$OPENBAO_MANIFEST_DIR/deployment.yaml" ]]; then - echo "[OK] OpenBao deployment manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/deployment.yaml" - ok=1 - fi - if [[ -f "$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" ]]; then - echo "[OK] Kerberos ConfigMap manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" - ok=1 - fi - - # K8s resources - if kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" >/dev/null 2>&1; then - local ready desired - ready=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao StatefulSet running ($ready/$desired ready)" - else - echo "[WARN] OpenBao StatefulSet not fully ready ($ready/$desired)" - ok=1 - fi - elif kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" >/dev/null 2>&1; then - # Get readiness - local ready desired - ready=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao Deployment running ($ready/$desired ready)" - else - echo "[WARN] OpenBao Deployment not fully ready ($ready/$desired)" - ok=1 - fi - else - echo "[MISSING] OpenBao Deployment or StatefulSet '$OPENBAO_NAME' in namespace '$NAMESPACE'" - ok=1 - fi - - if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then - echo "[OK] Kerberos ConfigMap 'prole-krb5-conf' present" - else - echo "[MISSING] Kerberos ConfigMap 'prole-krb5-conf' in namespace '$NAMESPACE'" - ok=1 - fi - - # Docker (optional local mode) - if command -v docker >/dev/null 2>&1; then - if docker ps --format '{{.Names}}' | grep -Fxq "$OPENBAO_NAME"; then - echo "[OK] Docker container '$OPENBAO_NAME' is running" - else - # Not necessarily an error; we primarily use k8s - echo "[INFO] Docker container '$OPENBAO_NAME' not running (k8s mode may be in use)" - fi - fi - - # Secrets and tokens - if [[ -f "$admin_key_priv" && -f "$admin_key_pub" ]]; then - echo "[OK] Admin ed25519 keypair present in $SECRETS_DIR" - else - echo "[MISSING] Admin keypair files in $SECRETS_DIR" - ok=1 - fi - if [[ -s "$root_token_file" ]]; then - echo "[OK] OpenBao root token file present" - else - echo "[MISSING] OpenBao root token file ($root_token_file)" - ok=1 - fi - - # OpenBao reachability and token validity (best-effort) - # Prefer explicit override, then localhost port-forward, then cluster DNS - local svc_url - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - svc_url="$PROLE_OPENBAO_URL" - elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - svc_url="http://127.0.0.1:18200" - else - svc_url="http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" - fi - if curl -sS "$svc_url/v1/sys/health" >/dev/null 2>&1; then - echo "[OK] OpenBao service reachable" - if [[ -s "$root_token_file" ]]; then - local code - code=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Vault-Token: $(cat "$root_token_file")" "$svc_url/v1/sys/mounts" || echo "000") - if [[ "$code" == "200" ]]; then - echo "[OK] OpenBao root token authenticates" - else - echo "[WARN] OpenBao root token did not authenticate (HTTP $code)" - ok=1 - fi - fi - else - echo "[WARN] OpenBao service not reachable at $svc_url" - ok=1 - fi - - # Service certificate existence (CNPG TLS) - local CNPG_CLUSTER_NAME - CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} - if kubectl -n "$NAMESPACE" get secret "${CNPG_CLUSTER_NAME}-tls" >/dev/null 2>&1; then - echo "[OK] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' exists" - else - echo "[INFO] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' not found" - fi - - echo "-------------------------------------" - if [[ $ok -eq 0 ]]; then - echo "Status: OK" - return 0 - else - echo "Status: Issues detected" - return 1 - fi -} - -case "$ACTION" in - start) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_start - ;; - status) - ensure_tools - cmd_status - ;; - stop) - ensure_docker - docker_stop - ;; - restart) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_restart - ;; - initialize) - ensure_tools - # Read password from stdin if provided - db_pass="" - if [[ ! -t 0 ]]; then - read -r db_pass - fi - - ensure_admin_keypair - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Creating database user secret 'prole-db-user' for '$username' ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username="$username" \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - - echo "Creating database superuser secret 'prole-db-superuser' ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - fi - - wait_for_openbao - - # Ensure port-forward is running for OpenBao - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - if ! curl -sS http://127.0.0.1:18200/v1/sys/health >/dev/null 2>&1; then - echo "ERROR: OpenBao not reachable at http://127.0.0.1:18200." >&2 - echo "Please start port-forwards: $SCRIPT_DIR/init_port_forwards.sh start openbao" >&2 - exit 1 - fi - init_openbao_kv_and_store_admin_key - echo "Initialization complete. Manifests in: $OPENBAO_MANIFEST_DIR" - ;; - update|reload) - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - echo "Re-applied manifests." - ;; - *) - echo "Usage: $0 {start|stop|status|restart|initialize|update|reload}" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/init_port_forwards.sh b/MagicMock/mock.Entry().get().strip()/4413171632/init_port_forwards.sh deleted file mode 100755 index 9ebea5c..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/init_port_forwards.sh +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env bash -set -u - -# init_port_forwards.sh -# Portable-ish (macOS, Ubuntu, Raspberry Pi OS, Alpine) bash init-style script -# Manages kubectl port-forward daemons defined in an XML file. - -PROG="init_port_forwards" -PROLE_HOME="${PROLE_HOME:-/Users/chrisfu/dev/prole}" -VERBOSE=0 -CONFIG_FILE="$PROLE_HOME/conf/port-mappings.properties" - -usage() { - cat < [component] - -Options: - -c, --config-file=FILE Path to local-ports.properties (XML) - -v, --verbose Verbose output - -Examples: - $PROG -c ./port-mappings.properties start - $PROG stop openbao - $PROG --verbose status -EOF -} - -TARGET_ID="" - -log() { printf '%s\n' "$*"; } -vlog() { [ "$VERBOSE" -eq 1 ] && printf '[verbose] %s\n' "$*" || true; } -err() { printf '[error] %s\n' "$*" >&2; } - -have() { command -v "$1" >/dev/null 2>&1; } - -# Choose a writable state dir for pid/log files: -# - Prefer XDG_RUNTIME_DIR if set and writable -# - Else /var/run if writable (rare without root) -# - Else ~/.local/state -# - Else /tmp -state_dir() { - if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -w "${XDG_RUNTIME_DIR:-}" ]; then - printf '%s/%s' "$XDG_RUNTIME_DIR" "$PROG" - return - fi - if [ -d "/var/run" ] && [ -w "/var/run" ]; then - printf '/var/run/%s' "$PROG" - return - fi - if [ -n "${HOME:-}" ]; then - mkdir -p "$HOME/.local/state" >/dev/null 2>&1 || true - if [ -d "$HOME/.local/state" ] && [ -w "$HOME/.local/state" ]; then - printf '%s/.local/state/%s' "$HOME" "$PROG" - return - fi - fi - printf '/tmp/%s' "$PROG" -} - -STATE_DIR="$(state_dir)" -PID_DIR="$STATE_DIR/pids" -LOG_DIR="$STATE_DIR/logs" - -ensure_dirs() { - mkdir -p "$PID_DIR" "$LOG_DIR" 2>/dev/null || true - if [ ! -d "$PID_DIR" ] || [ ! -d "$LOG_DIR" ]; then - err "Unable to create state directories under: $STATE_DIR" - exit 1 - fi -} - -# Use kubectl for actions; kubecolor is used only for prettier status output. -KUBECTL="kubectl" -detect_kubectl() { - if have kubectl; then - KUBECTL="kubectl" - else - err "kubectl not found in PATH" - exit 1 - fi -} - -# Basic environment validation -validate_env() { - detect_kubectl - ensure_dirs - - if ! "$KUBECTL" version --client >/dev/null 2>&1; then - err "kubectl seems broken or not executable" - exit 1 - fi - - # Can we reach the cluster? - if ! "$KUBECTL" cluster-info >/dev/null 2>&1; then - err "kubectl cannot reach a cluster (check KUBECONFIG/context)" - err "Try: kubectl config get-contexts && kubectl config use-context " - exit 1 - fi -} - -# ---- Preflight: Docker + k3d awareness ---- -# Return 0 when Docker CLI can talk to a running daemon. -docker_is_running() { - if ! have docker; then - return 1 - fi - docker info >/dev/null 2>&1 -} - -# Hard-fail with clean guidance when Docker is not up (used for start/restart). -ensure_docker_running() { - if docker_is_running; then - return 0 - fi - if ! have docker; then - err "Docker CLI not found. Please install Docker Desktop or docker CLI." - else - err "Docker is not running. Start Docker Desktop and wait until it is ready." - fi - err "Tip (macOS): open -a Docker" - err "Then re-run: $PROG start" - exit 3 -} - -# Detect k3d cluster name from env or current kubectl context. -# - If K3D_CLUSTER is set, use it. -# - Else, if current-context starts with 'k3d-', strip prefix to get name. -detect_k3d_context() { - if [ -n "${K3D_CLUSTER:-}" ]; then - printf '%s' "$K3D_CLUSTER" - return 0 - fi - local ctx - ctx="$($KUBECTL config current-context 2>/dev/null || echo)" - case "$ctx" in - k3d-*) printf '%s' "${ctx#k3d-}"; return 0 ;; - *) return 1 ;; - esac -} - -# Return 0 if the given k3d cluster exists and is running. -k3d_cluster_is_running() { - local name="$1" - have k3d || return 1 - # Use json output when available; fall back to grep otherwise - if k3d cluster list -o json >/dev/null 2>&1; then - k3d cluster list -o json 2>/dev/null | grep -q '"name"\s*:\s*"'"$name"'"' && \ - k3d cluster list -o json 2>/dev/null | sed -n 's/.*"name"\s*:\s*"\([^"]\+\)".*"serversRunning"\s*:\s*\([0-9]\+\).*/\1 \2/p' | awk -v n="$name" '$1==n {exit ($2>0)?0:1}' - return $? - else - k3d cluster list 2>/dev/null | grep -E "^$name\s" | grep -q running - return $? - fi -} - -# If current context indicates k3d, ensure the cluster is up; otherwise no-op. -ensure_k3d_ready_if_applicable() { - local k3d_name - if ! k3d_name="$(detect_k3d_context)"; then - return 0 - fi - if ! have k3d; then - err "k3d is not installed but kubectl context suggests k3d (context=$("$KUBECTL" config current-context))." - err "Install k3d: brew install k3d (macOS)" - err "Or switch context: kubectl config use-context " - exit 4 - fi - if ! k3d_cluster_is_running "$k3d_name"; then - err "k3d cluster '$k3d_name' is not running." - err "Start it: k3d cluster start $k3d_name" - err "Then re-run: $PROG start" - exit 4 - fi -} - -pid_file_for() { printf '%s/%s.pid' "$PID_DIR" "$1"; } -log_file_for() { printf '%s/%s.log' "$LOG_DIR" "$1"; } - -is_pid_running() { - # Return 0 if pid exists and running, else 1 - # kill -0 is portable. - local pid="$1" - [ -n "$pid" ] && kill -0 "$pid" >/dev/null 2>&1 -} - -read_pid() { - local pf="$1" - [ -f "$pf" ] || return 1 - # shellcheck disable=SC2162 - read pid <"$pf" || return 1 - printf '%s' "$pid" -} - -write_pid() { - local pf="$1" pid="$2" - printf '%s\n' "$pid" >"$pf" -} - -remove_pidfile() { - local pf="$1" - rm -f "$pf" >/dev/null 2>&1 || true -} - -# ---- XML parsing (simple attribute extraction) ---- -# We parse lines containing: -# Attributes must use double quotes in the XML (as in the sample). -get_attr() { - # $1 = line, $2 = attribute name - # outputs value or empty - printf '%s\n' "$1" | sed -n "s/.*$2=\"\([^\"]*\)\".*/\1/p" -} - -foreach_mapping() { - # Calls a provided function with mapping fields: - # callback id ns target address hostPort servicePort protocol description - local callback="$1" - [ -f "$CONFIG_FILE" ] || { err "Config file not found: $CONFIG_FILE"; exit 1; } - - # Support both single-line and multi-line self-closing mapping tags, e.g.: - # OR lines spanning multiple lines until "/>". - local in_mapping=0 in_comment=0 buffer="" line - while IFS= read -r line; do - # Handle XML comments: skip anything between - if [ $in_comment -eq 1 ]; then - case "$line" in - *"-->"*) in_comment=0; continue ;; - *) continue ;; - esac - fi - case "$line" in - *""*) - # single-line comment; skip line - continue - ;; - *) - in_comment=1 - continue - ;; - esac - ;; - esac - if [ $in_mapping -eq 0 ]; then - case "$line" in - *"' - buffer="$buffer $line" - fi - - if [ $in_mapping -eq 1 ] && printf '%s' "$line" | grep -q "/>"; then - # Normalize whitespace to make attribute extraction robust - local merged - merged=$(printf '%s\n' "$buffer" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g') - - local id ns target address hostPort servicePort protocol description - id="$(get_attr "$merged" "id")" - ns="$(get_attr "$merged" "namespace")" - target="$(get_attr "$merged" "target")" - address="$(get_attr "$merged" "address")" - hostPort="$(get_attr "$merged" "hostPort")" - servicePort="$(get_attr "$merged" "servicePort")" - protocol="$(get_attr "$merged" "protocol")" - description="$(get_attr "$merged" "description")" - - # Basic validation - if [ -z "$id" ] || [ -z "$ns" ] || [ -z "$target" ] || [ -z "$hostPort" ] || [ -z "$servicePort" ]; then - err "Invalid mapping (missing required attributes): $merged" - exit 1 - fi - - # Filter by TARGET_ID if set - if [ -n "$TARGET_ID" ] && [ "$id" != "$TARGET_ID" ]; then - in_mapping=0 - buffer="" - continue - fi - - if [ -z "$address" ]; then address="127.0.0.1"; fi - if [ -z "$protocol" ]; then protocol="TCP"; fi - - vlog "mapping: id=$id ns=$ns target=$target address=$address hostPort=$hostPort servicePort=$servicePort protocol=$protocol" - "$callback" "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - # Reset accumulator - in_mapping=0 - buffer="" - fi - done <"$CONFIG_FILE" -} - -build_port_forward_cmd() { - # echo a command string - local ns="$1" target="$2" address="$3" hostPort="$4" servicePort="$5" - # kubectl port-forward -n --address : - printf '%s port-forward -n %s --address %s %s %s:%s' \ - "$KUBECTL" "$ns" "$address" "$target" "$hostPort" "$servicePort" -} - -start_port_forward() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile logfile cmd pid - - # Aggressively stop existing processes before starting to avoid port conflicts - stop_port_forward "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - pidfile="$(pid_file_for "$id")" - logfile="$(log_file_for "$id")" - cmd="$(build_port_forward_cmd "$ns" "$target" "$address" "$hostPort" "$servicePort")" - - log "Starting: $id $address:$hostPort -> $target:$servicePort ($ns) ${description:-}" - vlog "Command: $cmd" - - # Start in background, keep output in log. - # nohup is available on macOS/Linux; redirect stdin from /dev/null to detach. - nohup sh -c "$cmd" >>"$logfile" 2>&1 /dev/null 2>&1 || true - - # wait a moment, then SIGKILL if needed - local i - for i in 1 2 3 4 5; do - if ! is_pid_running "$pid"; then break; fi - sleep 0.2 - done - if is_pid_running "$pid"; then - err "$id did not stop gracefully; sending SIGKILL" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - else - if [ -f "$pidfile" ]; then - vlog "$id stale pidfile (pid=$pid not running)" - fi - fi - remove_pidfile "$pidfile" - - # Aggressively remove any other matching kubectl port-forward processes - # Search for processes that match: kubectl port-forward -n ... : - local extra_pids - extra_pids=$(ps -ef | grep "port-forward" | grep "\-n" | grep "$ns" | grep "$target" | grep "$hostPort:$servicePort" | grep -v grep | awk '{print $2}') - - for epid in $extra_pids; do - if [ "$epid" != "$pid" ]; then - log "Cleaning up orphan process for $id (pid=$epid)" - kill -9 "$epid" >/dev/null 2>&1 || true - fi - done -} - -status_one() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile pid - - pidfile="$(pid_file_for "$id")" - pid="" - if [ -f "$pidfile" ]; then - pid="$(read_pid "$pidfile" || true)" - fi - - if [ -n "${pid:-}" ] && is_pid_running "$pid"; then - printf 'RUNNING %-12s pid=%-7s %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$pid" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - # ps details (portable flags vary; use a conservative format) - ps -p "$pid" -o pid=,ppid=,etime=,command= 2>/dev/null | sed 's/^/ /' || true - else - printf 'STOPPED %-12s (no live pid) %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - fi -} - -do_start() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping start_port_forward -} - -do_stop() { - # stop doesn't require cluster access, but it does need state dirs - ensure_dirs - foreach_mapping stop_port_forward -} - -do_restart() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping stop_port_forward - foreach_mapping start_port_forward -} - -do_status() { - validate_env - # Non-fatal awareness messages - if docker_is_running; then - log "[OK] Docker daemon is running" - else - if have docker; then - log "[WARN] Docker is not running" - else - log "[WARN] Docker CLI not found" - fi - fi - - local _k3d_name - if _k3d_name="$(detect_k3d_context)"; then - if have k3d; then - if k3d_cluster_is_running "$_k3d_name"; then - log "[OK] k3d cluster '$_k3d_name' is running" - else - log "[WARN] k3d cluster '$_k3d_name' is not running" - fi - else - log "[WARN] k3d not installed but context suggests k3d (cluster='$_k3d_name')" - fi - fi - - log "== Context / Cluster ==" - "$KUBECTL" config current-context 2>/dev/null | sed 's/^/ context: /' || true - "$KUBECTL" cluster-info 2>/dev/null | sed 's/^/ /' || true - log "" - - log "== Port-forward processes ==" - foreach_mapping status_one - log "" - - log "== Quick k3d awareness checks (best-effort) ==" - # If user is on k3d, current-context often includes k3d-... but not guaranteed. - # Show nodes + a few namespaces/services related to mappings (best effort). - "$KUBECTL" get nodes -o wide 2>/dev/null | sed 's/^/ /' || true - log "" - "$KUBECTL" get ns 2>/dev/null | sed 's/^/ /' || true - log "" - - # For each mapping, try to show target existence - log "== Target existence (best-effort) ==" - _target_check() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - # kubectl get -n - # If target is like "svc/name", "deploy/name", etc. - if "$KUBECTL" get -n "$ns" "$target" >/dev/null 2>&1; then - printf 'OK %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - else - printf 'MISSING %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - fi - } - foreach_mapping _target_check -} - -# ---- arg parsing ---- -ACTION="" - -while [ $# -gt 0 ]; do - case "$1" in - start|stop|restart|status) - if [ -z "$ACTION" ]; then - ACTION="$1" - else - TARGET_ID="$1" - fi - shift - ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - -c) - shift - [ $# -gt 0 ] || { err "-c requires a file path"; usage; exit 2; } - CONFIG_FILE="$1" - shift - ;; - --config-file=*) - CONFIG_FILE="${1#*=}" - shift - ;; - -h|--help) - usage - exit 0 - ;; - *) - if [ -z "$ACTION" ]; then - err "Unknown arg: $1" - usage - exit 2 - fi - TARGET_ID="$1" - shift - ;; - esac -done - -[ -n "$ACTION" ] || { usage; exit 2; } - -case "$ACTION" in - start) do_start ;; - stop) do_stop ;; - restart) do_restart ;; - status) do_status ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4413171632/init_prole-db.sh b/MagicMock/mock.Entry().get().strip()/4413171632/init_prole-db.sh deleted file mode 100755 index b87de05..0000000 --- a/MagicMock/mock.Entry().get().strip()/4413171632/init_prole-db.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_prole-db.sh -# Purpose: -# - Manage prole-db CloudNative-PG cluster operations (deploy, start, stop, etc.) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -ACTION=${1:-} -VERSION=${2:-latest} - -# Load env -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - source "$HOME/.prole/env.sh" -fi - -CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} -NAMESPACE=${NAMESPACE:-prole} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -ensure_tools() { - for t in kubectl jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -get_latest_image() { - local version_file="$SCRIPT_DIR/../conf/postgresql/.version" - if [[ -f "$version_file" ]]; then - echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" - else - echo "prole-db:17.7-033" - fi -} - -start() { - ensure_tools - echo "Checking dependencies..." - - # 1. k3d is running - if ! command -v k3d >/dev/null || ! k3d cluster list >/dev/null 2>&1; then - echo "ERROR: k3d is not running or not installed." >&2 - exit 1 - fi - - # 2. cnpg operator is loaded - if ! kubectl get deployment -n cnpg-system cnpg-controller-manager >/dev/null 2>&1; then - echo "ERROR: CloudNative-PG operator is not loaded." >&2 - exit 1 - fi - - # 3. openbao is configured - if ! kubectl get statefulset openbao -n "$NAMESPACE" >/dev/null 2>&1 && ! kubectl get deployment openbao -n "$NAMESPACE" >/dev/null 2>&1; then - echo "ERROR: OpenBao is not deployed." >&2 - exit 1 - fi - - # Compare latest image with deployed - local latest_image - latest_image=$(get_latest_image) - - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - - if [[ "$current_image" != "$latest_image" ]]; then - echo "Updating cluster image from '$current_image' to '$latest_image'..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$latest_image\"}}" - # Force a rollout to ensure the new image is pulled even if it was just a tag update (though we use unique tags) - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - else - echo "Cluster is already using the latest image: $latest_image" - fi - - echo "Starting prole-db cluster (ensuring manifest is applied)..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" -} - -stop() { - ensure_tools - echo "Stopping prole-db cluster $CNPG_CLUSTER_NAME..." - - # Identify instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - if [[ -z "$instances" ]]; then - echo "No instances found for cluster $CNPG_CLUSTER_NAME." - return - fi - - # Determine replicas and primary - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - - echo "Primary: $primary" - - # Shutdown replicas first - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Shutting down replica $pod..." - kubectl exec -n "$NAMESPACE" "$pod" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - done - - # Shutdown primary last - if [[ -n "$primary" ]]; then - echo "Shutting down primary $primary..." - kubectl exec -n "$NAMESPACE" "$primary" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - - echo "Deleting cluster resource..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found -} - -restart() { - ensure_tools - echo "Restarting prole-db cluster..." - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -deploy() { - ensure_tools - local image - if [[ "$VERSION" == "latest" ]]; then - image=$(get_latest_image) - else - image="prole-db:$VERSION" - fi - - echo "Deploying $image to cluster $CNPG_CLUSTER_NAME..." - - # If cluster doesn't exist, use init_cloudnative_pg.sh create first - if ! kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then - echo "Cluster not found. Running init_cloudnative_pg.sh create..." - bash "$SCRIPT_DIR/init_cloudnative_pg.sh" create - fi - - # Ensure image is updated if manifest has an older version - # First, apply the manifest to ensure the cluster exists/is updated - echo "Applying manifest $CNPG_MANIFEST..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - - # Then force the specific image version via patch if different - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - if [[ "$current_image" != "$image" ]]; then - echo "Patching cluster to use image '$image' (was '$current_image')..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$image\"}}" - # Force a rollout - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - fi -} - -rollback() { - ensure_tools - echo "Rollback: Updating to previous image (manually specified version or fallback)..." - if [[ "$VERSION" == "latest" ]]; then - echo "Please specify a version to rollback to. Usage: $0 rollback " - exit 1 - fi - deploy -} - -backup() { - echo "Backup - tbd, when we configure s3 or other block store" -} - -reset() { - ensure_tools - echo "Resetting prole-db cluster..." - echo "Removing cnpg instances and pods..." - kubectl delete cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --ignore-not-found - - # Wait for deletion - kubectl wait --for=delete cluster/"$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --timeout=60s || true - - echo "Reinstantiating..." - deploy -} - -case "$ACTION" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - deploy) - deploy - ;; - rollback) - rollback - ;; - backup) - backup - ;; - reset) - reset - ;; - *) - echo "Usage: $0 {start|stop|restart|deploy|rollback|backup|reset} [version]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/env.sh b/MagicMock/mock.Entry().get().strip()/4452427696/env.sh deleted file mode 100755 index a652599..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/env.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Prole environment configuration -# This file is generated by the installer. Source it in new shells, or execute as a wrapper: -# "$PROLE_HOME/env.sh" [args…] -# shellcheck shell=bash -export PROLE_HOME="" -export PROLE_CONF="" -export PROLE_DATA="" -export PROLE_LOGS="" -export PROLE_SERVICE="" - -# Ensure PATH works for GUI-launched shells (Docker, Ollama, etc.) -_prole_add_path() { case ":${PATH}:" in *":$1:"*) ;; *) PATH="$1:${PATH:-}" ;; esac; } -_prole_add_path "$PROLE_HOME/bin" -_prole_add_path "/opt/homebrew/bin" -_prole_add_path "/usr/local/bin" -_prole_add_path "/usr/bin" -_prole_add_path "/bin" -_prole_add_path "/usr/sbin" -_prole_add_path "/sbin" -export PATH - -# Add custom paths below if needed (examples): -# _prole_add_path "/Applications/Ollama.app/Contents/MacOS" - -# If executed with arguments, run them under this environment -if [ "$#" -gt 0 ]; then - exec "$@" -fi diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/hosts.txt b/MagicMock/mock.Entry().get().strip()/4452427696/hosts.txt deleted file mode 100644 index 4e73115..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/hosts.txt +++ /dev/null @@ -1,15 +0,0 @@ -myrddin.prole.org 10.0.0.3 -raspberry.prole.org 10.0.0.4 -pi.prole.org 10.0.0.5 -synology.prole.org 10.0.0.203 -morgoth.prole.org 10.0.0.204 -zinfandel.prole.org 10.0.0.205 -aventage.prole.org 10.0.0.206 -retropie.prole.org 10.0.0.207 -fairyland.prole.org 10.0.0.208 -k8s.prole.org zinfandel.prole.org -mc.prole.org 73.15.20.166 -morana.prole.org 10.0.0.66 -ollama.prole.org 73.15.20.166 -svc.prole.org 73.15.20.166 -www.prole.org ghs.googlehosted.com \ No newline at end of file diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/init_cloudnative_pg.sh b/MagicMock/mock.Entry().get().strip()/4452427696/init_cloudnative_pg.sh deleted file mode 100755 index 6708415..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/init_cloudnative_pg.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_cloudnative_pg.sh -# Purpose: -# - Distribute administrator ed25519 key pair to CloudNative‑PG as a Kubernetes Secret for cert auth -# - Configure Kerberos (GSSAPI) using external Kerberos KDC -# - Patch CNPG cluster to enable TLS and GSSAPI where possible -# -# Usage: -# ./init_cloudnative_pg.sh start|stop|status|restart -# ./init_cloudnative_pg.sh initialize # create/update k8s secrets/configs and patch CNPG -# ./init_cloudnative_pg.sh update|reload # re-apply/patch -# -# Requirements: -# - init_openbao.sh has been run (OpenBao running in k8s) -# - $PROLE_HOME/env.sh or $HOME/.prole/env.sh defining PROLE_SERVICE - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Load env without leaking our positional args to the env script (some env.sh may `exec "$@"`). -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -else - echo "ERROR: Missing env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env." >&2 - exit 1 -fi - -ACTION=${1:-} -CNPG_CLUSTER_NAME=${2:-${CNPG_CLUSTER_NAME:-prole-db}} -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -REALM=${REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-prole.org} -KRB5_KDC=${KRB5_KDC:-} -KRB5_ADMIN=${KRB5_ADMIN:-} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -SECRETS_DIR="$PROLE_SERVICE/secrets" -ADMIN_PRIV="$SECRETS_DIR/admin_ed25519.key" -ADMIN_PUB="$SECRETS_DIR/admin_ed25519.pub" -OPENBAO_TOKEN_FILE="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64 jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -# Resolve OpenBao URL: prefer explicit env, then localhost port-forward, then cluster DNS -bao_service_url() { - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - echo "$PROLE_OPENBAO_URL" - return 0 - fi - # Prefer standard local port-forward managed by etc/init_port_forwards.sh - if curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - echo "http://127.0.0.1:18200" - return 0 - fi - echo "http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" -} - -fetch_admin_keys_and_db_pass_from_bao_or_local() { - local token url - if [[ -f "$OPENBAO_TOKEN_FILE" ]]; then - token=$(cat "$OPENBAO_TOKEN_FILE") - else - token="" - fi - url=$(bao_service_url) - if [[ -n "$token" ]]; then - echo "Attempting to read admin key pair from OpenBao kv/prole/admin ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -e '.data.data' >/dev/null 2>&1; then - local priv_b64 pub_b64 - priv_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_private_key_b64') - pub_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_public_key_b64') - printf "%s" "$priv_b64" | base64 -d >"$ADMIN_PRIV" - printf "%s" "$pub_b64" | base64 -d >"$ADMIN_PUB" - chmod 0600 "$ADMIN_PRIV" - fi - - echo "Attempting to read database password from OpenBao kv/prole/db ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -e '.data.data' >/dev/null 2>&1; then - local db_pass - db_pass=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -r '.data.data.password') - if [[ -n "$db_pass" ]]; then - echo "Updating database user secret 'prole-db-user' from OpenBao ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username=prole \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - - echo "Updating database superuser secret 'prole-db-superuser' from OpenBao ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - fi - fi - fi - - if [[ -f "$ADMIN_PRIV" && -f "$ADMIN_PUB" ]]; then - echo "Using local admin key pair at $SECRETS_DIR" - return 0 - fi - echo "ERROR: Could not obtain admin key pair from OpenBao and no local files found." >&2 - exit 1 -} - -apply_cnpg_admin_secret() { - echo "Creating/updating Secret cnpg-admin-key ..." - kubectl create secret generic cnpg-admin-key -n "$NAMESPACE" \ - --from-file=admin.key="$ADMIN_PRIV" \ - --from-file=admin.pub="$ADMIN_PUB" \ - --dry-run=client -o yaml | kubectl apply -f - -} - -ensure_krb5_conf_configmap() { - echo "Creating/updating ConfigMap prole-krb5-conf ..." - - local kdc_val admin_val - if [[ -n "$KRB5_KDC" ]]; then - kdc_val="$KRB5_KDC" - admin_val=${KRB5_ADMIN:-$(echo "$KRB5_KDC" | cut -d, -f1)} - else - kdc_val="kdc.$DOMAIN" - admin_val="kdc.$DOMAIN" - fi - - local TMP - TMP=$(mktemp) - cat >"$TMP" </dev/null 2>&1; then - echo "CA secret $ca_secret_name already exists; skipping generation." - return 0 - fi - echo "Generating self-signed CA (RSA 4096) for CNPG ..." - local TMPD - TMPD=$(mktemp -d) - openssl genrsa -out "$TMPD/ca.key" 4096 - openssl req -x509 -new -key "$TMPD/ca.key" -out "$TMPD/ca.crt" -days 3650 -subj "/CN=Prole CNPG CA" - kubectl -n "$NAMESPACE" create secret generic "$ca_secret_name" \ - --from-file=ca.crt="$TMPD/ca.crt" \ - --from-file=ca.key="$TMPD/ca.key" \ - --dry-run=client -o yaml | kubectl apply -f - - rm -rf "$TMPD" -} - -patch_cnpg_cluster_for_auth() { - echo "Patching CNPG Cluster $CNPG_CLUSTER_NAME to enable GSSAPI and fix config (best-effort) ..." - # Best-effort patch; schema may vary with CNPG version. - # We remove krb_srvname as it is unrecognized in some PG 17 builds. - # We revert certificates to default to avoid operator TLS issues. - kubectl -n "$NAMESPACE" patch cluster "$CNPG_CLUSTER_NAME" --type merge -p "{ - \"spec\": { - \"postgresql\": { - \"parameters\": {\"krb_srvname\": null}, - \"pg_hba\": [ - \"local all postgres trust\", - \"host all postgres all scram-sha-256\", - \"host all all all gss include_realm=1 krb_realm=$REALM\", - \"host all all all scram-sha-256\" - ] - }, - \"certificates\": { - \"serverCASecret\": null, - \"clientCASecret\": null - } - } - }" >/dev/null || echo "Note: patch may need adjustment for your CNPG version." -} - -initialize() { - ensure_tools - - # Ensure port-forward is running for OpenBao (dependency) - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - fetch_admin_keys_and_db_pass_from_bao_or_local - apply_cnpg_admin_secret - ensure_krb5_conf_configmap - # generate_tls_if_missing - patch_cnpg_cluster_for_auth - - # Ensure port-forward is running for Postgres (local access) - echo "Ensuring port-forward for Postgres is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart postgres - - echo "Initialization complete for CNPG + Kerberos + cert artifacts." -} - -update_reload() { - initialize -} - -case "$ACTION" in - recreate) - ensure_tools - "$0" delete "$CNPG_CLUSTER_NAME" - "$0" create "$CNPG_CLUSTER_NAME" - ;; - create) - ensure_tools - echo "Installing CloudNative-PG operator ..." - kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml - - echo "Creating CloudNative-PG cluster and resources for '$CNPG_CLUSTER_NAME' ..." - - kubectl apply -k "$SCRIPT_DIR/../k8s/prole" - - # Ensure prole-index-html exists for prole deployment readiness probe - if ! kubectl get configmap prole-index-html -n prole >/dev/null 2>&1; then - echo "Creating prole-index-html configmap..." - printf "

Prole

" > /tmp/index.html - kubectl create configmap prole-index-html --from-file=/tmp/index.html -n prole - rm /tmp/index.html - fi - - # Ensure prole-nginx-tls exists (self-signed for dev) - if ! kubectl get secret prole-nginx-tls -n prole >/dev/null 2>&1; then - echo "Generating self-signed prole-nginx-tls for development..." - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /tmp/nginx-tls.key -out /tmp/nginx-tls.crt \ - -subj "/CN=prole.org" >/dev/null 2>&1 - kubectl create secret tls prole-nginx-tls --key /tmp/nginx-tls.key --cert /tmp/nginx-tls.crt -n prole - rm /tmp/nginx-tls.key /tmp/nginx-tls.crt - fi - - echo "Initializing and patching cluster ..." - initialize - ;; - delete) - ensure_tools - echo "Deleting all resources for '$CNPG_CLUSTER_NAME' ..." - kubectl delete -k "$SCRIPT_DIR/../k8s/prole" --ignore-not-found - ;; - start) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Starting CloudNative-PG cluster from $CNPG_MANIFEST in namespace $NAMESPACE..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - ;; - stop) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Stopping CloudNative-PG cluster using $CNPG_MANIFEST ..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found - ;; - status) - ensure_tools - echo "--- CloudNative-PG Cluster Status ($CNPG_CLUSTER_NAME) ---" - if kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" - echo "" - echo "CNPG Plugin Status:" - if kubectl cnpg version >/dev/null 2>&1; then - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - else - echo "Note: 'kubectl cnpg' plugin not found; skipping detailed status." - fi - else - echo "Cluster '$CNPG_CLUSTER_NAME' not found in namespace '$NAMESPACE'." - fi - ;; - restart) - ensure_tools - "$0" stop - "$0" start - ;; - initialize) - initialize - ;; - update|reload) - update_reload - ;; - *) - echo "Usage: $0 {create|delete|recreate|start|stop|status|restart|initialize|update|reload} [dbname]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/init_k8s.sh b/MagicMock/mock.Entry().get().strip()/4452427696/init_k8s.sh deleted file mode 100755 index 35f14aa..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/init_k8s.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# etc/init_k8s.sh -# Purpose: Manage k3d/k8s environment - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -# Default values -VERBOSE=false -ENVIRONMENT="prod" -HOST="" -CLUSTER_NAME_DEFAULT="prole-dev-cluster" -CLUSTER_PORT_DEFAULT="6443" - -usage() { - cat </dev/null || { echo "ERROR: Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - if ! docker info >/dev/null 2>&1; then - echo "ERROR: Docker is not running." >&2 - exit 1 - fi -} - -initialize() { - ensure_tools - ensure_docker - - if [[ "$ENVIRONMENT" == "dev" ]]; then - if [[ -z "$CLUSTER_NAME" ]]; then - if [[ -t 0 ]]; then - read -p "Enter k3d cluster name [$CLUSTER_NAME_DEFAULT]: " CLUSTER_NAME - CLUSTER_NAME=${CLUSTER_NAME:-$CLUSTER_NAME_DEFAULT} - else - CLUSTER_NAME=$CLUSTER_NAME_DEFAULT - fi - fi - - if k3d cluster list "$CLUSTER_NAME" >/dev/null 2>&1; then - log "Cluster '$CLUSTER_NAME' already exists." - else - log "Creating k3d cluster '$CLUSTER_NAME'..." - k3d cluster create "$CLUSTER_NAME" -p "0.0.0.0:$CLUSTER_PORT_DEFAULT:6443@server:0" - fi - else - if [[ -n "$HOST" ]]; then - log "Environment is $ENVIRONMENT. Host is $HOST." - log "TODO: Fetch kubeconfig from $HOST (placeholder)." - else - log "Environment is $ENVIRONMENT. Use -h|--host to specify the remote cluster host." - fi - fi -} - -status() { - ensure_tools - log "Checking Docker status..." - if docker info >/dev/null 2>&1; then - echo "Docker is running." - else - echo "Docker is NOT running." - fi - - log "Listing k3d clusters..." - k3d cluster list -} - -get_cluster_name() { - # If a name was provided or exists in env, use it. - # Otherwise, if there is only one cluster, use it. - # Finally, use default. - if [[ -n "${CLUSTER_NAME:-}" ]]; then - echo "$CLUSTER_NAME" - return - fi - - local clusters - clusters=$(k3d cluster list --no-headers | awk '{print $1}') - local count - count=$(echo "$clusters" | grep -c . || true) - - if [[ "$count" -eq 1 ]]; then - echo "$clusters" - else - echo "$CLUSTER_NAME_DEFAULT" - fi -} - -case "$ACTION" in - initialize) - initialize - ;; - status) - status - ;; - start) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Starting k3d cluster '$CLUSTER_NAME'..." - k3d cluster start "$CLUSTER_NAME" - ;; - stop) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Stopping k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - ;; - restart) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Restarting k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - k3d cluster start "$CLUSTER_NAME" - ;; - *) - usage - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/init_openbao.sh b/MagicMock/mock.Entry().get().strip()/4452427696/init_openbao.sh deleted file mode 100755 index 3e59151..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/init_openbao.sh +++ /dev/null @@ -1,490 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_openbao.sh -# Purpose: -# - Deploy OpenBao to Kubernetes (dev mode) and store admin ed25519 key pair -# Generate and apply a Kerberos krb5.conf ConfigMap for an external realm -# - Local Docker helpers for OpenBao (optional) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi - -ACTION=${1:-} - -# Defaults -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -OPENBAO_MANIFEST_DIR="$SCRIPT_DIR/../k8s/openbao" - -# Kerberos realm defaults -KRB5_REALM=${KRB5_REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-$(echo "$KRB5_REALM" | tr 'A-Z' 'a-z')} -KRB5_KDC=${KRB5_KDC:-kdc.$DOMAIN} -KRB5_ADMIN=${KRB5_ADMIN:-} - -# Secrets and token locations -SECRETS_DIR="$PROLE_SERVICE/secrets" -mkdir -p "$SECRETS_DIR" -admin_key_priv="$SECRETS_DIR/admin_ed25519.key" -admin_key_pub="$SECRETS_DIR/admin_ed25519.pub" -root_token_file="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - command -v docker >/dev/null || { echo "Missing required tool: docker" >&2; exit 1; } -} - -ensure_admin_keypair() { - # Ensure admin ed25519 keypair exists and a root token is available - mkdir -p "$SECRETS_DIR" - if [[ ! -f "$admin_key_priv" || ! -f "$admin_key_pub" ]]; then - echo "Generating admin ed25519 keypair in $SECRETS_DIR ..." - openssl genpkey -algorithm ED25519 -out "$admin_key_priv" - openssl pkey -in "$admin_key_priv" -pubout -out "$admin_key_pub" - chmod 0600 "$admin_key_priv" - fi - # Ensure a root token exists for OpenBao dev server interactions - if [[ ! -f "$root_token_file" || ! -s "$root_token_file" ]]; then - openssl rand -hex 24 >"$root_token_file" - chmod 0600 "$root_token_file" - fi -} - -generate_openbao_manifests() { - mkdir -p "$OPENBAO_MANIFEST_DIR" - # Only create a simple deployment if none exists; otherwise respect current file - local deploy="$OPENBAO_MANIFEST_DIR/deployment.yaml" - if [[ ! -f "$deploy" ]]; then - cat >"$deploy" <"$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" </dev/null 2>&1; then - kubectl rollout status statefulset/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - else - kubectl rollout status deploy/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - fi -} - -init_openbao_kv_and_store_admin_key() { - local token - token=$(cat "$root_token_file") - # Enable kv (if not already) and write keys - local svc="http://127.0.0.1:18200" - echo "Configuring KV at $svc ..." - - # Check if kv/ is already mounted - if curl -sS -H "X-Vault-Token: $token" "$svc/v1/sys/mounts" | grep -q '"kv/":'; then - echo "KV path 'kv/' is already enabled." - else - curl -sS -H "X-Vault-Token: $token" -X POST "$svc/v1/sys/mounts/kv" \ - -d '{"type":"kv","options":{"version":"2"}}' >/dev/null 2>&1 || true - fi - - local priv pub - priv=$(base64 <"$admin_key_priv" | tr -d '\n') - pub=$(base64 <"$admin_key_pub" | tr -d '\n') - - # Check if admin key already exists and matches - local existing_data - existing_data=$(curl -sS -H "X-Vault-Token: $token" "$svc/v1/kv/data/prole/admin" 2>/dev/null || true) - if [[ -n "$existing_data" ]]; then - local ex_priv ex_pub - ex_priv=$(echo "$existing_data" | grep -o '"admin_private_key_b64":"[^"]*' | cut -d'"' -f4 || true) - ex_pub=$(echo "$existing_data" | grep -o '"admin_public_key_b64":"[^"]*' | cut -d'"' -f4 || true) - - if [[ "$ex_priv" == "$priv" && "$ex_pub" == "$pub" ]]; then - echo "Admin key pair in OpenBao kv/prole/admin is already up to date." - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - - # Store User SSH keys if they exist - local user_key_priv="$HOME/.ssh/id_prole_ed25519" - local user_key_pub="$HOME/.ssh/id_prole_ed25519.pub" - if [[ -f "$user_key_priv" && -f "$user_key_pub" ]]; then - local u_priv u_pub - u_priv=$(base64 <"$user_key_priv" | tr -d '\n') - u_pub=$(base64 <"$user_key_pub" | tr -d '\n') - local username=${PROLE_DB_USER:-"prole"} - - echo "Writing user SSH keys for '$username' to kv/prole/user ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/user" \ - -d "{\"data\":{\"username\":\"$username\",\"private_key_b64\":\"$u_priv\",\"public_key_b64\":\"$u_pub\"}}" >/dev/null - echo "Stored user SSH keys in OpenBao kv/prole/user." - fi - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Writing database user password for '$username' to kv/prole/db ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/db" \ - -d "{\"data\":{\"username\":\"$username\",\"password\":\"$db_pass\"}}" >/dev/null - echo "Stored database password in OpenBao kv/prole/db." - fi -} - -# Removed: prompt_admin_password_and_apply_secret (no AD admin secret required) - -docker_start() { - echo "Starting local Docker container for OpenBao ..." - ensure_docker - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - # OpenBao dev - local token - token=$(cat "$root_token_file" 2>/dev/null || true) - if [[ -z "$token" ]]; then - token=$(openssl rand -hex 24) - printf "%s" "$token" >"$root_token_file" - chmod 0600 "$root_token_file" - fi - docker run -d --name "$OPENBAO_NAME" -p 18200:8200 \ - "$OPENBAO_IMAGE" server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id="$token" - echo "Docker container started: $OPENBAO_NAME" -} - -docker_stop() { - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - echo "Stopped OpenBao container if it was running." -} - -docker_restart() { - docker_stop - docker_start -} - -# status command implementation wrapped in a function to avoid top-level 'local' -cmd_status() { - echo "--- init_primary_domain status ---" - echo "Namespace: $NAMESPACE" - echo "OpenBao name: $OPENBAO_NAME" - echo "Manifest dir: $OPENBAO_MANIFEST_DIR" - - # Files/manifests present - local ok=0 - if [[ -f "$OPENBAO_MANIFEST_DIR/deployment.yaml" ]]; then - echo "[OK] OpenBao deployment manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/deployment.yaml" - ok=1 - fi - if [[ -f "$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" ]]; then - echo "[OK] Kerberos ConfigMap manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" - ok=1 - fi - - # K8s resources - if kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" >/dev/null 2>&1; then - local ready desired - ready=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao StatefulSet running ($ready/$desired ready)" - else - echo "[WARN] OpenBao StatefulSet not fully ready ($ready/$desired)" - ok=1 - fi - elif kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" >/dev/null 2>&1; then - # Get readiness - local ready desired - ready=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao Deployment running ($ready/$desired ready)" - else - echo "[WARN] OpenBao Deployment not fully ready ($ready/$desired)" - ok=1 - fi - else - echo "[MISSING] OpenBao Deployment or StatefulSet '$OPENBAO_NAME' in namespace '$NAMESPACE'" - ok=1 - fi - - if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then - echo "[OK] Kerberos ConfigMap 'prole-krb5-conf' present" - else - echo "[MISSING] Kerberos ConfigMap 'prole-krb5-conf' in namespace '$NAMESPACE'" - ok=1 - fi - - # Docker (optional local mode) - if command -v docker >/dev/null 2>&1; then - if docker ps --format '{{.Names}}' | grep -Fxq "$OPENBAO_NAME"; then - echo "[OK] Docker container '$OPENBAO_NAME' is running" - else - # Not necessarily an error; we primarily use k8s - echo "[INFO] Docker container '$OPENBAO_NAME' not running (k8s mode may be in use)" - fi - fi - - # Secrets and tokens - if [[ -f "$admin_key_priv" && -f "$admin_key_pub" ]]; then - echo "[OK] Admin ed25519 keypair present in $SECRETS_DIR" - else - echo "[MISSING] Admin keypair files in $SECRETS_DIR" - ok=1 - fi - if [[ -s "$root_token_file" ]]; then - echo "[OK] OpenBao root token file present" - else - echo "[MISSING] OpenBao root token file ($root_token_file)" - ok=1 - fi - - # OpenBao reachability and token validity (best-effort) - # Prefer explicit override, then localhost port-forward, then cluster DNS - local svc_url - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - svc_url="$PROLE_OPENBAO_URL" - elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - svc_url="http://127.0.0.1:18200" - else - svc_url="http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" - fi - if curl -sS "$svc_url/v1/sys/health" >/dev/null 2>&1; then - echo "[OK] OpenBao service reachable" - if [[ -s "$root_token_file" ]]; then - local code - code=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Vault-Token: $(cat "$root_token_file")" "$svc_url/v1/sys/mounts" || echo "000") - if [[ "$code" == "200" ]]; then - echo "[OK] OpenBao root token authenticates" - else - echo "[WARN] OpenBao root token did not authenticate (HTTP $code)" - ok=1 - fi - fi - else - echo "[WARN] OpenBao service not reachable at $svc_url" - ok=1 - fi - - # Service certificate existence (CNPG TLS) - local CNPG_CLUSTER_NAME - CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} - if kubectl -n "$NAMESPACE" get secret "${CNPG_CLUSTER_NAME}-tls" >/dev/null 2>&1; then - echo "[OK] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' exists" - else - echo "[INFO] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' not found" - fi - - echo "-------------------------------------" - if [[ $ok -eq 0 ]]; then - echo "Status: OK" - return 0 - else - echo "Status: Issues detected" - return 1 - fi -} - -case "$ACTION" in - start) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_start - ;; - status) - ensure_tools - cmd_status - ;; - stop) - ensure_docker - docker_stop - ;; - restart) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_restart - ;; - initialize) - ensure_tools - # Read password from stdin if provided - db_pass="" - if [[ ! -t 0 ]]; then - read -r db_pass - fi - - ensure_admin_keypair - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Creating database user secret 'prole-db-user' for '$username' ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username="$username" \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - - echo "Creating database superuser secret 'prole-db-superuser' ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - fi - - wait_for_openbao - - # Ensure port-forward is running for OpenBao - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - if ! curl -sS http://127.0.0.1:18200/v1/sys/health >/dev/null 2>&1; then - echo "ERROR: OpenBao not reachable at http://127.0.0.1:18200." >&2 - echo "Please start port-forwards: $SCRIPT_DIR/init_port_forwards.sh start openbao" >&2 - exit 1 - fi - init_openbao_kv_and_store_admin_key - echo "Initialization complete. Manifests in: $OPENBAO_MANIFEST_DIR" - ;; - update|reload) - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - echo "Re-applied manifests." - ;; - *) - echo "Usage: $0 {start|stop|status|restart|initialize|update|reload}" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/init_port_forwards.sh b/MagicMock/mock.Entry().get().strip()/4452427696/init_port_forwards.sh deleted file mode 100755 index 9ebea5c..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/init_port_forwards.sh +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env bash -set -u - -# init_port_forwards.sh -# Portable-ish (macOS, Ubuntu, Raspberry Pi OS, Alpine) bash init-style script -# Manages kubectl port-forward daemons defined in an XML file. - -PROG="init_port_forwards" -PROLE_HOME="${PROLE_HOME:-/Users/chrisfu/dev/prole}" -VERBOSE=0 -CONFIG_FILE="$PROLE_HOME/conf/port-mappings.properties" - -usage() { - cat < [component] - -Options: - -c, --config-file=FILE Path to local-ports.properties (XML) - -v, --verbose Verbose output - -Examples: - $PROG -c ./port-mappings.properties start - $PROG stop openbao - $PROG --verbose status -EOF -} - -TARGET_ID="" - -log() { printf '%s\n' "$*"; } -vlog() { [ "$VERBOSE" -eq 1 ] && printf '[verbose] %s\n' "$*" || true; } -err() { printf '[error] %s\n' "$*" >&2; } - -have() { command -v "$1" >/dev/null 2>&1; } - -# Choose a writable state dir for pid/log files: -# - Prefer XDG_RUNTIME_DIR if set and writable -# - Else /var/run if writable (rare without root) -# - Else ~/.local/state -# - Else /tmp -state_dir() { - if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -w "${XDG_RUNTIME_DIR:-}" ]; then - printf '%s/%s' "$XDG_RUNTIME_DIR" "$PROG" - return - fi - if [ -d "/var/run" ] && [ -w "/var/run" ]; then - printf '/var/run/%s' "$PROG" - return - fi - if [ -n "${HOME:-}" ]; then - mkdir -p "$HOME/.local/state" >/dev/null 2>&1 || true - if [ -d "$HOME/.local/state" ] && [ -w "$HOME/.local/state" ]; then - printf '%s/.local/state/%s' "$HOME" "$PROG" - return - fi - fi - printf '/tmp/%s' "$PROG" -} - -STATE_DIR="$(state_dir)" -PID_DIR="$STATE_DIR/pids" -LOG_DIR="$STATE_DIR/logs" - -ensure_dirs() { - mkdir -p "$PID_DIR" "$LOG_DIR" 2>/dev/null || true - if [ ! -d "$PID_DIR" ] || [ ! -d "$LOG_DIR" ]; then - err "Unable to create state directories under: $STATE_DIR" - exit 1 - fi -} - -# Use kubectl for actions; kubecolor is used only for prettier status output. -KUBECTL="kubectl" -detect_kubectl() { - if have kubectl; then - KUBECTL="kubectl" - else - err "kubectl not found in PATH" - exit 1 - fi -} - -# Basic environment validation -validate_env() { - detect_kubectl - ensure_dirs - - if ! "$KUBECTL" version --client >/dev/null 2>&1; then - err "kubectl seems broken or not executable" - exit 1 - fi - - # Can we reach the cluster? - if ! "$KUBECTL" cluster-info >/dev/null 2>&1; then - err "kubectl cannot reach a cluster (check KUBECONFIG/context)" - err "Try: kubectl config get-contexts && kubectl config use-context " - exit 1 - fi -} - -# ---- Preflight: Docker + k3d awareness ---- -# Return 0 when Docker CLI can talk to a running daemon. -docker_is_running() { - if ! have docker; then - return 1 - fi - docker info >/dev/null 2>&1 -} - -# Hard-fail with clean guidance when Docker is not up (used for start/restart). -ensure_docker_running() { - if docker_is_running; then - return 0 - fi - if ! have docker; then - err "Docker CLI not found. Please install Docker Desktop or docker CLI." - else - err "Docker is not running. Start Docker Desktop and wait until it is ready." - fi - err "Tip (macOS): open -a Docker" - err "Then re-run: $PROG start" - exit 3 -} - -# Detect k3d cluster name from env or current kubectl context. -# - If K3D_CLUSTER is set, use it. -# - Else, if current-context starts with 'k3d-', strip prefix to get name. -detect_k3d_context() { - if [ -n "${K3D_CLUSTER:-}" ]; then - printf '%s' "$K3D_CLUSTER" - return 0 - fi - local ctx - ctx="$($KUBECTL config current-context 2>/dev/null || echo)" - case "$ctx" in - k3d-*) printf '%s' "${ctx#k3d-}"; return 0 ;; - *) return 1 ;; - esac -} - -# Return 0 if the given k3d cluster exists and is running. -k3d_cluster_is_running() { - local name="$1" - have k3d || return 1 - # Use json output when available; fall back to grep otherwise - if k3d cluster list -o json >/dev/null 2>&1; then - k3d cluster list -o json 2>/dev/null | grep -q '"name"\s*:\s*"'"$name"'"' && \ - k3d cluster list -o json 2>/dev/null | sed -n 's/.*"name"\s*:\s*"\([^"]\+\)".*"serversRunning"\s*:\s*\([0-9]\+\).*/\1 \2/p' | awk -v n="$name" '$1==n {exit ($2>0)?0:1}' - return $? - else - k3d cluster list 2>/dev/null | grep -E "^$name\s" | grep -q running - return $? - fi -} - -# If current context indicates k3d, ensure the cluster is up; otherwise no-op. -ensure_k3d_ready_if_applicable() { - local k3d_name - if ! k3d_name="$(detect_k3d_context)"; then - return 0 - fi - if ! have k3d; then - err "k3d is not installed but kubectl context suggests k3d (context=$("$KUBECTL" config current-context))." - err "Install k3d: brew install k3d (macOS)" - err "Or switch context: kubectl config use-context " - exit 4 - fi - if ! k3d_cluster_is_running "$k3d_name"; then - err "k3d cluster '$k3d_name' is not running." - err "Start it: k3d cluster start $k3d_name" - err "Then re-run: $PROG start" - exit 4 - fi -} - -pid_file_for() { printf '%s/%s.pid' "$PID_DIR" "$1"; } -log_file_for() { printf '%s/%s.log' "$LOG_DIR" "$1"; } - -is_pid_running() { - # Return 0 if pid exists and running, else 1 - # kill -0 is portable. - local pid="$1" - [ -n "$pid" ] && kill -0 "$pid" >/dev/null 2>&1 -} - -read_pid() { - local pf="$1" - [ -f "$pf" ] || return 1 - # shellcheck disable=SC2162 - read pid <"$pf" || return 1 - printf '%s' "$pid" -} - -write_pid() { - local pf="$1" pid="$2" - printf '%s\n' "$pid" >"$pf" -} - -remove_pidfile() { - local pf="$1" - rm -f "$pf" >/dev/null 2>&1 || true -} - -# ---- XML parsing (simple attribute extraction) ---- -# We parse lines containing: -# Attributes must use double quotes in the XML (as in the sample). -get_attr() { - # $1 = line, $2 = attribute name - # outputs value or empty - printf '%s\n' "$1" | sed -n "s/.*$2=\"\([^\"]*\)\".*/\1/p" -} - -foreach_mapping() { - # Calls a provided function with mapping fields: - # callback id ns target address hostPort servicePort protocol description - local callback="$1" - [ -f "$CONFIG_FILE" ] || { err "Config file not found: $CONFIG_FILE"; exit 1; } - - # Support both single-line and multi-line self-closing mapping tags, e.g.: - # OR lines spanning multiple lines until "/>". - local in_mapping=0 in_comment=0 buffer="" line - while IFS= read -r line; do - # Handle XML comments: skip anything between - if [ $in_comment -eq 1 ]; then - case "$line" in - *"-->"*) in_comment=0; continue ;; - *) continue ;; - esac - fi - case "$line" in - *""*) - # single-line comment; skip line - continue - ;; - *) - in_comment=1 - continue - ;; - esac - ;; - esac - if [ $in_mapping -eq 0 ]; then - case "$line" in - *"' - buffer="$buffer $line" - fi - - if [ $in_mapping -eq 1 ] && printf '%s' "$line" | grep -q "/>"; then - # Normalize whitespace to make attribute extraction robust - local merged - merged=$(printf '%s\n' "$buffer" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g') - - local id ns target address hostPort servicePort protocol description - id="$(get_attr "$merged" "id")" - ns="$(get_attr "$merged" "namespace")" - target="$(get_attr "$merged" "target")" - address="$(get_attr "$merged" "address")" - hostPort="$(get_attr "$merged" "hostPort")" - servicePort="$(get_attr "$merged" "servicePort")" - protocol="$(get_attr "$merged" "protocol")" - description="$(get_attr "$merged" "description")" - - # Basic validation - if [ -z "$id" ] || [ -z "$ns" ] || [ -z "$target" ] || [ -z "$hostPort" ] || [ -z "$servicePort" ]; then - err "Invalid mapping (missing required attributes): $merged" - exit 1 - fi - - # Filter by TARGET_ID if set - if [ -n "$TARGET_ID" ] && [ "$id" != "$TARGET_ID" ]; then - in_mapping=0 - buffer="" - continue - fi - - if [ -z "$address" ]; then address="127.0.0.1"; fi - if [ -z "$protocol" ]; then protocol="TCP"; fi - - vlog "mapping: id=$id ns=$ns target=$target address=$address hostPort=$hostPort servicePort=$servicePort protocol=$protocol" - "$callback" "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - # Reset accumulator - in_mapping=0 - buffer="" - fi - done <"$CONFIG_FILE" -} - -build_port_forward_cmd() { - # echo a command string - local ns="$1" target="$2" address="$3" hostPort="$4" servicePort="$5" - # kubectl port-forward -n --address : - printf '%s port-forward -n %s --address %s %s %s:%s' \ - "$KUBECTL" "$ns" "$address" "$target" "$hostPort" "$servicePort" -} - -start_port_forward() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile logfile cmd pid - - # Aggressively stop existing processes before starting to avoid port conflicts - stop_port_forward "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - pidfile="$(pid_file_for "$id")" - logfile="$(log_file_for "$id")" - cmd="$(build_port_forward_cmd "$ns" "$target" "$address" "$hostPort" "$servicePort")" - - log "Starting: $id $address:$hostPort -> $target:$servicePort ($ns) ${description:-}" - vlog "Command: $cmd" - - # Start in background, keep output in log. - # nohup is available on macOS/Linux; redirect stdin from /dev/null to detach. - nohup sh -c "$cmd" >>"$logfile" 2>&1 /dev/null 2>&1 || true - - # wait a moment, then SIGKILL if needed - local i - for i in 1 2 3 4 5; do - if ! is_pid_running "$pid"; then break; fi - sleep 0.2 - done - if is_pid_running "$pid"; then - err "$id did not stop gracefully; sending SIGKILL" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - else - if [ -f "$pidfile" ]; then - vlog "$id stale pidfile (pid=$pid not running)" - fi - fi - remove_pidfile "$pidfile" - - # Aggressively remove any other matching kubectl port-forward processes - # Search for processes that match: kubectl port-forward -n ... : - local extra_pids - extra_pids=$(ps -ef | grep "port-forward" | grep "\-n" | grep "$ns" | grep "$target" | grep "$hostPort:$servicePort" | grep -v grep | awk '{print $2}') - - for epid in $extra_pids; do - if [ "$epid" != "$pid" ]; then - log "Cleaning up orphan process for $id (pid=$epid)" - kill -9 "$epid" >/dev/null 2>&1 || true - fi - done -} - -status_one() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile pid - - pidfile="$(pid_file_for "$id")" - pid="" - if [ -f "$pidfile" ]; then - pid="$(read_pid "$pidfile" || true)" - fi - - if [ -n "${pid:-}" ] && is_pid_running "$pid"; then - printf 'RUNNING %-12s pid=%-7s %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$pid" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - # ps details (portable flags vary; use a conservative format) - ps -p "$pid" -o pid=,ppid=,etime=,command= 2>/dev/null | sed 's/^/ /' || true - else - printf 'STOPPED %-12s (no live pid) %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - fi -} - -do_start() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping start_port_forward -} - -do_stop() { - # stop doesn't require cluster access, but it does need state dirs - ensure_dirs - foreach_mapping stop_port_forward -} - -do_restart() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping stop_port_forward - foreach_mapping start_port_forward -} - -do_status() { - validate_env - # Non-fatal awareness messages - if docker_is_running; then - log "[OK] Docker daemon is running" - else - if have docker; then - log "[WARN] Docker is not running" - else - log "[WARN] Docker CLI not found" - fi - fi - - local _k3d_name - if _k3d_name="$(detect_k3d_context)"; then - if have k3d; then - if k3d_cluster_is_running "$_k3d_name"; then - log "[OK] k3d cluster '$_k3d_name' is running" - else - log "[WARN] k3d cluster '$_k3d_name' is not running" - fi - else - log "[WARN] k3d not installed but context suggests k3d (cluster='$_k3d_name')" - fi - fi - - log "== Context / Cluster ==" - "$KUBECTL" config current-context 2>/dev/null | sed 's/^/ context: /' || true - "$KUBECTL" cluster-info 2>/dev/null | sed 's/^/ /' || true - log "" - - log "== Port-forward processes ==" - foreach_mapping status_one - log "" - - log "== Quick k3d awareness checks (best-effort) ==" - # If user is on k3d, current-context often includes k3d-... but not guaranteed. - # Show nodes + a few namespaces/services related to mappings (best effort). - "$KUBECTL" get nodes -o wide 2>/dev/null | sed 's/^/ /' || true - log "" - "$KUBECTL" get ns 2>/dev/null | sed 's/^/ /' || true - log "" - - # For each mapping, try to show target existence - log "== Target existence (best-effort) ==" - _target_check() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - # kubectl get -n - # If target is like "svc/name", "deploy/name", etc. - if "$KUBECTL" get -n "$ns" "$target" >/dev/null 2>&1; then - printf 'OK %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - else - printf 'MISSING %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - fi - } - foreach_mapping _target_check -} - -# ---- arg parsing ---- -ACTION="" - -while [ $# -gt 0 ]; do - case "$1" in - start|stop|restart|status) - if [ -z "$ACTION" ]; then - ACTION="$1" - else - TARGET_ID="$1" - fi - shift - ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - -c) - shift - [ $# -gt 0 ] || { err "-c requires a file path"; usage; exit 2; } - CONFIG_FILE="$1" - shift - ;; - --config-file=*) - CONFIG_FILE="${1#*=}" - shift - ;; - -h|--help) - usage - exit 0 - ;; - *) - if [ -z "$ACTION" ]; then - err "Unknown arg: $1" - usage - exit 2 - fi - TARGET_ID="$1" - shift - ;; - esac -done - -[ -n "$ACTION" ] || { usage; exit 2; } - -case "$ACTION" in - start) do_start ;; - stop) do_stop ;; - restart) do_restart ;; - status) do_status ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4452427696/init_prole-db.sh b/MagicMock/mock.Entry().get().strip()/4452427696/init_prole-db.sh deleted file mode 100755 index b87de05..0000000 --- a/MagicMock/mock.Entry().get().strip()/4452427696/init_prole-db.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_prole-db.sh -# Purpose: -# - Manage prole-db CloudNative-PG cluster operations (deploy, start, stop, etc.) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -ACTION=${1:-} -VERSION=${2:-latest} - -# Load env -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - source "$HOME/.prole/env.sh" -fi - -CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} -NAMESPACE=${NAMESPACE:-prole} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -ensure_tools() { - for t in kubectl jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -get_latest_image() { - local version_file="$SCRIPT_DIR/../conf/postgresql/.version" - if [[ -f "$version_file" ]]; then - echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" - else - echo "prole-db:17.7-033" - fi -} - -start() { - ensure_tools - echo "Checking dependencies..." - - # 1. k3d is running - if ! command -v k3d >/dev/null || ! k3d cluster list >/dev/null 2>&1; then - echo "ERROR: k3d is not running or not installed." >&2 - exit 1 - fi - - # 2. cnpg operator is loaded - if ! kubectl get deployment -n cnpg-system cnpg-controller-manager >/dev/null 2>&1; then - echo "ERROR: CloudNative-PG operator is not loaded." >&2 - exit 1 - fi - - # 3. openbao is configured - if ! kubectl get statefulset openbao -n "$NAMESPACE" >/dev/null 2>&1 && ! kubectl get deployment openbao -n "$NAMESPACE" >/dev/null 2>&1; then - echo "ERROR: OpenBao is not deployed." >&2 - exit 1 - fi - - # Compare latest image with deployed - local latest_image - latest_image=$(get_latest_image) - - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - - if [[ "$current_image" != "$latest_image" ]]; then - echo "Updating cluster image from '$current_image' to '$latest_image'..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$latest_image\"}}" - # Force a rollout to ensure the new image is pulled even if it was just a tag update (though we use unique tags) - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - else - echo "Cluster is already using the latest image: $latest_image" - fi - - echo "Starting prole-db cluster (ensuring manifest is applied)..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" -} - -stop() { - ensure_tools - echo "Stopping prole-db cluster $CNPG_CLUSTER_NAME..." - - # Identify instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - if [[ -z "$instances" ]]; then - echo "No instances found for cluster $CNPG_CLUSTER_NAME." - return - fi - - # Determine replicas and primary - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - - echo "Primary: $primary" - - # Shutdown replicas first - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Shutting down replica $pod..." - kubectl exec -n "$NAMESPACE" "$pod" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - done - - # Shutdown primary last - if [[ -n "$primary" ]]; then - echo "Shutting down primary $primary..." - kubectl exec -n "$NAMESPACE" "$primary" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - - echo "Deleting cluster resource..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found -} - -restart() { - ensure_tools - echo "Restarting prole-db cluster..." - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -deploy() { - ensure_tools - local image - if [[ "$VERSION" == "latest" ]]; then - image=$(get_latest_image) - else - image="prole-db:$VERSION" - fi - - echo "Deploying $image to cluster $CNPG_CLUSTER_NAME..." - - # If cluster doesn't exist, use init_cloudnative_pg.sh create first - if ! kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then - echo "Cluster not found. Running init_cloudnative_pg.sh create..." - bash "$SCRIPT_DIR/init_cloudnative_pg.sh" create - fi - - # Ensure image is updated if manifest has an older version - # First, apply the manifest to ensure the cluster exists/is updated - echo "Applying manifest $CNPG_MANIFEST..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - - # Then force the specific image version via patch if different - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - if [[ "$current_image" != "$image" ]]; then - echo "Patching cluster to use image '$image' (was '$current_image')..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$image\"}}" - # Force a rollout - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - fi -} - -rollback() { - ensure_tools - echo "Rollback: Updating to previous image (manually specified version or fallback)..." - if [[ "$VERSION" == "latest" ]]; then - echo "Please specify a version to rollback to. Usage: $0 rollback " - exit 1 - fi - deploy -} - -backup() { - echo "Backup - tbd, when we configure s3 or other block store" -} - -reset() { - ensure_tools - echo "Resetting prole-db cluster..." - echo "Removing cnpg instances and pods..." - kubectl delete cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --ignore-not-found - - # Wait for deletion - kubectl wait --for=delete cluster/"$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --timeout=60s || true - - echo "Reinstantiating..." - deploy -} - -case "$ACTION" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - deploy) - deploy - ;; - rollback) - rollback - ;; - backup) - backup - ;; - reset) - reset - ;; - *) - echo "Usage: $0 {start|stop|restart|deploy|rollback|backup|reset} [version]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/env.sh b/MagicMock/mock.Entry().get().strip()/4491602512/env.sh deleted file mode 100755 index 3b9f538..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/env.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Prole environment configuration -# This file is generated by the installer. Source it in new shells, or execute as a wrapper: -# "$PROLE_HOME/env.sh" [args…] -# shellcheck shell=bash -export PROLE_HOME="" -export PROLE_CONF="" -export PROLE_DATA="" -export PROLE_LOGS="" -export PROLE_SERVICE="" - -# Ensure PATH works for GUI-launched shells (Docker, Ollama, etc.) -_prole_add_path() { case ":${PATH}:" in *":$1:"*) ;; *) PATH="$1:${PATH:-}" ;; esac; } -_prole_add_path "$PROLE_HOME/bin" -_prole_add_path "/opt/homebrew/bin" -_prole_add_path "/usr/local/bin" -_prole_add_path "/usr/bin" -_prole_add_path "/bin" -_prole_add_path "/usr/sbin" -_prole_add_path "/sbin" -export PATH - -# Add custom paths below if needed (examples): -# _prole_add_path "/Applications/Ollama.app/Contents/MacOS" - -# If executed with arguments, run them under this environment -if [ "$#" -gt 0 ]; then - exec "$@" -fi diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/hosts.txt b/MagicMock/mock.Entry().get().strip()/4491602512/hosts.txt deleted file mode 100644 index 4e73115..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/hosts.txt +++ /dev/null @@ -1,15 +0,0 @@ -myrddin.prole.org 10.0.0.3 -raspberry.prole.org 10.0.0.4 -pi.prole.org 10.0.0.5 -synology.prole.org 10.0.0.203 -morgoth.prole.org 10.0.0.204 -zinfandel.prole.org 10.0.0.205 -aventage.prole.org 10.0.0.206 -retropie.prole.org 10.0.0.207 -fairyland.prole.org 10.0.0.208 -k8s.prole.org zinfandel.prole.org -mc.prole.org 73.15.20.166 -morana.prole.org 10.0.0.66 -ollama.prole.org 73.15.20.166 -svc.prole.org 73.15.20.166 -www.prole.org ghs.googlehosted.com \ No newline at end of file diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/init_cloudnative_pg.sh b/MagicMock/mock.Entry().get().strip()/4491602512/init_cloudnative_pg.sh deleted file mode 100755 index 6708415..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/init_cloudnative_pg.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_cloudnative_pg.sh -# Purpose: -# - Distribute administrator ed25519 key pair to CloudNative‑PG as a Kubernetes Secret for cert auth -# - Configure Kerberos (GSSAPI) using external Kerberos KDC -# - Patch CNPG cluster to enable TLS and GSSAPI where possible -# -# Usage: -# ./init_cloudnative_pg.sh start|stop|status|restart -# ./init_cloudnative_pg.sh initialize # create/update k8s secrets/configs and patch CNPG -# ./init_cloudnative_pg.sh update|reload # re-apply/patch -# -# Requirements: -# - init_openbao.sh has been run (OpenBao running in k8s) -# - $PROLE_HOME/env.sh or $HOME/.prole/env.sh defining PROLE_SERVICE - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Load env without leaking our positional args to the env script (some env.sh may `exec "$@"`). -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -else - echo "ERROR: Missing env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env." >&2 - exit 1 -fi - -ACTION=${1:-} -CNPG_CLUSTER_NAME=${2:-${CNPG_CLUSTER_NAME:-prole-db}} -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -REALM=${REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-prole.org} -KRB5_KDC=${KRB5_KDC:-} -KRB5_ADMIN=${KRB5_ADMIN:-} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -SECRETS_DIR="$PROLE_SERVICE/secrets" -ADMIN_PRIV="$SECRETS_DIR/admin_ed25519.key" -ADMIN_PUB="$SECRETS_DIR/admin_ed25519.pub" -OPENBAO_TOKEN_FILE="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64 jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -# Resolve OpenBao URL: prefer explicit env, then localhost port-forward, then cluster DNS -bao_service_url() { - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - echo "$PROLE_OPENBAO_URL" - return 0 - fi - # Prefer standard local port-forward managed by etc/init_port_forwards.sh - if curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - echo "http://127.0.0.1:18200" - return 0 - fi - echo "http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" -} - -fetch_admin_keys_and_db_pass_from_bao_or_local() { - local token url - if [[ -f "$OPENBAO_TOKEN_FILE" ]]; then - token=$(cat "$OPENBAO_TOKEN_FILE") - else - token="" - fi - url=$(bao_service_url) - if [[ -n "$token" ]]; then - echo "Attempting to read admin key pair from OpenBao kv/prole/admin ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -e '.data.data' >/dev/null 2>&1; then - local priv_b64 pub_b64 - priv_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_private_key_b64') - pub_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_public_key_b64') - printf "%s" "$priv_b64" | base64 -d >"$ADMIN_PRIV" - printf "%s" "$pub_b64" | base64 -d >"$ADMIN_PUB" - chmod 0600 "$ADMIN_PRIV" - fi - - echo "Attempting to read database password from OpenBao kv/prole/db ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -e '.data.data' >/dev/null 2>&1; then - local db_pass - db_pass=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -r '.data.data.password') - if [[ -n "$db_pass" ]]; then - echo "Updating database user secret 'prole-db-user' from OpenBao ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username=prole \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - - echo "Updating database superuser secret 'prole-db-superuser' from OpenBao ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - fi - fi - fi - - if [[ -f "$ADMIN_PRIV" && -f "$ADMIN_PUB" ]]; then - echo "Using local admin key pair at $SECRETS_DIR" - return 0 - fi - echo "ERROR: Could not obtain admin key pair from OpenBao and no local files found." >&2 - exit 1 -} - -apply_cnpg_admin_secret() { - echo "Creating/updating Secret cnpg-admin-key ..." - kubectl create secret generic cnpg-admin-key -n "$NAMESPACE" \ - --from-file=admin.key="$ADMIN_PRIV" \ - --from-file=admin.pub="$ADMIN_PUB" \ - --dry-run=client -o yaml | kubectl apply -f - -} - -ensure_krb5_conf_configmap() { - echo "Creating/updating ConfigMap prole-krb5-conf ..." - - local kdc_val admin_val - if [[ -n "$KRB5_KDC" ]]; then - kdc_val="$KRB5_KDC" - admin_val=${KRB5_ADMIN:-$(echo "$KRB5_KDC" | cut -d, -f1)} - else - kdc_val="kdc.$DOMAIN" - admin_val="kdc.$DOMAIN" - fi - - local TMP - TMP=$(mktemp) - cat >"$TMP" </dev/null 2>&1; then - echo "CA secret $ca_secret_name already exists; skipping generation." - return 0 - fi - echo "Generating self-signed CA (RSA 4096) for CNPG ..." - local TMPD - TMPD=$(mktemp -d) - openssl genrsa -out "$TMPD/ca.key" 4096 - openssl req -x509 -new -key "$TMPD/ca.key" -out "$TMPD/ca.crt" -days 3650 -subj "/CN=Prole CNPG CA" - kubectl -n "$NAMESPACE" create secret generic "$ca_secret_name" \ - --from-file=ca.crt="$TMPD/ca.crt" \ - --from-file=ca.key="$TMPD/ca.key" \ - --dry-run=client -o yaml | kubectl apply -f - - rm -rf "$TMPD" -} - -patch_cnpg_cluster_for_auth() { - echo "Patching CNPG Cluster $CNPG_CLUSTER_NAME to enable GSSAPI and fix config (best-effort) ..." - # Best-effort patch; schema may vary with CNPG version. - # We remove krb_srvname as it is unrecognized in some PG 17 builds. - # We revert certificates to default to avoid operator TLS issues. - kubectl -n "$NAMESPACE" patch cluster "$CNPG_CLUSTER_NAME" --type merge -p "{ - \"spec\": { - \"postgresql\": { - \"parameters\": {\"krb_srvname\": null}, - \"pg_hba\": [ - \"local all postgres trust\", - \"host all postgres all scram-sha-256\", - \"host all all all gss include_realm=1 krb_realm=$REALM\", - \"host all all all scram-sha-256\" - ] - }, - \"certificates\": { - \"serverCASecret\": null, - \"clientCASecret\": null - } - } - }" >/dev/null || echo "Note: patch may need adjustment for your CNPG version." -} - -initialize() { - ensure_tools - - # Ensure port-forward is running for OpenBao (dependency) - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - fetch_admin_keys_and_db_pass_from_bao_or_local - apply_cnpg_admin_secret - ensure_krb5_conf_configmap - # generate_tls_if_missing - patch_cnpg_cluster_for_auth - - # Ensure port-forward is running for Postgres (local access) - echo "Ensuring port-forward for Postgres is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart postgres - - echo "Initialization complete for CNPG + Kerberos + cert artifacts." -} - -update_reload() { - initialize -} - -case "$ACTION" in - recreate) - ensure_tools - "$0" delete "$CNPG_CLUSTER_NAME" - "$0" create "$CNPG_CLUSTER_NAME" - ;; - create) - ensure_tools - echo "Installing CloudNative-PG operator ..." - kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml - - echo "Creating CloudNative-PG cluster and resources for '$CNPG_CLUSTER_NAME' ..." - - kubectl apply -k "$SCRIPT_DIR/../k8s/prole" - - # Ensure prole-index-html exists for prole deployment readiness probe - if ! kubectl get configmap prole-index-html -n prole >/dev/null 2>&1; then - echo "Creating prole-index-html configmap..." - printf "

Prole

" > /tmp/index.html - kubectl create configmap prole-index-html --from-file=/tmp/index.html -n prole - rm /tmp/index.html - fi - - # Ensure prole-nginx-tls exists (self-signed for dev) - if ! kubectl get secret prole-nginx-tls -n prole >/dev/null 2>&1; then - echo "Generating self-signed prole-nginx-tls for development..." - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /tmp/nginx-tls.key -out /tmp/nginx-tls.crt \ - -subj "/CN=prole.org" >/dev/null 2>&1 - kubectl create secret tls prole-nginx-tls --key /tmp/nginx-tls.key --cert /tmp/nginx-tls.crt -n prole - rm /tmp/nginx-tls.key /tmp/nginx-tls.crt - fi - - echo "Initializing and patching cluster ..." - initialize - ;; - delete) - ensure_tools - echo "Deleting all resources for '$CNPG_CLUSTER_NAME' ..." - kubectl delete -k "$SCRIPT_DIR/../k8s/prole" --ignore-not-found - ;; - start) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Starting CloudNative-PG cluster from $CNPG_MANIFEST in namespace $NAMESPACE..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - ;; - stop) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Stopping CloudNative-PG cluster using $CNPG_MANIFEST ..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found - ;; - status) - ensure_tools - echo "--- CloudNative-PG Cluster Status ($CNPG_CLUSTER_NAME) ---" - if kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" - echo "" - echo "CNPG Plugin Status:" - if kubectl cnpg version >/dev/null 2>&1; then - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - else - echo "Note: 'kubectl cnpg' plugin not found; skipping detailed status." - fi - else - echo "Cluster '$CNPG_CLUSTER_NAME' not found in namespace '$NAMESPACE'." - fi - ;; - restart) - ensure_tools - "$0" stop - "$0" start - ;; - initialize) - initialize - ;; - update|reload) - update_reload - ;; - *) - echo "Usage: $0 {create|delete|recreate|start|stop|status|restart|initialize|update|reload} [dbname]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/init_k8s.sh b/MagicMock/mock.Entry().get().strip()/4491602512/init_k8s.sh deleted file mode 100755 index 35f14aa..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/init_k8s.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# etc/init_k8s.sh -# Purpose: Manage k3d/k8s environment - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -# Default values -VERBOSE=false -ENVIRONMENT="prod" -HOST="" -CLUSTER_NAME_DEFAULT="prole-dev-cluster" -CLUSTER_PORT_DEFAULT="6443" - -usage() { - cat </dev/null || { echo "ERROR: Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - if ! docker info >/dev/null 2>&1; then - echo "ERROR: Docker is not running." >&2 - exit 1 - fi -} - -initialize() { - ensure_tools - ensure_docker - - if [[ "$ENVIRONMENT" == "dev" ]]; then - if [[ -z "$CLUSTER_NAME" ]]; then - if [[ -t 0 ]]; then - read -p "Enter k3d cluster name [$CLUSTER_NAME_DEFAULT]: " CLUSTER_NAME - CLUSTER_NAME=${CLUSTER_NAME:-$CLUSTER_NAME_DEFAULT} - else - CLUSTER_NAME=$CLUSTER_NAME_DEFAULT - fi - fi - - if k3d cluster list "$CLUSTER_NAME" >/dev/null 2>&1; then - log "Cluster '$CLUSTER_NAME' already exists." - else - log "Creating k3d cluster '$CLUSTER_NAME'..." - k3d cluster create "$CLUSTER_NAME" -p "0.0.0.0:$CLUSTER_PORT_DEFAULT:6443@server:0" - fi - else - if [[ -n "$HOST" ]]; then - log "Environment is $ENVIRONMENT. Host is $HOST." - log "TODO: Fetch kubeconfig from $HOST (placeholder)." - else - log "Environment is $ENVIRONMENT. Use -h|--host to specify the remote cluster host." - fi - fi -} - -status() { - ensure_tools - log "Checking Docker status..." - if docker info >/dev/null 2>&1; then - echo "Docker is running." - else - echo "Docker is NOT running." - fi - - log "Listing k3d clusters..." - k3d cluster list -} - -get_cluster_name() { - # If a name was provided or exists in env, use it. - # Otherwise, if there is only one cluster, use it. - # Finally, use default. - if [[ -n "${CLUSTER_NAME:-}" ]]; then - echo "$CLUSTER_NAME" - return - fi - - local clusters - clusters=$(k3d cluster list --no-headers | awk '{print $1}') - local count - count=$(echo "$clusters" | grep -c . || true) - - if [[ "$count" -eq 1 ]]; then - echo "$clusters" - else - echo "$CLUSTER_NAME_DEFAULT" - fi -} - -case "$ACTION" in - initialize) - initialize - ;; - status) - status - ;; - start) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Starting k3d cluster '$CLUSTER_NAME'..." - k3d cluster start "$CLUSTER_NAME" - ;; - stop) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Stopping k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - ;; - restart) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Restarting k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - k3d cluster start "$CLUSTER_NAME" - ;; - *) - usage - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/init_openbao.sh b/MagicMock/mock.Entry().get().strip()/4491602512/init_openbao.sh deleted file mode 100755 index 3e59151..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/init_openbao.sh +++ /dev/null @@ -1,490 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_openbao.sh -# Purpose: -# - Deploy OpenBao to Kubernetes (dev mode) and store admin ed25519 key pair -# Generate and apply a Kerberos krb5.conf ConfigMap for an external realm -# - Local Docker helpers for OpenBao (optional) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi - -ACTION=${1:-} - -# Defaults -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -OPENBAO_MANIFEST_DIR="$SCRIPT_DIR/../k8s/openbao" - -# Kerberos realm defaults -KRB5_REALM=${KRB5_REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-$(echo "$KRB5_REALM" | tr 'A-Z' 'a-z')} -KRB5_KDC=${KRB5_KDC:-kdc.$DOMAIN} -KRB5_ADMIN=${KRB5_ADMIN:-} - -# Secrets and token locations -SECRETS_DIR="$PROLE_SERVICE/secrets" -mkdir -p "$SECRETS_DIR" -admin_key_priv="$SECRETS_DIR/admin_ed25519.key" -admin_key_pub="$SECRETS_DIR/admin_ed25519.pub" -root_token_file="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - command -v docker >/dev/null || { echo "Missing required tool: docker" >&2; exit 1; } -} - -ensure_admin_keypair() { - # Ensure admin ed25519 keypair exists and a root token is available - mkdir -p "$SECRETS_DIR" - if [[ ! -f "$admin_key_priv" || ! -f "$admin_key_pub" ]]; then - echo "Generating admin ed25519 keypair in $SECRETS_DIR ..." - openssl genpkey -algorithm ED25519 -out "$admin_key_priv" - openssl pkey -in "$admin_key_priv" -pubout -out "$admin_key_pub" - chmod 0600 "$admin_key_priv" - fi - # Ensure a root token exists for OpenBao dev server interactions - if [[ ! -f "$root_token_file" || ! -s "$root_token_file" ]]; then - openssl rand -hex 24 >"$root_token_file" - chmod 0600 "$root_token_file" - fi -} - -generate_openbao_manifests() { - mkdir -p "$OPENBAO_MANIFEST_DIR" - # Only create a simple deployment if none exists; otherwise respect current file - local deploy="$OPENBAO_MANIFEST_DIR/deployment.yaml" - if [[ ! -f "$deploy" ]]; then - cat >"$deploy" <"$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" </dev/null 2>&1; then - kubectl rollout status statefulset/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - else - kubectl rollout status deploy/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - fi -} - -init_openbao_kv_and_store_admin_key() { - local token - token=$(cat "$root_token_file") - # Enable kv (if not already) and write keys - local svc="http://127.0.0.1:18200" - echo "Configuring KV at $svc ..." - - # Check if kv/ is already mounted - if curl -sS -H "X-Vault-Token: $token" "$svc/v1/sys/mounts" | grep -q '"kv/":'; then - echo "KV path 'kv/' is already enabled." - else - curl -sS -H "X-Vault-Token: $token" -X POST "$svc/v1/sys/mounts/kv" \ - -d '{"type":"kv","options":{"version":"2"}}' >/dev/null 2>&1 || true - fi - - local priv pub - priv=$(base64 <"$admin_key_priv" | tr -d '\n') - pub=$(base64 <"$admin_key_pub" | tr -d '\n') - - # Check if admin key already exists and matches - local existing_data - existing_data=$(curl -sS -H "X-Vault-Token: $token" "$svc/v1/kv/data/prole/admin" 2>/dev/null || true) - if [[ -n "$existing_data" ]]; then - local ex_priv ex_pub - ex_priv=$(echo "$existing_data" | grep -o '"admin_private_key_b64":"[^"]*' | cut -d'"' -f4 || true) - ex_pub=$(echo "$existing_data" | grep -o '"admin_public_key_b64":"[^"]*' | cut -d'"' -f4 || true) - - if [[ "$ex_priv" == "$priv" && "$ex_pub" == "$pub" ]]; then - echo "Admin key pair in OpenBao kv/prole/admin is already up to date." - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - - # Store User SSH keys if they exist - local user_key_priv="$HOME/.ssh/id_prole_ed25519" - local user_key_pub="$HOME/.ssh/id_prole_ed25519.pub" - if [[ -f "$user_key_priv" && -f "$user_key_pub" ]]; then - local u_priv u_pub - u_priv=$(base64 <"$user_key_priv" | tr -d '\n') - u_pub=$(base64 <"$user_key_pub" | tr -d '\n') - local username=${PROLE_DB_USER:-"prole"} - - echo "Writing user SSH keys for '$username' to kv/prole/user ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/user" \ - -d "{\"data\":{\"username\":\"$username\",\"private_key_b64\":\"$u_priv\",\"public_key_b64\":\"$u_pub\"}}" >/dev/null - echo "Stored user SSH keys in OpenBao kv/prole/user." - fi - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Writing database user password for '$username' to kv/prole/db ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/db" \ - -d "{\"data\":{\"username\":\"$username\",\"password\":\"$db_pass\"}}" >/dev/null - echo "Stored database password in OpenBao kv/prole/db." - fi -} - -# Removed: prompt_admin_password_and_apply_secret (no AD admin secret required) - -docker_start() { - echo "Starting local Docker container for OpenBao ..." - ensure_docker - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - # OpenBao dev - local token - token=$(cat "$root_token_file" 2>/dev/null || true) - if [[ -z "$token" ]]; then - token=$(openssl rand -hex 24) - printf "%s" "$token" >"$root_token_file" - chmod 0600 "$root_token_file" - fi - docker run -d --name "$OPENBAO_NAME" -p 18200:8200 \ - "$OPENBAO_IMAGE" server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id="$token" - echo "Docker container started: $OPENBAO_NAME" -} - -docker_stop() { - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - echo "Stopped OpenBao container if it was running." -} - -docker_restart() { - docker_stop - docker_start -} - -# status command implementation wrapped in a function to avoid top-level 'local' -cmd_status() { - echo "--- init_primary_domain status ---" - echo "Namespace: $NAMESPACE" - echo "OpenBao name: $OPENBAO_NAME" - echo "Manifest dir: $OPENBAO_MANIFEST_DIR" - - # Files/manifests present - local ok=0 - if [[ -f "$OPENBAO_MANIFEST_DIR/deployment.yaml" ]]; then - echo "[OK] OpenBao deployment manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/deployment.yaml" - ok=1 - fi - if [[ -f "$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" ]]; then - echo "[OK] Kerberos ConfigMap manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" - ok=1 - fi - - # K8s resources - if kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" >/dev/null 2>&1; then - local ready desired - ready=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao StatefulSet running ($ready/$desired ready)" - else - echo "[WARN] OpenBao StatefulSet not fully ready ($ready/$desired)" - ok=1 - fi - elif kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" >/dev/null 2>&1; then - # Get readiness - local ready desired - ready=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao Deployment running ($ready/$desired ready)" - else - echo "[WARN] OpenBao Deployment not fully ready ($ready/$desired)" - ok=1 - fi - else - echo "[MISSING] OpenBao Deployment or StatefulSet '$OPENBAO_NAME' in namespace '$NAMESPACE'" - ok=1 - fi - - if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then - echo "[OK] Kerberos ConfigMap 'prole-krb5-conf' present" - else - echo "[MISSING] Kerberos ConfigMap 'prole-krb5-conf' in namespace '$NAMESPACE'" - ok=1 - fi - - # Docker (optional local mode) - if command -v docker >/dev/null 2>&1; then - if docker ps --format '{{.Names}}' | grep -Fxq "$OPENBAO_NAME"; then - echo "[OK] Docker container '$OPENBAO_NAME' is running" - else - # Not necessarily an error; we primarily use k8s - echo "[INFO] Docker container '$OPENBAO_NAME' not running (k8s mode may be in use)" - fi - fi - - # Secrets and tokens - if [[ -f "$admin_key_priv" && -f "$admin_key_pub" ]]; then - echo "[OK] Admin ed25519 keypair present in $SECRETS_DIR" - else - echo "[MISSING] Admin keypair files in $SECRETS_DIR" - ok=1 - fi - if [[ -s "$root_token_file" ]]; then - echo "[OK] OpenBao root token file present" - else - echo "[MISSING] OpenBao root token file ($root_token_file)" - ok=1 - fi - - # OpenBao reachability and token validity (best-effort) - # Prefer explicit override, then localhost port-forward, then cluster DNS - local svc_url - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - svc_url="$PROLE_OPENBAO_URL" - elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - svc_url="http://127.0.0.1:18200" - else - svc_url="http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" - fi - if curl -sS "$svc_url/v1/sys/health" >/dev/null 2>&1; then - echo "[OK] OpenBao service reachable" - if [[ -s "$root_token_file" ]]; then - local code - code=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Vault-Token: $(cat "$root_token_file")" "$svc_url/v1/sys/mounts" || echo "000") - if [[ "$code" == "200" ]]; then - echo "[OK] OpenBao root token authenticates" - else - echo "[WARN] OpenBao root token did not authenticate (HTTP $code)" - ok=1 - fi - fi - else - echo "[WARN] OpenBao service not reachable at $svc_url" - ok=1 - fi - - # Service certificate existence (CNPG TLS) - local CNPG_CLUSTER_NAME - CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} - if kubectl -n "$NAMESPACE" get secret "${CNPG_CLUSTER_NAME}-tls" >/dev/null 2>&1; then - echo "[OK] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' exists" - else - echo "[INFO] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' not found" - fi - - echo "-------------------------------------" - if [[ $ok -eq 0 ]]; then - echo "Status: OK" - return 0 - else - echo "Status: Issues detected" - return 1 - fi -} - -case "$ACTION" in - start) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_start - ;; - status) - ensure_tools - cmd_status - ;; - stop) - ensure_docker - docker_stop - ;; - restart) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_restart - ;; - initialize) - ensure_tools - # Read password from stdin if provided - db_pass="" - if [[ ! -t 0 ]]; then - read -r db_pass - fi - - ensure_admin_keypair - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Creating database user secret 'prole-db-user' for '$username' ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username="$username" \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - - echo "Creating database superuser secret 'prole-db-superuser' ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - fi - - wait_for_openbao - - # Ensure port-forward is running for OpenBao - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - if ! curl -sS http://127.0.0.1:18200/v1/sys/health >/dev/null 2>&1; then - echo "ERROR: OpenBao not reachable at http://127.0.0.1:18200." >&2 - echo "Please start port-forwards: $SCRIPT_DIR/init_port_forwards.sh start openbao" >&2 - exit 1 - fi - init_openbao_kv_and_store_admin_key - echo "Initialization complete. Manifests in: $OPENBAO_MANIFEST_DIR" - ;; - update|reload) - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - echo "Re-applied manifests." - ;; - *) - echo "Usage: $0 {start|stop|status|restart|initialize|update|reload}" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/init_port_forwards.sh b/MagicMock/mock.Entry().get().strip()/4491602512/init_port_forwards.sh deleted file mode 100755 index 9ebea5c..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/init_port_forwards.sh +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env bash -set -u - -# init_port_forwards.sh -# Portable-ish (macOS, Ubuntu, Raspberry Pi OS, Alpine) bash init-style script -# Manages kubectl port-forward daemons defined in an XML file. - -PROG="init_port_forwards" -PROLE_HOME="${PROLE_HOME:-/Users/chrisfu/dev/prole}" -VERBOSE=0 -CONFIG_FILE="$PROLE_HOME/conf/port-mappings.properties" - -usage() { - cat < [component] - -Options: - -c, --config-file=FILE Path to local-ports.properties (XML) - -v, --verbose Verbose output - -Examples: - $PROG -c ./port-mappings.properties start - $PROG stop openbao - $PROG --verbose status -EOF -} - -TARGET_ID="" - -log() { printf '%s\n' "$*"; } -vlog() { [ "$VERBOSE" -eq 1 ] && printf '[verbose] %s\n' "$*" || true; } -err() { printf '[error] %s\n' "$*" >&2; } - -have() { command -v "$1" >/dev/null 2>&1; } - -# Choose a writable state dir for pid/log files: -# - Prefer XDG_RUNTIME_DIR if set and writable -# - Else /var/run if writable (rare without root) -# - Else ~/.local/state -# - Else /tmp -state_dir() { - if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -w "${XDG_RUNTIME_DIR:-}" ]; then - printf '%s/%s' "$XDG_RUNTIME_DIR" "$PROG" - return - fi - if [ -d "/var/run" ] && [ -w "/var/run" ]; then - printf '/var/run/%s' "$PROG" - return - fi - if [ -n "${HOME:-}" ]; then - mkdir -p "$HOME/.local/state" >/dev/null 2>&1 || true - if [ -d "$HOME/.local/state" ] && [ -w "$HOME/.local/state" ]; then - printf '%s/.local/state/%s' "$HOME" "$PROG" - return - fi - fi - printf '/tmp/%s' "$PROG" -} - -STATE_DIR="$(state_dir)" -PID_DIR="$STATE_DIR/pids" -LOG_DIR="$STATE_DIR/logs" - -ensure_dirs() { - mkdir -p "$PID_DIR" "$LOG_DIR" 2>/dev/null || true - if [ ! -d "$PID_DIR" ] || [ ! -d "$LOG_DIR" ]; then - err "Unable to create state directories under: $STATE_DIR" - exit 1 - fi -} - -# Use kubectl for actions; kubecolor is used only for prettier status output. -KUBECTL="kubectl" -detect_kubectl() { - if have kubectl; then - KUBECTL="kubectl" - else - err "kubectl not found in PATH" - exit 1 - fi -} - -# Basic environment validation -validate_env() { - detect_kubectl - ensure_dirs - - if ! "$KUBECTL" version --client >/dev/null 2>&1; then - err "kubectl seems broken or not executable" - exit 1 - fi - - # Can we reach the cluster? - if ! "$KUBECTL" cluster-info >/dev/null 2>&1; then - err "kubectl cannot reach a cluster (check KUBECONFIG/context)" - err "Try: kubectl config get-contexts && kubectl config use-context " - exit 1 - fi -} - -# ---- Preflight: Docker + k3d awareness ---- -# Return 0 when Docker CLI can talk to a running daemon. -docker_is_running() { - if ! have docker; then - return 1 - fi - docker info >/dev/null 2>&1 -} - -# Hard-fail with clean guidance when Docker is not up (used for start/restart). -ensure_docker_running() { - if docker_is_running; then - return 0 - fi - if ! have docker; then - err "Docker CLI not found. Please install Docker Desktop or docker CLI." - else - err "Docker is not running. Start Docker Desktop and wait until it is ready." - fi - err "Tip (macOS): open -a Docker" - err "Then re-run: $PROG start" - exit 3 -} - -# Detect k3d cluster name from env or current kubectl context. -# - If K3D_CLUSTER is set, use it. -# - Else, if current-context starts with 'k3d-', strip prefix to get name. -detect_k3d_context() { - if [ -n "${K3D_CLUSTER:-}" ]; then - printf '%s' "$K3D_CLUSTER" - return 0 - fi - local ctx - ctx="$($KUBECTL config current-context 2>/dev/null || echo)" - case "$ctx" in - k3d-*) printf '%s' "${ctx#k3d-}"; return 0 ;; - *) return 1 ;; - esac -} - -# Return 0 if the given k3d cluster exists and is running. -k3d_cluster_is_running() { - local name="$1" - have k3d || return 1 - # Use json output when available; fall back to grep otherwise - if k3d cluster list -o json >/dev/null 2>&1; then - k3d cluster list -o json 2>/dev/null | grep -q '"name"\s*:\s*"'"$name"'"' && \ - k3d cluster list -o json 2>/dev/null | sed -n 's/.*"name"\s*:\s*"\([^"]\+\)".*"serversRunning"\s*:\s*\([0-9]\+\).*/\1 \2/p' | awk -v n="$name" '$1==n {exit ($2>0)?0:1}' - return $? - else - k3d cluster list 2>/dev/null | grep -E "^$name\s" | grep -q running - return $? - fi -} - -# If current context indicates k3d, ensure the cluster is up; otherwise no-op. -ensure_k3d_ready_if_applicable() { - local k3d_name - if ! k3d_name="$(detect_k3d_context)"; then - return 0 - fi - if ! have k3d; then - err "k3d is not installed but kubectl context suggests k3d (context=$("$KUBECTL" config current-context))." - err "Install k3d: brew install k3d (macOS)" - err "Or switch context: kubectl config use-context " - exit 4 - fi - if ! k3d_cluster_is_running "$k3d_name"; then - err "k3d cluster '$k3d_name' is not running." - err "Start it: k3d cluster start $k3d_name" - err "Then re-run: $PROG start" - exit 4 - fi -} - -pid_file_for() { printf '%s/%s.pid' "$PID_DIR" "$1"; } -log_file_for() { printf '%s/%s.log' "$LOG_DIR" "$1"; } - -is_pid_running() { - # Return 0 if pid exists and running, else 1 - # kill -0 is portable. - local pid="$1" - [ -n "$pid" ] && kill -0 "$pid" >/dev/null 2>&1 -} - -read_pid() { - local pf="$1" - [ -f "$pf" ] || return 1 - # shellcheck disable=SC2162 - read pid <"$pf" || return 1 - printf '%s' "$pid" -} - -write_pid() { - local pf="$1" pid="$2" - printf '%s\n' "$pid" >"$pf" -} - -remove_pidfile() { - local pf="$1" - rm -f "$pf" >/dev/null 2>&1 || true -} - -# ---- XML parsing (simple attribute extraction) ---- -# We parse lines containing: -# Attributes must use double quotes in the XML (as in the sample). -get_attr() { - # $1 = line, $2 = attribute name - # outputs value or empty - printf '%s\n' "$1" | sed -n "s/.*$2=\"\([^\"]*\)\".*/\1/p" -} - -foreach_mapping() { - # Calls a provided function with mapping fields: - # callback id ns target address hostPort servicePort protocol description - local callback="$1" - [ -f "$CONFIG_FILE" ] || { err "Config file not found: $CONFIG_FILE"; exit 1; } - - # Support both single-line and multi-line self-closing mapping tags, e.g.: - # OR lines spanning multiple lines until "/>". - local in_mapping=0 in_comment=0 buffer="" line - while IFS= read -r line; do - # Handle XML comments: skip anything between - if [ $in_comment -eq 1 ]; then - case "$line" in - *"-->"*) in_comment=0; continue ;; - *) continue ;; - esac - fi - case "$line" in - *""*) - # single-line comment; skip line - continue - ;; - *) - in_comment=1 - continue - ;; - esac - ;; - esac - if [ $in_mapping -eq 0 ]; then - case "$line" in - *"' - buffer="$buffer $line" - fi - - if [ $in_mapping -eq 1 ] && printf '%s' "$line" | grep -q "/>"; then - # Normalize whitespace to make attribute extraction robust - local merged - merged=$(printf '%s\n' "$buffer" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g') - - local id ns target address hostPort servicePort protocol description - id="$(get_attr "$merged" "id")" - ns="$(get_attr "$merged" "namespace")" - target="$(get_attr "$merged" "target")" - address="$(get_attr "$merged" "address")" - hostPort="$(get_attr "$merged" "hostPort")" - servicePort="$(get_attr "$merged" "servicePort")" - protocol="$(get_attr "$merged" "protocol")" - description="$(get_attr "$merged" "description")" - - # Basic validation - if [ -z "$id" ] || [ -z "$ns" ] || [ -z "$target" ] || [ -z "$hostPort" ] || [ -z "$servicePort" ]; then - err "Invalid mapping (missing required attributes): $merged" - exit 1 - fi - - # Filter by TARGET_ID if set - if [ -n "$TARGET_ID" ] && [ "$id" != "$TARGET_ID" ]; then - in_mapping=0 - buffer="" - continue - fi - - if [ -z "$address" ]; then address="127.0.0.1"; fi - if [ -z "$protocol" ]; then protocol="TCP"; fi - - vlog "mapping: id=$id ns=$ns target=$target address=$address hostPort=$hostPort servicePort=$servicePort protocol=$protocol" - "$callback" "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - # Reset accumulator - in_mapping=0 - buffer="" - fi - done <"$CONFIG_FILE" -} - -build_port_forward_cmd() { - # echo a command string - local ns="$1" target="$2" address="$3" hostPort="$4" servicePort="$5" - # kubectl port-forward -n --address : - printf '%s port-forward -n %s --address %s %s %s:%s' \ - "$KUBECTL" "$ns" "$address" "$target" "$hostPort" "$servicePort" -} - -start_port_forward() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile logfile cmd pid - - # Aggressively stop existing processes before starting to avoid port conflicts - stop_port_forward "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - pidfile="$(pid_file_for "$id")" - logfile="$(log_file_for "$id")" - cmd="$(build_port_forward_cmd "$ns" "$target" "$address" "$hostPort" "$servicePort")" - - log "Starting: $id $address:$hostPort -> $target:$servicePort ($ns) ${description:-}" - vlog "Command: $cmd" - - # Start in background, keep output in log. - # nohup is available on macOS/Linux; redirect stdin from /dev/null to detach. - nohup sh -c "$cmd" >>"$logfile" 2>&1 /dev/null 2>&1 || true - - # wait a moment, then SIGKILL if needed - local i - for i in 1 2 3 4 5; do - if ! is_pid_running "$pid"; then break; fi - sleep 0.2 - done - if is_pid_running "$pid"; then - err "$id did not stop gracefully; sending SIGKILL" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - else - if [ -f "$pidfile" ]; then - vlog "$id stale pidfile (pid=$pid not running)" - fi - fi - remove_pidfile "$pidfile" - - # Aggressively remove any other matching kubectl port-forward processes - # Search for processes that match: kubectl port-forward -n ... : - local extra_pids - extra_pids=$(ps -ef | grep "port-forward" | grep "\-n" | grep "$ns" | grep "$target" | grep "$hostPort:$servicePort" | grep -v grep | awk '{print $2}') - - for epid in $extra_pids; do - if [ "$epid" != "$pid" ]; then - log "Cleaning up orphan process for $id (pid=$epid)" - kill -9 "$epid" >/dev/null 2>&1 || true - fi - done -} - -status_one() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile pid - - pidfile="$(pid_file_for "$id")" - pid="" - if [ -f "$pidfile" ]; then - pid="$(read_pid "$pidfile" || true)" - fi - - if [ -n "${pid:-}" ] && is_pid_running "$pid"; then - printf 'RUNNING %-12s pid=%-7s %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$pid" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - # ps details (portable flags vary; use a conservative format) - ps -p "$pid" -o pid=,ppid=,etime=,command= 2>/dev/null | sed 's/^/ /' || true - else - printf 'STOPPED %-12s (no live pid) %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - fi -} - -do_start() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping start_port_forward -} - -do_stop() { - # stop doesn't require cluster access, but it does need state dirs - ensure_dirs - foreach_mapping stop_port_forward -} - -do_restart() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping stop_port_forward - foreach_mapping start_port_forward -} - -do_status() { - validate_env - # Non-fatal awareness messages - if docker_is_running; then - log "[OK] Docker daemon is running" - else - if have docker; then - log "[WARN] Docker is not running" - else - log "[WARN] Docker CLI not found" - fi - fi - - local _k3d_name - if _k3d_name="$(detect_k3d_context)"; then - if have k3d; then - if k3d_cluster_is_running "$_k3d_name"; then - log "[OK] k3d cluster '$_k3d_name' is running" - else - log "[WARN] k3d cluster '$_k3d_name' is not running" - fi - else - log "[WARN] k3d not installed but context suggests k3d (cluster='$_k3d_name')" - fi - fi - - log "== Context / Cluster ==" - "$KUBECTL" config current-context 2>/dev/null | sed 's/^/ context: /' || true - "$KUBECTL" cluster-info 2>/dev/null | sed 's/^/ /' || true - log "" - - log "== Port-forward processes ==" - foreach_mapping status_one - log "" - - log "== Quick k3d awareness checks (best-effort) ==" - # If user is on k3d, current-context often includes k3d-... but not guaranteed. - # Show nodes + a few namespaces/services related to mappings (best effort). - "$KUBECTL" get nodes -o wide 2>/dev/null | sed 's/^/ /' || true - log "" - "$KUBECTL" get ns 2>/dev/null | sed 's/^/ /' || true - log "" - - # For each mapping, try to show target existence - log "== Target existence (best-effort) ==" - _target_check() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - # kubectl get -n - # If target is like "svc/name", "deploy/name", etc. - if "$KUBECTL" get -n "$ns" "$target" >/dev/null 2>&1; then - printf 'OK %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - else - printf 'MISSING %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - fi - } - foreach_mapping _target_check -} - -# ---- arg parsing ---- -ACTION="" - -while [ $# -gt 0 ]; do - case "$1" in - start|stop|restart|status) - if [ -z "$ACTION" ]; then - ACTION="$1" - else - TARGET_ID="$1" - fi - shift - ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - -c) - shift - [ $# -gt 0 ] || { err "-c requires a file path"; usage; exit 2; } - CONFIG_FILE="$1" - shift - ;; - --config-file=*) - CONFIG_FILE="${1#*=}" - shift - ;; - -h|--help) - usage - exit 0 - ;; - *) - if [ -z "$ACTION" ]; then - err "Unknown arg: $1" - usage - exit 2 - fi - TARGET_ID="$1" - shift - ;; - esac -done - -[ -n "$ACTION" ] || { usage; exit 2; } - -case "$ACTION" in - start) do_start ;; - stop) do_stop ;; - restart) do_restart ;; - status) do_status ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4491602512/init_prole-db.sh b/MagicMock/mock.Entry().get().strip()/4491602512/init_prole-db.sh deleted file mode 100755 index b87de05..0000000 --- a/MagicMock/mock.Entry().get().strip()/4491602512/init_prole-db.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_prole-db.sh -# Purpose: -# - Manage prole-db CloudNative-PG cluster operations (deploy, start, stop, etc.) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -ACTION=${1:-} -VERSION=${2:-latest} - -# Load env -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - source "$HOME/.prole/env.sh" -fi - -CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} -NAMESPACE=${NAMESPACE:-prole} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -ensure_tools() { - for t in kubectl jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -get_latest_image() { - local version_file="$SCRIPT_DIR/../conf/postgresql/.version" - if [[ -f "$version_file" ]]; then - echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" - else - echo "prole-db:17.7-033" - fi -} - -start() { - ensure_tools - echo "Checking dependencies..." - - # 1. k3d is running - if ! command -v k3d >/dev/null || ! k3d cluster list >/dev/null 2>&1; then - echo "ERROR: k3d is not running or not installed." >&2 - exit 1 - fi - - # 2. cnpg operator is loaded - if ! kubectl get deployment -n cnpg-system cnpg-controller-manager >/dev/null 2>&1; then - echo "ERROR: CloudNative-PG operator is not loaded." >&2 - exit 1 - fi - - # 3. openbao is configured - if ! kubectl get statefulset openbao -n "$NAMESPACE" >/dev/null 2>&1 && ! kubectl get deployment openbao -n "$NAMESPACE" >/dev/null 2>&1; then - echo "ERROR: OpenBao is not deployed." >&2 - exit 1 - fi - - # Compare latest image with deployed - local latest_image - latest_image=$(get_latest_image) - - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - - if [[ "$current_image" != "$latest_image" ]]; then - echo "Updating cluster image from '$current_image' to '$latest_image'..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$latest_image\"}}" - # Force a rollout to ensure the new image is pulled even if it was just a tag update (though we use unique tags) - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - else - echo "Cluster is already using the latest image: $latest_image" - fi - - echo "Starting prole-db cluster (ensuring manifest is applied)..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" -} - -stop() { - ensure_tools - echo "Stopping prole-db cluster $CNPG_CLUSTER_NAME..." - - # Identify instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - if [[ -z "$instances" ]]; then - echo "No instances found for cluster $CNPG_CLUSTER_NAME." - return - fi - - # Determine replicas and primary - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - - echo "Primary: $primary" - - # Shutdown replicas first - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Shutting down replica $pod..." - kubectl exec -n "$NAMESPACE" "$pod" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - done - - # Shutdown primary last - if [[ -n "$primary" ]]; then - echo "Shutting down primary $primary..." - kubectl exec -n "$NAMESPACE" "$primary" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - - echo "Deleting cluster resource..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found -} - -restart() { - ensure_tools - echo "Restarting prole-db cluster..." - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -deploy() { - ensure_tools - local image - if [[ "$VERSION" == "latest" ]]; then - image=$(get_latest_image) - else - image="prole-db:$VERSION" - fi - - echo "Deploying $image to cluster $CNPG_CLUSTER_NAME..." - - # If cluster doesn't exist, use init_cloudnative_pg.sh create first - if ! kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then - echo "Cluster not found. Running init_cloudnative_pg.sh create..." - bash "$SCRIPT_DIR/init_cloudnative_pg.sh" create - fi - - # Ensure image is updated if manifest has an older version - # First, apply the manifest to ensure the cluster exists/is updated - echo "Applying manifest $CNPG_MANIFEST..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - - # Then force the specific image version via patch if different - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - if [[ "$current_image" != "$image" ]]; then - echo "Patching cluster to use image '$image' (was '$current_image')..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$image\"}}" - # Force a rollout - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - fi -} - -rollback() { - ensure_tools - echo "Rollback: Updating to previous image (manually specified version or fallback)..." - if [[ "$VERSION" == "latest" ]]; then - echo "Please specify a version to rollback to. Usage: $0 rollback " - exit 1 - fi - deploy -} - -backup() { - echo "Backup - tbd, when we configure s3 or other block store" -} - -reset() { - ensure_tools - echo "Resetting prole-db cluster..." - echo "Removing cnpg instances and pods..." - kubectl delete cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --ignore-not-found - - # Wait for deletion - kubectl wait --for=delete cluster/"$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --timeout=60s || true - - echo "Reinstantiating..." - deploy -} - -case "$ACTION" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - deploy) - deploy - ;; - rollback) - rollback - ;; - backup) - backup - ;; - reset) - reset - ;; - *) - echo "Usage: $0 {start|stop|restart|deploy|rollback|backup|reset} [version]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/env.sh b/MagicMock/mock.Entry().get().strip()/4494452656/env.sh deleted file mode 100755 index e1469ac..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/env.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Prole environment configuration -# This file is generated by the installer. Source it in new shells, or execute as a wrapper: -# "$PROLE_HOME/env.sh" [args…] -# shellcheck shell=bash -export PROLE_HOME="" -export PROLE_CONF="" -export PROLE_DATA="" -export PROLE_LOGS="" -export PROLE_SERVICE="" - -# Ensure PATH works for GUI-launched shells (Docker, Ollama, etc.) -_prole_add_path() { case ":${PATH}:" in *":$1:"*) ;; *) PATH="$1:${PATH:-}" ;; esac; } -_prole_add_path "$PROLE_HOME/bin" -_prole_add_path "/opt/homebrew/bin" -_prole_add_path "/usr/local/bin" -_prole_add_path "/usr/bin" -_prole_add_path "/bin" -_prole_add_path "/usr/sbin" -_prole_add_path "/sbin" -export PATH - -# Add custom paths below if needed (examples): -# _prole_add_path "/Applications/Ollama.app/Contents/MacOS" - -# If executed with arguments, run them under this environment -if [ "$#" -gt 0 ]; then - exec "$@" -fi diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/hosts.txt b/MagicMock/mock.Entry().get().strip()/4494452656/hosts.txt deleted file mode 100644 index 4e73115..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/hosts.txt +++ /dev/null @@ -1,15 +0,0 @@ -myrddin.prole.org 10.0.0.3 -raspberry.prole.org 10.0.0.4 -pi.prole.org 10.0.0.5 -synology.prole.org 10.0.0.203 -morgoth.prole.org 10.0.0.204 -zinfandel.prole.org 10.0.0.205 -aventage.prole.org 10.0.0.206 -retropie.prole.org 10.0.0.207 -fairyland.prole.org 10.0.0.208 -k8s.prole.org zinfandel.prole.org -mc.prole.org 73.15.20.166 -morana.prole.org 10.0.0.66 -ollama.prole.org 73.15.20.166 -svc.prole.org 73.15.20.166 -www.prole.org ghs.googlehosted.com \ No newline at end of file diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/init_cloudnative_pg.sh b/MagicMock/mock.Entry().get().strip()/4494452656/init_cloudnative_pg.sh deleted file mode 100755 index 6708415..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/init_cloudnative_pg.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_cloudnative_pg.sh -# Purpose: -# - Distribute administrator ed25519 key pair to CloudNative‑PG as a Kubernetes Secret for cert auth -# - Configure Kerberos (GSSAPI) using external Kerberos KDC -# - Patch CNPG cluster to enable TLS and GSSAPI where possible -# -# Usage: -# ./init_cloudnative_pg.sh start|stop|status|restart -# ./init_cloudnative_pg.sh initialize # create/update k8s secrets/configs and patch CNPG -# ./init_cloudnative_pg.sh update|reload # re-apply/patch -# -# Requirements: -# - init_openbao.sh has been run (OpenBao running in k8s) -# - $PROLE_HOME/env.sh or $HOME/.prole/env.sh defining PROLE_SERVICE - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Load env without leaking our positional args to the env script (some env.sh may `exec "$@"`). -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -else - echo "ERROR: Missing env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env." >&2 - exit 1 -fi - -ACTION=${1:-} -CNPG_CLUSTER_NAME=${2:-${CNPG_CLUSTER_NAME:-prole-db}} -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -REALM=${REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-prole.org} -KRB5_KDC=${KRB5_KDC:-} -KRB5_ADMIN=${KRB5_ADMIN:-} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -SECRETS_DIR="$PROLE_SERVICE/secrets" -ADMIN_PRIV="$SECRETS_DIR/admin_ed25519.key" -ADMIN_PUB="$SECRETS_DIR/admin_ed25519.pub" -OPENBAO_TOKEN_FILE="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64 jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -# Resolve OpenBao URL: prefer explicit env, then localhost port-forward, then cluster DNS -bao_service_url() { - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - echo "$PROLE_OPENBAO_URL" - return 0 - fi - # Prefer standard local port-forward managed by etc/init_port_forwards.sh - if curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - echo "http://127.0.0.1:18200" - return 0 - fi - echo "http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" -} - -fetch_admin_keys_and_db_pass_from_bao_or_local() { - local token url - if [[ -f "$OPENBAO_TOKEN_FILE" ]]; then - token=$(cat "$OPENBAO_TOKEN_FILE") - else - token="" - fi - url=$(bao_service_url) - if [[ -n "$token" ]]; then - echo "Attempting to read admin key pair from OpenBao kv/prole/admin ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -e '.data.data' >/dev/null 2>&1; then - local priv_b64 pub_b64 - priv_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_private_key_b64') - pub_b64=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/admin" | jq -r '.data.data.admin_public_key_b64') - printf "%s" "$priv_b64" | base64 -d >"$ADMIN_PRIV" - printf "%s" "$pub_b64" | base64 -d >"$ADMIN_PUB" - chmod 0600 "$ADMIN_PRIV" - fi - - echo "Attempting to read database password from OpenBao kv/prole/db ..." - if curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -e '.data.data' >/dev/null 2>&1; then - local db_pass - db_pass=$(curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/prole/db" | jq -r '.data.data.password') - if [[ -n "$db_pass" ]]; then - echo "Updating database user secret 'prole-db-user' from OpenBao ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username=prole \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - - echo "Updating database superuser secret 'prole-db-superuser' from OpenBao ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -f - - fi - fi - fi - - if [[ -f "$ADMIN_PRIV" && -f "$ADMIN_PUB" ]]; then - echo "Using local admin key pair at $SECRETS_DIR" - return 0 - fi - echo "ERROR: Could not obtain admin key pair from OpenBao and no local files found." >&2 - exit 1 -} - -apply_cnpg_admin_secret() { - echo "Creating/updating Secret cnpg-admin-key ..." - kubectl create secret generic cnpg-admin-key -n "$NAMESPACE" \ - --from-file=admin.key="$ADMIN_PRIV" \ - --from-file=admin.pub="$ADMIN_PUB" \ - --dry-run=client -o yaml | kubectl apply -f - -} - -ensure_krb5_conf_configmap() { - echo "Creating/updating ConfigMap prole-krb5-conf ..." - - local kdc_val admin_val - if [[ -n "$KRB5_KDC" ]]; then - kdc_val="$KRB5_KDC" - admin_val=${KRB5_ADMIN:-$(echo "$KRB5_KDC" | cut -d, -f1)} - else - kdc_val="kdc.$DOMAIN" - admin_val="kdc.$DOMAIN" - fi - - local TMP - TMP=$(mktemp) - cat >"$TMP" </dev/null 2>&1; then - echo "CA secret $ca_secret_name already exists; skipping generation." - return 0 - fi - echo "Generating self-signed CA (RSA 4096) for CNPG ..." - local TMPD - TMPD=$(mktemp -d) - openssl genrsa -out "$TMPD/ca.key" 4096 - openssl req -x509 -new -key "$TMPD/ca.key" -out "$TMPD/ca.crt" -days 3650 -subj "/CN=Prole CNPG CA" - kubectl -n "$NAMESPACE" create secret generic "$ca_secret_name" \ - --from-file=ca.crt="$TMPD/ca.crt" \ - --from-file=ca.key="$TMPD/ca.key" \ - --dry-run=client -o yaml | kubectl apply -f - - rm -rf "$TMPD" -} - -patch_cnpg_cluster_for_auth() { - echo "Patching CNPG Cluster $CNPG_CLUSTER_NAME to enable GSSAPI and fix config (best-effort) ..." - # Best-effort patch; schema may vary with CNPG version. - # We remove krb_srvname as it is unrecognized in some PG 17 builds. - # We revert certificates to default to avoid operator TLS issues. - kubectl -n "$NAMESPACE" patch cluster "$CNPG_CLUSTER_NAME" --type merge -p "{ - \"spec\": { - \"postgresql\": { - \"parameters\": {\"krb_srvname\": null}, - \"pg_hba\": [ - \"local all postgres trust\", - \"host all postgres all scram-sha-256\", - \"host all all all gss include_realm=1 krb_realm=$REALM\", - \"host all all all scram-sha-256\" - ] - }, - \"certificates\": { - \"serverCASecret\": null, - \"clientCASecret\": null - } - } - }" >/dev/null || echo "Note: patch may need adjustment for your CNPG version." -} - -initialize() { - ensure_tools - - # Ensure port-forward is running for OpenBao (dependency) - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - fetch_admin_keys_and_db_pass_from_bao_or_local - apply_cnpg_admin_secret - ensure_krb5_conf_configmap - # generate_tls_if_missing - patch_cnpg_cluster_for_auth - - # Ensure port-forward is running for Postgres (local access) - echo "Ensuring port-forward for Postgres is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart postgres - - echo "Initialization complete for CNPG + Kerberos + cert artifacts." -} - -update_reload() { - initialize -} - -case "$ACTION" in - recreate) - ensure_tools - "$0" delete "$CNPG_CLUSTER_NAME" - "$0" create "$CNPG_CLUSTER_NAME" - ;; - create) - ensure_tools - echo "Installing CloudNative-PG operator ..." - kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml - - echo "Creating CloudNative-PG cluster and resources for '$CNPG_CLUSTER_NAME' ..." - - kubectl apply -k "$SCRIPT_DIR/../k8s/prole" - - # Ensure prole-index-html exists for prole deployment readiness probe - if ! kubectl get configmap prole-index-html -n prole >/dev/null 2>&1; then - echo "Creating prole-index-html configmap..." - printf "

Prole

" > /tmp/index.html - kubectl create configmap prole-index-html --from-file=/tmp/index.html -n prole - rm /tmp/index.html - fi - - # Ensure prole-nginx-tls exists (self-signed for dev) - if ! kubectl get secret prole-nginx-tls -n prole >/dev/null 2>&1; then - echo "Generating self-signed prole-nginx-tls for development..." - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /tmp/nginx-tls.key -out /tmp/nginx-tls.crt \ - -subj "/CN=prole.org" >/dev/null 2>&1 - kubectl create secret tls prole-nginx-tls --key /tmp/nginx-tls.key --cert /tmp/nginx-tls.crt -n prole - rm /tmp/nginx-tls.key /tmp/nginx-tls.crt - fi - - echo "Initializing and patching cluster ..." - initialize - ;; - delete) - ensure_tools - echo "Deleting all resources for '$CNPG_CLUSTER_NAME' ..." - kubectl delete -k "$SCRIPT_DIR/../k8s/prole" --ignore-not-found - ;; - start) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Starting CloudNative-PG cluster from $CNPG_MANIFEST in namespace $NAMESPACE..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - ;; - stop) - ensure_tools - if [[ ! -f "$CNPG_MANIFEST" ]]; then - echo "ERROR: CNPG manifest not found at $CNPG_MANIFEST" >&2 - exit 1 - fi - echo "Stopping CloudNative-PG cluster using $CNPG_MANIFEST ..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found - ;; - status) - ensure_tools - echo "--- CloudNative-PG Cluster Status ($CNPG_CLUSTER_NAME) ---" - if kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" get cluster "$CNPG_CLUSTER_NAME" - echo "" - echo "CNPG Plugin Status:" - if kubectl cnpg version >/dev/null 2>&1; then - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - else - echo "Note: 'kubectl cnpg' plugin not found; skipping detailed status." - fi - else - echo "Cluster '$CNPG_CLUSTER_NAME' not found in namespace '$NAMESPACE'." - fi - ;; - restart) - ensure_tools - "$0" stop - "$0" start - ;; - initialize) - initialize - ;; - update|reload) - update_reload - ;; - *) - echo "Usage: $0 {create|delete|recreate|start|stop|status|restart|initialize|update|reload} [dbname]" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/init_k8s.sh b/MagicMock/mock.Entry().get().strip()/4494452656/init_k8s.sh deleted file mode 100755 index 35f14aa..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/init_k8s.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# etc/init_k8s.sh -# Purpose: Manage k3d/k8s environment - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -# Default values -VERBOSE=false -ENVIRONMENT="prod" -HOST="" -CLUSTER_NAME_DEFAULT="prole-dev-cluster" -CLUSTER_PORT_DEFAULT="6443" - -usage() { - cat </dev/null || { echo "ERROR: Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - if ! docker info >/dev/null 2>&1; then - echo "ERROR: Docker is not running." >&2 - exit 1 - fi -} - -initialize() { - ensure_tools - ensure_docker - - if [[ "$ENVIRONMENT" == "dev" ]]; then - if [[ -z "$CLUSTER_NAME" ]]; then - if [[ -t 0 ]]; then - read -p "Enter k3d cluster name [$CLUSTER_NAME_DEFAULT]: " CLUSTER_NAME - CLUSTER_NAME=${CLUSTER_NAME:-$CLUSTER_NAME_DEFAULT} - else - CLUSTER_NAME=$CLUSTER_NAME_DEFAULT - fi - fi - - if k3d cluster list "$CLUSTER_NAME" >/dev/null 2>&1; then - log "Cluster '$CLUSTER_NAME' already exists." - else - log "Creating k3d cluster '$CLUSTER_NAME'..." - k3d cluster create "$CLUSTER_NAME" -p "0.0.0.0:$CLUSTER_PORT_DEFAULT:6443@server:0" - fi - else - if [[ -n "$HOST" ]]; then - log "Environment is $ENVIRONMENT. Host is $HOST." - log "TODO: Fetch kubeconfig from $HOST (placeholder)." - else - log "Environment is $ENVIRONMENT. Use -h|--host to specify the remote cluster host." - fi - fi -} - -status() { - ensure_tools - log "Checking Docker status..." - if docker info >/dev/null 2>&1; then - echo "Docker is running." - else - echo "Docker is NOT running." - fi - - log "Listing k3d clusters..." - k3d cluster list -} - -get_cluster_name() { - # If a name was provided or exists in env, use it. - # Otherwise, if there is only one cluster, use it. - # Finally, use default. - if [[ -n "${CLUSTER_NAME:-}" ]]; then - echo "$CLUSTER_NAME" - return - fi - - local clusters - clusters=$(k3d cluster list --no-headers | awk '{print $1}') - local count - count=$(echo "$clusters" | grep -c . || true) - - if [[ "$count" -eq 1 ]]; then - echo "$clusters" - else - echo "$CLUSTER_NAME_DEFAULT" - fi -} - -case "$ACTION" in - initialize) - initialize - ;; - status) - status - ;; - start) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Starting k3d cluster '$CLUSTER_NAME'..." - k3d cluster start "$CLUSTER_NAME" - ;; - stop) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Stopping k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - ;; - restart) - ensure_tools - CLUSTER_NAME=$(get_cluster_name) - log "Restarting k3d cluster '$CLUSTER_NAME'..." - k3d cluster stop "$CLUSTER_NAME" - k3d cluster start "$CLUSTER_NAME" - ;; - *) - usage - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/init_openbao.sh b/MagicMock/mock.Entry().get().strip()/4494452656/init_openbao.sh deleted file mode 100755 index 3e59151..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/init_openbao.sh +++ /dev/null @@ -1,490 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_openbao.sh -# Purpose: -# - Deploy OpenBao to Kubernetes (dev mode) and store admin ed25519 key pair -# Generate and apply a Kerberos krb5.conf ConfigMap for an external realm -# - Local Docker helpers for OpenBao (optional) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Preserve positional args while sourcing env -__PROLE_SAVED_ARGS=("$@") -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - # shellcheck disable=SC1090 - source "$HOME/.prole/env.sh" -fi -set -- "${__PROLE_SAVED_ARGS[@]}" -unset __PROLE_SAVED_ARGS - -if [[ -z "${PROLE_SERVICE:-}" ]]; then - echo "ERROR: PROLE_SERVICE is not defined in env. Provide PROLE_HOME/env.sh or ~/.prole/env.sh" >&2 - exit 1 -fi - -ACTION=${1:-} - -# Defaults -NAMESPACE=${NAMESPACE:-prole} -OPENBAO_NAME=${OPENBAO_NAME:-openbao} -OPENBAO_MANIFEST_DIR="$SCRIPT_DIR/../k8s/openbao" - -# Kerberos realm defaults -KRB5_REALM=${KRB5_REALM:-PROLE.ORG} -DOMAIN=${DOMAIN:-$(echo "$KRB5_REALM" | tr 'A-Z' 'a-z')} -KRB5_KDC=${KRB5_KDC:-kdc.$DOMAIN} -KRB5_ADMIN=${KRB5_ADMIN:-} - -# Secrets and token locations -SECRETS_DIR="$PROLE_SERVICE/secrets" -mkdir -p "$SECRETS_DIR" -admin_key_priv="$SECRETS_DIR/admin_ed25519.key" -admin_key_pub="$SECRETS_DIR/admin_ed25519.pub" -root_token_file="$SECRETS_DIR/openbao-root-token" - -ensure_tools() { - for t in kubectl curl openssl base64; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -ensure_docker() { - command -v docker >/dev/null || { echo "Missing required tool: docker" >&2; exit 1; } -} - -ensure_admin_keypair() { - # Ensure admin ed25519 keypair exists and a root token is available - mkdir -p "$SECRETS_DIR" - if [[ ! -f "$admin_key_priv" || ! -f "$admin_key_pub" ]]; then - echo "Generating admin ed25519 keypair in $SECRETS_DIR ..." - openssl genpkey -algorithm ED25519 -out "$admin_key_priv" - openssl pkey -in "$admin_key_priv" -pubout -out "$admin_key_pub" - chmod 0600 "$admin_key_priv" - fi - # Ensure a root token exists for OpenBao dev server interactions - if [[ ! -f "$root_token_file" || ! -s "$root_token_file" ]]; then - openssl rand -hex 24 >"$root_token_file" - chmod 0600 "$root_token_file" - fi -} - -generate_openbao_manifests() { - mkdir -p "$OPENBAO_MANIFEST_DIR" - # Only create a simple deployment if none exists; otherwise respect current file - local deploy="$OPENBAO_MANIFEST_DIR/deployment.yaml" - if [[ ! -f "$deploy" ]]; then - cat >"$deploy" <"$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" </dev/null 2>&1; then - kubectl rollout status statefulset/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - else - kubectl rollout status deploy/$OPENBAO_NAME -n "$NAMESPACE" --timeout=120s - fi -} - -init_openbao_kv_and_store_admin_key() { - local token - token=$(cat "$root_token_file") - # Enable kv (if not already) and write keys - local svc="http://127.0.0.1:18200" - echo "Configuring KV at $svc ..." - - # Check if kv/ is already mounted - if curl -sS -H "X-Vault-Token: $token" "$svc/v1/sys/mounts" | grep -q '"kv/":'; then - echo "KV path 'kv/' is already enabled." - else - curl -sS -H "X-Vault-Token: $token" -X POST "$svc/v1/sys/mounts/kv" \ - -d '{"type":"kv","options":{"version":"2"}}' >/dev/null 2>&1 || true - fi - - local priv pub - priv=$(base64 <"$admin_key_priv" | tr -d '\n') - pub=$(base64 <"$admin_key_pub" | tr -d '\n') - - # Check if admin key already exists and matches - local existing_data - existing_data=$(curl -sS -H "X-Vault-Token: $token" "$svc/v1/kv/data/prole/admin" 2>/dev/null || true) - if [[ -n "$existing_data" ]]; then - local ex_priv ex_pub - ex_priv=$(echo "$existing_data" | grep -o '"admin_private_key_b64":"[^"]*' | cut -d'"' -f4 || true) - ex_pub=$(echo "$existing_data" | grep -o '"admin_public_key_b64":"[^"]*' | cut -d'"' -f4 || true) - - if [[ "$ex_priv" == "$priv" && "$ex_pub" == "$pub" ]]; then - echo "Admin key pair in OpenBao kv/prole/admin is already up to date." - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - else - echo "Writing admin key pair to kv/prole/admin ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/admin" \ - -d "{\"data\":{\"admin_private_key_b64\":\"$priv\",\"admin_public_key_b64\":\"$pub\"}}" >/dev/null - echo "Stored admin key pair in OpenBao kv/prole/admin." - fi - - # Store User SSH keys if they exist - local user_key_priv="$HOME/.ssh/id_prole_ed25519" - local user_key_pub="$HOME/.ssh/id_prole_ed25519.pub" - if [[ -f "$user_key_priv" && -f "$user_key_pub" ]]; then - local u_priv u_pub - u_priv=$(base64 <"$user_key_priv" | tr -d '\n') - u_pub=$(base64 <"$user_key_pub" | tr -d '\n') - local username=${PROLE_DB_USER:-"prole"} - - echo "Writing user SSH keys for '$username' to kv/prole/user ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/user" \ - -d "{\"data\":{\"username\":\"$username\",\"private_key_b64\":\"$u_priv\",\"public_key_b64\":\"$u_pub\"}}" >/dev/null - echo "Stored user SSH keys in OpenBao kv/prole/user." - fi - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Writing database user password for '$username' to kv/prole/db ..." - curl -sS -H "X-Vault-Token: $token" -H 'Content-Type: application/json' \ - -X POST "$svc/v1/kv/data/prole/db" \ - -d "{\"data\":{\"username\":\"$username\",\"password\":\"$db_pass\"}}" >/dev/null - echo "Stored database password in OpenBao kv/prole/db." - fi -} - -# Removed: prompt_admin_password_and_apply_secret (no AD admin secret required) - -docker_start() { - echo "Starting local Docker container for OpenBao ..." - ensure_docker - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - # OpenBao dev - local token - token=$(cat "$root_token_file" 2>/dev/null || true) - if [[ -z "$token" ]]; then - token=$(openssl rand -hex 24) - printf "%s" "$token" >"$root_token_file" - chmod 0600 "$root_token_file" - fi - docker run -d --name "$OPENBAO_NAME" -p 18200:8200 \ - "$OPENBAO_IMAGE" server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id="$token" - echo "Docker container started: $OPENBAO_NAME" -} - -docker_stop() { - docker rm -f "$OPENBAO_NAME" >/dev/null 2>&1 || true - echo "Stopped OpenBao container if it was running." -} - -docker_restart() { - docker_stop - docker_start -} - -# status command implementation wrapped in a function to avoid top-level 'local' -cmd_status() { - echo "--- init_primary_domain status ---" - echo "Namespace: $NAMESPACE" - echo "OpenBao name: $OPENBAO_NAME" - echo "Manifest dir: $OPENBAO_MANIFEST_DIR" - - # Files/manifests present - local ok=0 - if [[ -f "$OPENBAO_MANIFEST_DIR/deployment.yaml" ]]; then - echo "[OK] OpenBao deployment manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/deployment.yaml" - ok=1 - fi - if [[ -f "$OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" ]]; then - echo "[OK] Kerberos ConfigMap manifest exists" - else - echo "[MISSING] $OPENBAO_MANIFEST_DIR/kerberos-configmap.yaml" - ok=1 - fi - - # K8s resources - if kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" >/dev/null 2>&1; then - local ready desired - ready=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get statefulset "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao StatefulSet running ($ready/$desired ready)" - else - echo "[WARN] OpenBao StatefulSet not fully ready ($ready/$desired)" - ok=1 - fi - elif kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" >/dev/null 2>&1; then - # Get readiness - local ready desired - ready=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0") - desired=$(kubectl -n "$NAMESPACE" get deploy "$OPENBAO_NAME" -o jsonpath='{.status.replicas}' 2>/dev/null || echo "0") - ready=${ready:-0} - desired=${desired:-0} - if [[ "$ready" == "$desired" && "$ready" != "0" ]]; then - echo "[OK] OpenBao Deployment running ($ready/$desired ready)" - else - echo "[WARN] OpenBao Deployment not fully ready ($ready/$desired)" - ok=1 - fi - else - echo "[MISSING] OpenBao Deployment or StatefulSet '$OPENBAO_NAME' in namespace '$NAMESPACE'" - ok=1 - fi - - if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then - echo "[OK] Kerberos ConfigMap 'prole-krb5-conf' present" - else - echo "[MISSING] Kerberos ConfigMap 'prole-krb5-conf' in namespace '$NAMESPACE'" - ok=1 - fi - - # Docker (optional local mode) - if command -v docker >/dev/null 2>&1; then - if docker ps --format '{{.Names}}' | grep -Fxq "$OPENBAO_NAME"; then - echo "[OK] Docker container '$OPENBAO_NAME' is running" - else - # Not necessarily an error; we primarily use k8s - echo "[INFO] Docker container '$OPENBAO_NAME' not running (k8s mode may be in use)" - fi - fi - - # Secrets and tokens - if [[ -f "$admin_key_priv" && -f "$admin_key_pub" ]]; then - echo "[OK] Admin ed25519 keypair present in $SECRETS_DIR" - else - echo "[MISSING] Admin keypair files in $SECRETS_DIR" - ok=1 - fi - if [[ -s "$root_token_file" ]]; then - echo "[OK] OpenBao root token file present" - else - echo "[MISSING] OpenBao root token file ($root_token_file)" - ok=1 - fi - - # OpenBao reachability and token validity (best-effort) - # Prefer explicit override, then localhost port-forward, then cluster DNS - local svc_url - if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then - svc_url="$PROLE_OPENBAO_URL" - elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then - svc_url="http://127.0.0.1:18200" - else - svc_url="http://$OPENBAO_NAME.$NAMESPACE.svc.cluster.local:8200" - fi - if curl -sS "$svc_url/v1/sys/health" >/dev/null 2>&1; then - echo "[OK] OpenBao service reachable" - if [[ -s "$root_token_file" ]]; then - local code - code=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Vault-Token: $(cat "$root_token_file")" "$svc_url/v1/sys/mounts" || echo "000") - if [[ "$code" == "200" ]]; then - echo "[OK] OpenBao root token authenticates" - else - echo "[WARN] OpenBao root token did not authenticate (HTTP $code)" - ok=1 - fi - fi - else - echo "[WARN] OpenBao service not reachable at $svc_url" - ok=1 - fi - - # Service certificate existence (CNPG TLS) - local CNPG_CLUSTER_NAME - CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} - if kubectl -n "$NAMESPACE" get secret "${CNPG_CLUSTER_NAME}-tls" >/dev/null 2>&1; then - echo "[OK] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' exists" - else - echo "[INFO] Service certificate secret '${CNPG_CLUSTER_NAME}-tls' not found" - fi - - echo "-------------------------------------" - if [[ $ok -eq 0 ]]; then - echo "Status: OK" - return 0 - else - echo "Status: Issues detected" - return 1 - fi -} - -case "$ACTION" in - start) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_start - ;; - status) - ensure_tools - cmd_status - ;; - stop) - ensure_docker - docker_stop - ;; - restart) - ensure_tools - ensure_docker - ensure_admin_keypair - docker_restart - ;; - initialize) - ensure_tools - # Read password from stdin if provided - db_pass="" - if [[ ! -t 0 ]]; then - read -r db_pass - fi - - ensure_admin_keypair - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - - if [[ -n "$db_pass" ]]; then - local username=${PROLE_DB_USER:-"prole"} - echo "Creating database user secret 'prole-db-user' for '$username' ..." - kubectl create secret generic prole-db-user -n "$NAMESPACE" \ - --from-literal=username="$username" \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - - echo "Creating database superuser secret 'prole-db-superuser' ..." - kubectl create secret generic prole-db-superuser -n "$NAMESPACE" \ - --from-literal=username=postgres \ - --from-literal=password="$db_pass" \ - --dry-run=client -o yaml | kubectl apply -n "$NAMESPACE" -f - - fi - - wait_for_openbao - - # Ensure port-forward is running for OpenBao - echo "Ensuring port-forward for OpenBao is active ..." - "$SCRIPT_DIR/init_port_forwards.sh" restart openbao - - if ! curl -sS http://127.0.0.1:18200/v1/sys/health >/dev/null 2>&1; then - echo "ERROR: OpenBao not reachable at http://127.0.0.1:18200." >&2 - echo "Please start port-forwards: $SCRIPT_DIR/init_port_forwards.sh start openbao" >&2 - exit 1 - fi - init_openbao_kv_and_store_admin_key - echo "Initialization complete. Manifests in: $OPENBAO_MANIFEST_DIR" - ;; - update|reload) - generate_openbao_manifests - generate_kerberos_configmap - apply_k8s - echo "Re-applied manifests." - ;; - *) - echo "Usage: $0 {start|stop|status|restart|initialize|update|reload}" >&2 - exit 2 - ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/init_port_forwards.sh b/MagicMock/mock.Entry().get().strip()/4494452656/init_port_forwards.sh deleted file mode 100755 index 9ebea5c..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/init_port_forwards.sh +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env bash -set -u - -# init_port_forwards.sh -# Portable-ish (macOS, Ubuntu, Raspberry Pi OS, Alpine) bash init-style script -# Manages kubectl port-forward daemons defined in an XML file. - -PROG="init_port_forwards" -PROLE_HOME="${PROLE_HOME:-/Users/chrisfu/dev/prole}" -VERBOSE=0 -CONFIG_FILE="$PROLE_HOME/conf/port-mappings.properties" - -usage() { - cat < [component] - -Options: - -c, --config-file=FILE Path to local-ports.properties (XML) - -v, --verbose Verbose output - -Examples: - $PROG -c ./port-mappings.properties start - $PROG stop openbao - $PROG --verbose status -EOF -} - -TARGET_ID="" - -log() { printf '%s\n' "$*"; } -vlog() { [ "$VERBOSE" -eq 1 ] && printf '[verbose] %s\n' "$*" || true; } -err() { printf '[error] %s\n' "$*" >&2; } - -have() { command -v "$1" >/dev/null 2>&1; } - -# Choose a writable state dir for pid/log files: -# - Prefer XDG_RUNTIME_DIR if set and writable -# - Else /var/run if writable (rare without root) -# - Else ~/.local/state -# - Else /tmp -state_dir() { - if [ -n "${XDG_RUNTIME_DIR:-}" ] && [ -w "${XDG_RUNTIME_DIR:-}" ]; then - printf '%s/%s' "$XDG_RUNTIME_DIR" "$PROG" - return - fi - if [ -d "/var/run" ] && [ -w "/var/run" ]; then - printf '/var/run/%s' "$PROG" - return - fi - if [ -n "${HOME:-}" ]; then - mkdir -p "$HOME/.local/state" >/dev/null 2>&1 || true - if [ -d "$HOME/.local/state" ] && [ -w "$HOME/.local/state" ]; then - printf '%s/.local/state/%s' "$HOME" "$PROG" - return - fi - fi - printf '/tmp/%s' "$PROG" -} - -STATE_DIR="$(state_dir)" -PID_DIR="$STATE_DIR/pids" -LOG_DIR="$STATE_DIR/logs" - -ensure_dirs() { - mkdir -p "$PID_DIR" "$LOG_DIR" 2>/dev/null || true - if [ ! -d "$PID_DIR" ] || [ ! -d "$LOG_DIR" ]; then - err "Unable to create state directories under: $STATE_DIR" - exit 1 - fi -} - -# Use kubectl for actions; kubecolor is used only for prettier status output. -KUBECTL="kubectl" -detect_kubectl() { - if have kubectl; then - KUBECTL="kubectl" - else - err "kubectl not found in PATH" - exit 1 - fi -} - -# Basic environment validation -validate_env() { - detect_kubectl - ensure_dirs - - if ! "$KUBECTL" version --client >/dev/null 2>&1; then - err "kubectl seems broken or not executable" - exit 1 - fi - - # Can we reach the cluster? - if ! "$KUBECTL" cluster-info >/dev/null 2>&1; then - err "kubectl cannot reach a cluster (check KUBECONFIG/context)" - err "Try: kubectl config get-contexts && kubectl config use-context " - exit 1 - fi -} - -# ---- Preflight: Docker + k3d awareness ---- -# Return 0 when Docker CLI can talk to a running daemon. -docker_is_running() { - if ! have docker; then - return 1 - fi - docker info >/dev/null 2>&1 -} - -# Hard-fail with clean guidance when Docker is not up (used for start/restart). -ensure_docker_running() { - if docker_is_running; then - return 0 - fi - if ! have docker; then - err "Docker CLI not found. Please install Docker Desktop or docker CLI." - else - err "Docker is not running. Start Docker Desktop and wait until it is ready." - fi - err "Tip (macOS): open -a Docker" - err "Then re-run: $PROG start" - exit 3 -} - -# Detect k3d cluster name from env or current kubectl context. -# - If K3D_CLUSTER is set, use it. -# - Else, if current-context starts with 'k3d-', strip prefix to get name. -detect_k3d_context() { - if [ -n "${K3D_CLUSTER:-}" ]; then - printf '%s' "$K3D_CLUSTER" - return 0 - fi - local ctx - ctx="$($KUBECTL config current-context 2>/dev/null || echo)" - case "$ctx" in - k3d-*) printf '%s' "${ctx#k3d-}"; return 0 ;; - *) return 1 ;; - esac -} - -# Return 0 if the given k3d cluster exists and is running. -k3d_cluster_is_running() { - local name="$1" - have k3d || return 1 - # Use json output when available; fall back to grep otherwise - if k3d cluster list -o json >/dev/null 2>&1; then - k3d cluster list -o json 2>/dev/null | grep -q '"name"\s*:\s*"'"$name"'"' && \ - k3d cluster list -o json 2>/dev/null | sed -n 's/.*"name"\s*:\s*"\([^"]\+\)".*"serversRunning"\s*:\s*\([0-9]\+\).*/\1 \2/p' | awk -v n="$name" '$1==n {exit ($2>0)?0:1}' - return $? - else - k3d cluster list 2>/dev/null | grep -E "^$name\s" | grep -q running - return $? - fi -} - -# If current context indicates k3d, ensure the cluster is up; otherwise no-op. -ensure_k3d_ready_if_applicable() { - local k3d_name - if ! k3d_name="$(detect_k3d_context)"; then - return 0 - fi - if ! have k3d; then - err "k3d is not installed but kubectl context suggests k3d (context=$("$KUBECTL" config current-context))." - err "Install k3d: brew install k3d (macOS)" - err "Or switch context: kubectl config use-context " - exit 4 - fi - if ! k3d_cluster_is_running "$k3d_name"; then - err "k3d cluster '$k3d_name' is not running." - err "Start it: k3d cluster start $k3d_name" - err "Then re-run: $PROG start" - exit 4 - fi -} - -pid_file_for() { printf '%s/%s.pid' "$PID_DIR" "$1"; } -log_file_for() { printf '%s/%s.log' "$LOG_DIR" "$1"; } - -is_pid_running() { - # Return 0 if pid exists and running, else 1 - # kill -0 is portable. - local pid="$1" - [ -n "$pid" ] && kill -0 "$pid" >/dev/null 2>&1 -} - -read_pid() { - local pf="$1" - [ -f "$pf" ] || return 1 - # shellcheck disable=SC2162 - read pid <"$pf" || return 1 - printf '%s' "$pid" -} - -write_pid() { - local pf="$1" pid="$2" - printf '%s\n' "$pid" >"$pf" -} - -remove_pidfile() { - local pf="$1" - rm -f "$pf" >/dev/null 2>&1 || true -} - -# ---- XML parsing (simple attribute extraction) ---- -# We parse lines containing: -# Attributes must use double quotes in the XML (as in the sample). -get_attr() { - # $1 = line, $2 = attribute name - # outputs value or empty - printf '%s\n' "$1" | sed -n "s/.*$2=\"\([^\"]*\)\".*/\1/p" -} - -foreach_mapping() { - # Calls a provided function with mapping fields: - # callback id ns target address hostPort servicePort protocol description - local callback="$1" - [ -f "$CONFIG_FILE" ] || { err "Config file not found: $CONFIG_FILE"; exit 1; } - - # Support both single-line and multi-line self-closing mapping tags, e.g.: - # OR lines spanning multiple lines until "/>". - local in_mapping=0 in_comment=0 buffer="" line - while IFS= read -r line; do - # Handle XML comments: skip anything between - if [ $in_comment -eq 1 ]; then - case "$line" in - *"-->"*) in_comment=0; continue ;; - *) continue ;; - esac - fi - case "$line" in - *""*) - # single-line comment; skip line - continue - ;; - *) - in_comment=1 - continue - ;; - esac - ;; - esac - if [ $in_mapping -eq 0 ]; then - case "$line" in - *"' - buffer="$buffer $line" - fi - - if [ $in_mapping -eq 1 ] && printf '%s' "$line" | grep -q "/>"; then - # Normalize whitespace to make attribute extraction robust - local merged - merged=$(printf '%s\n' "$buffer" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g') - - local id ns target address hostPort servicePort protocol description - id="$(get_attr "$merged" "id")" - ns="$(get_attr "$merged" "namespace")" - target="$(get_attr "$merged" "target")" - address="$(get_attr "$merged" "address")" - hostPort="$(get_attr "$merged" "hostPort")" - servicePort="$(get_attr "$merged" "servicePort")" - protocol="$(get_attr "$merged" "protocol")" - description="$(get_attr "$merged" "description")" - - # Basic validation - if [ -z "$id" ] || [ -z "$ns" ] || [ -z "$target" ] || [ -z "$hostPort" ] || [ -z "$servicePort" ]; then - err "Invalid mapping (missing required attributes): $merged" - exit 1 - fi - - # Filter by TARGET_ID if set - if [ -n "$TARGET_ID" ] && [ "$id" != "$TARGET_ID" ]; then - in_mapping=0 - buffer="" - continue - fi - - if [ -z "$address" ]; then address="127.0.0.1"; fi - if [ -z "$protocol" ]; then protocol="TCP"; fi - - vlog "mapping: id=$id ns=$ns target=$target address=$address hostPort=$hostPort servicePort=$servicePort protocol=$protocol" - "$callback" "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - # Reset accumulator - in_mapping=0 - buffer="" - fi - done <"$CONFIG_FILE" -} - -build_port_forward_cmd() { - # echo a command string - local ns="$1" target="$2" address="$3" hostPort="$4" servicePort="$5" - # kubectl port-forward -n --address : - printf '%s port-forward -n %s --address %s %s %s:%s' \ - "$KUBECTL" "$ns" "$address" "$target" "$hostPort" "$servicePort" -} - -start_port_forward() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile logfile cmd pid - - # Aggressively stop existing processes before starting to avoid port conflicts - stop_port_forward "$id" "$ns" "$target" "$address" "$hostPort" "$servicePort" "$protocol" "$description" - - pidfile="$(pid_file_for "$id")" - logfile="$(log_file_for "$id")" - cmd="$(build_port_forward_cmd "$ns" "$target" "$address" "$hostPort" "$servicePort")" - - log "Starting: $id $address:$hostPort -> $target:$servicePort ($ns) ${description:-}" - vlog "Command: $cmd" - - # Start in background, keep output in log. - # nohup is available on macOS/Linux; redirect stdin from /dev/null to detach. - nohup sh -c "$cmd" >>"$logfile" 2>&1 /dev/null 2>&1 || true - - # wait a moment, then SIGKILL if needed - local i - for i in 1 2 3 4 5; do - if ! is_pid_running "$pid"; then break; fi - sleep 0.2 - done - if is_pid_running "$pid"; then - err "$id did not stop gracefully; sending SIGKILL" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - else - if [ -f "$pidfile" ]; then - vlog "$id stale pidfile (pid=$pid not running)" - fi - fi - remove_pidfile "$pidfile" - - # Aggressively remove any other matching kubectl port-forward processes - # Search for processes that match: kubectl port-forward -n ... : - local extra_pids - extra_pids=$(ps -ef | grep "port-forward" | grep "\-n" | grep "$ns" | grep "$target" | grep "$hostPort:$servicePort" | grep -v grep | awk '{print $2}') - - for epid in $extra_pids; do - if [ "$epid" != "$pid" ]; then - log "Cleaning up orphan process for $id (pid=$epid)" - kill -9 "$epid" >/dev/null 2>&1 || true - fi - done -} - -status_one() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - local pidfile pid - - pidfile="$(pid_file_for "$id")" - pid="" - if [ -f "$pidfile" ]; then - pid="$(read_pid "$pidfile" || true)" - fi - - if [ -n "${pid:-}" ] && is_pid_running "$pid"; then - printf 'RUNNING %-12s pid=%-7s %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$pid" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - # ps details (portable flags vary; use a conservative format) - ps -p "$pid" -o pid=,ppid=,etime=,command= 2>/dev/null | sed 's/^/ /' || true - else - printf 'STOPPED %-12s (no live pid) %s:%s -> %s:%s ns=%s %s\n' \ - "$id" "$address" "$hostPort" "$target" "$servicePort" "$ns" "${description:-}" - fi -} - -do_start() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping start_port_forward -} - -do_stop() { - # stop doesn't require cluster access, but it does need state dirs - ensure_dirs - foreach_mapping stop_port_forward -} - -do_restart() { - validate_env - # Preflight: require Docker daemon and k3d (if applicable) - ensure_docker_running - ensure_k3d_ready_if_applicable - foreach_mapping stop_port_forward - foreach_mapping start_port_forward -} - -do_status() { - validate_env - # Non-fatal awareness messages - if docker_is_running; then - log "[OK] Docker daemon is running" - else - if have docker; then - log "[WARN] Docker is not running" - else - log "[WARN] Docker CLI not found" - fi - fi - - local _k3d_name - if _k3d_name="$(detect_k3d_context)"; then - if have k3d; then - if k3d_cluster_is_running "$_k3d_name"; then - log "[OK] k3d cluster '$_k3d_name' is running" - else - log "[WARN] k3d cluster '$_k3d_name' is not running" - fi - else - log "[WARN] k3d not installed but context suggests k3d (cluster='$_k3d_name')" - fi - fi - - log "== Context / Cluster ==" - "$KUBECTL" config current-context 2>/dev/null | sed 's/^/ context: /' || true - "$KUBECTL" cluster-info 2>/dev/null | sed 's/^/ /' || true - log "" - - log "== Port-forward processes ==" - foreach_mapping status_one - log "" - - log "== Quick k3d awareness checks (best-effort) ==" - # If user is on k3d, current-context often includes k3d-... but not guaranteed. - # Show nodes + a few namespaces/services related to mappings (best effort). - "$KUBECTL" get nodes -o wide 2>/dev/null | sed 's/^/ /' || true - log "" - "$KUBECTL" get ns 2>/dev/null | sed 's/^/ /' || true - log "" - - # For each mapping, try to show target existence - log "== Target existence (best-effort) ==" - _target_check() { - local id="$1" ns="$2" target="$3" address="$4" hostPort="$5" servicePort="$6" protocol="$7" description="$8" - # kubectl get -n - # If target is like "svc/name", "deploy/name", etc. - if "$KUBECTL" get -n "$ns" "$target" >/dev/null 2>&1; then - printf 'OK %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - else - printf 'MISSING %-12s %s (ns=%s)\n' "$id" "$target" "$ns" - fi - } - foreach_mapping _target_check -} - -# ---- arg parsing ---- -ACTION="" - -while [ $# -gt 0 ]; do - case "$1" in - start|stop|restart|status) - if [ -z "$ACTION" ]; then - ACTION="$1" - else - TARGET_ID="$1" - fi - shift - ;; - -v|--verbose) - VERBOSE=1 - shift - ;; - -c) - shift - [ $# -gt 0 ] || { err "-c requires a file path"; usage; exit 2; } - CONFIG_FILE="$1" - shift - ;; - --config-file=*) - CONFIG_FILE="${1#*=}" - shift - ;; - -h|--help) - usage - exit 0 - ;; - *) - if [ -z "$ACTION" ]; then - err "Unknown arg: $1" - usage - exit 2 - fi - TARGET_ID="$1" - shift - ;; - esac -done - -[ -n "$ACTION" ] || { usage; exit 2; } - -case "$ACTION" in - start) do_start ;; - stop) do_stop ;; - restart) do_restart ;; - status) do_status ;; -esac diff --git a/MagicMock/mock.Entry().get().strip()/4494452656/init_prole-db.sh b/MagicMock/mock.Entry().get().strip()/4494452656/init_prole-db.sh deleted file mode 100755 index 73251d4..0000000 --- a/MagicMock/mock.Entry().get().strip()/4494452656/init_prole-db.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# init_prole-db.sh -# Purpose: -# - Manage prole-db CloudNative-PG cluster operations (deploy, start, stop, etc.) - -# Initialize SCRIPT_DIR -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -ACTION=${1:-} -VERSION=${2:-latest} - -# Load env -if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then - set -- - source "$PROLE_HOME/env.sh" -elif [[ -f "$HOME/.prole/env.sh" ]]; then - set -- - source "$HOME/.prole/env.sh" -fi - -CNPG_CLUSTER_NAME=${CNPG_CLUSTER_NAME:-prole-db} -NAMESPACE=${NAMESPACE:-prole} - -CNPG_MANIFEST="$SCRIPT_DIR/../k8s/prole/prole-db.yaml" - -ensure_tools() { - for t in kubectl jq; do - command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } - done -} - -get_latest_image() { - local version_file="$SCRIPT_DIR/../conf/postgresql/.version" - if [[ -f "$version_file" ]]; then - echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" - else - echo "prole-db:17.7-033" - fi -} - -start() { - ensure_tools - echo "Checking dependencies..." - - # 1. k3d is running - if ! command -v k3d >/dev/null || ! k3d cluster list >/dev/null 2>&1; then - echo "ERROR: k3d is not running or not installed." >&2 - exit 1 - fi - - # 2. cnpg operator is loaded - if ! kubectl get deployment -n cnpg-system cnpg-controller-manager >/dev/null 2>&1; then - echo "ERROR: CloudNative-PG operator is not loaded." >&2 - exit 1 - fi - - # 3. openbao is configured - if ! kubectl get statefulset openbao -n "$NAMESPACE" >/dev/null 2>&1 && ! kubectl get deployment openbao -n "$NAMESPACE" >/dev/null 2>&1; then - echo "ERROR: OpenBao is not deployed." >&2 - exit 1 - fi - - # Compare latest image with deployed - local latest_image - latest_image=$(get_latest_image) - - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - - if [[ "$current_image" != "$latest_image" ]]; then - echo "Updating cluster image from '$current_image' to '$latest_image'..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$latest_image\"}}" - # Force a rollout to ensure the new image is pulled even if it was just a tag update (though we use unique tags) - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - else - echo "Cluster is already using the latest image: $latest_image" - fi - - echo "Starting prole-db cluster (ensuring manifest is applied)..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" -} - -stop() { - ensure_tools - echo "Stopping prole-db cluster $CNPG_CLUSTER_NAME..." - - # Identify instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - if [[ -z "$instances" ]]; then - echo "No instances found for cluster $CNPG_CLUSTER_NAME." - return - fi - - # Determine replicas and primary - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - - echo "Primary: $primary" - - # Shutdown replicas first - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Shutting down replica $pod..." - kubectl exec -n "$NAMESPACE" "$pod" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - done - - # Shutdown primary last - if [[ -n "$primary" ]]; then - echo "Shutting down primary $primary..." - kubectl exec -n "$NAMESPACE" "$primary" -c postgres -- psql -U postgres -c "CHECKPOINT;" || true - fi - - echo "Deleting cluster resource..." - kubectl delete -f "$CNPG_MANIFEST" --ignore-not-found -} - -restart() { - ensure_tools - echo "Restarting prole-db cluster..." - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -deploy() { - ensure_tools - local image - if [[ "$VERSION" == "latest" ]]; then - image=$(get_latest_image) - else - image="prole-db:$VERSION" - fi - - echo "Deploying $image to cluster $CNPG_CLUSTER_NAME..." - - # If cluster doesn't exist, use init_cloudnative_pg.sh create first - if ! kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then - echo "Cluster not found. Running init_cloudnative_pg.sh create..." - bash "$SCRIPT_DIR/init_cloudnative_pg.sh" create - fi - - # Ensure image is updated if manifest has an older version - # First, apply the manifest to ensure the cluster exists/is updated - echo "Applying manifest $CNPG_MANIFEST..." - kubectl apply -n "$NAMESPACE" -f "$CNPG_MANIFEST" - - # Then force the specific image version via patch if different - local current_image - current_image=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.imageName}' 2>/dev/null || echo "") - if [[ "$current_image" != "$image" ]]; then - echo "Patching cluster to use image '$image' (was '$current_image')..." - kubectl patch cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --type merge -p "{\"spec\": {\"imageName\": \"$image\"}}" - # Force a rollout - kubectl cnpg restart "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" || true - fi -} - -rollback() { - ensure_tools - echo "Rollback: Updating to previous image (manually specified version or fallback)..." - if [[ "$VERSION" == "latest" ]]; then - echo "Please specify a version to rollback to. Usage: $0 rollback " - exit 1 - fi - deploy -} - -rollout() { - ensure_tools - echo "Starting manual recreate rollout for $CNPG_CLUSTER_NAME in $NAMESPACE..." - - # 1. Monitor status - echo "Current status:" - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - - # 2. Identify the primary instance - local primary - primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - if [[ -z "$primary" ]]; then - echo "ERROR: Could not identify primary instance." >&2 - exit 1 - fi - echo "Primary instance: $primary" - - # 3. Identify all pod instances - local instances - instances=$(kubectl get pods -n "$NAMESPACE" -l "cnpg.io/cluster=$CNPG_CLUSTER_NAME" -o jsonpath='{.items[*].metadata.name}') - - # 4. Recreate non-primary instances one at a time - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - echo "Recreating non-primary pod: $pod..." - kubectl delete pod -n "$NAMESPACE" "$pod" - - echo "Waiting for $pod to be recreated and healthy..." - while true; do - if kubectl get pod -n "$NAMESPACE" "$pod" >/dev/null 2>&1; then - local status - status=$(kubectl get pod -n "$NAMESPACE" "$pod" -o jsonpath='{.status.phase}') - local ready - ready=$(kubectl get pod -n "$NAMESPACE" "$pod" -o jsonpath='{.status.containerStatuses[0].ready}') - if [[ "$status" == "Running" && "$ready" == "true" ]]; then - echo "Pod $pod is active and healthy." - break - fi - fi - echo -n "." - sleep 5 - done - echo "" - - # Additional wait for CNPG to recognize it as joined and healthy - echo "Waiting for CNPG cluster to stabilize..." - sleep 10 - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" - fi - done - - # 5. When the last primary instance needs to be recreated, promote a new primary - echo "Promoting a new primary to recreate the old primary $primary..." - # We promote one of the newly recreated instances. - # kubectl cnpg promote - - local new_primary="" - for pod in $instances; do - if [[ "$pod" != "$primary" ]]; then - new_primary="$pod" - break - fi - done - - if [[ -z "$new_primary" ]]; then - echo "ERROR: No candidate for new primary found." >&2 - exit 1 - fi - - echo "Promoting $new_primary..." - kubectl cnpg promote "$CNPG_CLUSTER_NAME" "$new_primary" -n "$NAMESPACE" || { - echo "Promotion failed, but continuing rollout (CNPG might have already promoted it)..." - } - - echo "Waiting for $new_primary to become primary..." - while true; do - local current_primary - current_primary=$(kubectl get cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -o jsonpath='{.status.currentPrimary}') - if [[ "$current_primary" == "$new_primary" ]]; then - echo "$new_primary is now the primary." - break - fi - echo -n "." - sleep 5 - done - echo "" - - # 6. Rebuild the last pod (the old primary) to make the cluster consistent - echo "Recreating the old primary pod: $primary..." - kubectl delete pod -n "$NAMESPACE" "$primary" - - echo "Waiting for $primary to be recreated and healthy..." - while true; do - if kubectl get pod -n "$NAMESPACE" "$primary" >/dev/null 2>&1; then - local status - status=$(kubectl get pod -n "$NAMESPACE" "$primary" -o jsonpath='{.status.phase}') - local ready - ready=$(kubectl get pod -n "$NAMESPACE" "$primary" -o jsonpath='{.status.containerStatuses[0].ready}') - if [[ "$status" == "Running" && "$ready" == "true" ]]; then - echo "Pod $primary is active and healthy." - break - fi - fi - echo -n "." - sleep 5 - done - echo "" - - echo "Rollout complete. Final cluster status:" - kubectl cnpg status "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" -} - -backup() { - echo "Backup - tbd, when we configure s3 or other block store" -} - -reset() { - ensure_tools - echo "Resetting prole-db cluster..." - echo "Removing cnpg instances and pods..." - kubectl delete cluster "$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --ignore-not-found - - # Wait for deletion - kubectl wait --for=delete cluster/"$CNPG_CLUSTER_NAME" -n "$NAMESPACE" --timeout=60s || true - - echo "Reinstantiating..." - deploy -} - -case "$ACTION" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - deploy) - deploy - ;; - rollback) - rollback - ;; - rollout) - rollout - ;; - backup) - backup - ;; - reset) - reset - ;; - *) - echo "Usage: $0 {start|stop|restart|deploy|rollback|backup|reset} [version]" >&2 - exit 2 - ;; -esac diff --git a/img/installWindow.png b/img/installWindow.png deleted file mode 100644 index f6a4ad3..0000000 Binary files a/img/installWindow.png and /dev/null differ diff --git a/img/ringPerspective.jpg b/img/ringPerspective.jpg deleted file mode 100644 index d95b781..0000000 Binary files a/img/ringPerspective.jpg and /dev/null differ diff --git a/img/test.png b/img/test.png deleted file mode 100644 index 111bcec..0000000 Binary files a/img/test.png and /dev/null differ diff --git a/prole-db.iml b/prole-db.iml index 6fc55f8..20cc7ba 100644 --- a/prole-db.iml +++ b/prole-db.iml @@ -21,6 +21,12 @@ + + + + + + diff --git a/prole-dns/init-prole-dns.sh b/prole-net/init-prole-dns.sh similarity index 100% rename from prole-dns/init-prole-dns.sh rename to prole-net/init-prole-dns.sh diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml deleted file mode 100644 index d80081d..0000000 --- a/web/WEB-INF/web.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - \ No newline at end of file diff --git a/www/README.md b/www/README.md deleted file mode 100644 index dfdacdd..0000000 --- a/www/README.md +++ /dev/null @@ -1,131 +0,0 @@ -# Prole Shop - Spring WebMVC Shopping Application - -A comprehensive Spring Boot shopping application that supports both product sales and service bookings with calendar scheduling. - -## Features - -- **Product Catalog**: Browse and purchase physical products -- **Service Booking**: Book professional services with calendar scheduling -- **Shopping Cart**: Session-based shopping cart for products and services -- **Checkout Process**: Complete order processing with customer information -- **Shipping Estimation**: Automatic shipping cost calculation based on weight and order value -- **Calendar Integration**: View and book available time slots for services -- **Order Management**: Track orders with status and payment information - -## Technology Stack - -- **Spring Boot 3.1.0**: Main framework -- **Spring WebMVC**: Web layer -- **Spring Data JPA**: Data access layer -- **Thymeleaf**: Template engine -- **PostgreSQL**: Database (prole-db service) -- **Bootstrap 5**: UI framework - -## Database Configuration - -The application connects to the `prole-db` PostgreSQL database service defined in `cloudnative-pg-prole0-db.yaml`. - -Connection details: -- **Host**: prole-db-rw -- **Port**: 5432 -- **Database**: prole-db -- **User**: prole -- **Password**: Fr0b0zzg0bl!n! - -## Project Structure - -``` -www/ -├── src/ -│ ├── main/ -│ │ ├── java/ -│ │ │ └── org/prole/shop/ -│ │ │ ├── ShopApplication.java -│ │ │ ├── controller/ # MVC Controllers -│ │ │ ├── model/ # JPA Entities -│ │ │ ├── repository/ # Data Repositories -│ │ │ └── service/ # Business Logic -│ │ └── resources/ -│ │ ├── application.properties -│ │ ├── schema.sql # Database schema -│ │ ├── data.sql # Sample data -│ │ ├── templates/ # Thymeleaf templates -│ │ └── static/ # Static resources -│ └── test/ -└── pom.xml -``` - -## Running the Application - -1. Ensure the `prole-db` database service is running and accessible -2. Build the project: - ```bash - cd www - mvn clean install - ``` -3. Run the application: - ```bash - mvn spring-boot:run - ``` -4. Access the application at: http://localhost:8080 - -## Application Endpoints - -- `/` - Home page with featured products and services -- `/products` - List all products -- `/products/{id}` - Product detail page -- `/services` - List all services -- `/services/{id}` - Service detail page with calendar booking -- `/cart` - Shopping cart view -- `/checkout` - Checkout form -- `/checkout/success` - Order confirmation - -## Database Schema - -The application uses the following main entities: - -- **Product**: Physical products for sale -- **Service**: Professional services available for booking -- **ScheduleSlot**: Available time slots for services -- **CartItem**: Items in the shopping cart (session-based) -- **Order**: Customer orders -- **OrderItem**: Items within an order - -## Payment Processing - -Payment processing is currently a placeholder. The `OrderService.processPayment()` method simulates payment processing. Integration with an external payment processor (Stripe, PayPal, etc.) should be implemented in this method. - -## Shipping Calculation - -Shipping costs are calculated based on: -- Base shipping cost: $10.00 -- Cost per kg: $2.00 -- Free shipping threshold: $100.00 - -These values can be configured in `ShippingService.java`. - -## Sample Data - -The application includes sample data for development/testing: -- 6 sample products -- 6 sample services -- Sample schedule slots for services - -## Development Notes - -- The application uses session-based cart management -- Database schema is auto-created on startup (spring.jpa.hibernate.ddl-auto=update) -- Sample data is loaded from `data.sql` on startup -- Thymeleaf templates use Bootstrap 5 for styling - -## Future Enhancements - -- User authentication and accounts -- Order history and tracking -- Email notifications -- Payment processor integration (Stripe, PayPal, etc.) -- Advanced calendar features (recurring appointments, availability management) -- Product reviews and ratings -- Inventory management -- Admin dashboard - diff --git a/www/images/prole-type.gif b/www/images/prole-type.gif deleted file mode 100644 index f43ea08..0000000 Binary files a/www/images/prole-type.gif and /dev/null differ diff --git a/www/index.html b/www/index.html deleted file mode 100644 index e36a9b1..0000000 --- a/www/index.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - -prole.org - - - - - - - -
-
-
-
-

- -

-
-
-
-
- - diff --git a/www/installer.html b/www/installer.html deleted file mode 100644 index 3660d8f..0000000 --- a/www/installer.html +++ /dev/null @@ -1,762 +0,0 @@ - - - - - - Prole Service Dependencies Installer - - - -
- -
-
-

Prole Service Dependencies Installer

-

Install and configure required dependencies for Prole services

-
- -
- -
-

Step 1: Install Dependencies

- - -
-
-
- Docker -
-
- Container platform required for running Prole services -
-
- -
- - -
-
-
- Homebrew -
-
- Package manager for macOS (required for k3d installation) -
-
-
-
-
- Homebrew Installed & Current -
-
-
-
- -
-
-
-
-
- - -
-
-
- k3d -
-
- Lightweight wrapper to run k3s in Docker (installed via Homebrew) -
-
- -
- - -
- Commands to execute: - # Commands will appear here after checking dependencies -
- -
- -
-
- - -
-

Step 2: Create Home Cluster

- - -
-
-
- Docker Installed and Running -
-
- Verify Docker is installed and the daemon is running -
-
-
-
-
-
- - -
-
-
- k3d Command and Dependencies Ready -
-
- Verify k3d and all related dependencies are installed and ready -
-
-
-
-
-
- - -
- k3d cluster list output: -
Running k3d cluster list...
-
-
-
- - -
- - -
-
-
Prole Terminal
- -
-
-
$ what is my name?
-
- -
-
- - - - - - - - diff --git a/www/pom.xml b/www/pom.xml deleted file mode 100644 index 902013d..0000000 --- a/www/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 3.1.0 - - - - org.prole - prole-shop - 0.0.1-SNAPSHOT - prole-shop - Spring WebMVC Shopping Application - - - 24 - - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - - org.springframework.boot - spring-boot-starter-batch - - - - org.postgresql - postgresql - runtime - - - - - org.apache.avro - avro - 1.11.3 - - - - org.springframework.boot - spring-boot-starter-validation - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - diff --git a/www/soundBlock/index.html b/www/soundBlock/index.html deleted file mode 100644 index 8f8a2f3..0000000 --- a/www/soundBlock/index.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - prole.soundBlock - Sound Isolation Made Easy | sound.prole.org - - - - -
-

sound.prole.org

- -
- -
-
-
- prole.soundBlock -
- -
-

prole.soundBlock - 12" x 12" Sound Isolation Block

-

$49.99 (Price varies by location - see details below)

- -

- Tired of unwanted noise? The prole.soundBlock is a revolutionary sound isolation solution built on proven floating wall construction principles. We take the complexity out of soundproofing, delivering pre-built, interlocking 12" x 12" blocks that are easy to install and incredibly effective. -

- -

- Each block is meticulously crafted to meet local building codes, utilizing the maximum density rockwool (or equivalent high-performance poly insulation) permitted by fire regulations in your area. We handle the research, ensuring your project is safe and compliant. -

- -

Key Features:

-
    -
  • Dimensions: 12" x 12"
  • -
  • Construction: Robust 2x4 or 2x6 frame (choose option), 1/4" plywood layers, high-density rockwool/poly insulation, acoustic sealant, and finished with Homosote 440 for superior performance. Mitered corners, glued & tacked construction.
  • -
  • Customizable: We ensure compliance with *your* local fire codes and building regulations.
  • -
  • Easy Installation: Interlocking design simplifies installation - no specialized skills required.
  • -
  • Superior Sound Isolation: Effectively reduces noise transmission across a wide frequency range.
  • -
- -

Applications:

-
    -
  • Apartment Noise Management: Reduce noise bleed between apartments, creating a more peaceful living environment.
  • -
  • Recording Studio Sound Isolation: Build a quiet and controlled recording space, minimizing external noise and reflections.
  • -
  • Home Audio Bass Traps: Enhance your home theater experience by absorbing low-frequency sound waves and reducing unwanted vibrations.
  • -
  • Sound Reinforcement Applications: Isolate sound sources in venues, churches, or performance spaces.
  • -
- -
-

Important: Pricing and material selection (rockwool vs. poly) are dependent on your location to ensure code compliance. Please enter your zip code below to receive a personalized quote.

-
- - - -
-
- -
- - - -
-
-
- -
-

Professional Installation & Consultation

-

- Need help designing and installing your sound isolation system? Our team at Kifuthu LLC offers expert consultation and professional installation services. Contact us for a free estimate. -

-
-
- -
-

© 2024 sound.prole.org

-
- - - - - diff --git a/www/src/main/java/org/prole/shop/ShopApplication.java b/www/src/main/java/org/prole/shop/ShopApplication.java deleted file mode 100644 index 76efc15..0000000 --- a/www/src/main/java/org/prole/shop/ShopApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.prole.shop; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class ShopApplication { - - public static void main(String[] args) { - SpringApplication.run(ShopApplication.class, args); - } -} - diff --git a/www/src/main/java/org/prole/shop/batch/AvroMapItemWriter.java b/www/src/main/java/org/prole/shop/batch/AvroMapItemWriter.java deleted file mode 100644 index 7bb7575..0000000 --- a/www/src/main/java/org/prole/shop/batch/AvroMapItemWriter.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.prole.shop.batch; - -import org.apache.avro.Schema; -import org.apache.avro.file.DataFileWriter; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemStream; -import org.springframework.batch.item.ItemStreamException; -import org.springframework.batch.item.ItemWriter; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; - -/** - * Generic Avro writer that writes rows (as Map) to a single Avro file per step execution. - * All values are stringified to avoid complex type conversions and ensure broad compatibility for archiving. - */ -public class AvroMapItemWriter implements ItemWriter>, ItemStream { - - private final String tableName; - private final String basePath; - private final List columns; - - private DataFileWriter dataFileWriter; - private Schema schema; - - public AvroMapItemWriter(String tableName, String basePath, List columns) { - this.tableName = tableName; - this.basePath = basePath; - this.columns = columns; - } - - @Override - public void open(ExecutionContext executionContext) throws ItemStreamException { - try { - long ts = executionContext.containsKey("exportTimestamp") - ? executionContext.getLong("exportTimestamp") - : System.currentTimeMillis(); - LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneId.systemDefault()); - - // Build directory structure base/YYYY/MM/DD - String year = DateTimeFormatter.ofPattern("yyyy").format(dateTime); - String month = DateTimeFormatter.ofPattern("MM").format(dateTime); - String day = DateTimeFormatter.ofPattern("dd").format(dateTime); - - Path dir = Path.of(basePath, year, month, day); - Files.createDirectories(dir); - - String timestampPart = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(dateTime); - String fileName = tableName + "-" + timestampPart + ".avro"; - Path filePath = dir.resolve(fileName); - - // Build schema: each column is a nullable string - this.schema = buildSchema(tableName, columns); - - this.dataFileWriter = new DataFileWriter<>(new GenericDatumWriter<>(schema)); - this.dataFileWriter.create(schema, new File(filePath.toString())); - } catch (IOException e) { - throw new ItemStreamException("Failed to open Avro writer", e); - } - } - - @Override - public void update(ExecutionContext executionContext) throws ItemStreamException { - // Nothing to update periodically - } - - @Override - public void close() throws ItemStreamException { - if (dataFileWriter != null) { - try { - dataFileWriter.close(); - } catch (IOException e) { - throw new ItemStreamException("Failed to close Avro writer", e); - } - } - } - - @Override - public void write(List> items) throws Exception { - for (Map row : items) { - GenericRecord record = new GenericData.Record(schema); - for (String col : columns) { - Object val = row.get(col); - record.put(col, val == null ? null : String.valueOf(val)); - } - dataFileWriter.append(record); - } - } - - private static Schema buildSchema(String table, List columns) { - Schema record = Schema.createRecord(table, "Archive export for table " + table, "org.prole.shop.archive", false); - List fields = new java.util.ArrayList<>(); - for (String col : columns) { - Schema nullableString = Schema.createUnion(List.of(Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.STRING))); - fields.add(new Schema.Field(col, nullableString, null, Schema.NULL_VALUE)); - } - record.setFields(fields); - return record; - } -} diff --git a/www/src/main/java/org/prole/shop/batch/BatchExportConfiguration.java b/www/src/main/java/org/prole/shop/batch/BatchExportConfiguration.java deleted file mode 100644 index c9536eb..0000000 --- a/www/src/main/java/org/prole/shop/batch/BatchExportConfiguration.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.prole.shop.batch; - -import org.springframework.batch.core.Job; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.job.builder.JobBuilder; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.listener.StepExecutionListenerSupport; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.database.JdbcCursorItemReader; -import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder; -import org.springframework.batch.item.database.support.PostgresPagingQueryProvider; -import org.springframework.batch.item.support.builder.CompositeItemWriterBuilder; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.jdbc.core.ColumnMapRowMapper; - -import javax.sql.DataSource; -import java.time.Clock; -import java.util.List; -import java.util.Map; - -@Configuration -@EnableBatchProcessing -@EnableScheduling -public class BatchExportConfiguration { - - @Value("${prole.archive.base-path:storage/archive}") - private String archiveBasePath; - - @Bean - public Clock systemClock() { - return Clock.systemDefaultZone(); - } - - // --- Columns for each table --- - private static final List PRODUCTS_COLS = List.of( - "id","name","description","price","stock_quantity","sku","image_url","active","weight","length","width","height","created_at","updated_at" - ); - - private static final List SERVICES_COLS = List.of( - "id","name","description","price_per_hour","default_duration","image_url","active","provider_name","provider_email","provider_phone","created_at","updated_at" - ); - - private static final List SLOTS_COLS = List.of( - "id","service_id","start_time","end_time","available","created_at","updated_at" - ); - - private static final List CART_ITEMS_COLS = List.of( - "id","session_id","product_id","service_id","schedule_slot_id","quantity","unit_price","total_price","created_at","updated_at" - ); - - private static final List ORDERS_COLS = List.of( - "id","order_number","subtotal","shipping_cost","tax","total","status","payment_status","customer_name","customer_email","customer_phone","shipping_address_line1","shipping_address_line2","shipping_city","shipping_state","shipping_postal_code","shipping_country","payment_processor_transaction_id","payment_method","created_at","updated_at","shipped_at","delivered_at" - ); - - private static final List ORDER_ITEMS_COLS = List.of( - "id","order_id","product_id","service_id","schedule_slot_id","quantity","unit_price","total_price","item_name" - ); - - // --- ItemReaders per table using simple SELECT --- - private JdbcCursorItemReader> readerFor(DataSource ds, String table, List cols) { - String sql = "SELECT " + String.join(",", cols) + " FROM " + table + " ORDER BY 1"; - return new JdbcCursorItemReaderBuilder>() - .name("reader_" + table) - .dataSource(ds) - .sql(sql) - .rowMapper(new ColumnMapRowMapper()) - .build(); - } - - private AvroMapItemWriter writerFor(String table, List cols) { - return new AvroMapItemWriter(table, archiveBasePath, cols); - } - - private Step stepFor(String table, - List cols, - DataSource dataSource, - JobRepository jobRepository, - PlatformTransactionManager txManager) { - var reader = readerFor(dataSource, table, cols); - var writer = writerFor(table, cols); - - return new StepBuilder("export_" + table, jobRepository) - ., Map>chunk(500, txManager) - .reader(reader) - .writer(writer) - .listener(new TimestampPropagationListener()) - .build(); - } - - @Bean - public Step exportProductsStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("products", PRODUCTS_COLS, ds, jr, tx); - } - - @Bean - public Step exportServicesStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("services", SERVICES_COLS, ds, jr, tx); - } - - @Bean - public Step exportScheduleSlotsStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("schedule_slots", SLOTS_COLS, ds, jr, tx); - } - - @Bean - public Step exportCartItemsStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("cart_items", CART_ITEMS_COLS, ds, jr, tx); - } - - @Bean - public Step exportOrdersStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("orders", ORDERS_COLS, ds, jr, tx); - } - - @Bean - public Step exportOrderItemsStep(DataSource ds, JobRepository jr, PlatformTransactionManager tx) { - return stepFor("order_items", ORDER_ITEMS_COLS, ds, jr, tx); - } - - @Bean - public Job hourlyArchiveJob(JobRepository jobRepository, - Step exportProductsStep, - Step exportServicesStep, - Step exportScheduleSlotsStep, - Step exportCartItemsStep, - Step exportOrdersStep, - Step exportOrderItemsStep) { - return new JobBuilder("hourlyArchiveJob", jobRepository) - .start(exportProductsStep) - .next(exportServicesStep) - .next(exportScheduleSlotsStep) - .next(exportCartItemsStep) - .next(exportOrdersStep) - .next(exportOrderItemsStep) - .build(); - } - - /** - * Listener to seed a single timestamp into each Step's execution context so - * all files share the same time suffix and directory for a given run. - */ - static class TimestampPropagationListener extends StepExecutionListenerSupport { - @Override - public void beforeStep(org.springframework.batch.core.StepExecution stepExecution) { - ExecutionContext ctx = stepExecution.getExecutionContext(); - if (!ctx.containsKey("exportTimestamp")) { - long ts = stepExecution.getJobParameters().getLong("timestamp", System.currentTimeMillis()); - ctx.putLong("exportTimestamp", ts); - } - } - } -} diff --git a/www/src/main/java/org/prole/shop/batch/HourlyArchiveScheduler.java b/www/src/main/java/org/prole/shop/batch/HourlyArchiveScheduler.java deleted file mode 100644 index 54f1824..0000000 --- a/www/src/main/java/org/prole/shop/batch/HourlyArchiveScheduler.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.prole.shop.batch; - -import org.springframework.batch.core.Job; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.JobParametersBuilder; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Profile; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.time.Instant; - -@Component -public class HourlyArchiveScheduler { - - private final JobLauncher jobLauncher; - private final Job hourlyArchiveJob; - - @Value("${prole.archive.enabled:true}") - private boolean archiveEnabled; - - public HourlyArchiveScheduler(JobLauncher jobLauncher, Job hourlyArchiveJob) { - this.jobLauncher = jobLauncher; - this.hourlyArchiveJob = hourlyArchiveJob; - } - - // Top of every hour - @Scheduled(cron = "0 0 * * * *") - public void runHourlyExport() throws Exception { - if (!archiveEnabled) return; - - long ts = Instant.now().toEpochMilli(); - JobParameters params = new JobParametersBuilder() - .addLong("timestamp", ts) - .toJobParameters(); - jobLauncher.run(hourlyArchiveJob, params); - } -} diff --git a/www/src/main/java/org/prole/shop/controller/CartController.java b/www/src/main/java/org/prole/shop/controller/CartController.java deleted file mode 100644 index 6b6a8ed..0000000 --- a/www/src/main/java/org/prole/shop/controller/CartController.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.prole.shop.controller; - -import org.prole.shop.model.CartItem; -import org.prole.shop.service.CartService; -import org.prole.shop.service.ShippingService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; -import jakarta.servlet.http.HttpSession; -import java.math.BigDecimal; -import java.util.List; - -@Controller -@RequestMapping("/cart") -public class CartController { - - @Autowired - private CartService cartService; - - @Autowired - private ShippingService shippingService; - - private String getSessionId(HttpSession session) { - String sessionId = (String) session.getAttribute("sessionId"); - if (sessionId == null) { - sessionId = java.util.UUID.randomUUID().toString(); - session.setAttribute("sessionId", sessionId); - } - return sessionId; - } - - @GetMapping - public String viewCart(HttpSession session, Model model) { - String sessionId = getSessionId(session); - List cartItems = cartService.getCartItems(sessionId); - BigDecimal subtotal = cartService.getCartTotal(sessionId); - BigDecimal shippingCost = shippingService.calculateShippingCost(cartItems, subtotal); - BigDecimal tax = subtotal.add(shippingCost).multiply(new java.math.BigDecimal("0.08")); - BigDecimal total = subtotal.add(shippingCost).add(tax); - - model.addAttribute("cartItems", cartItems); - model.addAttribute("subtotal", subtotal); - model.addAttribute("shippingCost", shippingCost); - model.addAttribute("tax", tax); - model.addAttribute("total", total); - model.addAttribute("estimatedDelivery", shippingService.estimateDeliveryDays(cartItems)); - - return "cart/view"; - } - - @PostMapping("/add/product/{productId}") - public String addProductToCart( - @PathVariable Long productId, - @RequestParam(defaultValue = "1") Integer quantity, - HttpSession session) { - String sessionId = getSessionId(session); - cartService.addProductToCart(sessionId, productId, quantity); - return "redirect:/cart"; - } - - @PostMapping("/add/service/{serviceId}") - public String addServiceToCart( - @PathVariable Long serviceId, - @RequestParam Long scheduleSlotId, - HttpSession session) { - String sessionId = getSessionId(session); - cartService.addServiceToCart(sessionId, serviceId, scheduleSlotId); - return "redirect:/cart"; - } - - @PostMapping("/update/{cartItemId}") - public String updateCartItem( - @PathVariable Long cartItemId, - @RequestParam Integer quantity, - HttpSession session) { - cartService.updateCartItemQuantity(cartItemId, quantity); - return "redirect:/cart"; - } - - @PostMapping("/remove/{cartItemId}") - public String removeCartItem(@PathVariable Long cartItemId) { - cartService.removeCartItem(cartItemId); - return "redirect:/cart"; - } -} - diff --git a/www/src/main/java/org/prole/shop/controller/CheckoutController.java b/www/src/main/java/org/prole/shop/controller/CheckoutController.java deleted file mode 100644 index 2d4e3c2..0000000 --- a/www/src/main/java/org/prole/shop/controller/CheckoutController.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.prole.shop.controller; - -import org.prole.shop.model.CartItem; -import org.prole.shop.model.Order; -import org.prole.shop.service.CartService; -import org.prole.shop.service.OrderService; -import org.prole.shop.service.ShippingService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; -import jakarta.servlet.http.HttpSession; -import java.math.BigDecimal; -import java.util.List; - -@Controller -@RequestMapping("/checkout") -public class CheckoutController { - - @Autowired - private CartService cartService; - - @Autowired - private OrderService orderService; - - @Autowired - private ShippingService shippingService; - - private String getSessionId(HttpSession session) { - String sessionId = (String) session.getAttribute("sessionId"); - if (sessionId == null) { - sessionId = java.util.UUID.randomUUID().toString(); - session.setAttribute("sessionId", sessionId); - } - return sessionId; - } - - @GetMapping - public String checkout(HttpSession session, Model model) { - String sessionId = getSessionId(session); - List cartItems = cartService.getCartItems(sessionId); - - if (cartItems.isEmpty()) { - return "redirect:/cart"; - } - - BigDecimal subtotal = cartService.getCartTotal(sessionId); - BigDecimal shippingCost = shippingService.calculateShippingCost(cartItems, subtotal); - BigDecimal tax = subtotal.add(shippingCost).multiply(new BigDecimal("0.08")); - BigDecimal total = subtotal.add(shippingCost).add(tax); - - model.addAttribute("cartItems", cartItems); - model.addAttribute("subtotal", subtotal); - model.addAttribute("shippingCost", shippingCost); - model.addAttribute("tax", tax); - model.addAttribute("total", total); - model.addAttribute("order", new Order()); - - return "checkout/form"; - } - - @PostMapping - public String processCheckout( - @ModelAttribute Order order, - HttpSession session, - RedirectAttributes redirectAttributes) { - String sessionId = getSessionId(session); - - try { - Order createdOrder = orderService.createOrderFromCart(sessionId, order); - - // Process payment (placeholder - TBD) - String paymentTransactionId = "TXN-" + System.currentTimeMillis(); - orderService.processPayment(createdOrder, paymentTransactionId, "Credit Card"); - - redirectAttributes.addFlashAttribute("orderNumber", createdOrder.getOrderNumber()); - return "redirect:/checkout/success"; - } catch (Exception e) { - redirectAttributes.addFlashAttribute("error", "Error processing order: " + e.getMessage()); - return "redirect:/checkout"; - } - } - - @GetMapping("/success") - public String checkoutSuccess(@RequestParam(required = false) String orderNumber, Model model) { - if (orderNumber != null) { - model.addAttribute("orderNumber", orderNumber); - } - return "checkout/success"; - } -} - diff --git a/www/src/main/java/org/prole/shop/controller/HomeController.java b/www/src/main/java/org/prole/shop/controller/HomeController.java deleted file mode 100644 index fc1feae..0000000 --- a/www/src/main/java/org/prole/shop/controller/HomeController.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.prole.shop.controller; - -import org.prole.shop.model.Product; -import org.prole.shop.model.Service; -import org.prole.shop.service.ProductService; -import org.prole.shop.service.ServiceService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import java.util.List; - -@Controller -public class HomeController { - - @Autowired - private ProductService productService; - - @Autowired - private ServiceService serviceService; - - @GetMapping("/") - public String home(Model model) { - List featuredProducts = productService.getAllActiveProducts(); - List featuredServices = serviceService.getAllActiveServices(); - - // Limit to 6 items for homepage - if (featuredProducts.size() > 6) { - featuredProducts = featuredProducts.subList(0, 6); - } - if (featuredServices.size() > 6) { - featuredServices = featuredServices.subList(0, 6); - } - - model.addAttribute("featuredProducts", featuredProducts); - model.addAttribute("featuredServices", featuredServices); - - return "index"; - } -} - diff --git a/www/src/main/java/org/prole/shop/controller/ProductController.java b/www/src/main/java/org/prole/shop/controller/ProductController.java deleted file mode 100644 index 669ea47..0000000 --- a/www/src/main/java/org/prole/shop/controller/ProductController.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.prole.shop.controller; - -import org.prole.shop.model.Product; -import org.prole.shop.service.ProductService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import java.util.List; - -@Controller -@RequestMapping("/products") -public class ProductController { - - @Autowired - private ProductService productService; - - @GetMapping - public String listProducts(Model model) { - List products = productService.getAllActiveProducts(); - model.addAttribute("products", products); - return "products/list"; - } - - @GetMapping("/{id}") - public String productDetail(@PathVariable Long id, Model model) { - Product product = productService.getProductById(id) - .orElseThrow(() -> new RuntimeException("Product not found")); - model.addAttribute("product", product); - return "products/detail"; - } -} - diff --git a/www/src/main/java/org/prole/shop/controller/ServiceController.java b/www/src/main/java/org/prole/shop/controller/ServiceController.java deleted file mode 100644 index 944e444..0000000 --- a/www/src/main/java/org/prole/shop/controller/ServiceController.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.prole.shop.controller; - -import org.prole.shop.model.Service; -import org.prole.shop.model.ScheduleSlot; -import org.prole.shop.service.CalendarService; -import org.prole.shop.service.ServiceService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import java.time.LocalDateTime; -import java.util.List; - -@Controller -@RequestMapping("/services") -public class ServiceController { - - @Autowired - private ServiceService serviceService; - - @Autowired - private CalendarService calendarService; - - @GetMapping - public String listServices(Model model) { - List services = serviceService.getAllActiveServices(); - model.addAttribute("services", services); - return "services/list"; - } - - @GetMapping("/{id}") - public String serviceDetail( - @PathVariable Long id, - @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate, - @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate, - Model model) { - Service service = serviceService.getServiceById(id) - .orElseThrow(() -> new RuntimeException("Service not found")); - - List availableSlots = calendarService.getAvailableSlots(service, startDate, endDate); - - model.addAttribute("service", service); - model.addAttribute("availableSlots", availableSlots); - return "services/detail"; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/CartItem.java b/www/src/main/java/org/prole/shop/model/CartItem.java deleted file mode 100644 index 1174e7e..0000000 --- a/www/src/main/java/org/prole/shop/model/CartItem.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -@Entity -@Table(name = "cart_items") -public class CartItem { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String sessionId; // For session-based cart - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "product_id") - private Product product; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "service_id") - private Service service; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "schedule_slot_id") - private ScheduleSlot scheduleSlot; - - @Column(nullable = false) - private Integer quantity = 1; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal unitPrice; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal totalPrice; - - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - calculateTotalPrice(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - calculateTotalPrice(); - } - - private void calculateTotalPrice() { - if (unitPrice != null && quantity != null) { - totalPrice = unitPrice.multiply(BigDecimal.valueOf(quantity)); - } - } - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getSessionId() { - return sessionId; - } - - public void setSessionId(String sessionId) { - this.sessionId = sessionId; - } - - public Product getProduct() { - return product; - } - - public void setProduct(Product product) { - this.product = product; - } - - public Service getService() { - return service; - } - - public void setService(Service service) { - this.service = service; - } - - public ScheduleSlot getScheduleSlot() { - return scheduleSlot; - } - - public void setScheduleSlot(ScheduleSlot scheduleSlot) { - this.scheduleSlot = scheduleSlot; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - calculateTotalPrice(); - } - - public BigDecimal getUnitPrice() { - return unitPrice; - } - - public void setUnitPrice(BigDecimal unitPrice) { - this.unitPrice = unitPrice; - calculateTotalPrice(); - } - - public BigDecimal getTotalPrice() { - return totalPrice; - } - - public void setTotalPrice(BigDecimal totalPrice) { - this.totalPrice = totalPrice; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/Order.java b/www/src/main/java/org/prole/shop/model/Order.java deleted file mode 100644 index 375e077..0000000 --- a/www/src/main/java/org/prole/shop/model/Order.java +++ /dev/null @@ -1,290 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@Entity -@Table(name = "orders") -public class Order { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false, unique = true) - private String orderNumber; - - @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) - private List items = new ArrayList<>(); - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal subtotal; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal shippingCost; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal tax; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal total; - - @Enumerated(EnumType.STRING) - @Column(nullable = false) - private OrderStatus status = OrderStatus.PENDING; - - @Enumerated(EnumType.STRING) - @Column(nullable = false) - private PaymentStatus paymentStatus = PaymentStatus.PENDING; - - // Customer information - @Column(nullable = false) - private String customerName; - - @Column(nullable = false) - private String customerEmail; - - private String customerPhone; - - // Shipping address - private String shippingAddressLine1; - private String shippingAddressLine2; - private String shippingCity; - private String shippingState; - private String shippingPostalCode; - private String shippingCountry; - - // Payment information - private String paymentProcessorTransactionId; - private String paymentMethod; - - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - private LocalDateTime shippedAt; - private LocalDateTime deliveredAt; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - if (orderNumber == null) { - orderNumber = generateOrderNumber(); - } - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - private String generateOrderNumber() { - return "ORD-" + System.currentTimeMillis(); - } - - public enum OrderStatus { - PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED - } - - public enum PaymentStatus { - PENDING, PROCESSING, COMPLETED, FAILED, REFUNDED - } - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getOrderNumber() { - return orderNumber; - } - - public void setOrderNumber(String orderNumber) { - this.orderNumber = orderNumber; - } - - public List getItems() { - return items; - } - - public void setItems(List items) { - this.items = items; - } - - public BigDecimal getSubtotal() { - return subtotal; - } - - public void setSubtotal(BigDecimal subtotal) { - this.subtotal = subtotal; - } - - public BigDecimal getShippingCost() { - return shippingCost; - } - - public void setShippingCost(BigDecimal shippingCost) { - this.shippingCost = shippingCost; - } - - public BigDecimal getTax() { - return tax; - } - - public void setTax(BigDecimal tax) { - this.tax = tax; - } - - public BigDecimal getTotal() { - return total; - } - - public void setTotal(BigDecimal total) { - this.total = total; - } - - public OrderStatus getStatus() { - return status; - } - - public void setStatus(OrderStatus status) { - this.status = status; - } - - public PaymentStatus getPaymentStatus() { - return paymentStatus; - } - - public void setPaymentStatus(PaymentStatus paymentStatus) { - this.paymentStatus = paymentStatus; - } - - public String getCustomerName() { - return customerName; - } - - public void setCustomerName(String customerName) { - this.customerName = customerName; - } - - public String getCustomerEmail() { - return customerEmail; - } - - public void setCustomerEmail(String customerEmail) { - this.customerEmail = customerEmail; - } - - public String getCustomerPhone() { - return customerPhone; - } - - public void setCustomerPhone(String customerPhone) { - this.customerPhone = customerPhone; - } - - public String getShippingAddressLine1() { - return shippingAddressLine1; - } - - public void setShippingAddressLine1(String shippingAddressLine1) { - this.shippingAddressLine1 = shippingAddressLine1; - } - - public String getShippingAddressLine2() { - return shippingAddressLine2; - } - - public void setShippingAddressLine2(String shippingAddressLine2) { - this.shippingAddressLine2 = shippingAddressLine2; - } - - public String getShippingCity() { - return shippingCity; - } - - public void setShippingCity(String shippingCity) { - this.shippingCity = shippingCity; - } - - public String getShippingState() { - return shippingState; - } - - public void setShippingState(String shippingState) { - this.shippingState = shippingState; - } - - public String getShippingPostalCode() { - return shippingPostalCode; - } - - public void setShippingPostalCode(String shippingPostalCode) { - this.shippingPostalCode = shippingPostalCode; - } - - public String getShippingCountry() { - return shippingCountry; - } - - public void setShippingCountry(String shippingCountry) { - this.shippingCountry = shippingCountry; - } - - public String getPaymentProcessorTransactionId() { - return paymentProcessorTransactionId; - } - - public void setPaymentProcessorTransactionId(String paymentProcessorTransactionId) { - this.paymentProcessorTransactionId = paymentProcessorTransactionId; - } - - public String getPaymentMethod() { - return paymentMethod; - } - - public void setPaymentMethod(String paymentMethod) { - this.paymentMethod = paymentMethod; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - public LocalDateTime getShippedAt() { - return shippedAt; - } - - public void setShippedAt(LocalDateTime shippedAt) { - this.shippedAt = shippedAt; - } - - public LocalDateTime getDeliveredAt() { - return deliveredAt; - } - - public void setDeliveredAt(LocalDateTime deliveredAt) { - this.deliveredAt = deliveredAt; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/OrderItem.java b/www/src/main/java/org/prole/shop/model/OrderItem.java deleted file mode 100644 index d2e321d..0000000 --- a/www/src/main/java/org/prole/shop/model/OrderItem.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.math.BigDecimal; - -@Entity -@Table(name = "order_items") -public class OrderItem { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "order_id", nullable = false) - private Order order; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "product_id") - private Product product; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "service_id") - private Service service; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "schedule_slot_id") - private ScheduleSlot scheduleSlot; - - @Column(nullable = false) - private Integer quantity; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal unitPrice; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal totalPrice; - - private String itemName; // Snapshot of item name at time of order - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Order getOrder() { - return order; - } - - public void setOrder(Order order) { - this.order = order; - } - - public Product getProduct() { - return product; - } - - public void setProduct(Product product) { - this.product = product; - } - - public Service getService() { - return service; - } - - public void setService(Service service) { - this.service = service; - } - - public ScheduleSlot getScheduleSlot() { - return scheduleSlot; - } - - public void setScheduleSlot(ScheduleSlot scheduleSlot) { - this.scheduleSlot = scheduleSlot; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } - - public BigDecimal getUnitPrice() { - return unitPrice; - } - - public void setUnitPrice(BigDecimal unitPrice) { - this.unitPrice = unitPrice; - } - - public BigDecimal getTotalPrice() { - return totalPrice; - } - - public void setTotalPrice(BigDecimal totalPrice) { - this.totalPrice = totalPrice; - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/Product.java b/www/src/main/java/org/prole/shop/model/Product.java deleted file mode 100644 index 019ca4c..0000000 --- a/www/src/main/java/org/prole/shop/model/Product.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -@Entity -@Table(name = "products") -public class Product { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String name; - - @Column(length = 2000) - private String description; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal price; - - @Column(nullable = false) - private Integer stockQuantity; - - private String sku; - - private String imageUrl; - - @Column(nullable = false) - private Boolean active = true; - - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - - // Shipping properties - private BigDecimal weight; // in kg - private BigDecimal length; // in cm - private BigDecimal width; // in cm - private BigDecimal height; // in cm - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public BigDecimal getPrice() { - return price; - } - - public void setPrice(BigDecimal price) { - this.price = price; - } - - public Integer getStockQuantity() { - return stockQuantity; - } - - public void setStockQuantity(Integer stockQuantity) { - this.stockQuantity = stockQuantity; - } - - public String getSku() { - return sku; - } - - public void setSku(String sku) { - this.sku = sku; - } - - public String getImageUrl() { - return imageUrl; - } - - public void setImageUrl(String imageUrl) { - this.imageUrl = imageUrl; - } - - public Boolean getActive() { - return active; - } - - public void setActive(Boolean active) { - this.active = active; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - public BigDecimal getWeight() { - return weight; - } - - public void setWeight(BigDecimal weight) { - this.weight = weight; - } - - public BigDecimal getLength() { - return length; - } - - public void setLength(BigDecimal length) { - this.length = length; - } - - public BigDecimal getWidth() { - return width; - } - - public void setWidth(BigDecimal width) { - this.width = width; - } - - public BigDecimal getHeight() { - return height; - } - - public void setHeight(BigDecimal height) { - this.height = height; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/ScheduleSlot.java b/www/src/main/java/org/prole/shop/model/ScheduleSlot.java deleted file mode 100644 index a1c105d..0000000 --- a/www/src/main/java/org/prole/shop/model/ScheduleSlot.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.time.LocalDateTime; - -@Entity -@Table(name = "schedule_slots") -public class ScheduleSlot { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "service_id", nullable = false) - private Service service; - - @Column(nullable = false) - private LocalDateTime startTime; - - @Column(nullable = false) - private LocalDateTime endTime; - - @Column(nullable = false) - private Boolean available = true; - - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Service getService() { - return service; - } - - public void setService(Service service) { - this.service = service; - } - - public LocalDateTime getStartTime() { - return startTime; - } - - public void setStartTime(LocalDateTime startTime) { - this.startTime = startTime; - } - - public LocalDateTime getEndTime() { - return endTime; - } - - public void setEndTime(LocalDateTime endTime) { - this.endTime = endTime; - } - - public Boolean getAvailable() { - return available; - } - - public void setAvailable(Boolean available) { - this.available = available; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } -} - diff --git a/www/src/main/java/org/prole/shop/model/Service.java b/www/src/main/java/org/prole/shop/model/Service.java deleted file mode 100644 index b831fe4..0000000 --- a/www/src/main/java/org/prole/shop/model/Service.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.prole.shop.model; - -import jakarta.persistence.*; -import java.math.BigDecimal; -import java.time.Duration; -import java.time.LocalDateTime; - -@Entity -@Table(name = "services") -public class Service { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String name; - - @Column(length = 2000) - private String description; - - @Column(nullable = false, precision = 10, scale = 2) - private BigDecimal pricePerHour; - - @Column(nullable = false) - private Duration defaultDuration; // Default service duration - - private String imageUrl; - - @Column(nullable = false) - private Boolean active = true; - - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - - // Service provider information - private String providerName; - private String providerEmail; - private String providerPhone; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public BigDecimal getPricePerHour() { - return pricePerHour; - } - - public void setPricePerHour(BigDecimal pricePerHour) { - this.pricePerHour = pricePerHour; - } - - public Duration getDefaultDuration() { - return defaultDuration; - } - - public void setDefaultDuration(Duration defaultDuration) { - this.defaultDuration = defaultDuration; - } - - public String getImageUrl() { - return imageUrl; - } - - public void setImageUrl(String imageUrl) { - this.imageUrl = imageUrl; - } - - public Boolean getActive() { - return active; - } - - public void setActive(Boolean active) { - this.active = active; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - public String getProviderName() { - return providerName; - } - - public void setProviderName(String providerName) { - this.providerName = providerName; - } - - public String getProviderEmail() { - return providerEmail; - } - - public void setProviderEmail(String providerEmail) { - this.providerEmail = providerEmail; - } - - public String getProviderPhone() { - return providerPhone; - } - - public void setProviderPhone(String providerPhone) { - this.providerPhone = providerPhone; - } -} - diff --git a/www/src/main/java/org/prole/shop/repository/CartItemRepository.java b/www/src/main/java/org/prole/shop/repository/CartItemRepository.java deleted file mode 100644 index 71f7df5..0000000 --- a/www/src/main/java/org/prole/shop/repository/CartItemRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.prole.shop.repository; - -import org.prole.shop.model.CartItem; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import java.util.List; - -@Repository -public interface CartItemRepository extends JpaRepository { - List findBySessionId(String sessionId); - void deleteBySessionId(String sessionId); -} - diff --git a/www/src/main/java/org/prole/shop/repository/OrderRepository.java b/www/src/main/java/org/prole/shop/repository/OrderRepository.java deleted file mode 100644 index 1d41a42..0000000 --- a/www/src/main/java/org/prole/shop/repository/OrderRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.prole.shop.repository; - -import org.prole.shop.model.Order; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import java.util.Optional; - -@Repository -public interface OrderRepository extends JpaRepository { - Optional findByOrderNumber(String orderNumber); -} - diff --git a/www/src/main/java/org/prole/shop/repository/ProductRepository.java b/www/src/main/java/org/prole/shop/repository/ProductRepository.java deleted file mode 100644 index 2c6c6a8..0000000 --- a/www/src/main/java/org/prole/shop/repository/ProductRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.prole.shop.repository; - -import org.prole.shop.model.Product; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import java.util.List; - -@Repository -public interface ProductRepository extends JpaRepository { - List findByActiveTrue(); - List findByActiveTrueOrderByNameAsc(); -} - diff --git a/www/src/main/java/org/prole/shop/repository/ScheduleSlotRepository.java b/www/src/main/java/org/prole/shop/repository/ScheduleSlotRepository.java deleted file mode 100644 index 201545c..0000000 --- a/www/src/main/java/org/prole/shop/repository/ScheduleSlotRepository.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.prole.shop.repository; - -import org.prole.shop.model.ScheduleSlot; -import org.prole.shop.model.Service; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; -import java.time.LocalDateTime; -import java.util.List; - -@Repository -public interface ScheduleSlotRepository extends JpaRepository { - List findByServiceAndAvailableTrue(Service service); - - @Query("SELECT s FROM ScheduleSlot s WHERE s.service = :service AND s.available = true AND s.startTime >= :startTime AND s.endTime <= :endTime ORDER BY s.startTime") - List findAvailableSlotsByServiceAndDateRange( - @Param("service") Service service, - @Param("startTime") LocalDateTime startTime, - @Param("endTime") LocalDateTime endTime - ); - - List findByServiceAndStartTimeAfterAndAvailableTrue(Service service, LocalDateTime startTime); -} - diff --git a/www/src/main/java/org/prole/shop/repository/ServiceRepository.java b/www/src/main/java/org/prole/shop/repository/ServiceRepository.java deleted file mode 100644 index c329e71..0000000 --- a/www/src/main/java/org/prole/shop/repository/ServiceRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.prole.shop.repository; - -import org.prole.shop.model.Service; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import java.util.List; - -@Repository -public interface ServiceRepository extends JpaRepository { - List findByActiveTrue(); - List findByActiveTrueOrderByNameAsc(); -} - diff --git a/www/src/main/java/org/prole/shop/service/CalendarService.java b/www/src/main/java/org/prole/shop/service/CalendarService.java deleted file mode 100644 index d953236..0000000 --- a/www/src/main/java/org/prole/shop/service/CalendarService.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.ScheduleSlot; -import org.prole.shop.model.Service; -import org.prole.shop.repository.ScheduleSlotRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.List; - -@Service -@Transactional -public class CalendarService { - - @Autowired - private ScheduleSlotRepository scheduleSlotRepository; - - public List getAvailableSlots(Service service, LocalDateTime startDate, LocalDateTime endDate) { - if (startDate != null && endDate != null) { - return scheduleSlotRepository.findAvailableSlotsByServiceAndDateRange(service, startDate, endDate); - } else if (startDate != null) { - return scheduleSlotRepository.findByServiceAndStartTimeAfterAndAvailableTrue(service, startDate); - } else { - return scheduleSlotRepository.findByServiceAndAvailableTrue(service); - } - } - - public ScheduleSlot bookSlot(ScheduleSlot slot) { - slot.setAvailable(false); - return scheduleSlotRepository.save(slot); - } - - public ScheduleSlot createSlot(ScheduleSlot slot) { - return scheduleSlotRepository.save(slot); - } - - public ScheduleSlot getSlotById(Long id) { - return scheduleSlotRepository.findById(id).orElse(null); - } -} - diff --git a/www/src/main/java/org/prole/shop/service/CartService.java b/www/src/main/java/org/prole/shop/service/CartService.java deleted file mode 100644 index 9822598..0000000 --- a/www/src/main/java/org/prole/shop/service/CartService.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.CartItem; -import org.prole.shop.model.Product; -import org.prole.shop.model.ScheduleSlot; -import org.prole.shop.model.Service; -import org.prole.shop.repository.CartItemRepository; -import org.prole.shop.repository.ProductRepository; -import org.prole.shop.repository.ScheduleSlotRepository; -import org.prole.shop.repository.ServiceRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; -import java.time.Duration; -import java.util.List; -import java.util.Optional; - -@Service -@Transactional -public class CartService { - - @Autowired - private CartItemRepository cartItemRepository; - - @Autowired - private ProductRepository productRepository; - - @Autowired - private ServiceRepository serviceRepository; - - @Autowired - private ScheduleSlotRepository scheduleSlotRepository; - - public List getCartItems(String sessionId) { - return cartItemRepository.findBySessionId(sessionId); - } - - public CartItem addProductToCart(String sessionId, Long productId, Integer quantity) { - Product product = productRepository.findById(productId) - .orElseThrow(() -> new RuntimeException("Product not found")); - - // Check if item already in cart - List existingItems = cartItemRepository.findBySessionId(sessionId); - Optional existingItem = existingItems.stream() - .filter(item -> item.getProduct() != null && item.getProduct().getId().equals(productId)) - .findFirst(); - - if (existingItem.isPresent()) { - CartItem item = existingItem.get(); - item.setQuantity(item.getQuantity() + quantity); - return cartItemRepository.save(item); - } else { - CartItem cartItem = new CartItem(); - cartItem.setSessionId(sessionId); - cartItem.setProduct(product); - cartItem.setQuantity(quantity); - cartItem.setUnitPrice(product.getPrice()); - return cartItemRepository.save(cartItem); - } - } - - public CartItem addServiceToCart(String sessionId, Long serviceId, Long scheduleSlotId) { - Service service = serviceRepository.findById(serviceId) - .orElseThrow(() -> new RuntimeException("Service not found")); - - ScheduleSlot slot = scheduleSlotRepository.findById(scheduleSlotId) - .orElseThrow(() -> new RuntimeException("Schedule slot not found")); - - if (!slot.getAvailable()) { - throw new RuntimeException("Schedule slot is not available"); - } - - // Calculate price based on duration - Duration duration = Duration.between(slot.getStartTime(), slot.getEndTime()); - long hours = duration.toHours(); - if (duration.toMinutes() % 60 > 0) { - hours += 1; // Round up to next hour - } - BigDecimal totalPrice = service.getPricePerHour().multiply(BigDecimal.valueOf(hours)); - - CartItem cartItem = new CartItem(); - cartItem.setSessionId(sessionId); - cartItem.setService(service); - cartItem.setScheduleSlot(slot); - cartItem.setQuantity(1); - cartItem.setUnitPrice(totalPrice); - - return cartItemRepository.save(cartItem); - } - - public void removeCartItem(Long cartItemId) { - cartItemRepository.deleteById(cartItemId); - } - - public void updateCartItemQuantity(Long cartItemId, Integer quantity) { - CartItem item = cartItemRepository.findById(cartItemId) - .orElseThrow(() -> new RuntimeException("Cart item not found")); - item.setQuantity(quantity); - cartItemRepository.save(item); - } - - public void clearCart(String sessionId) { - cartItemRepository.deleteBySessionId(sessionId); - } - - public BigDecimal getCartTotal(String sessionId) { - List items = getCartItems(sessionId); - return items.stream() - .map(CartItem::getTotalPrice) - .reduce(BigDecimal.ZERO, BigDecimal::add); - } -} - diff --git a/www/src/main/java/org/prole/shop/service/OrderService.java b/www/src/main/java/org/prole/shop/service/OrderService.java deleted file mode 100644 index 247215a..0000000 --- a/www/src/main/java/org/prole/shop/service/OrderService.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.*; -import org.prole.shop.repository.CartItemRepository; -import org.prole.shop.repository.OrderRepository; -import org.prole.shop.repository.ScheduleSlotRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@Transactional -public class OrderService { - - @Autowired - private OrderRepository orderRepository; - - @Autowired - private CartItemRepository cartItemRepository; - - @Autowired - private ShippingService shippingService; - - @Autowired - private ScheduleSlotRepository scheduleSlotRepository; - - private static final BigDecimal TAX_RATE = new BigDecimal("0.08"); // 8% tax rate - - public Order createOrderFromCart(String sessionId, Order orderRequest) { - List cartItems = cartItemRepository.findBySessionId(sessionId); - - if (cartItems.isEmpty()) { - throw new RuntimeException("Cart is empty"); - } - - Order order = new Order(); - order.setCustomerName(orderRequest.getCustomerName()); - order.setCustomerEmail(orderRequest.getCustomerEmail()); - order.setCustomerPhone(orderRequest.getCustomerPhone()); - order.setShippingAddressLine1(orderRequest.getShippingAddressLine1()); - order.setShippingAddressLine2(orderRequest.getShippingAddressLine2()); - order.setShippingCity(orderRequest.getShippingCity()); - order.setShippingState(orderRequest.getShippingState()); - order.setShippingPostalCode(orderRequest.getShippingPostalCode()); - order.setShippingCountry(orderRequest.getShippingCountry()); - - // Calculate subtotal - BigDecimal subtotal = cartItems.stream() - .map(CartItem::getTotalPrice) - .reduce(BigDecimal.ZERO, BigDecimal::add); - order.setSubtotal(subtotal); - - // Calculate shipping - BigDecimal shippingCost = shippingService.calculateShippingCost(cartItems, subtotal); - order.setShippingCost(shippingCost); - - // Calculate tax - BigDecimal taxableAmount = subtotal.add(shippingCost); - BigDecimal tax = taxableAmount.multiply(TAX_RATE); - order.setTax(tax); - - // Calculate total - BigDecimal total = subtotal.add(shippingCost).add(tax); - order.setTotal(total); - - // Convert cart items to order items - List orderItems = cartItems.stream().map(cartItem -> { - OrderItem orderItem = new OrderItem(); - orderItem.setOrder(order); - orderItem.setProduct(cartItem.getProduct()); - orderItem.setService(cartItem.getService()); - orderItem.setScheduleSlot(cartItem.getScheduleSlot()); - orderItem.setQuantity(cartItem.getQuantity()); - orderItem.setUnitPrice(cartItem.getUnitPrice()); - orderItem.setTotalPrice(cartItem.getTotalPrice()); - - // Store item name snapshot - if (cartItem.getProduct() != null) { - orderItem.setItemName(cartItem.getProduct().getName()); - } else if (cartItem.getService() != null) { - orderItem.setItemName(cartItem.getService().getName()); - } - - return orderItem; - }).collect(Collectors.toList()); - - order.setItems(orderItems); - - // Mark schedule slots as unavailable - cartItems.stream() - .filter(item -> item.getScheduleSlot() != null) - .forEach(item -> { - ScheduleSlot slot = item.getScheduleSlot(); - slot.setAvailable(false); - scheduleSlotRepository.save(slot); - }); - - Order savedOrder = orderRepository.save(order); - - // Clear cart - cartItemRepository.deleteBySessionId(sessionId); - - return savedOrder; - } - - public Order processPayment(Order order, String paymentProcessorTransactionId, String paymentMethod) { - order.setPaymentProcessorTransactionId(paymentProcessorTransactionId); - order.setPaymentMethod(paymentMethod); - order.setPaymentStatus(Order.PaymentStatus.PROCESSING); - order.setStatus(Order.OrderStatus.PROCESSING); - - // TODO: Integrate with actual payment processor - // For now, simulate successful payment - order.setPaymentStatus(Order.PaymentStatus.COMPLETED); - order.setStatus(Order.OrderStatus.PROCESSING); - - return orderRepository.save(order); - } - - public Order getOrderByNumber(String orderNumber) { - return orderRepository.findByOrderNumber(orderNumber) - .orElseThrow(() -> new RuntimeException("Order not found")); - } -} - diff --git a/www/src/main/java/org/prole/shop/service/ProductService.java b/www/src/main/java/org/prole/shop/service/ProductService.java deleted file mode 100644 index 93bbd26..0000000 --- a/www/src/main/java/org/prole/shop/service/ProductService.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.Product; -import org.prole.shop.repository.ProductRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - -@Service -@Transactional -public class ProductService { - - @Autowired - private ProductRepository productRepository; - - public List getAllActiveProducts() { - return productRepository.findByActiveTrueOrderByNameAsc(); - } - - public Optional getProductById(Long id) { - return productRepository.findById(id); - } - - public Product saveProduct(Product product) { - return productRepository.save(product); - } - - public void deleteProduct(Long id) { - productRepository.deleteById(id); - } -} - diff --git a/www/src/main/java/org/prole/shop/service/ServiceService.java b/www/src/main/java/org/prole/shop/service/ServiceService.java deleted file mode 100644 index d695371..0000000 --- a/www/src/main/java/org/prole/shop/service/ServiceService.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.Service; -import org.prole.shop.repository.ServiceRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - -@Service -@Transactional -public class ServiceService { - - @Autowired - private ServiceRepository serviceRepository; - - public List getAllActiveServices() { - return serviceRepository.findByActiveTrueOrderByNameAsc(); - } - - public Optional getServiceById(Long id) { - return serviceRepository.findById(id); - } - - public Service saveService(Service service) { - return serviceRepository.save(service); - } - - public void deleteService(Long id) { - serviceRepository.deleteById(id); - } -} - diff --git a/www/src/main/java/org/prole/shop/service/ShippingService.java b/www/src/main/java/org/prole/shop/service/ShippingService.java deleted file mode 100644 index fecc03b..0000000 --- a/www/src/main/java/org/prole/shop/service/ShippingService.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.prole.shop.service; - -import org.prole.shop.model.CartItem; -import org.prole.shop.model.Product; -import org.springframework.stereotype.Service; -import java.math.BigDecimal; -import java.util.List; - -@Service -public class ShippingService { - - // Base shipping rates (can be configured) - private static final BigDecimal BASE_SHIPPING_COST = new BigDecimal("10.00"); - private static final BigDecimal COST_PER_KG = new BigDecimal("2.00"); - private static final BigDecimal FREE_SHIPPING_THRESHOLD = new BigDecimal("100.00"); - - public BigDecimal calculateShippingCost(List cartItems, BigDecimal subtotal) { - // Free shipping for orders over threshold - if (subtotal.compareTo(FREE_SHIPPING_THRESHOLD) >= 0) { - return BigDecimal.ZERO; - } - - // Calculate total weight - BigDecimal totalWeight = BigDecimal.ZERO; - for (CartItem item : cartItems) { - if (item.getProduct() != null && item.getProduct().getWeight() != null) { - BigDecimal itemWeight = item.getProduct().getWeight() - .multiply(BigDecimal.valueOf(item.getQuantity())); - totalWeight = totalWeight.add(itemWeight); - } - } - - // Calculate shipping cost: base + (weight * cost per kg) - BigDecimal weightCost = totalWeight.multiply(COST_PER_KG); - return BASE_SHIPPING_COST.add(weightCost); - } - - public String estimateDeliveryDays(List cartItems) { - // Simple estimation: 3-5 business days for standard shipping - // Can be enhanced with actual shipping provider integration - return "3-5 business days"; - } -} - diff --git a/www/src/main/resources/application.properties b/www/src/main/resources/application.properties deleted file mode 100644 index fa91d9d..0000000 --- a/www/src/main/resources/application.properties +++ /dev/null @@ -1,38 +0,0 @@ -# Database Configuration -spring.datasource.url=jdbc:postgresql://prole-db-rw:5432/prole-db -spring.datasource.username=prole -spring.datasource.password=Fr0b0zzg0bl!n! -spring.datasource.driver-class-name=org.postgresql.Driver - -# JPA Configuration -spring.jpa.hibernate.ddl-auto=update -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -spring.jpa.properties.hibernate.format_sql=true -spring.sql.init.mode=always -spring.sql.init.schema-locations=classpath:schema.sql -spring.sql.init.data-locations=classpath:data.sql - -# Server Configuration -server.port=8080 - -# Thymeleaf Configuration -spring.thymeleaf.prefix=classpath:/templates/ -spring.thymeleaf.suffix=.html -spring.thymeleaf.cache=false -spring.thymeleaf.mode=HTML - -# Static Resources -spring.web.resources.static-locations=classpath:/static/ -spring.mvc.static-path-pattern=/static/** - -# Batch/Archive Export -spring.batch.jdbc.initialize-schema=always -# Prevent auto-running jobs at startup; scheduler will launch -spring.batch.job.enabled=false - -# Base folder for Avro archives (will create YYYY/MM/DD structure inside) -prole.archive.base-path=storage/archive -# Turn off to disable scheduled exports without code changes -prole.archive.enabled=true - diff --git a/www/src/main/resources/data.sql b/www/src/main/resources/data.sql deleted file mode 100644 index 2ec888b..0000000 --- a/www/src/main/resources/data.sql +++ /dev/null @@ -1,40 +0,0 @@ --- Sample data for development/testing --- This file is executed after schema.sql when spring.jpa.hibernate.ddl-auto is set to create or create-drop - --- Sample Products -INSERT INTO products (name, description, price, stock_quantity, sku, image_url, weight, length, width, height, active) VALUES -('Wireless Headphones', 'Premium wireless headphones with noise cancellation', 99.99, 50, 'WH-001', '/static/images/placeholder.jpg', 0.3, 20, 18, 8, true), -('Smart Watch', 'Feature-rich smartwatch with fitness tracking', 249.99, 30, 'SW-002', '/static/images/placeholder.jpg', 0.05, 4, 4, 1, true), -('Laptop Stand', 'Ergonomic aluminum laptop stand', 49.99, 100, 'LS-003', '/static/images/placeholder.jpg', 0.8, 30, 25, 5, true), -('USB-C Cable', 'High-speed USB-C charging cable, 6ft', 19.99, 200, 'UC-004', '/static/images/placeholder.jpg', 0.1, 180, 1, 1, true), -('Wireless Mouse', 'Ergonomic wireless mouse with long battery life', 29.99, 75, 'WM-005', '/static/images/placeholder.jpg', 0.1, 10, 6, 4, true), -('Desk Organizer', 'Bamboo desk organizer with multiple compartments', 34.99, 60, 'DO-006', '/static/images/placeholder.jpg', 0.5, 30, 20, 10, true); - --- Sample Services -INSERT INTO services (name, description, price_per_hour, default_duration, image_url, provider_name, provider_email, provider_phone, active) VALUES -('Web Development Consultation', 'Expert consultation on web development projects and architecture', 150.00, INTERVAL '1 hour', '/static/images/placeholder.jpg', 'John Developer', 'john@example.com', '555-0101', true), -('Graphic Design Service', 'Professional graphic design for logos, branding, and marketing materials', 120.00, INTERVAL '2 hours', '/static/images/placeholder.jpg', 'Sarah Designer', 'sarah@example.com', '555-0102', true), -('IT Support', 'On-site or remote IT support and troubleshooting', 100.00, INTERVAL '1 hour', '/static/images/placeholder.jpg', 'Mike Technician', 'mike@example.com', '555-0103', true), -('Business Consulting', 'Strategic business consulting and planning', 200.00, INTERVAL '2 hours', '/static/images/placeholder.jpg', 'Lisa Consultant', 'lisa@example.com', '555-0104', true), -('Photography Session', 'Professional photography for events, portraits, or products', 175.00, INTERVAL '3 hours', '/static/images/placeholder.jpg', 'Alex Photographer', 'alex@example.com', '555-0105', true), -('Content Writing', 'Professional content writing for websites, blogs, and marketing', 80.00, INTERVAL '1 hour', '/static/images/placeholder.jpg', 'Emma Writer', 'emma@example.com', '555-0106', true); - --- Sample Schedule Slots (for the next 30 days) --- Web Development Consultation slots -INSERT INTO schedule_slots (service_id, start_time, end_time, available) -SELECT 1, - CURRENT_DATE + INTERVAL '1 day' + (n || ' hours')::INTERVAL, - CURRENT_DATE + INTERVAL '1 day' + ((n + 1) || ' hours')::INTERVAL, - true -FROM generate_series(9, 16) n -WHERE CURRENT_DATE + INTERVAL '1 day' + (n || ' hours')::INTERVAL > CURRENT_TIMESTAMP; - --- Graphic Design Service slots -INSERT INTO schedule_slots (service_id, start_time, end_time, available) -SELECT 2, - CURRENT_DATE + INTERVAL '2 days' + (n || ' hours')::INTERVAL, - CURRENT_DATE + INTERVAL '2 days' + ((n + 2) || ' hours')::INTERVAL, - true -FROM generate_series(10, 15) n -WHERE CURRENT_DATE + INTERVAL '2 days' + (n || ' hours')::INTERVAL > CURRENT_TIMESTAMP; - diff --git a/www/src/main/resources/schema.sql b/www/src/main/resources/schema.sql deleted file mode 100644 index 6973bd3..0000000 --- a/www/src/main/resources/schema.sql +++ /dev/null @@ -1,119 +0,0 @@ --- Prole Shop Database Schema --- This file contains the initial database schema for the shopping application - --- Products table -CREATE TABLE IF NOT EXISTS products ( - id BIGSERIAL PRIMARY KEY, - name VARCHAR(255) NOT NULL, - description TEXT, - price NUMERIC(10, 2) NOT NULL, - stock_quantity INTEGER NOT NULL, - sku VARCHAR(100), - image_url VARCHAR(500), - active BOOLEAN NOT NULL DEFAULT true, - weight NUMERIC(10, 2), - length NUMERIC(10, 2), - width NUMERIC(10, 2), - height NUMERIC(10, 2), - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP -); - --- Services table -CREATE TABLE IF NOT EXISTS services ( - id BIGSERIAL PRIMARY KEY, - name VARCHAR(255) NOT NULL, - description TEXT, - price_per_hour NUMERIC(10, 2) NOT NULL, - default_duration INTERVAL NOT NULL, - image_url VARCHAR(500), - active BOOLEAN NOT NULL DEFAULT true, - provider_name VARCHAR(255), - provider_email VARCHAR(255), - provider_phone VARCHAR(50), - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP -); - --- Schedule slots table -CREATE TABLE IF NOT EXISTS schedule_slots ( - id BIGSERIAL PRIMARY KEY, - service_id BIGINT NOT NULL REFERENCES services(id) ON DELETE CASCADE, - start_time TIMESTAMP NOT NULL, - end_time TIMESTAMP NOT NULL, - available BOOLEAN NOT NULL DEFAULT true, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP -); - --- Cart items table -CREATE TABLE IF NOT EXISTS cart_items ( - id BIGSERIAL PRIMARY KEY, - session_id VARCHAR(255) NOT NULL, - product_id BIGINT REFERENCES products(id) ON DELETE CASCADE, - service_id BIGINT REFERENCES services(id) ON DELETE CASCADE, - schedule_slot_id BIGINT REFERENCES schedule_slots(id) ON DELETE CASCADE, - quantity INTEGER NOT NULL DEFAULT 1, - unit_price NUMERIC(10, 2) NOT NULL, - total_price NUMERIC(10, 2) NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP, - CONSTRAINT cart_item_check CHECK ( - (product_id IS NOT NULL AND service_id IS NULL) OR - (product_id IS NULL AND service_id IS NOT NULL) - ) -); - --- Orders table -CREATE TABLE IF NOT EXISTS orders ( - id BIGSERIAL PRIMARY KEY, - order_number VARCHAR(255) NOT NULL UNIQUE, - subtotal NUMERIC(10, 2) NOT NULL, - shipping_cost NUMERIC(10, 2) NOT NULL, - tax NUMERIC(10, 2) NOT NULL, - total NUMERIC(10, 2) NOT NULL, - status VARCHAR(50) NOT NULL DEFAULT 'PENDING', - payment_status VARCHAR(50) NOT NULL DEFAULT 'PENDING', - customer_name VARCHAR(255) NOT NULL, - customer_email VARCHAR(255) NOT NULL, - customer_phone VARCHAR(50), - shipping_address_line1 VARCHAR(255), - shipping_address_line2 VARCHAR(255), - shipping_city VARCHAR(100), - shipping_state VARCHAR(100), - shipping_postal_code VARCHAR(20), - shipping_country VARCHAR(100), - payment_processor_transaction_id VARCHAR(255), - payment_method VARCHAR(50), - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP, - shipped_at TIMESTAMP, - delivered_at TIMESTAMP -); - --- Order items table -CREATE TABLE IF NOT EXISTS order_items ( - id BIGSERIAL PRIMARY KEY, - order_id BIGINT NOT NULL REFERENCES orders(id) ON DELETE CASCADE, - product_id BIGINT REFERENCES products(id) ON DELETE SET NULL, - service_id BIGINT REFERENCES services(id) ON DELETE SET NULL, - schedule_slot_id BIGINT REFERENCES schedule_slots(id) ON DELETE SET NULL, - quantity INTEGER NOT NULL, - unit_price NUMERIC(10, 2) NOT NULL, - total_price NUMERIC(10, 2) NOT NULL, - item_name VARCHAR(255), - CONSTRAINT order_item_check CHECK ( - (product_id IS NOT NULL AND service_id IS NULL) OR - (product_id IS NULL AND service_id IS NOT NULL) - ) -); - --- Create indexes for better performance -CREATE INDEX IF NOT EXISTS idx_products_active ON products(active); -CREATE INDEX IF NOT EXISTS idx_services_active ON services(active); -CREATE INDEX IF NOT EXISTS idx_schedule_slots_service ON schedule_slots(service_id); -CREATE INDEX IF NOT EXISTS idx_schedule_slots_available ON schedule_slots(available, start_time); -CREATE INDEX IF NOT EXISTS idx_cart_items_session ON cart_items(session_id); -CREATE INDEX IF NOT EXISTS idx_orders_order_number ON orders(order_number); -CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id); - diff --git a/www/src/main/resources/static/images/placeholder.jpg b/www/src/main/resources/static/images/placeholder.jpg deleted file mode 100644 index 4f2e970..0000000 --- a/www/src/main/resources/static/images/placeholder.jpg +++ /dev/null @@ -1 +0,0 @@ -PLACEHOLDER diff --git a/www/src/main/resources/templates/cart/view.html b/www/src/main/resources/templates/cart/view.html deleted file mode 100644 index 2036dc2..0000000 --- a/www/src/main/resources/templates/cart/view.html +++ /dev/null @@ -1,91 +0,0 @@ - - - -
-

Shopping Cart

- -
-
- - - - - - - - - - - - - - - - - - - - - -
ItemTypePriceQuantityTotalActions
- -
- -
-
- Product - Service - -
- -
-
-
- -
-
-
- -
-
-
-
-
Order Summary
- - - - - - - - - - - - - - - - - -
Subtotal:
Shipping:
Tax:
Total:
-

- Proceed to Checkout -
-
-
-
-
- -
-

Your cart is empty

-

Start shopping by browsing our products or services.

-
-
- - - diff --git a/www/src/main/resources/templates/checkout/form.html b/www/src/main/resources/templates/checkout/form.html deleted file mode 100644 index e67c8f9..0000000 --- a/www/src/main/resources/templates/checkout/form.html +++ /dev/null @@ -1,114 +0,0 @@ - - - -
-

Checkout

- -
-
-
-
-
-
Customer Information
-
-
-
- - -
-
- - -
-
- - -
-
-
- -
-
-
Shipping Address
-
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
-
- -
-
-
Payment Information
-
-
-
- Payment processing will be integrated with an external payment processor (TBD). - For now, this is a demonstration checkout flow. -
-

Payment method: Credit Card (TBD)

-
-
- - -
-
- -
-
-
-
Order Summary
-
-
- - - - - - - - - - - - - - - - - -
Subtotal:
Shipping:
Tax:
Total:
-
-
-
-
-
- - - diff --git a/www/src/main/resources/templates/checkout/success.html b/www/src/main/resources/templates/checkout/success.html deleted file mode 100644 index 51371f7..0000000 --- a/www/src/main/resources/templates/checkout/success.html +++ /dev/null @@ -1,21 +0,0 @@ - - - -
-
-
- -
-

Order Confirmed!

-

- Your order number is: -

-

- Thank you for your purchase. You will receive a confirmation email shortly. -

- Continue Shopping -
-
- - - diff --git a/www/src/main/resources/templates/index.html b/www/src/main/resources/templates/index.html deleted file mode 100644 index 05e91bb..0000000 --- a/www/src/main/resources/templates/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - -
-
-

Welcome to Prole Shop

-

Shop for products and book professional services

-
- -
-

Featured Products

-
-
-
- Product image -
-
-

-

- -

- View Details -
-
-
-
-
- -
-

Featured Services

-
-
-
- Service image -
-
-

-

- -

- View Details -
-
-
-
-
-
- - - diff --git a/www/src/main/resources/templates/layout.html b/www/src/main/resources/templates/layout.html deleted file mode 100644 index 67ffcce..0000000 --- a/www/src/main/resources/templates/layout.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - Prole Shop - - - - - - - -
- - -
-
- -
-
-

© 2024 Prole Shop. All rights reserved.

-
-
- - - - diff --git a/www/src/main/resources/templates/products/detail.html b/www/src/main/resources/templates/products/detail.html deleted file mode 100644 index c88b2af..0000000 --- a/www/src/main/resources/templates/products/detail.html +++ /dev/null @@ -1,38 +0,0 @@ - - - -
-
-
- Product image -
-
-

-

-

- -
- SKU: -
-
- Stock: - - Low Stock -
- -
-
- - -
- -
-
-
-
- - - diff --git a/www/src/main/resources/templates/products/list.html b/www/src/main/resources/templates/products/list.html deleted file mode 100644 index a5e865a..0000000 --- a/www/src/main/resources/templates/products/list.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -
-

Products

-
-
-
- Product image -
-
-

-

- - Low Stock -

- View Details -
-
-
-
-
- - - diff --git a/www/src/main/resources/templates/services/detail.html b/www/src/main/resources/templates/services/detail.html deleted file mode 100644 index ed02f2c..0000000 --- a/www/src/main/resources/templates/services/detail.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - -
-
-
- Service image -
-
-

-

-

- -
- Provider: -
-
- Email: -
-
- Phone: -
-
-
- -
-
-

Available Time Slots

-
-
-
-
-
-
-

- Time: - - - -

-
- - -
-
-
-
-
-
-
- No available time slots at the moment. Please check back later. -
-
-
-
- - - diff --git a/www/src/main/resources/templates/services/list.html b/www/src/main/resources/templates/services/list.html deleted file mode 100644 index 7a43040..0000000 --- a/www/src/main/resources/templates/services/list.html +++ /dev/null @@ -1,25 +0,0 @@ - - - -
-

Services

-
-
-
- Service image -
-
-

-

- -

- View Details & Book -
-
-
-
-
- - -