From d07cf7e470ac8be83cf5ca62adca0ce7d695112c Mon Sep 17 00:00:00 2001 From: Shahar Glazner Date: Sat, 16 Nov 2024 18:57:31 +0200 Subject: [PATCH] feat: adding haproxy support (#75) * feat: add haproxy support * feat: haproxy * feat: haproxy * feat: add tests for proxies * feat: add tests for proxies * feat: add tests for proxies * feat: add tests for proxies * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: tests * feat: test * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip * feat: wip --- .github/workflows/test-haproxy-ingress.yml | 237 ++++++++++++++++++ .github/workflows/test-nginx-ingress.yml | 228 +++++++++++++++++ charts/keep/Chart.yaml | 4 +- charts/keep/templates/ingress-haproxy.yaml | 105 ++++++++ .../{ingress.yaml => ingress-nginx.yaml} | 2 +- charts/keep/values.yaml | 1 + local_test_haproxy.sh | 139 ++++++++++ local_test_nginx.sh | 131 ++++++++++ 8 files changed, 844 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/test-haproxy-ingress.yml create mode 100644 .github/workflows/test-nginx-ingress.yml create mode 100644 charts/keep/templates/ingress-haproxy.yaml rename charts/keep/templates/{ingress.yaml => ingress-nginx.yaml} (97%) create mode 100644 local_test_haproxy.sh create mode 100644 local_test_nginx.sh diff --git a/.github/workflows/test-haproxy-ingress.yml b/.github/workflows/test-haproxy-ingress.yml new file mode 100644 index 0000000..c0675e3 --- /dev/null +++ b/.github/workflows/test-haproxy-ingress.yml @@ -0,0 +1,237 @@ +name: Test HAProxy Ingress + +on: + pull_request: + branches: + - main + workflow_dispatch: + inputs: + debug_enabled: + description: 'Run workflow with debug logging' + required: false + default: true + type: boolean + +jobs: + test-haproxy-ingress: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v3 + with: + version: v3.10.3 + + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install test dependencies + run: | + npm install -g wscat + sudo apt-get update && sudo apt-get install -y curl + + - name: Create kind config + run: | + cat <<-EOF > kind-config.yaml + kind: Cluster + apiVersion: kind.x-k8s.io/v1alpha4 + nodes: + - role: control-plane + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + EOF + + - name: Create kind cluster + uses: helm/kind-action@v1.9.0 + with: + wait: 600s + config: kind-config.yaml + + - name: Install HAProxy Ingress Controller + run: | + helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts + helm repo update + helm install haproxy haproxy-ingress/haproxy-ingress \ + --set controller.service.type=NodePort \ + --set controller.kind=DaemonSet \ + --set controller.daemonset.useHostPort=true \ + --set controller.service.ports.http=80 \ + --set controller.service.ports.https=443 \ + --set controller.service.ports.stat=30024 + + - name: Wait for HAProxy Ingress + run: | + echo "Waiting for HAProxy Ingress pods..." + kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/name=haproxy-ingress \ + --timeout=120s + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.1 + + - name: Create test values for haproxy + run: | + mkdir -p debug + cat < debug/haproxy-values.yaml + global: + ingress: + enabled: true + className: haproxy + classType: haproxy + websocketPrefix: /websocket + backendPrefix: /v2 + frontendPrefix: / + frontend: + enabled: true + backend: + enabled: true + websocket: + enabled: true + EOF + + - name: Debug - Show test values + if: ${{ inputs.debug_enabled }} + run: cat debug/haproxy-values.yaml + + - name: Install Keep chart + run: | + helm install keep ./charts/keep -f debug/haproxy-values.yaml + + - name: Wait for all pods + run: | + echo "Waiting for all pods to be ready..." + kubectl wait --for=condition=ready pod --all -n default --timeout=180s + + echo "Checking pod status..." + kubectl get pods -n default + + echo "Checking ingress status..." + kubectl get ingress -n default + + echo "Waiting additional 30s for services to stabilize..." + sleep 30 + + - name: Verify services and endpoints + run: | + echo "Service Status:" + kubectl get svc -n default + + echo "Endpoint Status:" + kubectl get endpoints -n default + + echo "Ingress Details:" + kubectl describe ingress -n default + + - name: Test HAProxy Ingress endpoints + run: | + INGRESS_IP="127.0.0.1" + APP_NAME=$(helm list -n default -o json | jq -r '.[0].name') + MAX_RETRIES=5 + RETRY_DELAY=10 + + test_endpoint() { + local url=$1 + local expected_code=$2 + local headers=${3:-""} + + for ((i=1; i<=MAX_RETRIES; i++)); do + echo "Attempt $i of $MAX_RETRIES for $url" + echo "Headers being sent: $headers" + + if [ -n "$headers" ]; then + echo "Full curl command: curl -v $headers \"$url\"" + RESP=$(curl -v $headers "$url" 2>&1) + else + echo "Full curl command: curl -v \"$url\"" + RESP=$(curl -v "$url" 2>&1) + fi + + # Extract response code, handling connection failures + RESP_CODE=$(echo "$RESP" | grep "< HTTP" | awk '{print $3}') + if [ -z "$RESP_CODE" ]; then + echo "โš ๏ธ No response code received - connection may have failed" + echo -e "\n๐Ÿ” Response Details:" + echo "------------------------" + echo "Response code: Connection failed" + echo -e "\n๐Ÿ“‹ Response Headers:" + echo "$RESP" | grep -E "^< " || echo "No headers found" + echo -e "\n๐Ÿ“ Response Body:" + echo "$RESP" | sed -n '/^* Connected/,/^* Connection/!p' | grep -v "^[*<>]" || echo "No body found" + echo "------------------------" + + if [ "$i" -lt "$MAX_RETRIES" ]; then + echo "โณ Waiting ${RETRY_DELAY}s before next attempt..." + sleep "$RETRY_DELAY" + continue + fi + echo "โŒ Failed to establish connection after $MAX_RETRIES attempts" + return 1 + fi + + echo -e "\n๐Ÿ” Response Details:" + echo "------------------------" + echo "Response code: $RESP_CODE" + echo -e "\n๐Ÿ“‹ Response Headers:" + echo "$RESP" | grep -E "^< " || echo "No headers found" + echo -e "\n๐Ÿ“ Response Body:" + echo "$RESP" | sed -n '/^* Connected/,/^* Connection/!p' | grep -v "^[*<>]" || echo "No body found" + echo "------------------------" + + if [ "$RESP_CODE" -eq "$expected_code" ]; then + echo "โœ… Expected response code $expected_code received" + return 0 + fi + + if [ "$i" -lt "$MAX_RETRIES" ]; then + echo "โณ Waiting ${RETRY_DELAY}s before next attempt..." + sleep "$RETRY_DELAY" + fi + done + echo "โŒ Failed to get expected response code $expected_code after $MAX_RETRIES attempts" + return 1 + } + + echo "๐ŸŒ Testing frontend endpoint..." + test_endpoint "http://$INGRESS_IP/" 307 || exit 1 + + echo "๐Ÿ”Œ Testing backend endpoint..." + test_endpoint "http://$INGRESS_IP/v2/docs" 200 || exit 1 + + echo "๐Ÿ”„ Testing websocket endpoint..." + # should return "OK" + test_endpoint "http://$INGRESS_IP/websocket/" 200 || exit 1 + + - name: Debug - Show logs on failure + if: ${{ failure() }} + run: | + echo "HAProxy Ingress Controller logs:" + kubectl logs -l app.kubernetes.io/instance=haproxy-ingress -n default --tail=100 + + echo "All pods status:" + kubectl get pods -n default -o wide + + echo "Application pods logs:" + for pod in $(kubectl get pods -n default -o name); do + echo "Logs for $pod:" + kubectl logs $pod -n default --tail=100 || true + done + + echo "Ingress configuration:" + kubectl get ingress -n default -o yaml + + echo "Endpoints:" + kubectl get endpoints -n default + + echo "Services:" + kubectl get svc -n default \ No newline at end of file diff --git a/.github/workflows/test-nginx-ingress.yml b/.github/workflows/test-nginx-ingress.yml new file mode 100644 index 0000000..fd8c62d --- /dev/null +++ b/.github/workflows/test-nginx-ingress.yml @@ -0,0 +1,228 @@ +name: Test Nginx Ingress + +on: + pull_request: + branches: + - main + workflow_dispatch: + inputs: + debug_enabled: + description: 'Run workflow with debug logging' + required: false + default: true + type: boolean + +jobs: + test-nginx-ingress: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v3 + with: + version: v3.10.3 + + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install test dependencies + run: | + npm install -g wscat + sudo apt-get update && sudo apt-get install -y curl + + - name: Create kind config + run: | + cat <<-EOF > kind-config.yaml + kind: Cluster + apiVersion: kind.x-k8s.io/v1alpha4 + nodes: + - role: control-plane + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + EOF + + - name: Debug kind config + if: ${{ inputs.debug_enabled }} + run: cat kind-config.yaml + + - name: Create kind cluster + uses: helm/kind-action@v1.9.0 + with: + wait: 600s + config: kind-config.yaml + + - name: Install Nginx Ingress Controller + run: | + helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx + helm repo update + helm install nginx-ingress ingress-nginx/ingress-nginx \ + --set controller.service.type=NodePort \ + --set controller.watchIngressWithoutClass=true \ + --set controller.allowSnippetAnnotations=true \ + --set controller.config.allow-snippets=true \ + --set controller.config.enable-snippets=true \ + --set controller.hostPort.enabled=true \ + --set controller.service.ports.http=80 \ + --set controller.service.ports.https=443 \ + --set controller.nodeSelector."kubernetes\.io/os"=linux \ + --set controller.admissionWebhooks.enabled=false + + - name: Wait for Nginx Ingress + run: | + echo "Waiting for Nginx Ingress pods..." + kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/instance=nginx-ingress \ + --timeout=90s + + - name: Create test values for nginx + run: | + mkdir -p debug + cat < debug/nginx-values.yaml + global: + ingress: + enabled: true + className: nginx + classType: nginx + websocketPrefix: /websocket + backendPrefix: /v2 + frontendPrefix: / + frontend: + enabled: true + backend: + enabled: true + websocket: + enabled: true + EOF + + - name: Debug - Show test values + if: ${{ inputs.debug_enabled }} + run: cat debug/nginx-values.yaml + + - name: Install Keep chart + run: | + helm install keep ./charts/keep -f debug/nginx-values.yaml + + - name: Wait for all pods + run: | + echo "Waiting for all pods to be ready..." + kubectl wait --for=condition=ready pod --all -n default --timeout=180s + + echo "Checking pod status..." + kubectl get pods -n default + + echo "Checking ingress status..." + kubectl get ingress -n default + + echo "Waiting additional 30s for services to stabilize..." + sleep 30 + + - name: Debug - Show resources + if: ${{ inputs.debug_enabled }} + run: | + echo "๐Ÿ” Checking all resources..." + kubectl get pods -A + kubectl get svc -A + kubectl get ingress -A + kubectl describe ingress -A + + - name: Test endpoints + run: | + INGRESS_IP="127.0.0.1" + APP_NAME=$(helm list -n default -o json | jq -r '.[0].name') + MAX_RETRIES=5 + RETRY_DELAY=10 + + test_endpoint() { + local url=$1 + local expected_code=$2 + local headers=${3:-""} + + for ((i=1; i<=MAX_RETRIES; i++)); do + echo "Attempt $i of $MAX_RETRIES for $url" + echo "Headers being sent: $headers" + + if [ -n "$headers" ]; then + echo "Full curl command: curl -v $headers \"$url\"" + RESP=$(curl -v $headers "$url" 2>&1) + else + echo "Full curl command: curl -v \"$url\"" + RESP=$(curl -v "$url" 2>&1) + fi + + # Extract response code, handling connection failures + RESP_CODE=$(echo "$RESP" | grep "< HTTP" | awk '{print $3}') + if [ -z "$RESP_CODE" ]; then + echo "โš ๏ธ No response code received - connection may have failed" + echo -e "\n๐Ÿ” Response Details:" + echo "------------------------" + echo "Response code: Connection failed" + echo -e "\n๐Ÿ“‹ Response Headers:" + echo "$RESP" | grep -E "^< " || echo "No headers found" + echo -e "\n๐Ÿ“ Response Body:" + echo "$RESP" | sed -n '/^* Connected/,/^* Connection/!p' | grep -v "^[*<>]" || echo "No body found" + echo "------------------------" + + if [ "$i" -lt "$MAX_RETRIES" ]; then + echo "โณ Waiting ${RETRY_DELAY}s before next attempt..." + sleep "$RETRY_DELAY" + continue + fi + echo "โŒ Failed to establish connection after $MAX_RETRIES attempts" + return 1 + fi + + echo -e "\n๐Ÿ” Response Details:" + echo "------------------------" + echo "Response code: $RESP_CODE" + echo -e "\n๐Ÿ“‹ Response Headers:" + echo "$RESP" | grep -E "^< " || echo "No headers found" + echo -e "\n๐Ÿ“ Response Body:" + echo "$RESP" | sed -n '/^* Connected/,/^* Connection/!p' | grep -v "^[*<>]" || echo "No body found" + echo "------------------------" + + if [ "$RESP_CODE" -eq "$expected_code" ]; then + echo "โœ… Expected response code $expected_code received" + return 0 + fi + + if [ "$i" -lt "$MAX_RETRIES" ]; then + echo "โณ Waiting ${RETRY_DELAY}s before next attempt..." + sleep "$RETRY_DELAY" + fi + done + echo "โŒ Failed to get expected response code $expected_code after $MAX_RETRIES attempts" + return 1 + } + + echo "๐ŸŒ Testing frontend endpoint..." + test_endpoint "http://$INGRESS_IP/" 307 || exit 1 + + echo "๐Ÿ”Œ Testing backend endpoint..." + test_endpoint "http://$INGRESS_IP/v2/docs" 200 || exit 1 + + echo "๐Ÿ”„ Testing websocket endpoint..." + # should return "OK" + test_endpoint "http://$INGRESS_IP/websocket/" 200 || exit 1 + + - name: Debug - Show logs on failure + if: ${{ failure() && inputs.debug_enabled }} + run: | + echo "๐Ÿ“œ Nginx Ingress Controller logs:" + kubectl logs -l app.kubernetes.io/instance=nginx-ingress --tail=100 + + echo "Application pods logs:" + for pod in $(kubectl get pods -n default -l app.kubernetes.io/instance=keep -o name); do + echo "Logs for $pod:" + kubectl logs $pod --tail=100 + done \ No newline at end of file diff --git a/charts/keep/Chart.yaml b/charts/keep/Chart.yaml index 22cf3b7..3252d0e 100644 --- a/charts/keep/Chart.yaml +++ b/charts/keep/Chart.yaml @@ -1,10 +1,10 @@ apiVersion: v2 name: keep -version: 0.1.39 +version: 0.1.40 description: Keep Helm Chart type: application icon: https://platform.keephq.dev/_next/image?url=%2Fkeep.png&w=48&q=75 -appVersion: 0.28.9 +appVersion: 0.29.0 deprecated: false annotations: app: keep diff --git a/charts/keep/templates/ingress-haproxy.yaml b/charts/keep/templates/ingress-haproxy.yaml new file mode 100644 index 0000000..366946e --- /dev/null +++ b/charts/keep/templates/ingress-haproxy.yaml @@ -0,0 +1,105 @@ +{{- if and .Values.global.ingress.enabled (or (eq .Values.global.ingress.className "haproxy") (eq .Values.global.ingress.classType "haproxy")) }} +{{- $fullName := include "keep.fullname" . }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }}-ingress + labels: + {{- include "keep.labels" . | nindent 4 }} + annotations: + kubernetes.io/ingress.class: "haproxy" + # HAProxy timeout configurations + haproxy-ingress.github.io/timeout-client: "3600s" + haproxy-ingress.github.io/timeout-server: "3600s" + haproxy-ingress.github.io/timeout-connect: "3600s" + haproxy-ingress.github.io/timeout-tunnel: "3600s" + + # WebSocket support + haproxy-ingress.github.io/config-backend: | + timeout tunnel 3600s + option http-keep-alive + http-reuse safe + + haproxy-ingress.github.io/ssl-redirect: "false" + + # Backend configurations for path rewrites + haproxy-ingress.github.io/config-backend: | + acl path_v2 path_beg {{ .Values.global.ingress.backendPrefix }}/ + acl path_ws path_beg {{ .Values.global.ingress.websocketPrefix }}/ + http-request set-path %[path,regsub(^{{ .Values.global.ingress.backendPrefix }}/,/)] if path_v2 + http-request set-path %[path,regsub(^{{ .Values.global.ingress.websocketPrefix }}/,/)] if path_ws + +spec: + ingressClassName: haproxy + {{- if .Values.global.ingress.tls }} + tls: + {{- range .Values.global.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- if .Values.global.ingress.hosts }} + {{- range .Values.global.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- if $.Values.websocket.enabled }} + - path: {{ $.Values.global.ingress.websocketPrefix }} + pathType: Prefix + backend: + service: + name: {{ $fullName }}-websocket + port: + number: {{ $.Values.websocket.service.port }} + {{- end }} + {{- if $.Values.backend.enabled }} + - path: {{ $.Values.global.ingress.backendPrefix }} + pathType: Prefix + backend: + service: + name: {{ $fullName }}-backend + port: + number: {{ $.Values.backend.service.port }} + {{- end }} + - path: "/" + pathType: Prefix + backend: + service: + name: {{ $fullName }}-frontend + port: + number: {{ $.Values.frontend.service.port }} + {{- end }} + {{- else }} + - http: + paths: + {{- if $.Values.websocket.enabled }} + - path: {{ $.Values.global.ingress.websocketPrefix }} + pathType: Prefix + backend: + service: + name: {{ $fullName }}-websocket + port: + number: {{ $.Values.websocket.service.port }} + {{- end }} + {{- if $.Values.backend.enabled }} + - path: {{ $.Values.global.ingress.backendPrefix }} + pathType: Prefix + backend: + service: + name: {{ $fullName }}-backend + port: + number: {{ $.Values.backend.service.port }} + {{- end }} + - path: "/" + pathType: Prefix + backend: + service: + name: {{ $fullName }}-frontend + port: + number: {{ $.Values.frontend.service.port }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/keep/templates/ingress.yaml b/charts/keep/templates/ingress-nginx.yaml similarity index 97% rename from charts/keep/templates/ingress.yaml rename to charts/keep/templates/ingress-nginx.yaml index 786772d..4f340d0 100644 --- a/charts/keep/templates/ingress.yaml +++ b/charts/keep/templates/ingress-nginx.yaml @@ -1,4 +1,4 @@ -{{- if .Values.global.ingress.enabled }} +{{- if and .Values.global.ingress.enabled (or (eq .Values.global.ingress.className "nginx") (eq .Values.global.ingress.classType "nginx")) }} {{- $fullName := include "keep.fullname" . }} apiVersion: networking.k8s.io/v1 kind: Ingress diff --git a/charts/keep/values.yaml b/charts/keep/values.yaml index 26e5e75..ad70f0c 100644 --- a/charts/keep/values.yaml +++ b/charts/keep/values.yaml @@ -11,6 +11,7 @@ global: # this section controls the ingress resource at nginx-ingress.yaml ingress: enabled: true + # Keep supports both nginx and haproxy ingress controllers className: "nginx" # this is for cases where you want nginx configuration but the nginx className is different. classType: "" diff --git a/local_test_haproxy.sh b/local_test_haproxy.sh new file mode 100644 index 0000000..7d3daf7 --- /dev/null +++ b/local_test_haproxy.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +# Create a debug folder and values file +mkdir -p debug +cat < debug/haproxy-values.yaml +global: + ingress: + enabled: true + className: haproxy + annotations: + ingress.class: haproxy + websocketPrefix: /websocket + backendPrefix: /v2/docs + frontendPrefix: / +frontend: + enabled: true +backend: + enabled: true +websocket: + enabled: true +EOF + +# Create Kind cluster with ingress ports exposed +cat < debug/kind-config.yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + - containerPort: 30024 + hostPort: 30024 + protocol: TCP +EOF + +# Function to check service/pod status +check_status() { + echo "๐Ÿ” Checking all resources..." + kubectl get pods -A + kubectl get svc -A + kubectl get ingress -A +} + +# Create cluster +kind create cluster --config debug/kind-config.yaml + +# Add and update HAProxy helm repo +echo "๐Ÿ“ฆ Adding HAProxy helm repo..." +helm repo add haproxytech https://haproxy-ingress.github.io/charts +helm repo update + +# Install HAProxy Ingress Controller +echo "๐Ÿ”ง Installing HAProxy Ingress Controller..." +helm install haproxy haproxy-ingress/haproxy-ingress \ + --set controller.service.type=NodePort \ + --set controller.kind=DaemonSet \ + --set controller.daemonset.useHostPort=true \ + --set controller.service.ports.http=80 \ + --set controller.service.ports.https=443 \ + --set controller.service.ports.stat=30024 + +# Wait for HAProxy ingress controller +echo "โณ Waiting for HAProxy ingress controller..." +kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/instance=haproxy \ + --timeout=90s + +# Install your chart +echo "๐Ÿ“Š Installing Keep chart..." +helm install keep ./charts/keep -f debug/haproxy-values.yaml + +# Wait for backend pod (the last one to be ready) +echo "โณ Waiting for Keep backend to be ready..." +kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/instance=keep,keep-component=backend \ + --timeout=90s + +# Check status +check_status + +# Test endpoints +echo "๐Ÿงช Testing endpoints..." + +echo "Frontend (/) - Should redirect to /incidents:" +RESP=$(curl -s -I http://localhost/) +echo "$RESP" | grep "HTTP" +LOCATION=$(echo "$RESP" | grep -i "location") +echo "$LOCATION" +if [[ "$LOCATION" == *"/incidents"* ]]; then + echo "โœ… Redirect to /incidents confirmed" +else + echo "โŒ Redirect to /incidents not found" + exit 1 +fi + +echo -e "\nBackend (/v2/docs) - Should return API info:" +RESP=$(curl -s http://localhost/v2/docs/) +echo "Response: $RESP" +if [[ $RESP == *"Rest API powering"* ]]; then + echo "โœ… Backend response contains expected message" +else + echo "โŒ Unexpected backend response" +fi + +echo -e "\nWebSocket (/websocket) - Testing connection:" +wscat -c "ws://localhost/websocket/app/keepappkey?protocol=7&client=js&version=8.3.0&flash=false" & +WSCAT_PID=$! +sleep 2 +kill $WSCAT_PID 2>/dev/null + +# Show HAProxy stats +echo -e "\n๐Ÿ“Š HAProxy Stats:" +curl -s "http://localhost:30024/stats?stats;csv" + +# Show logs if needed +echo -e "\n๐Ÿ“œ HAProxy controller logs:" +kubectl logs -l app.kubernetes.io/instance=haproxy --tail=100 + +# Keep script running for debugging +echo -e "\n๐Ÿ”„ Debug session active. Press Ctrl+C to cleanup." +echo "๐Ÿ“ Quick commands:" +echo " - kubectl get pods -A" +echo " - kubectl describe ingress" +echo " - kubectl logs " +echo " - curl -v http://localhost/" +echo " - curl -v http://localhost/v2/docs/" +echo " - curl -v -H \"Upgrade: websocket\" -H \"Connection: Upgrade\" http://localhost/websocket/" +echo " - curl http://localhost:30024/stats" + +# Wait for user interrupt +trap "kind delete cluster" EXIT +read -r -d '' _ debug/nginx-values.yaml +global: + ingress: + enabled: true + className: nginx + classType: nginx + websocketPrefix: /websocket + backendPrefix: /v2/docs + frontendPrefix: / +frontend: + enabled: true +backend: + enabled: true +websocket: + enabled: true +EOF + +# Create Kind cluster with ingress ports exposed +cat < debug/kind-config.yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP +EOF + +# Function to check service/pod status +check_status() { + echo "๐Ÿ” Checking all resources..." + kubectl get pods -A + kubectl get svc -A + kubectl get ingress -A +} + +# Create cluster +kind create cluster --config debug/kind-config.yaml + +# Install Nginx Ingress +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +helm install nginx-ingress ingress-nginx/ingress-nginx \ + --set controller.service.type=NodePort \ + --set controller.watchIngressWithoutClass=true \ + --set controller.allowSnippetAnnotations=true \ + --set controller.config.allow-snippets=true \ + --set controller.config.enable-snippets=true \ + --set controller.hostPort.enabled=true \ + --set controller.service.ports.http=80 \ + --set controller.service.ports.https=443 \ + --set controller.nodeSelector."kubernetes\.io/os"=linux \ + --set controller.admissionWebhooks.enabled=false + +# Wait for ingress controller +echo "โณ Waiting for Nginx ingress controller..." +kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/instance=nginx-ingress \ + --timeout=90s + +# Install your chart +helm install keep ./charts/keep -f debug/nginx-values.yaml + +# Wait for pods +echo "โณ Waiting for all pods to be ready..." +# Wait for backend pod (the last one to be ready) +echo "โณ Waiting for Keep backend to be ready..." +kubectl wait --namespace default \ + --for=condition=ready pod \ + --selector=app.kubernetes.io/instance=keep,keep-component=backend \ + --timeout=90s + +# Check status +check_status + +# Test endpoints +echo "๐Ÿงช Testing endpoints..." + +echo "Frontend (/) - Should redirect to /incidents:" +RESP=$(curl -s -I http://localhost/) +echo "$RESP" | grep "HTTP" +LOCATION=$(echo "$RESP" | grep -i "location") +echo "$LOCATION" +if [[ "$LOCATION" == *"/incidents"* ]]; then + echo "โœ… Redirect to /incidents confirmed" +else + echo "โŒ Redirect to /incidents not found" + exit 1 +fi + +echo -e "\nBackend (/v2/docs) - Should return API info:" +RESP=$(curl -s http://localhost/v2/docs/) +echo "Response: $RESP" +if [[ $RESP == *"Rest API powering"* ]]; then + echo "โœ… Backend response contains expected message" +else + echo "โŒ Unexpected backend response" +fi + +echo -e "\nWebSocket (/websocket) - Testing connection:" +wscat -c "ws://localhost/websocket/app/keepappkey?protocol=7&client=js&version=8.3.0&flash=false" & +WSCAT_PID=$! +sleep 2 +kill $WSCAT_PID 2>/dev/null + +# Show logs if needed +echo -e "\n๐Ÿ“œ Ingress controller logs:" +kubectl logs -l app.kubernetes.io/instance=nginx-ingress --tail=100 + +# Keep script running for debugging +echo -e "\n๐Ÿ”„ Debug session active. Press Ctrl+C to cleanup." +echo "๐Ÿ“ Quick commands:" +echo " - kubectl get pods -A" +echo " - kubectl describe ingress" +echo " - kubectl logs " +echo " - curl -v http://localhost/" +echo " - curl -v http://localhost/v2/docs/" +echo " - curl -v -H \"Upgrade: websocket\" -H \"Connection: Upgrade\" http://localhost/websocket/" + +# Wait for user interrupt +trap "kind delete cluster" EXIT +read -r -d '' _