Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/improve checks #8

Merged
merged 12 commits into from
Apr 30, 2024
10 changes: 10 additions & 0 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@
platformAutomerge: false,
prHourlyLimit: 6,
prConcurrentLimit: 20,
customManagers: [
{
"customType": "regex",
"fileMatch": ["\.sh",],
"matchStrings": [
"datasource=(?<datasource>.*?) depName=(?<depName>.*?)( registryUrl=(?<registryUrl>.*?))?( versioning=(?<versioning>.*?))?\\s.*?(- |=|: )(?<currentValue>.*)",
],
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}"
},
]
}
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# # C8 Self-Managed Checks
# C8 Self-Managed Checks

[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Expand Down Expand Up @@ -91,14 +91,14 @@ This script retrieves an access token from an authorization server using client
```bash
Usage: ./checks/zeebe/token.sh [-h] [-a AUTH_SERVER_URL] [-i CLIENT_ID] [-s CLIENT_SECRET] [-u TOKEN_AUDIENCE]
Options:
-h Display this help message
-a AUTH_SERVER_URL Specify the authorization server URL (e.g.: https://local.distro.ultrawombat.com/auth/realms/camunda-platform/protocol/openid-connect/token)
-i CLIENT_ID Specify the client ID
-s CLIENT_SECRET Specify the client secret
-u TOKEN_AUDIENCE Specify the token audience
-k Skip TLS verification (insecure mode)
-r CACERT Specify the path to CA certificate file
-j CLIENTCERT Specify the path to client certificate file
-h Display this help message
-a ZEEBE_AUTHORIZATION_SERVER_URL Specify the authorization server URL (e.g.: https://local.distro.ultrawombat.com/auth/realms/camunda-platform/protocol/openid-connect/token)
-i ZEEBE_CLIENT_ID Specify the client ID
-s ZEEBE_CLIENT_SECRET Specify the client secret
-u ZEEBE_TOKEN_AUDIENCE Specify the token audience
-k Skip TLS verification (insecure mode)
-r CACERT Specify the path to CA certificate file
-j CLIENTCERT Specify the path to client certificate file
```

##### Example:
Expand All @@ -121,17 +121,17 @@ This script verifies connectivity to a Zeebe instance using HTTP/2 and gRPC prot
```bash
Usage: ./checks/zeebe/connectivity.sh [-h] [-H ZEEBE_HOST]
Options:
-h Display this help message
-H ZEEBE_HOST Specify the Zeebe host (e.g., zeebe.c8.camunda.example.com)
-f PROTO_FILE Specify the path to gateway.proto file or leave empty to download it
-k Skip TLS verification (insecure mode)
-r CACERT Specify the path to CA certificate file
-j CLIENTCERT Specify the path to Client certificate file
-a AUTH_SERVER_URL Specify the authorization server URL (e.g.: https://local.distro.example.com/auth/realms/camunda-platform/protocol/openid-connect/t
oken)
-i CLIENT_ID Specify the client ID
-s CLIENT_SECRET Specify the client secret
-u TOKEN_AUDIENCE Specify the token audience
-h Display this help message
-H ZEEBE_HOST Specify the Zeebe host with the port (e.g., zeebe.c8.camunda.example.com:443)
-p ZEEBE_VERSION Specify the Zeebe version (default is latest version: 8.x.x)
-f PROTO_FILE Specify the path to gateway.proto file or leave empty to download it (default behavior is to download the protofile)
-k Skip TLS verification (insecure mode)
-r CACERT Specify the path to CA certificate file
-j CLIENTCERT Specify the path to Client certificate file
-a ZEEBE_AUTHORIZATION_SERVER_URL Specify the authorization server URL (e.g.: https://local.distro.example.com/auth/realms/camunda-platform/protocol/openid-connect/token)
-i ZEEBE_CLIENT_ID Specify the client ID
-s ZEEBE_CLIENT_SECRET Specify the client secret
-u ZEEBE_TOKEN_AUDIENCE Specify the token audience
```

##### Example:
Expand Down
40 changes: 29 additions & 11 deletions checks/kube/connectivity.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,19 @@ command -v kubectl >/dev/null 2>&1 || { echo >&2 "Error: kubectl is required but

# check if all services can be resolved in pods with curl in the pod
check_services_resolution() {
echo "Check services can be resolved in the pods"
echo "[INFO] Check services can be resolved in the pods"

local pods
pods=$(kubectl get pods -n "$NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
local pods_command
pods_command="kubectl get pods -n \"$NAMESPACE\" -o jsonpath='{range .items[*]}{.metadata.name}{\"\n\"}{end}'"
echo "[INFO] Running command: ${pods_command}"
pods=$(eval "${pods_command}")

local services
services=$(kubectl get services -n "$NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
local services_command
services_command="kubectl get services -n \"$NAMESPACE\" -o jsonpath='{range .items[*]}{.metadata.name}{\"\n\"}{end}'"
echo "[INFO] Running command: ${services_command}"
services=$(eval "${services_command}")

# for each pod, we check if all the services can be resolved
for pod in $pods; do
Expand All @@ -75,13 +81,16 @@ check_services_resolution() {

for service in $services; do
local curl_output
curl_output=$(kubectl exec -n "$NAMESPACE" "$pod" -- curl -s -v --max-time 1 "$service" 2>&1)
local curl_command
curl_command="kubectl exec -n \"$NAMESPACE\" \"$pod\" -- curl -s -v --max-time 1 \"$service\""
echo "[INFO] Running command: ${curl_command}"
curl_output=$(eval "${curl_command}" 2>&1)

# Check if the output contains "Trying ip:port" (IPv4 or IPv6)
if echo "$curl_output" | grep -Eq "Trying ([0-9.]*|\[[0-9a-fA-F:]*\]):[0-9]*"; then
echo "[OK] Service $service resolved successfully from pod $pod in namespace $NAMESPACE"
else
echo "[KO] Service $service resolution failed from pod $pod in namespace $NAMESPACE: $curl_output" >&2
echo "[FAIL] Service $service resolution failed from pod $pod in namespace $NAMESPACE: $curl_output" >&2
SCRIPT_STATUS_OUTPUT=2
fi
done
Expand All @@ -90,18 +99,27 @@ check_services_resolution() {
check_services_resolution

check_ingress_class_and_config() {
echo "Check ingress and associated configuration"
echo "[INFO] Check ingress and associated configuration"

local annotation_found
annotation_found=0

ingress_list=$(kubectl get ingress -n "$NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
local ingress_list
local ingress_list_command
ingress_list_command="kubectl get ingress -n \"$NAMESPACE\" -o jsonpath='{range .items[*]}{.metadata.name}{\"\n\"}{end}'"
echo "[INFO] Running command: ${ingress_list_command}"
ingress_list=$(eval "${ingress_list_command}")

# check each ingress listed
for ingress_name in $ingress_list; do
ingress_class=$(kubectl get ingress -n "$NAMESPACE" "$ingress_name" -o jsonpath='{.spec.ingressClassName}')
local ingress_class
local ingress_class_command
ingress_class_command="kubectl get ingress -n \"$NAMESPACE\" \"$ingress_name\" -o jsonpath='{.spec.ingressClassName}'"
echo "[INFO] Running command: ${ingress_class_command}"
ingress_class=$(eval "${ingress_class_command}")

if [ "$ingress_class" != "nginx" ]; then
echo "[KO] Ingress class is not nginx for $ingress_name. Actual class: $ingress_class." >&2
echo "[FAIL] Ingress class is not nginx for $ingress_name. Actual class: $ingress_class." >&2
echo "If you configured it on purpose, please the SKIP_CHECK_INGRESS_CLASS option." >&2
SCRIPT_STATUS_OUTPUT=3
else
Expand All @@ -114,7 +132,7 @@ check_ingress_class_and_config() {
done

if [ "$annotation_found" -eq 0 ]; then
echo "[KO] None of the ingresses contain the annotation nginx.ingress.kubernetes.io/backend-protocol: GRPC, which is required for zeebe ingress." >&2
echo "[FAIL] None of the ingresses contain the annotation nginx.ingress.kubernetes.io/backend-protocol: GRPC, which is required for zeebe ingress." >&2
SCRIPT_STATUS_OUTPUT=5
fi
}
Expand All @@ -124,7 +142,7 @@ fi

# Check if SCRIPT_STATUS_OUTPUT is not equal to zero
if [ "$SCRIPT_STATUS_OUTPUT" -ne 0 ]; then
echo "[KO] ${LVL_1_SCRIPT_NAME}: At least one of the tests failed (error code: ${SCRIPT_STATUS_OUTPUT})." 1>&2
echo "[FAIL] ${LVL_1_SCRIPT_NAME}: At least one of the tests failed (error code: ${SCRIPT_STATUS_OUTPUT})." 1>&2
exit $SCRIPT_STATUS_OUTPUT
else
echo "[OK] ${LVL_1_SCRIPT_NAME}: All test passed."
Expand Down
31 changes: 20 additions & 11 deletions checks/kube/deployment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,24 @@ command -v kubectl >/dev/null 2>&1 || { echo >&2 "Error: kubectl is required but

# Helm checks of the deployment
check_helm_deployment() {
echo "Check status of the last helm deployment"
echo "[INFO] Check status of the last helm deployment"

local last_deployment
last_deployment=$(helm list -n "$NAMESPACE" | grep "$HELM_DEPLOYMENT_NAME" | head -n 1)
local last_deployment_command
last_deployment_command="helm list -n \"$NAMESPACE\" | grep \"$HELM_DEPLOYMENT_NAME\" | head -n 1"
echo "[INFO] Running command: ${last_deployment_command}"
last_deployment=$(eval "${last_deployment_command}")

if [[ -n "$last_deployment" ]]; then
deployment_status=$(echo "$last_deployment" | awk '{ print $8 }')
if [[ "$deployment_status" == "deployed" ]]; then
echo "[OK] Last Helm deployment $HELM_DEPLOYMENT_NAME was successful"
else
echo "[KO] Last Helm deployment $HELM_DEPLOYMENT_NAME was not successful: (status=$deployment_status)" >&2
echo "[FAIL] Last Helm deployment $HELM_DEPLOYMENT_NAME was not successful: (status=$deployment_status)" >&2
SCRIPT_STATUS_OUTPUT=2
fi
else
echo "[KO] No deployment found for $HELM_DEPLOYMENT_NAME in namespace $NAMESPACE" >&2
echo "[FAIL] No deployment found for $HELM_DEPLOYMENT_NAME in namespace $NAMESPACE" >&2
SCRIPT_STATUS_OUTPUT=3
fi
}
Expand All @@ -92,15 +95,18 @@ fi

# check if any pod is in an unhealthy state in the namespace
check_unhealthy_pods() {
echo "Check absenced of unhealthy containers"
echo "[INFO] Check absenced of unhealthy containers"

local unhealthy_pods
unhealthy_pods=$(kubectl get pods -n "$NAMESPACE" --field-selector=status.phase!=Running --no-headers)
local unhealthy_pods_command
unhealthy_pods_command="kubectl get pods -n \"$NAMESPACE\" --field-selector=status.phase!=Running --no-headers"
echo "[INFO] Running command: ${unhealthy_pods_command}"
unhealthy_pods=$(eval "${unhealthy_pods_command}")

if [[ -z "$unhealthy_pods" ]]; then
echo "[OK] All pods are in an healthy state in namespace $NAMESPACE"
else
echo "[KO] Pods in unhealthy state in namespace $NAMESPACE:" >&2
echo "[FAIL] Pods in unhealthy state in namespace $NAMESPACE:" >&2
echo "$unhealthy_pods" >&2
SCRIPT_STATUS_OUTPUT=4
fi
Expand All @@ -111,15 +117,18 @@ check_unhealthy_pods
check_containers_in_pods() {
local required_containers
required_containers=("${REQUIRED_CONTAINERS[@]}")
echo "Check presence of required containers ${required_containers[*]}"
echo "[INFO] Check presence of required containers ${required_containers[*]}"

local pods_containers
pods_containers=$(kubectl get pods -n "$NAMESPACE" -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}')
local pods_containers_command
pods_containers_command="kubectl get pods -n \"$NAMESPACE\" -o jsonpath='{range .items[*]}{.metadata.name}{\"\t\"}{.spec.containers[*].name}{\"\n\"}{end}'"
echo "[INFO] Running command: ${pods_containers_command}"
pods_containers=$(eval "${pods_containers_command}")

for container in "${required_containers[@]}"; do
# Check if the container exists in any pod
if ! echo "$pods_containers" | awk -v container="$container" '$0 ~ container { found = 1; exit } END { exit !found }'; then
echo "[KO] The following required container is missing in the pods in namespace $NAMESPACE: $container" >&2
echo "[FAIL] The following required container is missing in the pods in namespace $NAMESPACE: $container" >&2
SCRIPT_STATUS_OUTPUT=5
fi
done
Expand All @@ -128,7 +137,7 @@ check_containers_in_pods

# Check if SCRIPT_STATUS_OUTPUT is not equal to zero
if [ "$SCRIPT_STATUS_OUTPUT" -ne 0 ]; then
echo "[KO] ${LVL_1_SCRIPT_NAME}: At least one of the tests failed (error code: ${SCRIPT_STATUS_OUTPUT})." 1>&2
echo "[FAIL] ${LVL_1_SCRIPT_NAME}: At least one of the tests failed (error code: ${SCRIPT_STATUS_OUTPUT})." 1>&2
exit $SCRIPT_STATUS_OUTPUT
else
echo "[OK] ${LVL_1_SCRIPT_NAME}: All test passed."
Expand Down
Loading