191 lines
5.8 KiB
Bash
Executable File
191 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ============================================================================
|
|
# VaultMesh GitLab Console Session Helper
|
|
#
|
|
# Wires GitLab CI pipelines into the Console engine as sessions.
|
|
# Each pipeline becomes a Console session with start/end receipts.
|
|
#
|
|
# Usage:
|
|
# ./scripts/gitlab_console_session.sh start
|
|
# ./scripts/gitlab_console_session.sh end
|
|
# ./scripts/gitlab_console_session.sh cmd <name> <exit_code>
|
|
# ./scripts/gitlab_console_session.sh request_approval <action_type>
|
|
#
|
|
# Environment Variables (set in GitLab CI/CD Settings → Variables):
|
|
# VAULTMESH_CONSOLE_BASE - Console HTTP bridge URL
|
|
# VAULTMESH_CALLER_DID - DID for GitLab CI service
|
|
# VAULTMESH_APPROVER_DID - Default approver DID
|
|
# VM_ENV - Environment: dev, staging, or prod
|
|
#
|
|
# GitLab CI Variables (automatic):
|
|
# CI_PIPELINE_ID, CI_PROJECT_PATH, CI_COMMIT_SHA, CI_JOB_STATUS
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
# Defaults
|
|
BASE="${VAULTMESH_CONSOLE_BASE:-http://127.0.0.1:9110/v1/console}"
|
|
ENDPOINT="$BASE/receipt"
|
|
CALLER="${VAULTMESH_CALLER_DID:-did:vm:service:gitlab-ci}"
|
|
APPROVER="${VAULTMESH_APPROVER_DID:-did:vm:human:karol}"
|
|
SESSION_ID="gitlab-pipeline-${CI_PIPELINE_ID:-unknown}"
|
|
PROJECT="${CI_PROJECT_PATH:-unknown}"
|
|
COMMIT="${CI_COMMIT_SHA:-unknown}"
|
|
ENV="${VM_ENV:-prod}" # Default to prod (most restrictive)
|
|
|
|
# Emit a receipt to Console
|
|
emit() {
|
|
local type="$1"
|
|
local payload="$2"
|
|
|
|
curl -sS -X POST "$ENDPOINT" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{
|
|
\"type\":\"$type\",
|
|
\"session_id\":\"$SESSION_ID\",
|
|
\"payload\":$payload
|
|
}" >/dev/null || echo "[VaultMesh] Warning: Failed to emit $type receipt"
|
|
}
|
|
|
|
# Request approval and return approval_id
|
|
request_approval() {
|
|
local action_type="$1"
|
|
local details="${2:-{}}"
|
|
|
|
local resp
|
|
resp=$(curl -sS -X POST "$BASE/approvals/request" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{
|
|
\"session_id\":\"$SESSION_ID\",
|
|
\"action_type\":\"$action_type\",
|
|
\"action_details\":$details,
|
|
\"requested_by\":\"$CALLER\",
|
|
\"approvers\":[\"$APPROVER\"],
|
|
\"timeout_minutes\": 120
|
|
}")
|
|
|
|
echo "$resp"
|
|
}
|
|
|
|
# Check if approval is still pending
|
|
check_pending() {
|
|
local approval_id="$1"
|
|
|
|
local resp
|
|
resp=$(curl -sS "$BASE/approvals/pending?session_id=$SESSION_ID")
|
|
|
|
# Check if approval_id is in pending list
|
|
if echo "$resp" | jq -e ".pending[] | select(.approval_id == \"$approval_id\")" >/dev/null 2>&1; then
|
|
echo "pending"
|
|
else
|
|
echo "decided"
|
|
fi
|
|
}
|
|
|
|
# Main dispatch
|
|
case "${1:-}" in
|
|
start)
|
|
echo "[VaultMesh] Starting Console session: $SESSION_ID (env: $ENV)"
|
|
emit "console_session_start" "{
|
|
\"agent_type\":\"gitlab-ci\",
|
|
\"model_id\":\"none\",
|
|
\"caller\":\"$CALLER\",
|
|
\"project_path\":\"$PROJECT\",
|
|
\"pipeline_id\":\"${CI_PIPELINE_ID:-unknown}\",
|
|
\"commit\":\"$COMMIT\",
|
|
\"env\":\"$ENV\"
|
|
}"
|
|
echo "[VaultMesh] Session started"
|
|
;;
|
|
|
|
end)
|
|
STATUS="${CI_JOB_STATUS:-unknown}"
|
|
echo "[VaultMesh] Ending Console session: $SESSION_ID (status: $STATUS)"
|
|
emit "console_session_end" "{
|
|
\"duration_ms\":0,
|
|
\"commands_executed\":0,
|
|
\"files_modified\":0,
|
|
\"exit_reason\":\"pipeline-$STATUS\"
|
|
}"
|
|
echo "[VaultMesh] Session ended"
|
|
;;
|
|
|
|
cmd)
|
|
CMD_NAME="${2:-unknown}"
|
|
EXIT_CODE="${3:-0}"
|
|
echo "[VaultMesh] Recording command: $CMD_NAME (exit: $EXIT_CODE)"
|
|
emit "console_command" "{
|
|
\"command\":\"$CMD_NAME\",
|
|
\"args_hash\":\"$COMMIT\",
|
|
\"exit_code\":$EXIT_CODE,
|
|
\"duration_ms\":0
|
|
}"
|
|
;;
|
|
|
|
request_approval)
|
|
ACTION_TYPE="${2:-deploy}"
|
|
DETAILS="${3:-{\"env\":\"$ENV\",\"commit\":\"$COMMIT\",\"pipeline_id\":\"${CI_PIPELINE_ID:-unknown}\"}}"
|
|
|
|
echo "[VaultMesh] Requesting approval for: $ACTION_TYPE (env: $ENV)"
|
|
RESP=$(request_approval "$ACTION_TYPE" "$DETAILS")
|
|
APPROVAL_ID=$(echo "$RESP" | jq -r '.approval_id')
|
|
|
|
echo "[VaultMesh] Approval requested: $APPROVAL_ID"
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "ACTION REQUIRES APPROVAL"
|
|
echo "============================================================"
|
|
echo ""
|
|
echo "Approval ID: $APPROVAL_ID"
|
|
echo "Action Type: $ACTION_TYPE"
|
|
echo ""
|
|
echo "To approve, run on VaultMesh host:"
|
|
echo ""
|
|
echo " export VAULTMESH_ACTOR_DID=\"$APPROVER\""
|
|
echo " vm console approve $APPROVAL_ID --reason \"Approved from GitLab\""
|
|
echo ""
|
|
echo "============================================================"
|
|
|
|
# Exit 1 to fail the job (approval required)
|
|
exit 1
|
|
;;
|
|
|
|
check_approval)
|
|
APPROVAL_ID="${2:-}"
|
|
if [ -z "$APPROVAL_ID" ]; then
|
|
echo "Usage: $0 check_approval <approval_id>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
STATUS=$(check_pending "$APPROVAL_ID")
|
|
echo "[VaultMesh] Approval $APPROVAL_ID status: $STATUS"
|
|
|
|
if [ "$STATUS" = "pending" ]; then
|
|
echo "Approval still pending. Cannot proceed."
|
|
exit 1
|
|
else
|
|
echo "Approval decided. Proceeding."
|
|
exit 0
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
echo "VaultMesh GitLab Console Session Helper"
|
|
echo ""
|
|
echo "Usage: $0 {start|end|cmd|request_approval|check_approval}"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " start - Emit console_session_start"
|
|
echo " end - Emit console_session_end"
|
|
echo " cmd <name> <exit_code> - Emit console_command"
|
|
echo " request_approval <type> - Request approval and exit 1"
|
|
echo " check_approval <id> - Check if approval decided"
|
|
echo ""
|
|
echo "Environment:"
|
|
echo " VAULTMESH_CONSOLE_BASE - Console HTTP bridge URL"
|
|
echo " VAULTMESH_CALLER_DID - DID for GitLab CI service"
|
|
echo " VAULTMESH_APPROVER_DID - Default approver DID"
|
|
exit 1
|
|
;;
|
|
esac
|