diff --git a/.gitignore b/.gitignore index 6f72f892..3b2d2054 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out - +.task # Dependency directories (remove the comment below to include it) # vendor/ diff --git a/Taskfile.yaml b/Taskfile.yaml index fe909a49..8c672360 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -1,5 +1,9 @@ --- version: 3 +includes: + git: + taskfile: https://raw.githubusercontent.com/stuttgart-things/platform-engineering-showcase/refs/heads/main/taskfiles/git.yaml + vars: PROJECT: sh: echo ${PROJECT} @@ -124,16 +128,6 @@ tasks: - git branch - git branch --set-upstream-to=origin/main ${BRANCH_NAME} - pr: - desc: Create pull request into main - cmds: - - task: commit - - gh pr create -t "{{ .BRANCH }}" -b "{{ .BRANCH }} branch into main" - - sleep 2s - # - gh pr checks $(gh pr list | grep "^[^#;]" | awk '{print $1}') --watch - - gh pr merge $(gh pr list | grep "^[^#;]" | grep '{{ .BRANCH }}' | awk '{print $1}') --auto --rebase --delete-branch - - git checkout main && git pull - release: deps: - check @@ -324,29 +318,6 @@ tasks: - | echo *.$(kubectl get nodes -o json | jq -r '.items[] | select(.metadata.labels."ingress-ready" == "true") | .status.addresses[] | select(.type == "InternalIP") | .address').nip.io - check: - desc: "Run pre-commit hooks" - cmds: - - pre-commit run -a - - switch-remote: - desc: Switch to remote branch - cmds: - - | - git fetch - branches=($(git branch -r | grep -v 'origin/HEAD' | sed 's|origin/||')) - branch=$(printf "%s\n" "${branches[@]}" | gum choose) - git switch -c ${branch} --track origin/${branch} - git branch && git status - - switch-local: - desc: Switch to local branch - cmds: - - | - branches=$(git branch -a | grep -v 'remotes') - branch=$(printf "%s\n" "${branches[@]}" | gum choose) - git checkout ${branch} && git pull - tests-create-includes: desc: Create test files cmds: @@ -416,38 +387,12 @@ tasks: exit 0 silent: false - commit: - desc: Commit + push code into branch - deps: - - check - cmds: - - git branch --set-upstream-to=origin/{{ .BRANCH }} - - git pull - - git status - - | - git add * - git status - if [[ -n $(git status --porcelain) ]]; then - echo "Review the changes above." - gum confirm "Do you want to commit these changes?" || exit 0 - - echo "ENTER COMMIT MESSAGE" - COMMIT_MESSAGE=$(gum choose "CUSTOM MESSAGE" "feat: {{ .BRANCH }}" "fix: {{ .BRANCH }}" "BREAKING CHANGE: {{ .BRANCH }}") - - if [ "$COMMIT_MESSAGE" == "CUSTOM MESSAGE" ]; then - CHANGED_FILES=$(git status --short | awk '{print $2}' | tr '\n' ' ') - COMMIT_MESSAGE=$(gum input --placeholder "Commit message" --value "Changed: $CHANGED_FILES") - fi - - git commit --allow-empty -a -m "$COMMIT_MESSAGE" - else - echo "No changes to commit." - fi - - git push origin -u {{ .BRANCH }} - do: desc: Select a task to run cmds: - | - task=$(yq e '.tasks | keys' Taskfile.yaml | sed 's/^- //' | grep -v '^do$' | gum choose) - task ${task} + # Extract task names (keep internal colons, remove only trailing colon) + task_name=$(task -l | awk '/^\*/ {print $2}' | sed 's/:$//' | gum choose) + + # Run the selected task + [ -n "$task_name" ] && task "$task_name" diff --git a/apps/README.md b/apps/README.md index 8e23f616..570f0160 100644 --- a/apps/README.md +++ b/apps/README.md @@ -6,19 +6,33 @@ App Helmfile templates. ## SERVICES -
REDIS-STACK +
HOMERUN-BASE-STACK ```bash -# BASIC -cat < redis-stack.yaml ---- -helmfiles: - - path: git::https://github.com/stuttgart-things/helm.git@apps/redis-stack.yaml.gotmpl - values: - - namespace: redis-stack - - password: {{ env "REDIS_STACK_PASSWORD" | default "whateverpa$$w0rd" }} - - storageClass: standard -EOF +# BASIC APPLY + +export redisPassword= +export genericPitcherToken= + +helmfile apply -f \ +git::https://github.com/stuttgart-things/helm.git@apps/apps/homerun-base-stack.yaml.gotmpl \ +--state-values-set redisStackStorageClass=openebs-hostpath\ +--state-values-set genericPitcherDomain=demo-infra.example.com +``` + +```bash +# CREATE REDISEARCH INDEX +sudo apt install redis-tools -y +kubectl port-forward -n homerun svc/redis-stack 6379:6379 +redis-cli -h localhost -p 6379 -a + +FT.CREATE homerun ON HASH PREFIX 1 "message:" SCHEMA messageID TEXT SORTABLE timestamp NUMERIC SORTABLE +FT._LIST +``` + +```bash +export HOMERUN_ADDRESS=https://homerun.demo-infra.whatever.de/generic +bash tests/homerun-send-events.sh ```
diff --git a/apps/homerun-base-stack.yaml.gotmpl b/apps/homerun-base-stack.yaml.gotmpl new file mode 100644 index 00000000..db6d6a57 --- /dev/null +++ b/apps/homerun-base-stack.yaml.gotmpl @@ -0,0 +1,69 @@ +--- +environments: + default: + values: + - version: {{ .Values.version | default "v0.2.1" }} + - namespace: {{ .Values.namespace | default "homerun" }} + - redisStackEnabled: {{ .Values.redisStackEnabled | default true }} + - redisStackServiceType: {{ .Values.redisStackServiceType | default "ClusterIP" }} + - redisStackStorageClass: {{ .Values.redisStackStorageClass | default "openebs-hostpath" }} + - redisStackStorageSize: {{ .Values.redisStackStorageSize | default "4Gi" }} + - redisStackPort: {{ .Values.redisStackPort | default 6379 }} + - redisStackServiceName: {{ .Values.redisStackServiceName | default "redis-stack-headless" }} + - redisStackPassword: {{ env "redisPassword" }} + - textCatcherEnabled: {{ .Values.textCatcherEnabled | default true }} + - textCatcherLogging: {{ .Values.textCatcherLogging | default "terminal" }} + - textCatcherName: {{ .Values.textCatcherName | default "homerun-text-catcher" }} + - genericPitcherEnabled: {{ .Values.genericPitcherEnabled | default true }} + - genericPitcherName: {{ .Values.genericPitcherName | default "homerun-generic-pitcher" }} + - genericPitcherIngressClass: {{ .Values.genericPitcherIngressClass | default "nginx" }} + - genericPitcherIngressPort: {{ .Values.genericPitcherIngressPort | default 80 }} + - genericPitcherContainerPort: {{ .Values.genericPitcherContainerPort | default 4000 }} + - genericPitcherApiPath: {{ .Values.genericPitcherApiPath | default "generic" }} + - genericPitcherHostname: {{ .Values.genericPitcherHostname | default "homerun" }} + - genericPitcherDomain: {{ .Values.genericPitcherDomain | default "example.com" }} + - genericPitcherIssuerKind: {{ .Values.genericPitcherIssuerKind | default "ClusterIssuer" }} + - genericPitcherIssuerName: {{ .Values.genericPitcherIssuerName | default "selfsigned" }} + - genericPitcherToken: {{ env "genericPitcherToken" }} + - stream: {{ .Values.stream | default "homerun" }} + - searchIndex: {{ .Values.searchIndex | default "homerun" }} + +{{- if .Values.redisStackEnabled }} +helmfiles: + - path: ../database/redis-stack.yaml.gotmpl + values: + - namespace: {{ .Values.namespace }} + - password: {{ .Values.redisStackPassword }} + - storageClass: {{ .Values.redisStackStorageClass }} + - serviceType: {{ .Values.redisStackServiceType }} + - storageSize: {{ .Values.redisStackStorageSize }} +{{- end }} + +releases: +{{- if .Values.genericPitcherEnabled }} + - name: homerun-generic-pitcher + installed: true + namespace: {{ .Values.namespace }} + chart: stuttgart-things/homerun + version: {{ .Values.version }} + values: + - "values/generic-pitcher.values.yaml.gotmpl" + set: + - name: genericPitcherDomain + value: {{ .Values.genericPitcherDomain }} +{{- end }} + +{{- if .Values.textCatcherEnabled }} + - name: homerun-text-catcher + installed: true + namespace: {{ .Values.namespace }} + chart: stuttgart-things/homerun + version: {{ .Values.version }} + values: + - "values/text-catcher.values.yaml.gotmpl" +{{- end }} + +repositories: + - name: stuttgart-things + url: ghcr.io/stuttgart-things + oci: true diff --git a/apps/tests/homerun-send-events.sh b/apps/tests/homerun-send-events.sh new file mode 100644 index 00000000..04aec851 --- /dev/null +++ b/apps/tests/homerun-send-events.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +read -r -p "ENTER COUNT MESSAGES [5]: " COUNT_MESSAGE +COUNT_MESSAGE=${COUNT_MESSAGE:-5} +echo "$COUNT_MESSAGE" + +ADDRESS_DEFAULT="${HOMERUN_ADDRESS:-https://your-custom-address.com/endpoint}" +read -r -p "ENTER ADDRESS [${ADDRESS_DEFAULT}]: " ADDRESS +ADDRESS=${ADDRESS:-$ADDRESS_DEFAULT} +echo "$ADDRESS" + +read -r -p "ENTER DELAY [10]: " DELAY +DELAY=${DELAY:-5} +echo "$DELAY" + +# POSSIBLE DATA +SYSTEMS=("github" "gitlab") #) "flux" "ansible") +TITLES=("System Alert" "System Incident" "Incident") +MESSAGES=("Memory usage is high" "CPU usage is high" "Memory and CPU usage is high") +SEVERITES=("INFO" "ERROR" "WARNING") +AUTHORS=("bibi" "gude" "andreu" "qolf" "pat") +ARTIFACTS=("image-1.23.tar.gz" "test.tar.gz" "report.json" "result.txt") +TAGS=("usage,alert" "cpu" "cpu,usage,alert" "memory,usage,alert" "monitoring,usage,alert, memory") + +# FUNCTION TO GET A RANDOM ITEM FROM A LIST +get_random_item() { + local items=("$@") + local count=${#items[@]} + local random_index=$((RANDOM % count)) + echo "${items[$random_index]}" +} + +generate_random_email() { + local domains=("example.com" "test.com" "mail.com" "demo.com") + local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + local length=8 + local local_part="" + + for i in $(seq 1 $length); do + local_part+=${chars:RANDOM%${#chars}:1} + done + + local domain=${domains[RANDOM%${#domains[@]}]} + echo "${local_part}@${domain}" +} + +# Function to generate a random ISO 8601 timestamp +generate_random_timestamp() { + # Generate random values for the timestamp components + local year=$((RANDOM % 10 + 2024)) # Random year from 2024 to 2033 + local month + month=$(printf "%02d" $((RANDOM % 12 + 1))) # Random month from 01 to 12 + local day + day=$(printf "%02d" $((RANDOM % 28 + 1))) # Random day from 01 to 28 + local hour + hour=$(printf "%02d" $((RANDOM % 24))) # Random hour from 00 to 23 + local minute + minute=$(printf "%02d" $((RANDOM % 60))) # Random minute from 00 to 59 + local second + second=$(printf "%02d" $((RANDOM % 60))) # Random second from 00 to 59 + + # Construct the ISO 8601 timestamp + echo "${year}-${month}-${day}T${hour}:${minute}:${second}Z" +} + +generate_random_url() { + local protocols=("http" "https") + local domains=("example.com" "test.com" "site.net" "demo.org" "mydomain.io") + local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + local sub_length=6 + local path_length=10 + local subdomain="" + local path="" + + # Wähle ein zufälliges Protokoll + local protocol=${protocols[RANDOM % ${#protocols[@]}]} + + # Erzeuge den Subdomain-Teil + for i in $(seq 1 $sub_length); do + subdomain+=${chars:RANDOM%${#chars}:1} + done + + # Wähle eine zufällige Domain + local domain=${domains[RANDOM % ${#domains[@]}]} + + # Erzeuge den Pfad + for i in $(seq 1 $path_length); do + path+=${chars:RANDOM%${#chars}:1} + done + + # Konstruktion der vollständigen URL + echo "${protocol}://${subdomain}.${domain}/${path}" +} + +for ((i=1; i<=COUNT_MESSAGE; i++)); do + + RANDOM_TIMESTAMP=$(generate_random_timestamp) + #echo "RANDOM TIMESTAMP: ${RANDOM_TIMESTAMP}" + + SYSTEM=$(get_random_item "${SYSTEMS[@]}") + echo "SYSTEM: ${SYSTEM}" + + TITLE=$(get_random_item "${TITLES[@]}") + echo "TITLE: ${TITLE}" + + MESSAGE=$(get_random_item "${MESSAGES[@]}") + echo "MESSAGE: ${MESSAGE}" + + SEVERITY=$(get_random_item "${SEVERITES[@]}") + echo "SEVERITY: ${SEVERITY}" + + AUTHOR=$(get_random_item "${AUTHORS[@]}") + echo "AUTHOR: ${AUTHOR}" + + MAIL=$(generate_random_email) + #echo "RANDOMLY GENERATED E-MAIL: ${MAIL}" + + ASSIGNE=$(get_random_item "${AUTHORS[@]}") + #echo "ASSIGNE: ${ASSIGNE}" + + TAG=$(get_random_item "${TAGS[@]}") + echo "TAGS: ${TAG}" + + RANDOM_URL=$(generate_random_url) + #echo "URLS: ${RANDOM_URL}" + + ARTIFACT=$(get_random_item "${ARTIFACTS[@]}") + #echo "ARTIFACT: ${ARTIFACT}" + + printf '\nWAITING FOR %s SECONDS BEFORE SENDING THE (NEXT) EVENT\n' "${DELAY}" + sleep "$DELAY" # Pause für die angegebene Anzahl von Sekunden zwischen den Events + + curl -k -X POST "${ADDRESS}" \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: Atlan7is2026!" \ + -d "{ + \"title\": \"${TITLE}\", + \"message\": \"${MESSAGE}\", + \"severity\": \"${SEVERITY}\", + \"author\": \"${AUTHOR}\", + \"timestamp\": \"${RANDOM_TIMESTAMP}\", + \"system\": \"${SYSTEM}\", + \"tags\": \"${TAG}\", + \"assigneeaddress\": \"${MAIL}\", + \"assigneename\": \"${ASSIGNE}\", + \"artifacts\": \"${ARTIFACT}\", + \"url\": \"${RANDOM_URL}\" + }" + + printf "\n\n" + +done diff --git a/apps/values/generic-pitcher.values.yaml.gotmpl b/apps/values/generic-pitcher.values.yaml.gotmpl new file mode 100644 index 00000000..0fc0eb8c --- /dev/null +++ b/apps/values/generic-pitcher.values.yaml.gotmpl @@ -0,0 +1,65 @@ +--- +generic-pitcher: + enabled: {{ .Values.genericPitcherEnabled }} + + configmaps: + {{ .Values.genericPitcherName }}: + API_PATH: {{ .Values.genericPitcherApiPath }} + PORT: "{{ .Values.genericPitcherContainerPort }}" + REDIS_STREAM: {{ .Values.stream }} + REDISEARCH_INDEX: {{ .Values.searchIndex }} + + secrets: + generic-token: + name: generic-token + labels: + app: {{ .Values.genericPitcherName }} + dataType: stringData + secretKVs: + WEBHOOK_TOKEN: {{ .Values.genericPitcherToken }} + + redis-connection-{{ .Values.genericPitcherName }}: + name: redis-connection-{{ .Values.genericPitcherName }} + labels: + app: {{ .Values.genericPitcherName }} + dataType: stringData + secretKVs: + REDIS_SERVER: {{ .Values.redisStackServiceName }}.{{ .Release.Namespace }}.svc.cluster.local + REDIS_PORT: {{ .Values.redisStackPort }} + REDIS_PASSWORD: {{ .Values.redisStackPassword }} + + customresources: + {{ .Values.genericPitcherName }}-certificate: + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: {{ .Values.genericPitcherName }}-ingress + labels: + app: {{ .Values.genericPitcherName }} + spec: + commonName: {{ .Values.genericPitcherHostname }}.{{ .Values.genericPitcherDomain }} + dnsNames: + - {{ .Values.genericPitcherHostname }}.{{ .Values.genericPitcherDomain }} + issuerRef: + name: {{ .Values.genericPitcherIssuerName }} + kind: {{ .Values.genericPitcherIssuerKind }} + secretName: {{ .Values.genericPitcherName }}-ingress-tls + + ingress: + {{ .Values.genericPitcherName }}-ingress: + labels: + app: {{ .Values.genericPitcherName }} + name: {{ .Values.genericPitcherName }} + ingressClassName: {{ .Values.genericPitcherIngressClass }} + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "true" + service: + name: {{ .Values.genericPitcherName }}-service + port: {{ .Values.genericPitcherContainerPort }} + path: /{{ .Values.genericPitcherApiPath }} + pathType: Prefix + hostname: {{ .Values.genericPitcherHostname }} + domain: {{ .Values.genericPitcherDomain }} + tls: + secretName: {{ .Values.genericPitcherName }}-ingress-tls + host: {{ .Values.genericPitcherHostname }}.{{ .Values.genericPitcherDomain }} diff --git a/apps/values/text-catcher.values.yaml.gotmpl b/apps/values/text-catcher.values.yaml.gotmpl new file mode 100644 index 00000000..ff2ad3b4 --- /dev/null +++ b/apps/values/text-catcher.values.yaml.gotmpl @@ -0,0 +1,17 @@ +--- +text-catcher: + enabled: {{ .Values.textCatcherEnabled }} + configmaps: + homerun-text-catcher: + REDIS_STREAM: {{ .Values.stream }} + LOGGING: {{ .Values.textCatcherLogging }} + secrets: + redis-connection-{{ .Values.textCatcherName }}: + name: redis-connection-{{ .Values.textCatcherName }} + labels: + app: {{ .Values.textCatcherName }} + dataType: stringData + secretKVs: + REDIS_SERVER: {{ .Values.redisStackServiceName }}.{{ .Release.Namespace }}.svc.cluster.local + REDIS_PORT: {{ .Values.redisStackPort }} + REDIS_PASSWORD: {{ .Values.redisStackPassword }} diff --git a/database/README.md b/database/README.md index eca637d0..e073f449 100644 --- a/database/README.md +++ b/database/README.md @@ -6,6 +6,35 @@ Database Helmfile templates for deploying common stateful services. ## SERVICES +
REDIS-STACK + +```bash +# IMPERATIVE +helmfile apply -f \ +git::https://github.com/stuttgart-things/helm.git@database/redis-stack.yaml.gotmpl \ +--state-values-set storageClass=openebs-hostpath \ +--state-values-set password= +``` + +
REDIS-STACK + +```bash +# DECLARATIVE +cat < redis-stack.yaml +--- +helmfiles: + - path: git::https://github.com/stuttgart-things/helm.git@apps/redis-stack.yaml.gotmpl + values: + - namespace: redis-stack + - password: {{ env "REDIS_STACK_PASSWORD" | default "whateverpa$$w0rd" }} + - storageClass: standard +EOF +``` + +
+ +
+
OPENLDAP ```bash diff --git a/database/redis-stack.yaml.gotmpl b/database/redis-stack.yaml.gotmpl index 831884c5..cc8b672e 100644 --- a/database/redis-stack.yaml.gotmpl +++ b/database/redis-stack.yaml.gotmpl @@ -8,6 +8,7 @@ environments: - password: - persistenceEnabled: true - storageClass: standard + - storageSize: 8Gi - imageRegistry: ghcr.io - imageRepository: stuttgart-things/redis-stack-server - redisStackVersion: 7.2.0-v18 #6.2.6-v9 diff --git a/database/values/redis-stack.yaml.gotmpl b/database/values/redis-stack.yaml.gotmpl index 46fecfd5..62bd428a 100644 --- a/database/values/redis-stack.yaml.gotmpl +++ b/database/values/redis-stack.yaml.gotmpl @@ -24,6 +24,7 @@ master: persistence: enabled: {{ .Values.persistenceEnabled }} storageClass: {{ .Values.storageClass }} + size: {{ .Values.storageSize }} args: - -c - /opt/bitnami/scripts/merged-start-scripts/start-master.sh @@ -39,6 +40,8 @@ replica: persistence: enabled: {{ .Values.persistenceEnabled }} storageClass: {{ .Values.storageClass }} + size: {{ .Values.storageSize }} + replicaCount: 1 args: - -c