Files
vm-core/scripts/gitlab_console_session.sh
2025-12-27 00:10:32 +00:00

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