From e274032d476419b004ce91cf3dac539841f64038 Mon Sep 17 00:00:00 2001 From: Floppy Disk Date: Tue, 15 Oct 2024 14:56:11 +0300 Subject: [PATCH] add e2e for apps --- .pre-commit-config.yaml | 15 ++++- hack/Makefile | 16 +++++ hack/e2e.applications.sh | 54 +++++++++++++++ hack/modules/check_helmrelease_status.sh | 32 +++++++++ hack/modules/colors.sh | 6 ++ hack/modules/create_git_repo.sh | 33 ++++++++++ hack/modules/ignored_charts | 6 ++ hack/modules/install_all_apps.sh | 66 +++++++++++++++++++ hack/modules/install_chart.sh | 60 +++++++++++++++++ hack/modules/install_tenant.sh | 11 ++++ hack/values/tenant.yaml | 6 ++ packages/apps/ferretdb/Chart.yaml | 2 +- .../apps/ferretdb/templates/init-script.yaml | 7 +- packages/apps/versions_map | 3 +- 14 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 hack/Makefile create mode 100755 hack/e2e.applications.sh create mode 100755 hack/modules/check_helmrelease_status.sh create mode 100755 hack/modules/colors.sh create mode 100644 hack/modules/create_git_repo.sh create mode 100644 hack/modules/ignored_charts create mode 100755 hack/modules/install_all_apps.sh create mode 100755 hack/modules/install_chart.sh create mode 100755 hack/modules/install_tenant.sh create mode 100644 hack/values/tenant.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c669497f..994cecaa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,10 +7,19 @@ repos: - id: mixed-line-ending args: [--fix=lf] - id: check-yaml - exclude: packages/apps/postgres/templates/init-script.yaml + exclude: .*/init-script\.yaml$ args: [--unsafe] - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.41.0 hooks: - - id: markdownlint - args: [--fix, --disable, MD013, MD041, --] + - id: markdownlint + args: [--fix, --disable, MD013, MD041, --] +- repo: local + hooks: + - id: gen-versions-map + name: Generate versions map and check for changes + entry: bash -c 'cd packages/apps && make check-version-map' + language: system + types: [file] + pass_filenames: false + description: Run the script and fail if it generates changes diff --git a/hack/Makefile b/hack/Makefile new file mode 100644 index 00000000..c7763255 --- /dev/null +++ b/hack/Makefile @@ -0,0 +1,16 @@ +.PHONY: test clean help + +SCRIPT=./e2e.applications.sh +PRECHECKS=./pre-checks.sh + +help: + @echo "Usage: make {test|clean}" + @echo " test - Run the end-to-end tests." + @echo " clean - Clean up resources." + +test: + @bash $(PRECHECKS) test + @bash $(SCRIPT) test + +clean: + @bash $(SCRIPT) clean diff --git a/hack/e2e.applications.sh b/hack/e2e.applications.sh new file mode 100755 index 00000000..d5f7dde3 --- /dev/null +++ b/hack/e2e.applications.sh @@ -0,0 +1,54 @@ +for file in ./modules/*.sh; do + source "$file" +done + +ROOT_NS="tenant-root" +TEST_TENANT="tenant-e2e" + +FLUX_NS="cozy-fluxcd" +GITREPO_NAME="e2e-repo" +BRANCH="main" + +function test() { + create_git_repo $GITREPO_NAME $FLUX_NS $BRANCH + + install_tenant $TEST_TENANT $ROOT_NS $GITREPO_NAME $FLUX_NS + check_helmrelease_status $TEST_TENANT $ROOT_NS + + install_all_apps "../packages/apps" "$TEST_TENANT" $GITREPO_NAME $FLUX_NS + + if true; then + echo -e "${GREEN}All tests passed!${RESET}" + return 0 + else + echo -e "${RED}Some tests failed!${RESET}" + return 1 + fi +} + +function clean() { + kubectl delete gitrepository.source.toolkit.fluxcd.io $GITREPO_NAME -n $FLUX_NS + kubectl delete helmrelease.helm.toolkit.fluxcd.io $TEST_TENANT -n $ROOT_NS + if true; then + echo -e "${GREEN}Cleanup successful!${RESET}" + return 0 + else + echo -e "${RED}Cleanup failed!${RESET}" + return 1 + fi +} + +case "$1" in + test) + echo -e "${YELLOW}Running tests...${RESET}" + test + ;; + clean) + echo -e "${YELLOW}Cleaning up...${RESET}" + clean + ;; + *) + echo -e "${RED}Usage: $0 {test|clean}${RESET}" + exit 1 + ;; +esac diff --git a/hack/modules/check_helmrelease_status.sh b/hack/modules/check_helmrelease_status.sh new file mode 100755 index 00000000..b4178fb5 --- /dev/null +++ b/hack/modules/check_helmrelease_status.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +source ./modules/colors.sh + +function check_helmrelease_status() { + local release_name="$1" + local namespace="$2" + local timeout=300 # Timeout in seconds + local interval=5 # Interval between checks in seconds + local elapsed=0 + + while [[ $elapsed -lt $timeout ]]; do + local status_output + status_output=$(kubectl get helmrelease "$release_name" -n "$namespace" -o json | jq -r '.status.conditions[-1].reason') + + if [[ "$status_output" == "InstallSucceeded" ]]; then + echo -e "${GREEN}Helm release '$release_name' is ready.${RESET}" + return 0 + elif [[ "$status_output" == "InstallFailed" ]]; then + echo -e "${RED}Helm release '$release_name': InstallFailed${RESET}" + exit 1 + else + echo -e "${YELLOW}Helm release '$release_name' is not ready. Current status: $status_output${RESET}" + fi + + sleep "$interval" + elapsed=$((elapsed + interval)) + done + + echo -e "${RED}Timeout reached. Helm release '$release_name' is still not ready after $timeout seconds.${RESET}" + exit 1 +} diff --git a/hack/modules/colors.sh b/hack/modules/colors.sh new file mode 100755 index 00000000..ed80c40d --- /dev/null +++ b/hack/modules/colors.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +RESET='\033[0m' +YELLOW='\033[0;33m' diff --git a/hack/modules/create_git_repo.sh b/hack/modules/create_git_repo.sh new file mode 100644 index 00000000..7715cd03 --- /dev/null +++ b/hack/modules/create_git_repo.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +function create_git_repo() { + local repo_name="$1" + local namespace="$2" + local branch="$3" + + if [[ -z "$repo_name" || -z "$namespace" || -z "$branch" ]]; then + echo "Usage: create_git_repo " + return 1 + fi + + local gitrepo_file=$(mktemp /tmp/GitRepository.XXXXXX.yaml) + { + echo "apiVersion: source.toolkit.fluxcd.io/v1" + echo "kind: GitRepository" + echo "metadata:" + echo " name: \"$repo_name\"" + echo " namespace: \"$namespace\"" + echo "spec:" + echo " interval: 1m" + echo " url: https://github.com/aenix-io/cozystack" + echo " ref:" + echo " branch: \"$branch\"" + echo " ignore: |" + echo " !/packages/apps/ " + + } > "$gitrepo_file" + + kubectl apply -f "$gitrepo_file" + + rm -f "$gitrepo_file" +} diff --git a/hack/modules/ignored_charts b/hack/modules/ignored_charts new file mode 100644 index 00000000..916dad6a --- /dev/null +++ b/hack/modules/ignored_charts @@ -0,0 +1,6 @@ +tenant +http-cache +mysql +rabbitmq +virtual-machine +vpn diff --git a/hack/modules/install_all_apps.sh b/hack/modules/install_all_apps.sh new file mode 100755 index 00000000..9faf35e2 --- /dev/null +++ b/hack/modules/install_all_apps.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +source ./modules/colors.sh + +# Function to load ignored charts from a file +function load_ignored_charts() { + local ignore_file="$1" + local ignored_charts=() + + if [[ -f "$ignore_file" ]]; then + while IFS= read -r chart; do + ignored_charts+=("$chart") + done < "$ignore_file" + else + echo "Ignore file not found: $ignore_file" + fi + + # Return the array of ignored charts + echo "${ignored_charts[@]}" +} + +# Function to check if a chart is in the ignored list +function is_chart_ignored() { + local chart_name="$1" + shift + local ignored_charts=("$@") + + for ignored_chart in "${ignored_charts[@]}"; do + if [[ "$ignored_chart" == "$chart_name" ]]; then + return 0 + fi + done + return 1 +} + +function install_all_apps() { + local charts_dir="$1" + local namespace="$2" + local gitrepo_name="$3" + local flux_ns="$4" + + local ignore_file="./modules/ignored_charts" + local ignored_charts + ignored_charts=($(load_ignored_charts "$ignore_file")) + + for chart_path in "$charts_dir"/*; do + if [[ -d "$chart_path" ]]; then + local chart_name + chart_name=$(basename "$chart_path") + # Check if the chart is in the ignored list + if is_chart_ignored "$chart_name" "${ignored_charts[@]}"; then + echo "Skipping chart: $chart_name (listed in ignored charts)" + continue + fi + + chart_name="$chart_name-e2e" + echo "Installing chart: $chart_name" + install_helmrelease "$chart_name" "$namespace" "$chart_path" "$gitrepo_name" "$flux_ns" + + echo "Checking status for HelmRelease: $chart_name" + check_helmrelease_status "$chart_name" "$namespace" + else + echo "$chart_path is not a directory. Skipping." + fi + done +} diff --git a/hack/modules/install_chart.sh b/hack/modules/install_chart.sh new file mode 100755 index 00000000..7fe53be1 --- /dev/null +++ b/hack/modules/install_chart.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +source ./modules/colors.sh + +function install_helmrelease() { + local release_name="$1" + local namespace="$2" + local chart_path="$3" + local gitrepo_name="$4" + local flux_ns="$5" + local values_file="$6" + + if [[ -z "$release_name" ]]; then + echo -e "${RED}Error: Release name is required.${RESET}" + exit 1 + fi + + if [[ -z "$namespace" ]]; then + echo -e "${RED}Error: Namespace name is required.${RESET}" + exit 1 + fi + + if [[ -z "$chart_path" ]]; then + echo -e "${RED}Error: Chart path name is required.${RESET}" + exit 1 + fi + + local helmrelease_file=$(mktemp /tmp/HelmRelease.XXXXXX.yaml) + + { + echo "apiVersion: helm.toolkit.fluxcd.io/v2" + echo "kind: HelmRelease" + echo "metadata:" + echo " labels:" + echo " cozystack.io/ui: \"true\"" + echo " name: \"$release_name\"" + echo " namespace: \"$namespace\"" + echo "spec:" + echo " chart:" + echo " spec:" + echo " chart: \"$chart_path\"" + echo " reconcileStrategy: Revision" + echo " sourceRef:" + echo " kind: GitRepository" + echo " name: \"$gitrepo_name\"" + echo " namespace: \"$flux_ns\"" + echo " version: '*'" + echo " interval: 1m0s" + echo " timeout: 5m0s" + + if [[ -n "$values_file" && -f "$values_file" ]]; then + echo " values:" + cat "$values_file" | sed 's/^/ /' + fi + } > "$helmrelease_file" + + kubectl apply -f "$helmrelease_file" + + rm -f "$helmrelease_file" +} diff --git a/hack/modules/install_tenant.sh b/hack/modules/install_tenant.sh new file mode 100755 index 00000000..ed4c3291 --- /dev/null +++ b/hack/modules/install_tenant.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +function install_tenant (){ + local release_name="$1" + local namespace="$2" + local gitrepo_name="$3" + local flux_ns="$4" + local values_file="${5:-tenant.yaml}" + + install_helmrelease "$release_name" "$namespace" "../../packages/apps/tenant" "$gitrepo_name" "$flux_ns" "$values_file" +} diff --git a/hack/values/tenant.yaml b/hack/values/tenant.yaml new file mode 100644 index 00000000..1a7862d7 --- /dev/null +++ b/hack/values/tenant.yaml @@ -0,0 +1,6 @@ +host: "" +etcd: false +monitoring: true +ingress: false +seaweedfs: true +isolated: true diff --git a/packages/apps/ferretdb/Chart.yaml b/packages/apps/ferretdb/Chart.yaml index d23dfe5e..0b8fc993 100644 --- a/packages/apps/ferretdb/Chart.yaml +++ b/packages/apps/ferretdb/Chart.yaml @@ -16,7 +16,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.4.0 +version: 0.4.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/packages/apps/ferretdb/templates/init-script.yaml b/packages/apps/ferretdb/templates/init-script.yaml index beef5a5a..35723ede 100644 --- a/packages/apps/ferretdb/templates/init-script.yaml +++ b/packages/apps/ferretdb/templates/init-script.yaml @@ -34,6 +34,9 @@ stringData: init.sh: | #!/bin/bash set -e + + until pg_isready ; do sleep 5; done + echo "== create users" {{- if .Values.users }} psql -v ON_ERROR_STOP=1 <<\EOT @@ -60,7 +63,7 @@ stringData: DROP USER $user; EOT done - + echo "== create roles" psql -v ON_ERROR_STOP=1 --echo-all <<\EOT SELECT 'CREATE ROLE app_admin NOINHERIT;' @@ -80,7 +83,7 @@ stringData: FOR schema_record IN SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('pg_catalog', 'information_schema') LOOP -- Changing Schema Ownership EXECUTE format('ALTER SCHEMA %I OWNER TO %I', schema_record.schema_name, 'app_admin'); - + -- Add rights for the admin role EXECUTE format('GRANT ALL ON SCHEMA %I TO %I', schema_record.schema_name, 'app_admin'); EXECUTE format('GRANT ALL ON ALL TABLES IN SCHEMA %I TO %I', schema_record.schema_name, 'app_admin'); diff --git a/packages/apps/versions_map b/packages/apps/versions_map index 5e06c332..a88b0f9e 100644 --- a/packages/apps/versions_map +++ b/packages/apps/versions_map @@ -9,7 +9,8 @@ ferretdb 0.1.0 4ffa8615 ferretdb 0.1.1 5ca8823 ferretdb 0.2.0 adaf603 ferretdb 0.3.0 aa2f553 -ferretdb 0.4.0 HEAD +ferretdb 0.4.0 def2eb0f +ferretdb 0.4.1 HEAD http-cache 0.1.0 a956713 http-cache 0.2.0 5ca8823 http-cache 0.3.0 fab5940