mirror of
https://github.com/taylanbakircioglu/flowfish.git
synced 2026-09-23 19:06:34 +00:00
6e503368f7
- Grafana Beyla DaemonSet for kernel-level HTTP/gRPC/DNS capture (passive, zero application changes, W3C traceparent header propagation) - flowfish-l7-collector in-cluster bridge: OTLP receiver + buffered pull API - L7 Ingestion Service: K8s service-proxy poll → enrich → RabbitMQ - ClickHouse l7_http_flows / l7_grpc_flows / l7_dns_flows + APM RED MVs - Neo4j L7Workload nodes + SAME_WORKLOAD cross-cluster bridges - New pages: Service Map, Trace Explorer, APM Services List, APM Service Detail - Analysis Wizard now supports L4 / L7 / Both modes with HTTP/gRPC/DNS picks - Integration Hub gains L7 dependency summary + tree-summary integrations - Multi-Cluster Management: dual-agent install (Inspector Gadget L4 + Beyla L7), runtime OpenShift detection so SCCs auto-install with kubectl too - ServiceMap edge → Trace Explorer drill-down with virtual_trace_id correlation - Docs: new L7 architecture diagram, README L7 sections, 3 new screenshots
587 lines
24 KiB
Bash
Executable File
587 lines
24 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
echo "================================================"
|
|
echo "Deploying Infrastructure Components"
|
|
echo "================================================"
|
|
|
|
# Azure Pipelines downloads artifacts to $(Pipeline.Workspace)/artifactName
|
|
# Try multiple possible locations
|
|
if [ -d "${PIPELINE_WORKSPACE}/manifests" ]; then
|
|
MANIFEST_DIR="${PIPELINE_WORKSPACE}/manifests"
|
|
elif [ -d "${BUILD_ARTIFACTSTAGINGDIRECTORY}/manifests" ]; then
|
|
MANIFEST_DIR="${BUILD_ARTIFACTSTAGINGDIRECTORY}/manifests"
|
|
elif [ -d "${AGENT_BUILDDIRECTORY}/manifests" ]; then
|
|
MANIFEST_DIR="${AGENT_BUILDDIRECTORY}/manifests"
|
|
else
|
|
echo "ERROR: Manifests directory not found!"
|
|
echo " Tried:"
|
|
echo " ${PIPELINE_WORKSPACE}/manifests"
|
|
echo " ${BUILD_ARTIFACTSTAGINGDIRECTORY}/manifests"
|
|
echo " ${AGENT_BUILDDIRECTORY}/manifests"
|
|
echo ""
|
|
echo "Available directories:"
|
|
ls -la ${PIPELINE_WORKSPACE}/ || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "Using manifests from: $MANIFEST_DIR"
|
|
|
|
cd $MANIFEST_DIR
|
|
|
|
# Login to OpenShift
|
|
echo "Logging into OpenShift..."
|
|
|
|
if [ -z "${OPENSHIFT_API_URL}" ] || [ -z "${OPENSHIFT_USER}" ] || [ -z "${OPENSHIFT_PASSWORD}" ] || [ -z "${OPENSHIFT_NAMESPACE}" ]; then
|
|
echo "ERROR: OpenShift credentials not set!"
|
|
echo "Required: OPENSHIFT_API_URL, OPENSHIFT_USER, OPENSHIFT_PASSWORD, OPENSHIFT_NAMESPACE"
|
|
exit 1
|
|
fi
|
|
|
|
oc login ${OPENSHIFT_API_URL} -u ${OPENSHIFT_USER} -p ${OPENSHIFT_PASSWORD} --insecure-skip-tls-verify=true
|
|
|
|
# Create namespace if not exists
|
|
echo "Checking namespace ${OPENSHIFT_NAMESPACE}..."
|
|
# Check if namespace exists, create if not (ignore error if already exists or no permission)
|
|
if ! oc get project ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
echo "Namespace does not exist, attempting to create..."
|
|
oc new-project ${OPENSHIFT_NAMESPACE} 2>/dev/null || echo "Cannot create namespace, assuming it exists or will be created by manifest..."
|
|
else
|
|
echo "Namespace already exists"
|
|
fi
|
|
|
|
# Switch to namespace
|
|
oc project ${OPENSHIFT_NAMESPACE} || true
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "Deploying Base Resources"
|
|
echo "================================================"
|
|
|
|
# Apply namespace, RBAC, configmaps, secrets
|
|
# Skip namespace - it should already exist and TFSSERVICE user doesn't have permission to patch it
|
|
echo "Skipping namespace application (assuming it already exists)..."
|
|
|
|
echo "Applying RBAC..."
|
|
oc apply -f 01-rbac.yaml || echo "Warning: Could not apply RBAC (may require admin permissions)"
|
|
oc apply -f 02-rbac.yaml || echo "Warning: Could not apply RBAC (may require admin permissions)"
|
|
# Note: cluster-manager ClusterRole RBAC (13-cluster-manager-rbac.yaml) requires cluster-admin
|
|
# and must be applied manually. See docs for details.
|
|
|
|
echo "Applying configmaps with backup..."
|
|
|
|
# Backup directory for ConfigMaps
|
|
CONFIGMAP_BACKUP_DIR="/tmp/flowfish-configmap-backups-$(date +%s)"
|
|
mkdir -p "$CONFIGMAP_BACKUP_DIR"
|
|
|
|
echo " Backup directory: $CONFIGMAP_BACKUP_DIR"
|
|
echo ""
|
|
|
|
# Function to safely apply ConfigMap with backup and rollback
|
|
apply_configmap_safe() {
|
|
local file=$1
|
|
local cm_names=$2 # Can be comma-separated list or single name
|
|
|
|
echo "[INFO] Processing file: $file"
|
|
|
|
# Check if file exists
|
|
if [ ! -f "$file" ]; then
|
|
echo " [ERROR] File not found: $file"
|
|
return 1
|
|
fi
|
|
|
|
# Extract ConfigMap names from file if not provided
|
|
if [ -z "$cm_names" ]; then
|
|
cm_names=$(grep "^ name:" "$file" | awk '{print $2}' | tr '\n' ',' | sed 's/,$//')
|
|
fi
|
|
|
|
if [ -z "$cm_names" ]; then
|
|
echo " [WARN] No ConfigMap names found, applying file as-is..."
|
|
oc apply -f "$file" -n ${OPENSHIFT_NAMESPACE}
|
|
return $?
|
|
fi
|
|
|
|
# Backup existing ConfigMaps
|
|
echo " [INFO] ConfigMaps in file: $cm_names"
|
|
IFS=',' read -ra CM_ARRAY <<< "$cm_names"
|
|
|
|
for cm_name in "${CM_ARRAY[@]}"; do
|
|
cm_name=$(echo "$cm_name" | xargs) # Trim whitespace
|
|
if oc get configmap "$cm_name" -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
echo " [BACKUP] Backing up: $cm_name"
|
|
oc get configmap "$cm_name" -n ${OPENSHIFT_NAMESPACE} -o yaml > "$CONFIGMAP_BACKUP_DIR/${cm_name}.yaml"
|
|
else
|
|
echo " [NOTE] New ConfigMap: $cm_name (no backup needed)"
|
|
fi
|
|
done
|
|
|
|
# Apply the file
|
|
echo " [RESTART] Applying ConfigMap(s)..."
|
|
if oc apply -f "$file" -n ${OPENSHIFT_NAMESPACE}; then
|
|
echo " [OK] ConfigMap(s) applied successfully"
|
|
|
|
# Verify each ConfigMap exists
|
|
local all_verified=true
|
|
for cm_name in "${CM_ARRAY[@]}"; do
|
|
cm_name=$(echo "$cm_name" | xargs)
|
|
if oc get configmap "$cm_name" -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
echo " [OK] Verified: $cm_name"
|
|
else
|
|
echo " [ERROR] Verification failed: $cm_name"
|
|
all_verified=false
|
|
fi
|
|
done
|
|
|
|
if [ "$all_verified" = true ]; then
|
|
echo " [OK] All ConfigMaps verified"
|
|
return 0
|
|
else
|
|
echo " [WARN] Some ConfigMaps failed verification"
|
|
return 1
|
|
fi
|
|
else
|
|
echo " [ERROR] Failed to apply ConfigMap(s), restoring backups..."
|
|
|
|
# Restore backups
|
|
for cm_name in "${CM_ARRAY[@]}"; do
|
|
cm_name=$(echo "$cm_name" | xargs)
|
|
if [ -f "$CONFIGMAP_BACKUP_DIR/${cm_name}.yaml" ]; then
|
|
echo " [RESTART] Restoring: $cm_name"
|
|
oc apply -f "$CONFIGMAP_BACKUP_DIR/${cm_name}.yaml" -n ${OPENSHIFT_NAMESPACE} || echo " [ERROR] Failed to restore $cm_name"
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ==============================================================================
|
|
# ConfigMap Change Detection and Auto-Restart
|
|
# ==============================================================================
|
|
|
|
# Function to get ConfigMap data checksum (only .data field, not metadata/status)
|
|
# This avoids false positives from OpenShift-added fields
|
|
get_configmap_data_checksum() {
|
|
local configmap_name=$1
|
|
# Get only the .data field as JSON and hash it - ignores metadata, status, etc.
|
|
oc get configmap "$configmap_name" -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.data}' 2>/dev/null | md5sum | cut -d' ' -f1 || echo "none"
|
|
}
|
|
|
|
# Track which deployments need restart due to ConfigMap changes
|
|
declare -A RESTART_DEPLOYMENTS
|
|
declare -A RESTART_DAEMONSETS
|
|
|
|
# Apply main configmaps (backend-config, frontend-config)
|
|
echo "Applying main ConfigMaps (03-configmaps.yaml)..."
|
|
|
|
# Get checksums before applying (only .data field)
|
|
BACKEND_CONFIG_OLD=$(get_configmap_data_checksum "backend-config")
|
|
FRONTEND_CONFIG_OLD=$(get_configmap_data_checksum "frontend-config")
|
|
|
|
apply_configmap_safe "03-configmaps.yaml" "backend-config,frontend-config" || echo "[WARN] Warning: Some main ConfigMaps may have issues"
|
|
|
|
# Get checksums after applying (only .data field)
|
|
BACKEND_CONFIG_NEW=$(get_configmap_data_checksum "backend-config")
|
|
FRONTEND_CONFIG_NEW=$(get_configmap_data_checksum "frontend-config")
|
|
|
|
# Mark deployments for restart if ConfigMap changed
|
|
if [ "$BACKEND_CONFIG_OLD" != "$BACKEND_CONFIG_NEW" ]; then
|
|
echo " [NOTE] backend-config changed"
|
|
RESTART_DEPLOYMENTS["backend"]=1
|
|
RESTART_DEPLOYMENTS["api-gateway"]=1
|
|
RESTART_DEPLOYMENTS["analysis-orchestrator"]=1
|
|
RESTART_DEPLOYMENTS["cluster-manager"]=1
|
|
RESTART_DEPLOYMENTS["ingestion-service"]=1
|
|
RESTART_DEPLOYMENTS["timeseries-writer"]=1
|
|
RESTART_DEPLOYMENTS["graph-writer"]=1
|
|
RESTART_DEPLOYMENTS["graph-query"]=1
|
|
else
|
|
echo " [OK] backend-config unchanged"
|
|
fi
|
|
|
|
if [ "$FRONTEND_CONFIG_OLD" != "$FRONTEND_CONFIG_NEW" ]; then
|
|
echo " [NOTE] frontend-config changed"
|
|
RESTART_DEPLOYMENTS["frontend"]=1
|
|
else
|
|
echo " [OK] frontend-config unchanged"
|
|
fi
|
|
echo ""
|
|
|
|
# Apply Inspektor Gadget ConfigMap
|
|
echo "Applying Inspektor Gadget ConfigMap..."
|
|
GADGET_CONFIG_CHANGED=false
|
|
if [ -f "09-inspektor-gadget-config.yaml" ]; then
|
|
GADGET_CONFIG_OLD=$(get_configmap_data_checksum "inspektor-gadget-config")
|
|
|
|
apply_configmap_safe "09-inspektor-gadget-config.yaml" "inspektor-gadget-config" || echo "[WARN] Warning: Inspektor Gadget ConfigMap may have issues"
|
|
|
|
GADGET_CONFIG_NEW=$(get_configmap_data_checksum "inspektor-gadget-config")
|
|
|
|
if [ "$GADGET_CONFIG_OLD" != "$GADGET_CONFIG_NEW" ]; then
|
|
echo " [NOTE] inspektor-gadget-config changed"
|
|
GADGET_CONFIG_CHANGED=true
|
|
RESTART_DAEMONSETS["inspektor-gadget"]=1
|
|
else
|
|
echo " [OK] inspektor-gadget-config unchanged"
|
|
fi
|
|
else
|
|
echo "[WARN] 09-inspektor-gadget-config.yaml not found, skipping Inspektor Gadget ConfigMap"
|
|
fi
|
|
echo ""
|
|
|
|
echo "ConfigMap application complete!"
|
|
echo "Backup location: $CONFIGMAP_BACKUP_DIR"
|
|
|
|
# Show which resources will be restarted
|
|
if [ ${#RESTART_DEPLOYMENTS[@]} -gt 0 ] || [ ${#RESTART_DAEMONSETS[@]} -gt 0 ]; then
|
|
echo ""
|
|
echo "[INFO] Resources marked for restart due to ConfigMap changes:"
|
|
for dep in "${!RESTART_DEPLOYMENTS[@]}"; do
|
|
echo " - Deployment: $dep"
|
|
done
|
|
for ds in "${!RESTART_DAEMONSETS[@]}"; do
|
|
echo " - DaemonSet: $ds"
|
|
done
|
|
fi
|
|
|
|
echo "Applying secrets..."
|
|
oc apply -f 04-secrets.yaml
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "Deploying Database Services"
|
|
echo "================================================"
|
|
|
|
# Deploy PostgreSQL
|
|
echo "Deploying PostgreSQL..."
|
|
|
|
# Check if PostgreSQL is already running and healthy
|
|
if oc get statefulset/postgresql -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
READY_REPLICAS=$(oc get statefulset/postgresql -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
|
if [ "$READY_REPLICAS" -ge "1" ]; then
|
|
echo " PostgreSQL already running and healthy (ready replicas: $READY_REPLICAS), skipping deployment"
|
|
else
|
|
echo " PostgreSQL exists but not ready, re-deploying..."
|
|
oc apply -f 05-postgresql.yaml
|
|
oc rollout status statefulset/postgresql -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
else
|
|
echo " PostgreSQL not found, deploying..."
|
|
oc apply -f 05-postgresql.yaml
|
|
sleep 5
|
|
oc rollout status statefulset/postgresql -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
|
|
# Only run init job on first deployment
|
|
echo " Running PostgreSQL init job..."
|
|
oc delete job postgres-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 05-postgresql.yaml # This includes the init job
|
|
fi
|
|
|
|
# Deploy Redis
|
|
echo "Deploying Redis..."
|
|
|
|
# Check if Redis is already running and healthy
|
|
if oc get statefulset/redis -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
READY_REPLICAS=$(oc get statefulset/redis -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
|
if [ "$READY_REPLICAS" -ge "1" ]; then
|
|
echo " Redis already running and healthy (ready replicas: $READY_REPLICAS), skipping deployment"
|
|
else
|
|
echo " Redis exists but not ready, re-deploying..."
|
|
oc apply -f 06-redis.yaml
|
|
oc rollout status statefulset/redis -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
else
|
|
echo " Redis not found, deploying..."
|
|
oc apply -f 06-redis.yaml
|
|
sleep 5
|
|
oc rollout status statefulset/redis -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
|
|
# Deploy RabbitMQ
|
|
echo "Deploying RabbitMQ..."
|
|
|
|
# Check if RabbitMQ is already running and healthy
|
|
if oc get statefulset/rabbitmq -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
READY_REPLICAS=$(oc get statefulset/rabbitmq -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
|
if [ "$READY_REPLICAS" -ge "1" ]; then
|
|
echo " RabbitMQ already running and healthy (ready replicas: $READY_REPLICAS), skipping deployment"
|
|
else
|
|
echo " RabbitMQ exists but not ready, re-deploying..."
|
|
oc delete job rabbitmq-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 06-rabbitmq.yaml
|
|
oc rollout status statefulset/rabbitmq -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
else
|
|
echo " RabbitMQ not found, deploying..."
|
|
oc delete job rabbitmq-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 06-rabbitmq.yaml
|
|
sleep 5
|
|
oc rollout status statefulset/rabbitmq -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
|
|
# Deploy Neo4j
|
|
echo "Deploying Neo4j Graph Database..."
|
|
# NOTE: Neo4j requires anyuid SCC. Grant manually if not already done:
|
|
# oc adm policy add-scc-to-user anyuid -z flowfish-neo4j -n ${OPENSHIFT_NAMESPACE}
|
|
|
|
# Check if Neo4j is already running and healthy
|
|
if oc get statefulset/neo4j -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
READY_REPLICAS=$(oc get statefulset/neo4j -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
|
if [ "$READY_REPLICAS" -ge "1" ]; then
|
|
echo " Neo4j already running and healthy (ready replicas: $READY_REPLICAS), skipping deployment"
|
|
|
|
# Check if schema is already initialized by querying Neo4j directly
|
|
echo " Checking if Neo4j schema is already initialized..."
|
|
NEO4J_PASSWORD=$(oc get secret flowfish-secrets -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.data.NEO4J_PASSWORD}' | base64 -d)
|
|
# Use head -1 to ensure single integer value, tr to remove newlines
|
|
SCHEMA_CHECK=$(oc exec neo4j-0 -n ${OPENSHIFT_NAMESPACE} -- cypher-shell -u neo4j -p "$NEO4J_PASSWORD" "SHOW CONSTRAINTS" 2>/dev/null | grep -E "workload_id|namespace_name|cluster_name" | wc -l | tr -d ' \n' || echo "0")
|
|
SCHEMA_CHECK=${SCHEMA_CHECK:-0}
|
|
|
|
if [ "$SCHEMA_CHECK" -ge "1" ] 2>/dev/null; then
|
|
echo " Neo4j schema already initialized (constraints exist), skipping init job"
|
|
else
|
|
echo " Neo4j schema not initialized, running init job..."
|
|
oc delete job neo4j-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
sleep 2
|
|
oc apply -f 08-neo4j-init.yaml
|
|
oc wait --for=condition=complete job/neo4j-init -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
else
|
|
echo " Neo4j exists but not ready, re-deploying..."
|
|
oc apply -f 07-neo4j.yaml
|
|
oc rollout status statefulset/neo4j -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
|
|
echo " Running Neo4j init job..."
|
|
oc delete job neo4j-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 08-neo4j-init.yaml
|
|
oc wait --for=condition=complete job/neo4j-init -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
else
|
|
echo " Neo4j not found, deploying..."
|
|
oc apply -f 07-neo4j.yaml
|
|
sleep 5
|
|
oc rollout status statefulset/neo4j -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
|
|
echo " Running Neo4j init job..."
|
|
oc delete job neo4j-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 08-neo4j-init.yaml
|
|
oc wait --for=condition=complete job/neo4j-init -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
fi
|
|
echo "Neo4j deployment complete!"
|
|
|
|
# Deploy ClickHouse
|
|
echo "Deploying ClickHouse..."
|
|
# NOTE: ClickHouse requires anyuid SCC. Grant manually if not already done:
|
|
# oc adm policy add-scc-to-user anyuid -z flowfish-clickhouse -n ${OPENSHIFT_NAMESPACE}
|
|
|
|
# Check if ClickHouse is already running and healthy
|
|
if oc get statefulset/clickhouse -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
READY_REPLICAS=$(oc get statefulset/clickhouse -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
|
if [ "$READY_REPLICAS" -ge "1" ]; then
|
|
echo " ClickHouse already running and healthy (ready replicas: $READY_REPLICAS), skipping deployment"
|
|
|
|
# Check if schema is already initialized by querying ClickHouse directly
|
|
echo " Checking if ClickHouse schema is already initialized..."
|
|
CLICKHOUSE_PASSWORD=$(oc get secret database-credentials -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.data.clickhouse-password}' | base64 -d)
|
|
SCHEMA_CHECK=$(oc exec clickhouse-0 -n ${OPENSHIFT_NAMESPACE} -- clickhouse-client --user flowfish --password "$CLICKHOUSE_PASSWORD" --query "SHOW DATABASES" 2>/dev/null | grep -c "flowfish" || echo "0")
|
|
|
|
if [ "$SCHEMA_CHECK" -ge "1" ]; then
|
|
echo " ClickHouse schema already initialized (database 'flowfish' exists), skipping init job"
|
|
else
|
|
echo " ClickHouse schema not initialized, running init job..."
|
|
oc delete job clickhouse-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
sleep 2
|
|
oc apply -f 08-clickhouse.yaml # This includes the init job
|
|
oc wait --for=condition=complete job/clickhouse-init -n ${OPENSHIFT_NAMESPACE} --timeout=3m || true
|
|
fi
|
|
else
|
|
echo " ClickHouse exists but not ready, re-deploying..."
|
|
oc delete job clickhouse-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 08-clickhouse.yaml
|
|
oc rollout status statefulset/clickhouse -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
oc wait --for=condition=complete job/clickhouse-init -n ${OPENSHIFT_NAMESPACE} --timeout=3m || true
|
|
fi
|
|
else
|
|
echo " ClickHouse not found, deploying..."
|
|
oc delete job clickhouse-init -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
oc apply -f 08-clickhouse.yaml
|
|
sleep 5
|
|
oc rollout status statefulset/clickhouse -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
oc wait --for=condition=complete job/clickhouse-init -n ${OPENSHIFT_NAMESPACE} --timeout=3m || true
|
|
fi
|
|
echo "ClickHouse deployment complete!"
|
|
|
|
# Run database migrations
|
|
echo "Running database migrations..."
|
|
|
|
# ALWAYS delete and recreate migration job to ensure new migrations run
|
|
# Migration scripts use "CREATE TABLE IF NOT EXISTS" and "ON CONFLICT DO NOTHING"
|
|
# so they are idempotent and safe to run multiple times
|
|
echo " Deleting any existing migration job..."
|
|
oc delete job flowfish-migrations -n ${OPENSHIFT_NAMESPACE} --ignore-not-found=true
|
|
sleep 2
|
|
|
|
echo " Creating and running migration job..."
|
|
oc apply -f 03-migrations-job.yaml
|
|
sleep 5
|
|
|
|
echo " Waiting for migration job to complete..."
|
|
if oc wait --for=condition=complete job/flowfish-migrations -n ${OPENSHIFT_NAMESPACE} --timeout=10m; then
|
|
echo " [OK] Database migrations completed successfully"
|
|
|
|
# Show migration logs
|
|
echo " Migration logs:"
|
|
oc logs job/flowfish-migrations -c postgres-migrations -n ${OPENSHIFT_NAMESPACE} --tail=20 || true
|
|
else
|
|
echo " [WARN] Migration job may have issues, checking logs..."
|
|
oc logs job/flowfish-migrations -c postgres-migrations -n ${OPENSHIFT_NAMESPACE} --tail=50 || true
|
|
fi
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "Deploying Inspektor Gadget (eBPF Observability)"
|
|
echo "================================================"
|
|
|
|
# NOTE: Cluster-scoped resources (CRDs, ClusterRoles) are NOT applied by pipeline
|
|
# They must be applied manually by cluster admin before first deployment
|
|
# See: deployment/manual-rbac/README.md
|
|
|
|
echo "[INFO] Skipping cluster-scoped resources (applied manually by cluster admin):"
|
|
echo " - CRDs (09-inspektor-gadget-crds.yaml)"
|
|
echo " - ClusterRole/ClusterRoleBinding (10-inspektor-gadget-rbac-cluster.yaml)"
|
|
echo " - ClusterRole/ClusterRoleBinding (flowfish-gadget-reader)"
|
|
|
|
# 3. Always apply DaemonSet manifest (to pick up any updates)
|
|
echo "Applying Inspektor Gadget DaemonSet..."
|
|
|
|
# Get current image before update
|
|
CURRENT_IMAGE=""
|
|
if oc get daemonset inspektor-gadget -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
CURRENT_IMAGE=$(oc get daemonset inspektor-gadget -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.spec.template.spec.containers[0].image}' 2>/dev/null || echo "none")
|
|
echo " Current image: $CURRENT_IMAGE"
|
|
fi
|
|
|
|
# Apply the manifest (this will update if changed)
|
|
oc apply -f 10-inspektor-gadget.yaml
|
|
|
|
# Get new image after update
|
|
NEW_IMAGE=$(oc get daemonset inspektor-gadget -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.spec.template.spec.containers[0].image}' 2>/dev/null || echo "none")
|
|
echo " Target image: $NEW_IMAGE"
|
|
|
|
# Check if image changed or ConfigMap changed
|
|
if [ "$CURRENT_IMAGE" != "$NEW_IMAGE" ] || [ -z "$CURRENT_IMAGE" ]; then
|
|
echo " [RESTART] Image changed, waiting for rollout..."
|
|
oc rollout status daemonset/inspektor-gadget -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
elif [ "${RESTART_DAEMONSETS[inspektor-gadget]:-0}" = "1" ]; then
|
|
echo " [RESTART] ConfigMap changed, restarting DaemonSet to pick up new config..."
|
|
oc rollout restart daemonset/inspektor-gadget -n ${OPENSHIFT_NAMESPACE}
|
|
oc rollout status daemonset/inspektor-gadget -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
else
|
|
echo " [OK] Image and ConfigMap unchanged, checking pod health..."
|
|
|
|
DESIRED=$(oc get daemonset inspektor-gadget -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.desiredNumberScheduled}')
|
|
READY=$(oc get daemonset inspektor-gadget -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.numberReady}')
|
|
|
|
if [ "$READY" = "$DESIRED" ] && [ "$READY" != "0" ]; then
|
|
echo " [OK] All $READY/$DESIRED pods ready"
|
|
else
|
|
echo " [WARN] Only $READY/$DESIRED pods ready, waiting..."
|
|
oc rollout status daemonset/inspektor-gadget -n ${OPENSHIFT_NAMESPACE} --timeout=3m || true
|
|
fi
|
|
fi
|
|
|
|
echo " Inspektor Gadget pods:"
|
|
oc get pods -n ${OPENSHIFT_NAMESPACE} -l app=inspektor-gadget -o wide
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "Beyla eBPF L7 Agent"
|
|
echo "================================================"
|
|
echo " [INFO] Initial Beyla install is done per-cluster via the UI agent script."
|
|
echo " [INFO] Once installed, the pipeline keeps its ConfigMap and DaemonSet up to date."
|
|
|
|
if oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} &>/dev/null; then
|
|
DESIRED=$(oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.desiredNumberScheduled}' 2>/dev/null || echo "0")
|
|
READY=$(oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.numberReady}' 2>/dev/null || echo "0")
|
|
BEYLA_IMG=$(oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.spec.template.spec.containers[0].image}' 2>/dev/null || echo "unknown")
|
|
echo " [OK] Beyla DaemonSet found: $READY/$DESIRED ready, image: $BEYLA_IMG"
|
|
|
|
BEYLA_NEEDS_RESTART=false
|
|
|
|
# --- ConfigMap change detection ---
|
|
if [ -f "20-beyla.yaml" ]; then
|
|
BEYLA_CONFIG_OLD=$(get_configmap_data_checksum "beyla-config")
|
|
|
|
echo " [INFO] Applying Beyla manifest (ConfigMap + DaemonSet)..."
|
|
# Apply the full manifest; SCC/ClusterRole may fail on non-admin — that's fine
|
|
oc apply -f 20-beyla.yaml -n ${OPENSHIFT_NAMESPACE} 2>&1 | while read -r line; do
|
|
case "$line" in
|
|
*"forbidden"*|*"Forbidden"*|*"cluster-scoped"*) echo " [SKIP] $line" ;;
|
|
*) echo " $line" ;;
|
|
esac
|
|
done
|
|
|
|
BEYLA_CONFIG_NEW=$(get_configmap_data_checksum "beyla-config")
|
|
if [ "$BEYLA_CONFIG_OLD" != "$BEYLA_CONFIG_NEW" ]; then
|
|
echo " [NOTE] beyla-config ConfigMap changed — DaemonSet restart required"
|
|
BEYLA_NEEDS_RESTART=true
|
|
else
|
|
echo " [OK] beyla-config ConfigMap unchanged"
|
|
fi
|
|
|
|
# Check if DaemonSet pod template changed (env vars, resources, image)
|
|
NEW_DS_GEN=$(oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.metadata.generation}' 2>/dev/null || echo "0")
|
|
OBSERVED_GEN=$(oc get daemonset beyla -n ${OPENSHIFT_NAMESPACE} -o jsonpath='{.status.observedGeneration}' 2>/dev/null || echo "0")
|
|
if [ "$NEW_DS_GEN" != "$OBSERVED_GEN" ]; then
|
|
echo " [NOTE] Beyla DaemonSet spec changed (generation $OBSERVED_GEN -> $NEW_DS_GEN)"
|
|
BEYLA_NEEDS_RESTART=true
|
|
fi
|
|
fi
|
|
|
|
# --- Perform restart if needed ---
|
|
if [ "$BEYLA_NEEDS_RESTART" = "true" ]; then
|
|
echo " [RESTART] Rolling restart of Beyla DaemonSet..."
|
|
oc rollout restart daemonset/beyla -n ${OPENSHIFT_NAMESPACE}
|
|
oc rollout status daemonset/beyla -n ${OPENSHIFT_NAMESPACE} --timeout=5m || true
|
|
else
|
|
echo " [OK] No changes detected, Beyla pods kept as-is"
|
|
fi
|
|
|
|
echo " Beyla pods after pipeline:"
|
|
oc get pods -n ${OPENSHIFT_NAMESPACE} -l app=beyla -o wide 2>/dev/null || true
|
|
else
|
|
echo " [INFO] No Beyla DaemonSet in ${OPENSHIFT_NAMESPACE} (install via UI when needed)"
|
|
fi
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "Infrastructure deployment complete"
|
|
echo "================================================"
|
|
|
|
# Show infrastructure status
|
|
echo "Infrastructure Pods:"
|
|
oc get pods -n ${OPENSHIFT_NAMESPACE} -l tier=infrastructure
|
|
|
|
echo ""
|
|
echo "Infrastructure Services:"
|
|
oc get svc -n ${OPENSHIFT_NAMESPACE} -l tier=infrastructure
|
|
|
|
echo ""
|
|
echo "Inspektor Gadget DaemonSet:"
|
|
oc get daemonset -n ${OPENSHIFT_NAMESPACE} inspektor-gadget || echo " Inspektor Gadget not found"
|
|
|
|
echo ""
|
|
echo "Inspektor Gadget Pods:"
|
|
oc get pods -n ${OPENSHIFT_NAMESPACE} -l app=inspektor-gadget || echo " No Inspektor Gadget pods found"
|
|
|
|
echo ""
|
|
echo "Beyla DaemonSet:"
|
|
oc get daemonset -n ${OPENSHIFT_NAMESPACE} beyla 2>/dev/null || echo " Beyla not found"
|
|
|
|
echo ""
|
|
echo "Beyla Pods:"
|
|
oc get pods -n ${OPENSHIFT_NAMESPACE} -l app=beyla 2>/dev/null || echo " No Beyla pods found"
|
|
|
|
echo "================================================"
|
|
|