From e3d595997eabd91384b60f41a36bc04479d25be8 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Wed, 17 Jan 2024 09:32:59 +0100 Subject: [PATCH] Rethink the db-operator chart testing (#16) Co-authored-by: Denis Dabischa --- .github/workflows/chart-release.yaml | 33 --- .github/workflows/db-instances-test.yaml | 59 ----- .github/workflows/helm-workflow.yaml | 134 ++++++++++ .github/workflows/test.yaml | 119 --------- .gitignore | 3 + .yamlfmt | 2 + Makefile | 48 +++- charts/db-instances/Chart.yaml | 2 +- charts/db-instances/README.md | 125 +++++++-- ...gen-test-service-monitor-values.yaml.tmpl} | 0 .../templates/tests/test_service_monitor.yaml | 11 +- charts/db-instances/values.yaml | 9 - charts/db-operator/Chart.yaml | 5 +- charts/db-operator/Makefile | 2 - charts/db-operator/README.md | 194 +++++++++----- charts/db-operator/README.md.gotmpl | 128 ++++++++++ charts/db-operator/ci/0-crds-test-values.yaml | 8 + .../db-operator/ci/0-nocrds-test-values.yaml | 9 + .../db-operator/ci/1-mysql-test-values.yaml | 13 + .../ci/1-postgresql-test-values.yaml | 13 + charts/db-operator/ci/2-gsql-test-values.yaml | 66 +++++ ...i-1-values.yaml => 3-linter-values-1.yaml} | 4 +- ...i-2-values.yaml => 3-linter-values-2.yaml} | 36 +-- ...i-3-values.yaml => 3-linter-values-3.yaml} | 38 +-- ...i-4-values.yaml => 3-linter-values-4.yaml} | 32 +-- ...i-5-values.yaml => 3-linter-values-5.yaml} | 3 +- charts/db-operator/files/queries.yaml | 6 +- .../db-operator/scripts/mysql}/test_read.sh | 0 .../db-operator/scripts/mysql}/test_write.sh | 0 .../scripts/postgresql}/test_read.sh | 0 .../scripts/postgresql}/test_write.sh | 0 charts/db-operator/scripts/test_crds | 35 +++ charts/db-operator/scripts/test_gsql | 44 ++++ charts/db-operator/scripts/test_values | 23 +- charts/db-operator/templates/NOTES.txt | 102 ++++++++ .../db-operator/templates/test/crds-test.yaml | 101 ++++++++ .../db-operator/templates/test/gsql-test.yaml | 237 ++++++++++++++++++ .../templates/test/mysql-test.yaml | 183 ++++++++++++++ .../templates/test/postgres-test.yaml | 183 ++++++++++++++ .../templates/test/test-scripts.yaml | 17 ++ charts/db-operator/values-local.yaml | 57 ++--- charts/db-operator/values-stanley.yaml | 11 +- charts/db-operator/values.yaml | 25 +- .../ci/helmfile.yaml => helmfile.yaml | 45 ++-- tests/db-operator/integration.sh | 146 ----------- tests/db-operator/mock-googleapi/Chart.yaml | 5 - .../mock-googleapi/templates/api.yaml | 45 ---- tests/db-operator/mock-googleapi/values.yaml | 0 tests/db-operator/mysql-generic/Chart.yaml | 5 - .../mysql-generic/templates/db.yaml | 13 - .../mysql-generic/templates/instance.yaml | 23 -- .../mysql-generic/templates/mysql-server.yaml | 40 --- .../mysql-generic/templates/test/test.yaml | 95 ------- .../mysql-generic/templates/testscript.yaml | 10 - tests/db-operator/mysql-generic/values.yaml | 11 - tests/db-operator/postgres-generic/Chart.yaml | 5 - .../postgres-generic/templates/db.yaml | 13 - .../postgres-generic/templates/instance.yaml | 22 -- .../templates/postgres-server.yaml | 39 --- .../postgres-generic/templates/test/test.yaml | 95 ------- .../templates/testscript.yaml | 10 - .../db-operator/postgres-generic/values.yaml | 5 - tests/db-operator/postgres-gsql/Chart.yaml | 5 - .../postgres-gsql/templates/config.yaml | 7 - .../postgres-gsql/templates/instance.yaml | 29 --- tests/db-operator/postgres-gsql/values.yaml | 29 --- 66 files changed, 1647 insertions(+), 1170 deletions(-) delete mode 100644 .github/workflows/chart-release.yaml delete mode 100644 .github/workflows/db-instances-test.yaml create mode 100644 .github/workflows/helm-workflow.yaml delete mode 100644 .github/workflows/test.yaml create mode 100644 .gitignore create mode 100644 .yamlfmt rename charts/db-instances/ci/{ci-test-service-monitor-values.yaml => ci-gen-test-service-monitor-values.yaml.tmpl} (100%) delete mode 100644 charts/db-operator/Makefile create mode 100644 charts/db-operator/README.md.gotmpl create mode 100644 charts/db-operator/ci/0-crds-test-values.yaml create mode 100644 charts/db-operator/ci/0-nocrds-test-values.yaml create mode 100644 charts/db-operator/ci/1-mysql-test-values.yaml create mode 100644 charts/db-operator/ci/1-postgresql-test-values.yaml create mode 100644 charts/db-operator/ci/2-gsql-test-values.yaml rename charts/db-operator/ci/{ci-1-values.yaml => 3-linter-values-1.yaml} (88%) rename charts/db-operator/ci/{ci-2-values.yaml => 3-linter-values-2.yaml} (82%) rename charts/db-operator/ci/{ci-3-values.yaml => 3-linter-values-3.yaml} (86%) rename charts/db-operator/ci/{ci-4-values.yaml => 3-linter-values-4.yaml} (72%) rename charts/db-operator/ci/{ci-5-values.yaml => 3-linter-values-5.yaml} (55%) rename {tests/db-operator/mysql-generic/scripts => charts/db-operator/scripts/mysql}/test_read.sh (100%) rename {tests/db-operator/mysql-generic/scripts => charts/db-operator/scripts/mysql}/test_write.sh (100%) rename {tests/db-operator/postgres-generic/scripts => charts/db-operator/scripts/postgresql}/test_read.sh (100%) rename {tests/db-operator/postgres-generic/scripts => charts/db-operator/scripts/postgresql}/test_write.sh (100%) create mode 100755 charts/db-operator/scripts/test_crds create mode 100755 charts/db-operator/scripts/test_gsql create mode 100644 charts/db-operator/templates/NOTES.txt create mode 100644 charts/db-operator/templates/test/crds-test.yaml create mode 100644 charts/db-operator/templates/test/gsql-test.yaml create mode 100644 charts/db-operator/templates/test/mysql-test.yaml create mode 100644 charts/db-operator/templates/test/postgres-test.yaml create mode 100644 charts/db-operator/templates/test/test-scripts.yaml rename charts/db-instances/ci/helmfile.yaml => helmfile.yaml (71%) delete mode 100755 tests/db-operator/integration.sh delete mode 100644 tests/db-operator/mock-googleapi/Chart.yaml delete mode 100644 tests/db-operator/mock-googleapi/templates/api.yaml delete mode 100644 tests/db-operator/mock-googleapi/values.yaml delete mode 100644 tests/db-operator/mysql-generic/Chart.yaml delete mode 100644 tests/db-operator/mysql-generic/templates/db.yaml delete mode 100644 tests/db-operator/mysql-generic/templates/instance.yaml delete mode 100644 tests/db-operator/mysql-generic/templates/mysql-server.yaml delete mode 100644 tests/db-operator/mysql-generic/templates/test/test.yaml delete mode 100644 tests/db-operator/mysql-generic/templates/testscript.yaml delete mode 100644 tests/db-operator/mysql-generic/values.yaml delete mode 100644 tests/db-operator/postgres-generic/Chart.yaml delete mode 100644 tests/db-operator/postgres-generic/templates/db.yaml delete mode 100644 tests/db-operator/postgres-generic/templates/instance.yaml delete mode 100644 tests/db-operator/postgres-generic/templates/postgres-server.yaml delete mode 100644 tests/db-operator/postgres-generic/templates/test/test.yaml delete mode 100644 tests/db-operator/postgres-generic/templates/testscript.yaml delete mode 100644 tests/db-operator/postgres-generic/values.yaml delete mode 100644 tests/db-operator/postgres-gsql/Chart.yaml delete mode 100644 tests/db-operator/postgres-gsql/templates/config.yaml delete mode 100644 tests/db-operator/postgres-gsql/templates/instance.yaml delete mode 100644 tests/db-operator/postgres-gsql/values.yaml diff --git a/.github/workflows/chart-release.yaml b/.github/workflows/chart-release.yaml deleted file mode 100644 index 5582834..0000000 --- a/.github/workflows/chart-release.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: Release Charts - -on: - workflow_run: - workflows: ["Test"] - branches: [main] - types: - - completed - -jobs: - chart-release: - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Configure Git - run: | - git config user.name "$GITHUB_ACTOR" - git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - - - name: Install Helm - uses: azure/setup-helm@v3 - with: - version: v3.9.4 - - - name: Run chart-releaser - uses: helm/chart-releaser-action@v1.4.0 - env: - CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/db-instances-test.yaml b/.github/workflows/db-instances-test.yaml deleted file mode 100644 index 4f09f4a..0000000 --- a/.github/workflows/db-instances-test.yaml +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: Test db-instances chart -on: push - -env: - HELM_VERSION: "3.12.1" - PYTHON_VERSION: "3.9" - -jobs: - test-chart: - 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: "v${{ env.HELM_VERSION }}" - - - uses: actions/setup-python@v4 - with: - python-version: ${{ env.PYTHON_VERSION }} - check-latest: true - - - name: Set up chart-testing - uses: helm/chart-testing-action@v2.3.0 - - - name: Run chart-testing (list-changed) - id: list-changed - run: | - changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) - if [[ "$changed" == *"db-instances"* ]]; then - echo "changed=true" >> "$GITHUB_OUTPUT" - fi - - - name: Run chart-testing (lint) - if: steps.list-changed.outputs.changed == 'true' - run: ct lint --validate-maintainers=false --target-branch main --charts charts/db-instances - - - name: Setup helmfile - uses: mamezou-tech/setup-helmfile@v1.2.0 - - - name: Create kind cluster - uses: helm/kind-action@v1.7.0 - - - name: Install helm dependnencies - run: | - helmfile -f charts/db-instances/ci/helmfile.yaml -l name=prometheus-stack sync - helmfile -f charts/db-instances/ci/helmfile.yaml sync - sleep 60 - - - name: Run chart-testing (install) - run: ct install --target-branch main --charts charts/db-instances - # -- TODO: Enable once there is a tested version released - # - name: Run chart-testing (upgrade) - # run: ct install --target-branch main --upgrade --charts charts/db-instances diff --git a/.github/workflows/helm-workflow.yaml b/.github/workflows/helm-workflow.yaml new file mode 100644 index 0000000..95644e8 --- /dev/null +++ b/.github/workflows/helm-workflow.yaml @@ -0,0 +1,134 @@ +name: Helm +on: push +env: + HELM_VERSION: v3.12.1 + PYTHON_VERSION: 3.9 +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + - name: Set up Helm + uses: azure/setup-helm@v3 + with: + version: ${{ env.HELM_VERSION }} + - uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + check-latest: true + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.0 + - name: Run chart-testing (lint) + run: ct lint --target-branch main --validate-maintainers=false + test-values: + needs: lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Run the test + run: | + cd charts/db-operator + ./scripts/test_values -p ./ci/unit-test + test: + needs: test-values + runs-on: ubuntu-latest + strategy: + matrix: + k8s_version: + - v1.22.15 + - v1.23.17 + - v1.24.15 + - v1.25.11 + - v1.26.6 + - v1.27.3 + - v1.28.0 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + - name: Set up Helm + uses: azure/setup-helm@v3 + with: + version: ${{ env.HELM_VERSION }} + - uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + check-latest: true + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.1 + # It's not used anymore, but it's a small step, maybe we'll need it in the future, so let it be here + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Setup helmfile + uses: mamezou-tech/setup-helmfile@v1.2.0 + - name: Prepare a config for the kind cluster + run: | + cat > kind-config.yaml <> "$GITHUB_OUTPUT" - fi - - - name: Run chart-testing (lint) - if: steps.list-changed.outputs.changed == 'true' - run: ct lint --validate-maintainers=false --target-branch main - - test-values: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Run the test - run: | - cd charts/db-operator - ./scripts/test_values -p ./ci/unit-test - - db-operator-test: - runs-on: ubuntu-latest - needs: get-chart - if: ${{ contains(needs.get-chart.outputs.changed_charts, 'db-operator') || contains(needs.get-chart.outputs.changed_charts, 'db-instances') }} - strategy: - matrix: - k8s_version: - - v1.22.8 - - v1.23.5 - - v1.24.16 - - v1.25.12 - - v1.26.7 - - v1.27.4 - steps: - - name: Checkout - uses: actions/checkout@v3 - - # The existing apparmor profile for mysql needs to be removed. - # https://github.com/actions/virtual-environments/issues/181 - # https://github.com/moby/moby/issues/7512#issuecomment-51845976 - - name: Remove MySQL App Armour Configuration - run: | - set -x - sudo apt-get remove mysql-server --purge - sudo apt-get update -y - sudo apt-get install apparmor-profiles - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - - - name: Create k3d cluster - env: - K8S_VERSION: ${{ matrix.k8s_version }} - run: make k3d - - - name: Install Cert Manager - run: make cert-manager - - - name: Install Helm chart - run: make db-operator - - - name: Integration test - run: ./tests/db-operator/integration.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3b506b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin + +ci-gen*.yaml diff --git a/.yamlfmt b/.yamlfmt new file mode 100644 index 0000000..a1bf578 --- /dev/null +++ b/.yamlfmt @@ -0,0 +1,2 @@ +formatter: + pad_line_comments: 2 diff --git a/Makefile b/Makefile index a5a22cd..e1b73c6 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,49 @@ - .PHONY: all deploy build helm .ONESHELL: test ifeq ($(K8S_VERSION),) -K8S_VERSION := v1.22.13 +K8S_VERSION := v1.28.4 endif +LOCALBIN_DIR ?= $(shell pwd)/bin +$(LOCALBIN_DIR): + mkdir -p $(LOCALBIN_DIR) + k3d: @curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash @k3d cluster create myk3s -i rancher/k3s:$(K8S_VERSION)-k3s1 @kubectl get pod -lint: ## lint helm manifests - @helm lint -f charts/db-operator/values.yaml -f charts/db-operator/ci/ci-1-values.yaml --strict ./charts/db-operator - @helm lint -f charts/db-instances/values.yaml --strict ./charts/db-instances +helmfile-operator: ## Syncs the helmfile with dependencies for testing operator + helmfile sync -f ./helmfile.yaml + +helmfile-instances: ## Syncs the helmfile with dependencies for testing dbinstances + helmfile sync -f ./helmfile.yaml -e instances + +lint: ## lint helm charts + ct lint --target-branch main --validate-maintainers=false + +test-values: + cd charts/db-operator && \ + bash ./scripts/test_values -p ./ci/unit-test + +test-operator: helmfile-operator ## test helm charts + ct install --target-branch main --charts ./charts/db-operator + +test-upgrade-operator: helmfile-operator ## test helm charts + ct install --upgrade --target-branch main --charts ./charts/db-operator + +test-instances: helmfile-instances ## test helm charts + ct install --target-branch main --charts ./charts/db-instances + +test-upgrade-instances: helmfile-instances ## test helm charts + ct install --upgrade --target-branch main --charts ./charts/db-instances + +.PHONY: gen_docs +gen-docs: ## Generate helm documentation + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN_DIR) go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest + ./bin/helm-docs --template-files=./charts/db-operator/README.md.gotmpl \ + --sort-values-order file --chart-to-generate=charts/db-operator + ./bin/helm-docs --template-files=./charts/db-isntances/README.md.gotmpl --sort-values-order file --chart-to-generate=charts/db-instances -cert-manager: ## install cert-manager chart if not exist and install local chart using helm upgrade --install command - @helm repo add jetstack https://charts.jetstack.io - @helm repo update - @helm upgrade --install --create-namespace --namespace cert-manager cert-manager jetstack/cert-manager --set installCRDs=true -db-operator: ## install db-operator chart if not exist and install local chart using helm upgrade --install command - @helm upgrade --install --create-namespace --namespace operator my-dboperator charts/db-operator -f charts/db-operator/values.yaml -f charts/db-operator/values-local.yaml - @kubectl rollout status deploy/db-operator -n operator diff --git a/charts/db-instances/Chart.yaml b/charts/db-instances/Chart.yaml index 5a69682..0b80f45 100644 --- a/charts/db-instances/Chart.yaml +++ b/charts/db-instances/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: Database Instances for db operator name: db-instances -version: 2.1.1 +version: 2.2.0 diff --git a/charts/db-instances/README.md b/charts/db-instances/README.md index 0623c4d..f810aea 100644 --- a/charts/db-instances/README.md +++ b/charts/db-instances/README.md @@ -1,15 +1,112 @@ # db-instances -Create DB Instance resources for is DB Operator - -## Installing Chart -To install the chart with the release name my-release: -``` -$ helm install --name my-release db-operator/db-instances -``` -The command deploys DB Operator on Kubernetes with default configuration. - -## Uninstalling Chart -To uninstall the `my-release` deployment: -``` -$ helm delete my-release -``` \ No newline at end of file + +![Version: 2.2.0](https://img.shields.io/badge/Version-2.2.0-informational?style=flat-square) ![AppVersion: 1.0](https://img.shields.io/badge/AppVersion-1.0-informational?style=flat-square) + +Database Instances for db operator + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| dbinstances | object | `{}` | | +| nodeSelector | object | `{}` | | +| exporter.postgres.image | string | `"wrouesnel/postgres_exporter:latest"` | | +| exporter.postgres.query.pg_postmaster.query | string | `"SELECT pg_postmaster_start_time as start_time_seconds from pg_postmaster_start_time()"` | | +| exporter.postgres.query.pg_postmaster.metrics[0].start_time_seconds.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_postmaster.metrics[0].start_time_seconds.description | string | `"Time at which postmaster started"` | | +| exporter.postgres.query.pg_stat_user_tables.query | string | `"SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan, idx_tup_fetch, n_tup_ins, n_tup_upd, n_tup_del, n_tup_hot_upd, n_live_tup, n_dead_tup, n_mod_since_analyze, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, vacuum_count, autovacuum_count, analyze_count, autoanalyze_count FROM pg_stat_user_tables"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[0].schemaname.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[0].schemaname.description | string | `"Name of the schema that this table is in"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[1].relname.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[1].relname.description | string | `"Name of this table"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[2].seq_scan.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[2].seq_scan.description | string | `"Number of sequential scans initiated on this table"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[3].seq_tup_read.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[3].seq_tup_read.description | string | `"Number of live rows fetched by sequential scans"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[4].idx_scan.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[4].idx_scan.description | string | `"Number of index scans initiated on this table"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[5].idx_tup_fetch.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[5].idx_tup_fetch.description | string | `"Number of live rows fetched by index scans"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[6].n_tup_ins.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[6].n_tup_ins.description | string | `"Number of rows inserted"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[7].n_tup_upd.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[7].n_tup_upd.description | string | `"Number of rows updated"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[8].n_tup_del.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[8].n_tup_del.description | string | `"Number of rows deleted"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[9].n_tup_hot_upd.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[9].n_tup_hot_upd.description | string | `"Number of rows HOT updated (i.e., with no separate index update required)"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[10].n_live_tup.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[10].n_live_tup.description | string | `"Estimated number of live rows"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[11].n_dead_tup.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[11].n_dead_tup.description | string | `"Estimated number of dead rows"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[12].n_mod_since_analyze.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[12].n_mod_since_analyze.description | string | `"Estimated number of rows changed since last analyze"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[13].last_vacuum.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[13].last_vacuum.description | string | `"Last time at which this table was manually vacuumed (not counting VACUUM FULL)"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[14].last_autovacuum.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[14].last_autovacuum.description | string | `"Last time at which this table was vacuumed by the autovacuum daemon"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[15].last_analyze.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[15].last_analyze.description | string | `"Last time at which this table was manually analyzed"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[16].last_autoanalyze.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[16].last_autoanalyze.description | string | `"Last time at which this table was analyzed by the autovacuum daemon"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[17].vacuum_count.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[17].vacuum_count.description | string | `"Number of times this table has been manually vacuumed (not counting VACUUM FULL)"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[18].autovacuum_count.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[18].autovacuum_count.description | string | `"Number of times this table has been vacuumed by the autovacuum daemon"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[19].analyze_count.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[19].analyze_count.description | string | `"Number of times this table has been manually analyzed"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[20].autoanalyze_count.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_user_tables.metrics[20].autoanalyze_count.description | string | `"Number of times this table has been analyzed by the autovacuum daemon"` | | +| exporter.postgres.query.pg_database.query | string | `"SELECT pg_database.datname, pg_database_size(pg_database.datname) as size FROM pg_database"` | | +| exporter.postgres.query.pg_database.metrics[0].datname.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_database.metrics[0].datname.description | string | `"Name of the database"` | | +| exporter.postgres.query.pg_database.metrics[1].size.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_database.metrics[1].size.description | string | `"Disk space used by the database"` | | +| exporter.postgres.query.pg_stat_database.query | string | `"SELECT datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit, tup_fetched, tup_inserted, tup_updated, tup_deleted, temp_bytes, deadlocks FROM pg_catalog.pg_stat_database;"` | | +| exporter.postgres.query.pg_stat_database.metrics[0].datname.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_database.metrics[0].datname.description | string | `"database NAME"` | | +| exporter.postgres.query.pg_stat_database.metrics[1].numbackends.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[1].numbackends.description | string | `"Number of backends currently connected to this database."` | | +| exporter.postgres.query.pg_stat_database.metrics[2].xact_commit.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[2].xact_commit.description | string | `"Number of transactions in this database that have been committed"` | | +| exporter.postgres.query.pg_stat_database.metrics[3].xact_rollback.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[3].xact_rollback.description | string | `"Number of transactions in this database that have been rolled back"` | | +| exporter.postgres.query.pg_stat_database.metrics[4].blks_read.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_database.metrics[4].blks_read.description | string | `"Number of disk blocks read in this database"` | | +| exporter.postgres.query.pg_stat_database.metrics[5].blks_hit.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_database.metrics[5].blks_hit.description | string | `"Number of times disk blocks were found already in the buffer cache, so that a read was not necessary"` | | +| exporter.postgres.query.pg_stat_database.metrics[6].tup_fetched.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[6].tup_fetched.description | string | `"Number of rows fetched by queries in this database"` | | +| exporter.postgres.query.pg_stat_database.metrics[7].tup_inserted.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[7].tup_inserted.description | string | `"Number of rows inserted by queries in this database"` | | +| exporter.postgres.query.pg_stat_database.metrics[8].tup_updated.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[8].tup_updated.description | string | `"Number of rows updated by queries in this database"` | | +| exporter.postgres.query.pg_stat_database.metrics[9].tup_deleted.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[9].tup_deleted.description | string | `"Number of rows deleted by queries in this database"` | | +| exporter.postgres.query.pg_stat_database.metrics[10].temp_bytes.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_database.metrics[10].temp_bytes.description | string | `"Total amount of data written to temporary files by queries in this database."` | | +| exporter.postgres.query.pg_stat_database.metrics[11].deadlocks.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_database.metrics[11].deadlocks.description | string | `"Number of deadlocks detected in this database"` | | +| exporter.postgres.query.pg_stat_statements.query | string | `"SELECT userid, pgss.dbid, pgdb.datname, queryid, query, calls, total_time, mean_time, rows FROM pg_stat_statements pgss LEFT JOIN (select oid as dbid, datname from pg_database) as pgdb on pgdb.dbid = pgss.dbid WHERE not queryid isnull ORDER BY mean_time desc limit 20"` | | +| exporter.postgres.query.pg_stat_statements.metrics[0].userid.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_statements.metrics[0].userid.description | string | `"User ID"` | | +| exporter.postgres.query.pg_stat_statements.metrics[1].dbid.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_statements.metrics[1].dbid.description | string | `"database ID"` | | +| exporter.postgres.query.pg_stat_statements.metrics[2].datname.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_statements.metrics[2].datname.description | string | `"database NAME"` | | +| exporter.postgres.query.pg_stat_statements.metrics[3].queryid.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_statements.metrics[3].queryid.description | string | `"Query unique Hash Code"` | | +| exporter.postgres.query.pg_stat_statements.metrics[4].query.usage | string | `"LABEL"` | | +| exporter.postgres.query.pg_stat_statements.metrics[4].query.description | string | `"Query class"` | | +| exporter.postgres.query.pg_stat_statements.metrics[5].calls.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_statements.metrics[5].calls.description | string | `"Number of times executed"` | | +| exporter.postgres.query.pg_stat_statements.metrics[6].total_time.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_statements.metrics[6].total_time.description | string | `"Total time spent in the statement, in milliseconds"` | | +| exporter.postgres.query.pg_stat_statements.metrics[7].mean_time.usage | string | `"GAUGE"` | | +| exporter.postgres.query.pg_stat_statements.metrics[7].mean_time.description | string | `"Mean time spent in the statement, in milliseconds"` | | +| exporter.postgres.query.pg_stat_statements.metrics[8].rows.usage | string | `"COUNTER"` | | +| exporter.postgres.query.pg_stat_statements.metrics[8].rows.description | string | `"Total number of rows retrieved or affected by the statement"` | | +| mysql.enabled | bool | `false` | | +| postgresql.enabled | bool | `false` | | +| tests | object | `{"serviceMonitor":{"enabled":false}}` | ------------------------------------------------------------------- | + diff --git a/charts/db-instances/ci/ci-test-service-monitor-values.yaml b/charts/db-instances/ci/ci-gen-test-service-monitor-values.yaml.tmpl similarity index 100% rename from charts/db-instances/ci/ci-test-service-monitor-values.yaml rename to charts/db-instances/ci/ci-gen-test-service-monitor-values.yaml.tmpl diff --git a/charts/db-instances/templates/tests/test_service_monitor.yaml b/charts/db-instances/templates/tests/test_service_monitor.yaml index 55aa7eb..dc2154b 100644 --- a/charts/db-instances/templates/tests/test_service_monitor.yaml +++ b/charts/db-instances/templates/tests/test_service_monitor.yaml @@ -1,6 +1,6 @@ {{- if (((.Values.tests).serviceMonitor).enabled) }} # --------------------------------------------------------------------- -# -- A config map with a script to test ServiceMonitor +# -- A config map with a script to test serviceMonitor # --------------------------------------------------------------------- --- apiVersion: v1 @@ -14,10 +14,7 @@ metadata: "helm.sh/hook-weight": "1" "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded data: - test.sh: |- -{{ range .Files.Lines "files/test_service_monitor" }} - {{ . }} -{{- end }} +{{ (.Files.Glob "files/*").AsConfig | indent 2 }} --- apiVersion: v1 @@ -43,8 +40,8 @@ spec: volumeMounts: - name: test-script readOnly: true - mountPath: /test.sh - subPath: test.sh + mountPath: /test_service_monitor + subPath: test_service_monitor args: - /test.sh restartPolicy: Never diff --git a/charts/db-instances/values.yaml b/charts/db-instances/values.yaml index 2a167c3..6ad6daf 100644 --- a/charts/db-instances/values.yaml +++ b/charts/db-instances/values.yaml @@ -1,7 +1,5 @@ dbinstances: {} - nodeSelector: {} - exporter: postgres: image: wrouesnel/postgres_exporter:latest @@ -12,7 +10,6 @@ exporter: - start_time_seconds: usage: "GAUGE" description: "Time at which postmaster started" - pg_stat_user_tables: query: "SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan, idx_tup_fetch, n_tup_ins, n_tup_upd, n_tup_del, n_tup_hot_upd, n_live_tup, n_dead_tup, n_mod_since_analyze, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, vacuum_count, autovacuum_count, analyze_count, autoanalyze_count FROM pg_stat_user_tables" metrics: @@ -79,7 +76,6 @@ exporter: - autoanalyze_count: usage: "COUNTER" description: "Number of times this table has been analyzed by the autovacuum daemon" - pg_database: query: "SELECT pg_database.datname, pg_database_size(pg_database.datname) as size FROM pg_database" metrics: @@ -89,7 +85,6 @@ exporter: - size: usage: "GAUGE" description: "Disk space used by the database" - pg_stat_database: query: "SELECT datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit, tup_fetched, tup_inserted, tup_updated, tup_deleted, temp_bytes, deadlocks FROM pg_catalog.pg_stat_database;" metrics: @@ -129,7 +124,6 @@ exporter: - deadlocks: usage: "COUNTER" description: "Number of deadlocks detected in this database" - pg_stat_statements: query: "SELECT userid, pgss.dbid, pgdb.datname, queryid, query, calls, total_time, mean_time, rows FROM pg_stat_statements pgss LEFT JOIN (select oid as dbid, datname from pg_database) as pgdb on pgdb.dbid = pgss.dbid WHERE not queryid isnull ORDER BY mean_time desc limit 20" metrics: @@ -160,13 +154,10 @@ exporter: - rows: usage: "COUNTER" description: "Total number of rows retrieved or affected by the statement" - mysql: enabled: false - postgresql: enabled: false - # Overwrite Namespace if secrets get created and release namespace != operator ns # operatorNamespace: diff --git a/charts/db-operator/Chart.yaml b/charts/db-operator/Chart.yaml index ada0b3a..d4353f9 100644 --- a/charts/db-operator/Chart.yaml +++ b/charts/db-operator/Chart.yaml @@ -1,8 +1,7 @@ ---- apiVersion: v2 type: application name: db-operator -version: 1.16.2 +version: 1.17.0 # --------------------------------------------------------------------------------- # -- All supported k8s versions are in the test: # -- https://github.com/db-operator/charts/blob/main/.github/workflows/test.yaml @@ -11,12 +10,10 @@ kubeVersion: ">= 1.22-prerelease" appVersion: "2.1.1" description: The DB Operator creates databases and make them available in the cluster via Custom Resource. home: https://github.com/db-operator/db-operator - maintainers: - name: Nikolai Rodionov email: allanger@zohomail.com url: https://badhouseplants.net - sources: - https://github.com/db-operator/db-operator - https://github.com/db-operator/cloudish-sql diff --git a/charts/db-operator/Makefile b/charts/db-operator/Makefile deleted file mode 100644 index 97d4272..0000000 --- a/charts/db-operator/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -gen_docs: - \ No newline at end of file diff --git a/charts/db-operator/README.md b/charts/db-operator/README.md index a91b2fb..42f0f0e 100644 --- a/charts/db-operator/README.md +++ b/charts/db-operator/README.md @@ -1,107 +1,167 @@ # db-operator -![Version: 1.9.1](https://img.shields.io/badge/Version-1.9.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.12.0](https://img.shields.io/badge/AppVersion-1.12.0-informational?style=flat-square) +![Version: 1.17.0](https://img.shields.io/badge/Version-1.17.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.1.1](https://img.shields.io/badge/AppVersion-2.1.1-informational?style=flat-square) -DB Operator is Kubernetes operator -The source of the operator can be found here: https://github.com/db-operator/db-operator +The DB Operator creates databases and make them available in the cluster via Custom Resource. -## Installing Chart -To install the chart with the release name my-release: -``` -$ helm install --name my-release db-operator/db-operator +## Source Code + +* +* +* +* + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Nikolai Rodionov | | | + +## Requirements + +Kubernetes: `>= 1.22-prerelease` + +## Installing the Chart + +```console +$ helm repo add db-operator https://db-operator.github.io/charts +$ helm repo update +$ helm install db-operator/db-operator ``` -The command deploys DB Operator on Kubernetes with default configuration. For the configuration options see details [Parameters](#Parameters) -## Uninstalling Chart -To uninstall the `my-release` deployment: +If you want to manage `CRDs` yourself, you need to set `.Values.crds.install` to `false`. In that case they won't be a part of templated manifests. + +We don't support this way of `CRD` management officially though, so we can't promise to answer your questions if you choose to go this way. If you want to know more about it, keep reading, we'll talk about it later. + +## Upgarding the Chart + +If there are breaking changes, they should be described in this README's latest item and in helm-chart notes. So if you run `helm upgrade db-operator db-operator/db-operator --dry-run`, you will see if there are breaking changes there. + +## Uninstalling the Chart + +To uninstall the operator only, run + +```console +$ helm uninstall db-operator ``` -$ helm delete my-release + +If you have CRDs installed by the chart, you will also have to run something like: + +```console +# !!! This command will remove all kinda.rocks CRDs from the cluster, +# so please make sure that you really want to run it +$ for crd in $(kubectl get crds | awk '{print $1}' | grep 'kinda.rocks'); do kubectl delete crd "${crd}"; done ``` -## Webhooks +## Why are we packaging CRDs in templates? + +There are several reasons for that. The main one is that we are using webhooks and they require certificates to be created. If you have a look at the `CRDs` templates, you'll see something like that: -You can disable webhooks if you don't need them, by providing this value -```yaml -webhook: - create: false +```mustache + annotations: + controller-gen.kubebuilder.io/version: v0.12.1 + {{- if .Values.webhook.certificate.create }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ .Values.webhook.certificate.name}} + {{ else }} + cert-manager.io/inject-ca-from-secret: {{ .Release.Namespace }}/{{ .Values.webhook.certificate.secretName}} + {{- end }} + {{- if .Values.crds.keep }} + helm.sh/resource-policy: keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} ``` -## Requirements +So, as you can see they require some information about the release, so they can't be static. Since the webhook is an important part of what we're distributing, we don't want to have it disabled by default. -Kubernetes: `>= 1.22-prerelease` +Also, we do not have `CRs` in the package, so there is no chicken-egg problem here. You don't need to have `CRDs` installed to install the chart. Since `CRDs` are a part of the operator and you can't have one without another, having them packaged and distributed together makes more sense to us. + +But it's still possible for users to manage `CRDs` on their own. You need to set `.Values.crds.install` to false and go to the [db-operator rgit repository](https://github.com/db-operator/db-operator). There, in the `config/crd/bases` directory, you'll find `CRD` manifests. But if you decided to go this way and you have problems with `CRDs`, you're most probably on your own, you still can open issues though. -If you use webhooks, you also might need to have cert-manager +## Why do we need cert-manager? -## Values +At the moment, `db-operator` chart requires `cert-manager` to be present in the cluster. It's because webhook related resources are using it to create certificates. It should change one day, since we would like this chart to be self-sufficient, but currently that's what we've got. +## What is `.Values.tests`? + +We use helm tests feature for testing the chart in CI. Though we know that this feature should be used by users to test their intsallations, we do not think that it can be very helpful in this particular case. Test resources are creating a powerful `ClusterRoles`, so **please make sure you don't have them enabled**, unless you really know what you're doing and why. + +## Chart Values | Key | Type | Default | Description | |-----|------|---------|-------------| -| affinity | object | `{}` | | +| nameOverride | string | `""` | | +| image.repository | string | `"ghcr.io/db-operator/db-operator"` | | +| image.pullPolicy | string | `"Always"` | | +| image.logLevel | string | `"info"` | | +| reconcileInterval | string | `"60"` | | +| watchNamespace | string | `""` | | +| checkForChanges | bool | `false` | ---------------------------------------------------------- | +| rbac.create | bool | `true` | | +| serviceAccount.create | bool | `true` | | +| crds.install | bool | `true` | | +| crds.keep | bool | `true` | | +| crds.annotations | object | `{}` | | +| webhook.enabled | bool | `true` | | +| webhook.serviceAccount.create | bool | `true` | | +| webhook.names.mutating | string | `"db-operator-mutating-webhook-configuration"` | | +| webhook.names.validating | string | `"db-operator-validating-webhook-configuration"` | | +| webhook.certificate.create | bool | `true` | ------------------------------------------ | +| webhook.certificate.name | string | `"db-operator-webhook"` | | +| webhook.certificate.secretName | string | `"db-operator-webhook-cert"` | | +| webhook.certificate.issuer.create | bool | `true` | | +| webhook.certificate.issuer.name | string | `"db-operator-issuer"` | | +| webhook.certificate.issuer.kind | string | `"Issuer"` | --------------------------------------- | +| security | object | `{}` | | +| resources | object | `{}` | | +| nodeSelector | object | `{}` | | | annotations | object | `{}` | | -| config.backup.activeDeadlineSeconds | int | `600` | | -| config.backup.mysql.image | string | `"kloeckneri/mydump-gcs:latest"` | | -| config.backup.nodeSelector | object | `{}` | | -| config.backup.postgres.image | string | `"kloeckneri/pgdump-gcs:latest"` | | -| config.backup.resources.requests.cpu | float | `0.2` | | -| config.backup.resources.requests.memory | string | `"64Mi"` | | -| config.instance.generic | object | `{}` | | +| podLabels | object | `{}` | | +| affinity | object | `{}` | | +| tolerations | list | `[]` | | +| config.instance.google.proxy.nodeSelector | object | `{}` | | | config.instance.google.proxy.image | string | `"ghcr.io/db-operator/db-auth-gateway:v0.1.10"` | | | config.instance.google.proxy.metricsPort | int | `9090` | | -| config.instance.google.proxy.nodeSelector | object | `{}` | | +| config.instance.generic | object | `{}` | | | config.instance.percona.proxy.image | string | `"severalnines/proxysql:2.0"` | | | config.instance.percona.proxy.metricsPort | int | `9090` | | +| config.backup.activeDeadlineSeconds | int | `600` | | +| config.backup.nodeSelector | object | `{}` | | +| config.backup.postgres.image | string | `"kloeckneri/pgdump-gcs:latest"` | | +| config.backup.mysql.image | string | `"kloeckneri/mydump-gcs:latest"` | | +| config.backup.resources.requests.memory | string | `"64Mi"` | | +| config.backup.resources.requests.cpu | float | `0.2` | | +| config.monitoring.promPushGateway | string | `""` | | | config.monitoring.nodeSelector | object | `{}` | | | config.monitoring.postgres.image | string | `"wrouesnel/postgres_exporter:latest"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[0].userid.description | string | `"User ID"` | | +| config.monitoring.postgres.queries.pg_stat_statements.query | string | `"SELECT userid, pgss.dbid, pgdb.datname, queryid, query, calls, total_time, mean_time, rows FROM pg_stat_statements pgss LEFT JOIN (select oid as dbid, datname from pg_database) as pgdb on pgdb.dbid = pgss.dbid WHERE not queryid isnull ORDER BY mean_time desc limit 20"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[0].userid.usage | string | `"LABEL"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[1].dbid.description | string | `"database ID"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[0].userid.description | string | `"User ID"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[1].dbid.usage | string | `"LABEL"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[2].datname.description | string | `"database NAME"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[1].dbid.description | string | `"database ID"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[2].datname.usage | string | `"LABEL"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[3].queryid.description | string | `"Query unique Hash Code"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[2].datname.description | string | `"database NAME"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[3].queryid.usage | string | `"LABEL"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[4].query.description | string | `"Query class"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[3].queryid.description | string | `"Query unique Hash Code"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[4].query.usage | string | `"LABEL"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[5].calls.description | string | `"Number of times executed"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[4].query.description | string | `"Query class"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[5].calls.usage | string | `"COUNTER"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[6].total_time.description | string | `"Total time spent in the statement, in milliseconds"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[5].calls.description | string | `"Number of times executed"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[6].total_time.usage | string | `"COUNTER"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[7].mean_time.description | string | `"Mean time spent in the statement, in milliseconds"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[6].total_time.description | string | `"Total time spent in the statement, in milliseconds"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[7].mean_time.usage | string | `"GAUGE"` | | -| config.monitoring.postgres.queries.pg_stat_statements.metrics[8].rows.description | string | `"Total number of rows retrieved or affected by the statement"` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[7].mean_time.description | string | `"Mean time spent in the statement, in milliseconds"` | | | config.monitoring.postgres.queries.pg_stat_statements.metrics[8].rows.usage | string | `"COUNTER"` | | -| config.monitoring.postgres.queries.pg_stat_statements.query | string | `"SELECT userid, pgss.dbid, pgdb.datname, queryid, query, calls, total_time, mean_time, rows FROM pg_stat_statements pgss LEFT JOIN (select oid as dbid, datname from pg_database) as pgdb on pgdb.dbid = pgss.dbid WHERE not queryid isnull ORDER BY mean_time desc limit 20"` | | -| config.monitoring.promPushGateway | string | `""` | | -| crds.annotations | object | `{}` | | -| crds.install | bool | `true` | | -| crds.keep | bool | `true` | | -| image.logLevel | string | `"info"` | | -| image.pullPolicy | string | `"Always"` | | -| image.repository | string | `"ghcr.io/db-operator/db-operator"` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| podLabels | object | `{}` | | -| rbac.create | bool | `true` | | -| reconcileInterval | string | `"60"` | | -| resources | object | `{}` | | +| config.monitoring.postgres.queries.pg_stat_statements.metrics[8].rows.description | string | `"Total number of rows retrieved or affected by the statement"` | | | secrets.gsql | object | `{}` | | -| security | object | `{}` | | +| serviceMonitor.enabled | bool | `false` | | | service.annotations | object | `{}` | | -| service.port | int | `8080` | | | service.type | string | `"ClusterIP"` | | -| serviceAccount.create | bool | `true` | | -| serviceMonitor.enabled | bool | `false` | | -| tolerations | list | `[]` | | -| watchNamespace | string | `""` | | -| webhook.certificate.create | bool | `true` | ------------------------------------------ | -| webhook.certificate.issuer.create | bool | `true` | | -| webhook.certificate.issuer.kind | string | `"Issuer"` | --------------------------------------- | -| webhook.certificate.issuer.name | string | `"db-operator-issuer"` | | -| webhook.certificate.name | string | `"db-operator-webhook"` | | -| webhook.certificate.secretName | string | `"db-operator-webhook-cert"` | | -| webhook.names.mutating | string | `"db-operator-mutating-webhook-configuration"` | | -| webhook.names.validating | string | `"db-operator-validating-webhook-configuration"` | | -| webhook.serviceName | string | `"db-operator-webhook"` | | +| service.port | int | `8080` | | +| tests | object | `{"attempts":{"amount":10,"timeout":30},"cleanup":true,"enabled":[]}` | ------------------------------------------------------------------- | +## Dev Notes + +After changing default `Values`, please execute `make gen_docs` to update the `README.md` file. Readme file is generated by the `helm-docs` tool, so make sure not to edit it manually. ## Upgrading diff --git a/charts/db-operator/README.md.gotmpl b/charts/db-operator/README.md.gotmpl new file mode 100644 index 0000000..73c2d78 --- /dev/null +++ b/charts/db-operator/README.md.gotmpl @@ -0,0 +1,128 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.requirementsSection" . }} + + +## Installing the Chart + +```console +$ helm repo add db-operator https://db-operator.github.io/charts +$ helm repo update +$ helm install db-operator/db-operator +``` + +If you want to manage `CRDs` yourself, you need to set `.Values.crds.install` to `false`. In that case they won't be a part of templated manifests. + +We don't support this way of `CRD` management officially though, so we can't promise to answer your questions if you choose to go this way. If you want to know more about it, keep reading, we'll talk about it later. + +## Upgarding the Chart + +If there are breaking changes, they should be described in this README's latest item and in helm-chart notes. So if you run `helm upgrade db-operator db-operator/db-operator --dry-run`, you will see if there are breaking changes there. + +## Uninstalling the Chart + +To uninstall the operator only, run + +```console +$ helm uninstall db-operator +``` + +If you have CRDs installed by the chart, you will also have to run something like: + +```console +# !!! This command will remove all kinda.rocks CRDs from the cluster, +# so please make sure that you really want to run it +$ for crd in $(kubectl get crds | awk '{print $1}' | grep 'kinda.rocks'); do kubectl delete crd "${crd}"; done +``` + +## Why are we packaging CRDs in templates? + +There are several reasons for that. The main one is that we are using webhooks and they require certificates to be created. If you have a look at the `CRDs` templates, you'll see something like that: + +```mustache + annotations: + controller-gen.kubebuilder.io/version: v0.12.1 + {{ `{{- if .Values.webhook.certificate.create }} `}} + cert-manager.io/inject-ca-from: {{ `{{ .Release.Namespace }}/{{ .Values.webhook.certificate.name}}` }} + {{ `{{ else }}` }} + cert-manager.io/inject-ca-from-secret: {{ `{{ .Release.Namespace }}/{{ .Values.webhook.certificate.secretName}}` }} + {{ `{{- end }}` }} + {{ `{{- if .Values.crds.keep }}` }} + helm.sh/resource-policy: keep + {{ `{{- end }}` }} + {{ `{{- with .Values.crds.annotations }}` }} + {{ `{{- toYaml . | nindent 4 }}` }} + {{ `{{- end }}` }} +``` + +So, as you can see they require some information about the release, so they can't be static. Since the webhook is an important part of what we're distributing, we don't want to have it disabled by default. + +Also, we do not have `CRs` in the package, so there is no chicken-egg problem here. You don't need to have `CRDs` installed to install the chart. Since `CRDs` are a part of the operator and you can't have one without another, having them packaged and distributed together makes more sense to us. + +But it's still possible for users to manage `CRDs` on their own. You need to set `.Values.crds.install` to false and go to the [db-operator rgit repository](https://github.com/db-operator/db-operator). There, in the `config/crd/bases` directory, you'll find `CRD` manifests. But if you decided to go this way and you have problems with `CRDs`, you're most probably on your own, you still can open issues though. + +## Why do we need cert-manager? + +At the moment, `db-operator` chart requires `cert-manager` to be present in the cluster. It's because webhook related resources are using it to create certificates. It should change one day, since we would like this chart to be self-sufficient, but currently that's what we've got. + +## What is `.Values.tests`? + +We use helm tests feature for testing the chart in CI. Though we know that this feature should be used by users to test their intsallations, we do not think that it can be very helpful in this particular case. Test resources are creating a powerful `ClusterRoles`, so **please make sure you don't have them enabled**, unless you really know what you're doing and why. + +## Chart Values +{{ template "chart.valuesTable" . }} +## Dev Notes + +After changing default `Values`, please execute `make gen_docs` to update the `README.md` file. Readme file is generated by the `helm-docs` tool, so make sure not to edit it manually. + + +## Upgrading + +If there is an breaking change, or something that might make the upgrade complicated, it should be described here + +
+ To `v1.11.0` +Additional selectors were added to the default templates in an attempt to follow the same labelling scheme everywhere, but since selectors are immutable, the upgrade will require removing of the db-operator deployment. + +```bash +$ kubectl get deploy +NAME READY UP-TO-DATE AVAILABLE AGE +db-operator 1/1 1 1 22s +$ kubectl delete deploy db-operator +deployment.apps "db-operator" deleted +$ helm upgrade db-operator db-operator/db-operator --version 1.11.0 +``` + +
+ +
+ To `v1.10.0` + +CRDs are moved to the `templates` folder, so now they are part of the release. It means that after the upgrade, you will get errors about resource ownerships. Thow errors will contain messages about missing `labels` and `annotations`, and the easiest way to fix it, will be just to add the `metadata` that helm can't find. So you can follow those messages one by one and when all the `CRDs` are patched, you'll be able to install the release. + +For example: + +```BASH +$ helm upgrade my-release . +Error: UPGRADE FAILED: rendered manifests contain a resource that already exists. Unable to continue with update: CustomResourceDefinition "databases.kinda.rocks" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "my-release"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "default" +``` + +So you should add following metadata: +```YAML +metadata: + labels: + "app.kubernetes.io/managed-by": Helm + annotations: + "meta.helm.sh/release-name": my-release + "meta.helm.sh/release-namespace": default +``` +
diff --git a/charts/db-operator/ci/0-crds-test-values.yaml b/charts/db-operator/ci/0-crds-test-values.yaml new file mode 100644 index 0000000..50013e1 --- /dev/null +++ b/charts/db-operator/ci/0-crds-test-values.yaml @@ -0,0 +1,8 @@ +reconcileInterval: "10" +crds: + keep: false +tests: + enabled: + - crds + crds: + installed: true diff --git a/charts/db-operator/ci/0-nocrds-test-values.yaml b/charts/db-operator/ci/0-nocrds-test-values.yaml new file mode 100644 index 0000000..21987b3 --- /dev/null +++ b/charts/db-operator/ci/0-nocrds-test-values.yaml @@ -0,0 +1,9 @@ +reconcileInterval: "10" +crds: + keep: false + install: false +tests: + enabled: + - crds + crds: + installed: false diff --git a/charts/db-operator/ci/1-mysql-test-values.yaml b/charts/db-operator/ci/1-mysql-test-values.yaml new file mode 100644 index 0000000..d4207f6 --- /dev/null +++ b/charts/db-operator/ci/1-mysql-test-values.yaml @@ -0,0 +1,13 @@ +reconcileInterval: "10" +crds: + keep: false +tests: + enabled: + - mysql + mysql: + admin: + password: 123123!! + user: root + service: + name: mysql-instance + namespace: databases diff --git a/charts/db-operator/ci/1-postgresql-test-values.yaml b/charts/db-operator/ci/1-postgresql-test-values.yaml new file mode 100644 index 0000000..c719754 --- /dev/null +++ b/charts/db-operator/ci/1-postgresql-test-values.yaml @@ -0,0 +1,13 @@ +reconcileInterval: "10" +crds: + keep: false +tests: + enabled: + - postgresql + postgresql: + admin: + password: 123123!! + user: postgres + service: + name: postgres-instance-postgresql + namespace: databases diff --git a/charts/db-operator/ci/2-gsql-test-values.yaml b/charts/db-operator/ci/2-gsql-test-values.yaml new file mode 100644 index 0000000..b233912 --- /dev/null +++ b/charts/db-operator/ci/2-gsql-test-values.yaml @@ -0,0 +1,66 @@ +reconcileInterval: "10" +crds: + keep: false +secrets: + gsql: + admin: | + { + "type": "service_account", + "project_id": "integration-project", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "admin", + "auth_uri": "", + "token_uri": "", + "auth_provider_x509_cert_url": "", + "client_x509_cert_url": "" + } + readonly: | + { + "type": "service_account", + "project_id": "integration-project", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "readonly", + "auth_uri": "", + "token_uri": "", + "auth_provider_x509_cert_url": "", + "client_x509_cert_url": "" + } +tests: + enabled: + - gsql + gsql: + cloudishSQL: + image: + repository: ghcr.io/db-operator/cloudish-sql + tag: v1.0.1 + dbin: + adminUser: postgres + adminPassword: Passw0rd + instanceConfig: + data: | + { + "databaseVersion": "POSTGRES_11", + "settings": { + "tier": "db-f1-micro", + "availabilityType": "ZONAL", + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "activationPolicy": "ALWAYS", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true + }, + "dataDiskType": "PD_SSD", + "backupConfiguration": { + "enabled": false + }, + "storageAutoResizeLimit": "0", + "storageAutoResize": true + }, + "backendType": "SECOND_GEN", + "region": "somewhere" + } diff --git a/charts/db-operator/ci/ci-1-values.yaml b/charts/db-operator/ci/3-linter-values-1.yaml similarity index 88% rename from charts/db-operator/ci/ci-1-values.yaml rename to charts/db-operator/ci/3-linter-values-1.yaml index a575b45..2b5d23e 100644 --- a/charts/db-operator/ci/ci-1-values.yaml +++ b/charts/db-operator/ci/3-linter-values-1.yaml @@ -1,11 +1,11 @@ +crds: + keep: false secrets: gsql: admin: "sa-json" readonly: "sa-json" rbac: create: false - priorityClassName: "" - imagePullSecrets: - name: myRegistrySecret diff --git a/charts/db-operator/ci/ci-2-values.yaml b/charts/db-operator/ci/3-linter-values-2.yaml similarity index 82% rename from charts/db-operator/ci/ci-2-values.yaml rename to charts/db-operator/ci/3-linter-values-2.yaml index 2c11cab..18b228f 100644 --- a/charts/db-operator/ci/ci-2-values.yaml +++ b/charts/db-operator/ci/3-linter-values-2.yaml @@ -1,39 +1,14 @@ +crds: + keep: false image: repository: ghcr.io/db-operator/db-operator pullPolicy: Always - reconcileInterval: "60" - rbac: {} - serviceAccount: {} - resources: {} - nodeSelector: {} - annotations: {} - -affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - preference: - matchExpressions: - - key: another-node-label-key - operator: In - values: - - another-node-label-value -tolerations: - - key: "key1" - operator: "Equal" - value: "value1" - effect: "NoSchedule" - - key: "key2" - operator: "Equal" - value: "value2" - effect: "NoSchedule" - config: instance: google: @@ -48,16 +23,12 @@ config: metricsPort: 9090 backup: activeDeadlineSeconds: 600 # 10m - nodeSelector: - nodetype: database postgres: image: "kloeckneri/pgdump-gcs:latest" mysql: image: "kloeckneri/mydump-gcs:latest" monitoring: promPushGateway: prometheus-pushgateway.monitoring:9090 - nodeSelector: - nodetype: database postgres: image: wrouesnel/postgres_exporter:latest queries: @@ -91,12 +62,10 @@ config: - rows: usage: "COUNTER" description: "Total number of rows retrieved or affected by the statement" - secrets: gsql: admin: "sa-json" readonly: "sa-json" - serviceMonitor: enabled: false interval: 10s @@ -117,7 +86,6 @@ relabelings: targetLabel: nodename replacement: $1 action: replace - service: annotations: {} type: ClusterIP diff --git a/charts/db-operator/ci/ci-3-values.yaml b/charts/db-operator/ci/3-linter-values-3.yaml similarity index 86% rename from charts/db-operator/ci/ci-3-values.yaml rename to charts/db-operator/ci/3-linter-values-3.yaml index 103e74d..381816c 100644 --- a/charts/db-operator/ci/ci-3-values.yaml +++ b/charts/db-operator/ci/3-linter-values-3.yaml @@ -1,15 +1,13 @@ +crds: + keep: false image: repository: ghcr.io/db-operator/db-operator pullPolicy: Always - reconcileInterval: "60" - rbac: create: true - serviceAccount: create: true - resources: limits: cpu: 10m @@ -17,40 +15,15 @@ resources: requests: cpu: 10m memory: 32Mi - -nodeSelector: - nodetype: database - annotations: some.custom.annotation: "*" - podLabels: key1: value-one key2: value-two - -affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/e2e-az-name - operator: In - values: - - e2e-eu1 - - e2e-us2 - -tolerations: - - key: "key1" - operator: "Equal" - value: "value1" - effect: "NoSchedule" - config: instance: google: proxy: - nodeSelector: - nodetype: database image: ghcr.io/db-operator/db-auth-gateway:latest metricsPort: 9090 generic: {} @@ -60,16 +33,12 @@ config: metricsPort: 9090 backup: activeDeadlineSeconds: 600 # 10m - nodeSelector: - nodetype: database postgres: image: "kloeckneri/pgdump-gcs:latest" mysql: image: "kloeckneri/mydump-gcs:latest" monitoring: promPushGateway: prometheus-pushgateway.monitoring:9090 - nodeSelector: - nodetype: database postgres: image: wrouesnel/postgres_exporter:latest queries: @@ -103,7 +72,6 @@ config: - rows: usage: "COUNTER" description: "Total number of rows retrieved or affected by the statement" - secrets: gsql: admin: | @@ -132,7 +100,6 @@ secrets: "auth_provider_x509_cert_url": "", "client_x509_cert_url": "" } - serviceMonitor: enabled: false interval: 10s @@ -153,7 +120,6 @@ relabelings: targetLabel: nodename replacement: $1 action: replace - service: annotations: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp diff --git a/charts/db-operator/ci/ci-4-values.yaml b/charts/db-operator/ci/3-linter-values-4.yaml similarity index 72% rename from charts/db-operator/ci/ci-4-values.yaml rename to charts/db-operator/ci/3-linter-values-4.yaml index e352a64..63d0cbe 100644 --- a/charts/db-operator/ci/ci-4-values.yaml +++ b/charts/db-operator/ci/3-linter-values-4.yaml @@ -1,3 +1,5 @@ +crds: + keep: false resources: limits: cpu: 10m @@ -5,34 +7,11 @@ resources: requests: cpu: 10m memory: 32Mi - -nodeSelector: - nodetype: database - annotations: some.custom.annotation: "*" - podLabels: key1: value-one key2: value-two - -affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/e2e-az-name - operator: In - values: - - e2e-eu1 - - e2e-us2 - -tolerations: - - key: "key1" - operator: "Equal" - value: "value1" - effect: "NoSchedule" - config: instance: google: @@ -47,24 +26,18 @@ config: metricsPort: 9090 backup: activeDeadlineSeconds: 600 # 10m - nodeSelector: - nodetype: database postgres: image: "kloeckneri/pgdump-gcs:latest" mysql: image: "kloeckneri/mydump-gcs:latest" monitoring: promPushGateway: "" - nodeSelector: - nodetype: database postgres: image: wrouesnel/postgres_exporter:latest queries: pg_stat_statements: {} - secrets: gsql: {} - serviceMonitor: enabled: false interval: 10s @@ -85,7 +58,6 @@ relabelings: targetLabel: nodename replacement: $1 action: replace - service: annotations: {} type: ClusterIP diff --git a/charts/db-operator/ci/ci-5-values.yaml b/charts/db-operator/ci/3-linter-values-5.yaml similarity index 55% rename from charts/db-operator/ci/ci-5-values.yaml rename to charts/db-operator/ci/3-linter-values-5.yaml index f3b78eb..4dbc9c0 100644 --- a/charts/db-operator/ci/ci-5-values.yaml +++ b/charts/db-operator/ci/3-linter-values-5.yaml @@ -1,3 +1,4 @@ ---- +crds: + keep: false webhook: create: false diff --git a/charts/db-operator/files/queries.yaml b/charts/db-operator/files/queries.yaml index f8a282c..59ceb5c 100644 --- a/charts/db-operator/files/queries.yaml +++ b/charts/db-operator/files/queries.yaml @@ -4,7 +4,6 @@ pg_postmaster: - start_time_seconds: usage: "GAUGE" description: "Time at which postmaster started" - pg_stat_user_tables: query: "SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan, idx_tup_fetch, n_tup_ins, n_tup_upd, n_tup_del, n_tup_hot_upd, n_live_tup, n_dead_tup, n_mod_since_analyze, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, vacuum_count, autovacuum_count, analyze_count, autoanalyze_count FROM pg_stat_user_tables" metrics: @@ -71,7 +70,6 @@ pg_stat_user_tables: - autoanalyze_count: usage: "COUNTER" description: "Number of times this table has been analyzed by the autovacuum daemon" - pg_stat_statements: query: "SELECT userid, pgss.dbid, pgdb.datname, queryid, query, calls, total_time, mean_time, rows FROM pg_stat_statements pgss LEFT JOIN (select oid as dbid, datname from pg_database) as pgdb on pgdb.dbid = pgss.dbid WHERE not queryid isnull ORDER BY mean_time desc limit 20" metrics: @@ -102,9 +100,8 @@ pg_stat_statements: - rows: usage: "COUNTER" description: "Total number of rows retrieved or affected by the statement" - pg_database: - query: "SELECT pg_database.datname, pg_database_size(pg_database.datname) as size FROM pg_database WHERE pg_database.datname=current_database()" + query: "SELECT pg_database.datname, pg_database_size(pg_database.datname) as size FROM pg_database WHERE pg_database.datname=current_database()" metrics: - datname: usage: "LABEL" @@ -112,7 +109,6 @@ pg_database: - size: usage: "GAUGE" description: "Disk space used by the database" - pg_stat_database: query: "SELECT datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit, tup_fetched, tup_inserted, tup_updated, tup_deleted, temp_bytes, deadlocks FROM pg_catalog.pg_stat_database WHERE datname=current_database();" metrics: diff --git a/tests/db-operator/mysql-generic/scripts/test_read.sh b/charts/db-operator/scripts/mysql/test_read.sh similarity index 100% rename from tests/db-operator/mysql-generic/scripts/test_read.sh rename to charts/db-operator/scripts/mysql/test_read.sh diff --git a/tests/db-operator/mysql-generic/scripts/test_write.sh b/charts/db-operator/scripts/mysql/test_write.sh similarity index 100% rename from tests/db-operator/mysql-generic/scripts/test_write.sh rename to charts/db-operator/scripts/mysql/test_write.sh diff --git a/tests/db-operator/postgres-generic/scripts/test_read.sh b/charts/db-operator/scripts/postgresql/test_read.sh similarity index 100% rename from tests/db-operator/postgres-generic/scripts/test_read.sh rename to charts/db-operator/scripts/postgresql/test_read.sh diff --git a/tests/db-operator/postgres-generic/scripts/test_write.sh b/charts/db-operator/scripts/postgresql/test_write.sh similarity index 100% rename from tests/db-operator/postgres-generic/scripts/test_write.sh rename to charts/db-operator/scripts/postgresql/test_write.sh diff --git a/charts/db-operator/scripts/test_crds b/charts/db-operator/scripts/test_crds new file mode 100755 index 0000000..8ae1e1d --- /dev/null +++ b/charts/db-operator/scripts/test_crds @@ -0,0 +1,35 @@ +#! /usr/bin/env bash +set -e +# --------------------------------------------------------------------- +# -- This script is checking whether CRDS are installed or not +# --------------------------------------------------------------------- +ATTEMPTS_AMOUNT="${TEST_ATTEMPTS_AMOUNT:-10}" +ATTEMPTS_TIMEOUT="${TEST_ATTEMPTS_TIMEOUT:-30}" +INSTALLED="${TEST_INSTALLED:-true}" +CRDS=("databases.kinda.rocks" "dbinstances.kinda.rocks" "dbusers.kinda.rocks") +TEST_PASSED=false + +for _ in $(seq 1 "${ATTEMPTS_AMOUNT}"); do + for CRD in "${CRDS[@]}"; do + SUCCESS=true + if ! kubectl get crd "$CRD"; then + SUCCESS=false + fi; + if [ "${SUCCESS}" == "${INSTALLED}" ]; then + echo "[INFO]: Test is passed, ${CRD} installed -> ${INSTALLED}" + TEST_PASSED=true; + else + TEST_PASSED=false + break + fi + done + if [ "${TEST_PASSED}" == "true" ]; then + exit 0 + fi + echo "[INFO]: Sleeping ${ATTEMPTS_TIMEOUT} seconds" + sleep "$ATTEMPTS_TIMEOUT" +done + +echo "[ERROR]: Test is failed, check the kubectl get crds output" +kubectl get crds +exit 1; diff --git a/charts/db-operator/scripts/test_gsql b/charts/db-operator/scripts/test_gsql new file mode 100755 index 0000000..3d5478a --- /dev/null +++ b/charts/db-operator/scripts/test_gsql @@ -0,0 +1,44 @@ +#!/bin/bash + +ATTEMPTS_AMOUNT="${TEST_ATTEMPTS_AMOUNT:-10}" +ATTEMPTS_TIMEOUT="${TEST_ATTEMPTS_TIMEOUT:-30}" +DB_INSTANCE_NAME="${TEST_DB_INSTANCE_NAME}" +CLOUD_PROXY_DEPLOYMENT="dbinstance-${TEST_CLOUD_PROXY_DEPLOYMENT:-${DB_INSTANCE_NAME}-gsql-instance-cloudproxy}" +EXPECTED_STATUS=true +TEST_PASSED=false + +for _ in $(seq 1 "$ATTEMPTS_AMOUNT"); do + echo "[INFO]: Sleeping ${ATTEMPTS_TIMEOUT} seconds" + sleep "$ATTEMPTS_TIMEOUT" + ACTUAL_STATUS=$(kubectl get dbinstance "${DB_INSTANCE_NAME}" -o yaml | yq '.status.status') + + if [ "${ACTUAL_STATUS}" == "${EXPECTED_STATUS}" ]; then + echo "[INFO]: Test is passed, dbinstance is ready" + TEST_PASSED=true; + break + fi + +done + +if [ "${TEST_PASSED}" != "true" ]; then + echo "[ERROR]: Test is failed, check the kubectl get dbinstance output" + kubectl get dbinstance "${DB_INSTANCE_NAME}" -o yaml | yq + exit 1; +fi + +for _ in $(seq 1 "$ATTEMPTS_AMOUNT"); do + echo "[INFO]: Sleeping ${ATTEMPTS_TIMEOUT} seconds" + sleep "$ATTEMPTS_TIMEOUT" + ACTUAL_STATUS=$(kubectl get deployment "${CLOUD_PROXY_DEPLOYMENT}" -o yaml | yq '.status.availableReplicas') + DESIRED_STATUS=$(kubectl get deployment "${CLOUD_PROXY_DEPLOYMENT}" -o yaml | yq '.status.replicas') + + if [ "${ACTUAL_STATUS}" == "${DESIRED_STATUS}" ]; then + echo "[INFO]: Test is passed, cloud proxy is deployed" + exit 0 + fi + +done + +echo "[ERROR]: Test is failed, check the kubectl get dbinstance output" +kubectl get dbinstance "${DB_INSTANCE_NAME}" -o yaml | yq +exit 1; diff --git a/charts/db-operator/scripts/test_values b/charts/db-operator/scripts/test_values index 9a91a61..a7011b0 100755 --- a/charts/db-operator/scripts/test_values +++ b/charts/db-operator/scripts/test_values @@ -3,8 +3,8 @@ set -e # ----------------------------------------------------------------------- # -- It's a script that should check if values are working correctly -# -- -# -- It's not checking the content of generated files, but only checks +# -- +# -- It's not checking the content of generated files, but only checks # -- which files are generated (currently) # -- # -- This scripts requires go-yq and helm @@ -12,7 +12,7 @@ set -e function usage() { cat <&2 done -shift $(($OPTIND - 1)) +shift $((OPTIND - 1)) if [ -z "${VALUES_PATH}" ]; then echo VALUES_PATH is not set @@ -41,13 +41,12 @@ fi CURRENT_DIR=$(pwd) -ERROR=false -for FILE in $(find $VALUES_PATH -type f); do +find "$VALUES_PATH" -type f | while read -r FILE; do WORKDIR=$(mktemp -d) echo "Checking $FILE" - cd $WORKDIR + cd "$WORKDIR" yq '.values' "$CURRENT_DIR/$FILE" > values.yaml - helm template db-operator $CURRENT_DIR -f values.yaml | yq -s '.kind + "-" + .metadata.name' + helm template db-operator "$CURRENT_DIR" -f values.yaml | yq -s '.kind + "-" + .metadata.name' rm -f values.yaml ACTUAL_FILES=($(ls $WORKDIR)) EXPECTED_FILES=($(yq '.files[]' $CURRENT_DIR/$FILE)) @@ -56,11 +55,7 @@ for FILE in $(find $VALUES_PATH -type f); do echo "PASSED" rm -rf "${WORKDIR}" else - ERROR=true echo "FAILED: Please check unexpected files -> ${DIFF[*]}" + exit 1 fi done - -if $ERROR; then - exit 1 -fi diff --git a/charts/db-operator/templates/NOTES.txt b/charts/db-operator/templates/NOTES.txt new file mode 100644 index 0000000..8ab32a3 --- /dev/null +++ b/charts/db-operator/templates/NOTES.txt @@ -0,0 +1,102 @@ +----------------------------------------------------------------------- + .-"``"-. + /______; \ + {_______}\| + (/ a a \)(_) + (.-.).-.) + _______________________ooo__( ^ )___________________________ + / '-.___.-' \ +| Please read these notes, they might be usefull and we will try to | +| make them as short as possible | + \________________________________________ooo_______________________/ + |_ | _| jgs + \___|___/ + {___|___} + |_ | _| + /-'Y'-\ + (__/ \__) + +----------------------------------------------------------------------- +Release information +The Chart name: {{ .Chart.Name }}. +The Repo URL: https://db-operator.github.io/charts +The Release name {{ .Release.Name }}. +----------------------------------------------------------------------- +Breaking changes and migration paths + +{{ .Chart.Version }} is not breaking, you don't have to worry + +{{- if not .Values.crds.install }} +----------------------------------------------------------------------- +You've chosen not to install CRDs with this release. + +We officially do not distribute CRDs outside of this helm chart, so +you will have to deal with that on your own. + +If it was a mistake, update the values so they contain the following: + +".Values.crds.install: true" + +{{- end }} +{{- if not .Values.webhook.enabled }} +----------------------------------------------------------------------- +You've chosen not to install and configure the webhook. +Your "kinda.rocks" manifests won't be validated and converted when +the API version is upgraded. + +It's not required by db-operator to work, but if you want to have the +webhook in place, you can set ".Values.webhook.enabled" to "true" +{{- end }} + +{{- if has "gsql" .Values.tests.enabled }} +----------------------------------------------------------------------- +You seem to have the gsql test set to true, usually, +it shouldn't be done. + +Make sure that you want to run tests, and not using this installation +in production in any form. + +Or remove 'gsql' '.Values.tests.enabled' +{{- end }} + +{{- if has "postgresql" .Values.tests.enabled }} +----------------------------------------------------------------------- +You seem to have the postgresql test set to true, usually, +it shouldn't be done. + +Make sure that you want to run tests, and not using this installation +in production in any form. + +Or remove 'postgresql' .Values.tests.enabled' + +Also, if you want to test your postgresql installation, you need to +provide a postgres server yourself. Test itself doesn't deploy a server +{{- end }} + +{{- if has "mysql" .Values.tests.enabled }} +----------------------------------------------------------------------- +You seem to have the mysql test set to true, usually, +it shouldn't be done. + +Make sure that you want to run tests, and not using this installation +in production in any form. + +Or remove 'mysql' '.Values.tests.enabled' + +Also, if you want to test your mysql installation, you need to +provide a mysql server yourself. Test itself doesn't deploy a server +{{- end }} + +{{- if has "crds" .Values.tests.enabled }} +----------------------------------------------------------------------- +You seem to have the crds test set to true, usually, +it shouldn't be done. + +!! This test uses a ClusterRole that has an access to all the resoucres +in the cluster, so make sure that you want to run tests, +and not using this installation. + +Or remove 'crds' '.Values.tests.enabled' +{{- end }} + + diff --git a/charts/db-operator/templates/test/crds-test.yaml b/charts/db-operator/templates/test/crds-test.yaml new file mode 100644 index 0000000..499e362 --- /dev/null +++ b/charts/db-operator/templates/test/crds-test.yaml @@ -0,0 +1,101 @@ +{{- $version := semver .Capabilities.KubeVersion.Version }} +{{- if has "crds" .Values.tests.enabled }} +# --------------------------------------------------------------------- +# -- Test that CRDs are installed +# --------------------------------------------------------------------- +# --------------------------------------------------------------------- +# -- Prepare roles and bindings to access k8s resources from the test +# --------------------------------------------------------------------- +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "db-operator.name" . }}-dbin-role + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["get", "list",] + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "db-operator.name" . }}-dbin-sa + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +automountServiceAccountToken: true + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "db-operator.name" . }}-db-rb + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +subjects: +- kind: ServiceAccount + name: {{ template "db-operator.name" . }}-dbin-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "db-operator.name" . }}-dbin-role + apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "db-operator.name" . }}-test + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "7" +spec: + serviceAccountName: {{ template "db-operator.name" . }}-dbin-sa + automountServiceAccountToken: true + volumes: + - name: test-script + configMap: + name: {{ template "db-operator.name" . }}-test-script + containers: + - name: tester + image: alpine/k8s:{{ $version.Major }}.{{ $version.Minor }}.{{ $version.Patch }} + volumeMounts: + - name: test-script + readOnly: true + mountPath: /test_crds + subPath: test_crds + env: + - name: TEST_INSTALLED + value: "{{ .Values.tests.crds.installed }}" + command: + - bash + args: + - -e + - /test_crds + restartPolicy: Never +{{- end }} diff --git a/charts/db-operator/templates/test/gsql-test.yaml b/charts/db-operator/templates/test/gsql-test.yaml new file mode 100644 index 0000000..9736163 --- /dev/null +++ b/charts/db-operator/templates/test/gsql-test.yaml @@ -0,0 +1,237 @@ +{{- $version := semver .Capabilities.KubeVersion.Version }} +{{- if has "gsql" .Values.tests.enabled }} +# --------------------------------------------------------------------- +# -- Test Google API requests with cloudish-sql +# -- https://github.com/db-operator/cloudish-sql +# -- +# -- The script that is running checks is added to a configmap, and +# -- later exexuted in pod. If you want to see the logic of this test, +# -- please, go to the bottom of the file and find a configmap with +# -- with a bash script +# --------------------------------------------------------------------- +# -- Prepare clousdish sql and dependencies +# --------------------------------------------------------------------- +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "db-operator.name" . }}-mock-google-api + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +spec: + replicas: 1 + selector: + matchLabels: + app: googleAPI + role: test + template: + metadata: + labels: + app: googleAPI + role: test + spec: + containers: + - name: api + image: "{{ .Values.tests.gsql.cloudishSQL.image.repository }}:{{ .Values.tests.gsql.cloudishSQL.image.tag }}" + ports: + - containerPort: 8080 + name: http + imagePullPolicy: IfNotPresent + env: + - name: LOG_LEVEL + value: "DEBUG" + command: + - /usr/local/bin/cloudish-sql + - --db-address=pg-test-db:5432 + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "db-operator.name" . }}-mock-google-api + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app: googleAPI + role: test + type: ClusterIP + +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "db-operator.name" . }}-gsql-admin-creds + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +type: Opaque +data: + password: {{ .Values.tests.gsql.dbin.adminPassword | b64enc }} + user: {{ .Values.tests.gsql.dbin.adminUser | b64enc }} + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "db-operator.name" . }}-gsql-instance-config + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +data: + config: | +{{ .Values.tests.gsql.dbin.instanceConfig.data | indent 4 }} + +--- +# --------------------------------------------------------------------- +# -- Prepare roles and bindings to access k8s resources from the test +# --------------------------------------------------------------------- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "db-operator.name" . }}-gsql-dbin-role + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +rules: +- apiGroups: ["kinda.rocks", "apps"] + resources: ["*"] + verbs: ["get", "watch", "list", "delete"] + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "db-operator.name" . }}-gsql-dbin-sa + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +automountServiceAccountToken: true + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "db-operator.name" . }}-gsql-dbin-rb + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +subjects: +- kind: ServiceAccount + name: {{ template "db-operator.name" . }}-gsql-dbin-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "db-operator.name" . }}-gsql-dbin-role + apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: kinda.rocks/v1beta1 +kind: DbInstance +metadata: + name: {{ template "db-operator.name" . }}-gsql-instance + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "2" +spec: + adminSecretRef: + Name: {{ template "db-operator.name" . }}-gsql-admin-creds + Namespace: {{ .Release.Namespace }} + engine: postgres + google: + configmapRef: + Name: {{ template "db-operator.name" . }}-gsql-instance-config + Namespace: {{ .Release.Namespace }} + clientSecretRef: + Name: cloudsql-admin-serviceaccount + Namespace: {{ .Release.Namespace }} + instance: gsql-local-postgres + apiEndpoint: http://{{ template "db-operator.name" . }}-mock-google-api + monitoring: + enabled: true + +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "db-operator.name" . }}-test + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "7" +spec: + serviceAccountName: {{ template "db-operator.name" . }}-gsql-dbin-sa + automountServiceAccountToken: true + volumes: + - name: test-script + configMap: + name: {{ template "db-operator.name" . }}-test-script + containers: + - name: tester + image: alpine/k8s:{{ $version.Major }}.{{ $version.Minor }}.{{ $version.Patch }} + volumeMounts: + - name: test-script + readOnly: true + mountPath: /test_gsql + subPath: test_gsql + env: + - name: TEST_DB_INSTANCE_NAME + value: {{ template "db-operator.name" . }}-gsql-instance + command: + - bash + args: + - -e + - /test_gsql + restartPolicy: Never +{{- end }} diff --git a/charts/db-operator/templates/test/mysql-test.yaml b/charts/db-operator/templates/test/mysql-test.yaml new file mode 100644 index 0000000..b2220fe --- /dev/null +++ b/charts/db-operator/templates/test/mysql-test.yaml @@ -0,0 +1,183 @@ +{{- if has "mysql" .Values.tests.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "db-operator.name" . }}-mysql-admin-password + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +type: Opaque +data: + password: {{ .Values.tests.mysql.admin.password | b64enc }} + user: {{ .Values.tests.mysql.admin.user | b64enc }} + +--- +apiVersion: kinda.rocks/v1beta1 +kind: DbInstance +metadata: + name: {{ template "db-operator.name" . }}-mysql + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +spec: + adminSecretRef: + Namespace: {{ .Release.Namespace }} + Name: {{ template "db-operator.name" . }}-mysql-admin-password + engine: mysql + generic: + host: {{ .Values.tests.mysql.service.name }}.{{ .Values.tests.mysql.service.namespace }}.svc.cluster.local + port: 3306 + publicIp: "1.2.3.4" + backupHost: {{ .Values.tests.mysql.service.name }}.{{ .Values.tests.mysql.service.namespace }}.svc.cluster.local + +--- +apiVersion: "kinda.rocks/v1beta1" +kind: "Database" +metadata: + name: {{ template "db-operator.name" . }}-mysql + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "2" +spec: + secretName: {{ template "db-operator.name" . }}-mysql-credentials # where to save db name user, password for application + instance: {{ template "db-operator.name" . }}-mysql + backup: + enable: false + cron: "" + deletionProtected: true + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "db-operator.name" . }}-mysql-test-script + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "3" +data: + write.sh: | +{{ .Files.Get "scripts/mysql/test_write.sh" | indent 4}} + read.sh: | +{{ .Files.Get "scripts/mysql/test_read.sh" | indent 4}} + +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "db-operator.name" . }}-tester-app-{{ randAlphaNum 5 | lower }} + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "4" +spec: + containers: + - name: mysql-writer + image: imega/mysql-client + command: + - sh + - -c + - exec sh /app/write.sh + env: + - name: MYSQL_PASSWORD_FILE + value: /run/secrets/mysql/PASSWORD + - name: MYSQL_USERNAME + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: USER + - name: MYSQL_DB + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: DB + - name: MYSQL_HOST + valueFrom: + configMapKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: DB_CONN + volumeMounts: + - name: db-secret + mountPath: /run/secrets/mysql/ + readOnly: true + - name: script + mountPath: /app/ + - name: shared-data + mountPath: /tmp + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 100m + memory: 128Mi + - name: mysql-reader + image: imega/mysql-client + command: + - sh + - -c + - exec sh /app/read.sh + env: + - name: MYSQL_PASSWORD_FILE + value: /run/secrets/mysql/PASSWORD + - name: MYSQL_USERNAME + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: USER + - name: MYSQL_DB + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: DB + - name: MYSQL_HOST + valueFrom: + configMapKeyRef: + name: {{ template "db-operator.name" . }}-mysql-credentials + key: DB_CONN + volumeMounts: + - name: db-secret + mountPath: /run/secrets/mysql/ + readOnly: true + - name: script + mountPath: /app/ + - name: shared-data + mountPath: /tmp + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 100m + memory: 128Mi + restartPolicy: Never + volumes: + - name: db-secret + secret: + secretName: {{ template "db-operator.name" . }}-mysql-credentials + - name: script + configMap: + name: {{ template "db-operator.name" . }}-mysql-test-script + - name: shared-data + emptyDir: {} +{{- end }} diff --git a/charts/db-operator/templates/test/postgres-test.yaml b/charts/db-operator/templates/test/postgres-test.yaml new file mode 100644 index 0000000..3cd1399 --- /dev/null +++ b/charts/db-operator/templates/test/postgres-test.yaml @@ -0,0 +1,183 @@ +{{- if has "postgresql" .Values.tests.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "db-operator.name" . }}-postgresql-admin-password + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +type: Opaque +data: + password: {{ .Values.tests.postgresql.admin.password | b64enc }} + user: {{ .Values.tests.postgresql.admin.user | b64enc }} + +--- +apiVersion: kinda.rocks/v1beta1 +kind: DbInstance +metadata: + name: {{ template "db-operator.name" . }}-postgresql + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +spec: + adminSecretRef: + Namespace: {{ .Release.Namespace }} + Name: {{ template "db-operator.name" . }}-postgresql-admin-password + engine: postgres + generic: + host: {{ .Values.tests.postgresql.service.name }}.{{ .Values.tests.postgresql.service.namespace }}.svc.cluster.local + port: 5432 + publicIp: "1.2.3.4" + backupHost: {{ .Values.tests.postgresql.service.name }}.{{ .Values.tests.postgresql.service.namespace }}.svc.cluster.local + +--- +apiVersion: "kinda.rocks/v1beta1" +kind: "Database" +metadata: + name: {{ template "db-operator.name" . }}-postgresql + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "2" +spec: + secretName: {{ template "db-operator.name" . }}-postgresql-credentials + instance: {{ template "db-operator.name" . }}-postgresql + backup: + enable: false + cron: "" + deletionProtected: true + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "db-operator.name" . }}-postgresql-test-script + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "3" +data: + write.sh: | +{{ .Files.Get "scripts/postgresql/test_write.sh" | indent 4}} + read.sh: | +{{ .Files.Get "scripts/postgresql/test_read.sh" | indent 4}} + +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "db-operator.name" . }}-tester-app-{{ randAlphaNum 5 | lower }} + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "4" +spec: + containers: + - name: postgres-writer + image: postgres:10.4 + command: + - sh + - -c + - exec sh /app/write.sh + env: + - name: POSTGRES_PASSWORD_FILE + value: /run/secrets/postgres/POSTGRES_PASSWORD + - name: POSTGRES_USERNAME + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: POSTGRES_USER + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: POSTGRES_DB + - name: POSTGRES_HOST + valueFrom: + configMapKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: DB_CONN + volumeMounts: + - name: db-secret + mountPath: /run/secrets/postgres/ + readOnly: true + - name: script + mountPath: /app/ + - name: shared-data + mountPath: /tmp + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 100m + memory: 128Mi + - name: postgres-reader + image: postgres:10.4 + command: + - sh + - -c + - exec sh /app/read.sh + env: + - name: POSTGRES_PASSWORD_FILE + value: /run/secrets/postgres/POSTGRES_PASSWORD + - name: POSTGRES_USERNAME + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: POSTGRES_USER + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: POSTGRES_DB + - name: POSTGRES_HOST + valueFrom: + configMapKeyRef: + name: {{ template "db-operator.name" . }}-postgresql-credentials + key: DB_CONN + volumeMounts: + - name: db-secret + mountPath: /run/secrets/postgres/ + readOnly: true + - name: script + mountPath: /app/ + - name: shared-data + mountPath: /tmp + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 100m + memory: 128Mi + restartPolicy: Never + volumes: + - name: db-secret + secret: + secretName: {{ template "db-operator.name" . }}-postgresql-credentials + - name: script + configMap: + name: {{ template "db-operator.name" . }}-postgresql-test-script + - name: shared-data + emptyDir: {} +{{- end }} diff --git a/charts/db-operator/templates/test/test-scripts.yaml b/charts/db-operator/templates/test/test-scripts.yaml new file mode 100644 index 0000000..271c3bb --- /dev/null +++ b/charts/db-operator/templates/test/test-scripts.yaml @@ -0,0 +1,17 @@ +{{- if or (has "crds" .Values.tests.enabled) (has "gsql" .Values.tests.enabled) }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "db-operator.name" . }}-test-script + labels: + {{- include "labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + {{- if .Values.tests.cleanup }} + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- end }} + "helm.sh/hook-weight": "1" +data: +{{ (.Files.Glob "scripts/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/db-operator/values-local.yaml b/charts/db-operator/values-local.yaml index 6bfd067..fec4aeb 100644 --- a/charts/db-operator/values-local.yaml +++ b/charts/db-operator/values-local.yaml @@ -1,36 +1,33 @@ reconcileInterval: "10" - image: pullPolicy: IfNotPresent - secrets: - gsql: - admin: | - { - "type": "service_account", - "project_id": "integration-project", - "private_key_id": "", - "private_key": "", - "client_email": "", - "client_id": "admin", - "auth_uri": "", - "token_uri": "", - "auth_provider_x509_cert_url": "", - "client_x509_cert_url": "" - } - readonly: | - { - "type": "service_account", - "project_id": "integration-project", - "private_key_id": "", - "private_key": "", - "client_email": "", - "client_id": "readonly", - "auth_uri": "", - "token_uri": "", - "auth_provider_x509_cert_url": "", - "client_x509_cert_url": "" - } - + gsql: + admin: | + { + "type": "service_account", + "project_id": "integration-project", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "admin", + "auth_uri": "", + "token_uri": "", + "auth_provider_x509_cert_url": "", + "client_x509_cert_url": "" + } + readonly: | + { + "type": "service_account", + "project_id": "integration-project", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "readonly", + "auth_uri": "", + "token_uri": "", + "auth_provider_x509_cert_url": "", + "client_x509_cert_url": "" + } serviceMonitor: enabled: true diff --git a/charts/db-operator/values-stanley.yaml b/charts/db-operator/values-stanley.yaml index b107fcc..4596f43 100644 --- a/charts/db-operator/values-stanley.yaml +++ b/charts/db-operator/values-stanley.yaml @@ -2,18 +2,15 @@ image: repository: registry.kinda.rocks/devops/db-operator tag: latest pullPolicy: IfNotPresent - resources: limits: - cpu: "0.5" - memory: 512Mi + cpu: "0.5" + memory: 512Mi requests: - cpu: 100m - memory: 128Mi - + cpu: 100m + memory: 128Mi nodeSelector: env: production - annotations: prometheus.io/scrape: "true" prometheus.io/port: "60000" diff --git a/charts/db-operator/values.yaml b/charts/db-operator/values.yaml index 345c324..780e536 100644 --- a/charts/db-operator/values.yaml +++ b/charts/db-operator/values.yaml @@ -1,13 +1,10 @@ nameOverride: "" - image: repository: ghcr.io/db-operator/db-operator pullPolicy: Always logLevel: info - # imagePullSecrets: # - name: myRegistrySecret - reconcileInterval: "60" # watchNamespace value is comma-separated list of namespace names. It's necessary to set "" to watch cluster wide. watchNamespace: "" @@ -21,18 +18,14 @@ watchNamespace: "" # -- NOTE: Currently, it's only working with Database Users # ------------------------------------------------------------ checkForChanges: false - rbac: create: true - serviceAccount: create: true - crds: install: true keep: true annotations: {} - webhook: enabled: true serviceAccount: @@ -60,23 +53,16 @@ webhook: # -- ClusterIssuer or Issuer # ----------------------------------------- kind: Issuer - security: {} # runAsUser: 1000 # fsGroup: 1000 resources: {} - nodeSelector: {} - annotations: {} - podLabels: {} - affinity: {} - tolerations: [] - config: instance: google: @@ -136,10 +122,8 @@ config: - rows: usage: "COUNTER" description: "Total number of rows retrieved or affected by the statement" - secrets: gsql: {} - serviceMonitor: enabled: false # interval: 10s @@ -169,3 +153,12 @@ service: annotations: {} type: ClusterIP port: 8080 +# --------------------------------------------------------------------- +# -- These values are used in tests, they should not affect users +# --------------------------------------------------------------------- +tests: + enabled: [] + attempts: + amount: 10 + timeout: 30 + cleanup: true diff --git a/charts/db-instances/ci/helmfile.yaml b/helmfile.yaml similarity index 71% rename from charts/db-instances/ci/helmfile.yaml rename to helmfile.yaml index 7a9a8df..b97fc6f 100644 --- a/charts/db-instances/ci/helmfile.yaml +++ b/helmfile.yaml @@ -1,36 +1,46 @@ +environments: + default: + instances: + +--- repositories: + - name: jetstack + url: https://charts.jetstack.io - name: bitnami url: https://charts.bitnami.com/bitnami - name: prometheus-community url: https://prometheus-community.github.io/helm-charts - - name: jetstack - url: https://charts.jetstack.io -charts: +releases: - name: cert-manager chart: jetstack/cert-manager namespace: cert-manager createNamespace: true - needs: - - monitoring/prometheus-stack values: - installCRDs: true + - name: postgres-instance - installed: true - namespace: postgres - createNamespace: true + namespace: databases chart: bitnami/postgresql - needs: - - monitoring/prometheus-stack values: - - global: - postgresql: - auth: - postgresPassword: 123123!! + - global: + postgresql: + auth: + postgresPassword: 123123!! + + - name: mysql-instance + namespace: databases + chart: bitnami/mysql + values: + - auth: + rootPassword: 123123!! + password: 123123!! + - name: prometheus-stack namespace: monitoring createNamespace: true - disableValidationOnInstall: true + disableValidation: true + disableOpenAPIValidation: true chart: prometheus-community/kube-prometheus-stack values: - prometheus: @@ -48,9 +58,12 @@ charts: any: true serviceMonitorSelector: {} serviceMonitorSelectorNilUsesHelmValues: false + - name: db-operator namespace: db-operator createNamespace: true - chart: ../../db-operator needs: - cert-manager/cert-manager + installed: {{ eq .Environment.Name "instances" | toYaml }} + chart: ./charts/db-operator + diff --git a/tests/db-operator/integration.sh b/tests/db-operator/integration.sh deleted file mode 100755 index 6a5f358..0000000 --- a/tests/db-operator/integration.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh -e -# requirements: jq - -OPERATOR_NAMESPACE="operator" -TEST_NAMESPACE="test" -TEST_CHARTS_DIR="tests/db-operator" - -retry=30 -interval=15 - -case $TEST_K8S in - "microk8s") - export HELM_CMD="sudo microk8s.helm3" - export KUBECTL_CMD="sudo microk8s.kubectl" - ;; - *) - export HELM_CMD="helm" - export KUBECTL_CMD="kubectl" -esac - -check_requirements() { - jq --version > /dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "jq not installed" - exit 1; - fi -} - -check_dboperator_log() { - $KUBECTL_CMD logs -l app=db-operator -n ${OPERATOR_NAMESPACE} -} - -check_instance_status() { - echo "[DbInstance] checking" - for i in $(seq 1 $retry) - do - count=$($KUBECTL_CMD get dbin -o json | jq '.items | length') - if [ "$count" -eq 0 ]; then - echo "DbInstance resource doesn't exists" - continue; - fi - - ready_count=$($KUBECTL_CMD get dbin -o json | jq '[.items[] | select(.status.status == true)] | length') - - if [ "$ready_count" -eq "$count" ]; then - echo "[DbInstance] Status OK!" - return 0 # finish check - fi - - echo "[DbInstance] Status false" - $KUBECTL_CMD get dbin - check_dboperator_log - echo "Retrying after $interval seconds..." - sleep $interval; # retry with interval - done # end retry - echo "DbInstance not healthy" - exit 1 # return false -} - -create_googleapi_mock_server() { - $HELM_CMD upgrade --install --namespace ${OPERATOR_NAMESPACE} --create-namespace mock-googleapi ${TEST_CHARTS_DIR}/mock-googleapi --wait -} - -create_test_resources() { - echo "[Test] creating" - $KUBECTL_CMD create ns ${TEST_NAMESPACE} --dry-run=client -o yaml | $KUBECTL_CMD apply -f - \ - && $HELM_CMD upgrade --install --namespace ${TEST_NAMESPACE} test-mysql-generic ${TEST_CHARTS_DIR}/mysql-generic --wait \ - && $HELM_CMD upgrade --install --namespace ${TEST_NAMESPACE} test-pg-generic ${TEST_CHARTS_DIR}/postgres-generic --wait \ - && $HELM_CMD upgrade --install --namespace ${TEST_NAMESPACE} test-pg-gsql ${TEST_CHARTS_DIR}/postgres-gsql --wait - if [ $? -ne 0 ]; then - echo "[Test] failed to create" - exit 1; - fi - echo "[Test] created" -} - -check_databases_status() { - echo "[Database] checking" - for i in $(seq 1 $retry) - do - count=$($KUBECTL_CMD get db -n ${TEST_NAMESPACE} -o json | jq '.items | length') - if [ $count -eq 0 ]; then - echo "Database resource doesn't exists" - continue; - fi - - ready_count=$($KUBECTL_CMD get db -n ${TEST_NAMESPACE} -o json | jq '[.items[] | select(.status.status == true)] | length') - - if [ "$ready_count" -eq "$count" ]; then - echo "[Database] Status OK!" - return 0 # finish check - fi - - echo "[Database] Status false" - $KUBECTL_CMD get db -n ${TEST_NAMESPACE} - check_dboperator_log - echo "Retrying after $interval seconds..." - sleep $interval; # retry with interval - done # end retry - echo "Database not healthy" - exit 1 # return false -} - -run_test() { - echo "[Test] testing read write to database" - $HELM_CMD test test-mysql-generic -n ${TEST_NAMESPACE} \ - && $HELM_CMD test test-pg-generic -n ${TEST_NAMESPACE} - if [ $? -ne 0 ]; then - echo "[Test] failed" - exit 1; - fi - echo "[Test] OK!" -} - -delete_databases() { - echo "[Database] deleting" - $KUBECTL_CMD delete db -n ${TEST_NAMESPACE} --all \ - && echo "[Database] deleted!" -} - -check_databases_deleted() { - echo "[Database] checking deleted" - for _ in $(seq 1 $retry) - do - count=$($KUBECTL_CMD get db -n ${TEST_NAMESPACE} -o json | jq '.items | length') - if [ "$count" -ne 0 ]; then - echo "[Database] $(echo $item | jq -r '.metadata.name') not deleted" - check_dboperator_log - continue; - fi - echo "[Database] All deleted!" - return 0 # all good - done - check_dboperator_log - echo "[Database] not deleted" - exit 1 # return false -} - -check_requirements -create_googleapi_mock_server -create_test_resources -check_instance_status -check_databases_status -run_test -delete_databases -check_databases_deleted diff --git a/tests/db-operator/mock-googleapi/Chart.yaml b/tests/db-operator/mock-googleapi/Chart.yaml deleted file mode 100644 index a0fc898..0000000 --- a/tests/db-operator/mock-googleapi/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: Mock of google api server to test gsql instance -name: mock-googleapi -version: 0.1.0 diff --git a/tests/db-operator/mock-googleapi/templates/api.yaml b/tests/db-operator/mock-googleapi/templates/api.yaml deleted file mode 100644 index 3012004..0000000 --- a/tests/db-operator/mock-googleapi/templates/api.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mock-google-api -spec: - replicas: 1 - selector: - matchLabels: - app: googleAPI - role: test - template: - metadata: - labels: - app: googleAPI - role: test - spec: - containers: - - name: api - image: ghcr.io/db-operator/cloudish-sql:v1.0.1 - ports: - - containerPort: 8080 - name: http - imagePullPolicy: IfNotPresent - env: - - name: LOG_LEVEL - value: "DEBUG" - command: - - /usr/local/bin/cloudish-sql - - --db-address=pg-test-db:5432 ---- -apiVersion: v1 -kind: Service -metadata: - name: mock-google-api -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http - selector: - app: googleAPI - role: test - type: ClusterIP diff --git a/tests/db-operator/mock-googleapi/values.yaml b/tests/db-operator/mock-googleapi/values.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/tests/db-operator/mysql-generic/Chart.yaml b/tests/db-operator/mysql-generic/Chart.yaml deleted file mode 100644 index 0a3ba27..0000000 --- a/tests/db-operator/mysql-generic/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: Integration test for db operator mysql -name: test-mysql-generic-db-operator -version: 0.1.0 diff --git a/tests/db-operator/mysql-generic/templates/db.yaml b/tests/db-operator/mysql-generic/templates/db.yaml deleted file mode 100644 index d5e42f1..0000000 --- a/tests/db-operator/mysql-generic/templates/db.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: "kinda.rocks/v1beta1" -kind: "Database" -metadata: - name: {{ .Values.db.name }} - labels: - env: test -spec: - secretName: {{ .Values.db.name }}-credentials # where to save db name user, password for application - instance: {{ .Values.instance.name }} - backup: - enable: false - cron: "" - deletionProtected: false diff --git a/tests/db-operator/mysql-generic/templates/instance.yaml b/tests/db-operator/mysql-generic/templates/instance.yaml deleted file mode 100644 index 17d3101..0000000 --- a/tests/db-operator/mysql-generic/templates/instance.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: kinda.rocks/v1beta1 -kind: DbInstance -metadata: - name: {{ .Values.instance.name }} -spec: - adminSecretRef: - Namespace: {{ .Release.Namespace }} - Name: {{ .Values.instance.name }}-admin-password - engine: mysql - generic: - host: {{ .Values.mysql.serviceName }}.{{ .Release.Namespace }} - port: 3306 - publicIp: "1.2.3.4" - backupHost: {{ .Values.mysql.serviceName }}.{{ .Release.Namespace }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: {{ .Values.instance.name }}-admin-password -type: Opaque -data: - password: {{ .Values.mysql.adminPassword | b64enc }} - user: {{ .Values.mysql.adminUser | b64enc }} diff --git a/tests/db-operator/mysql-generic/templates/mysql-server.yaml b/tests/db-operator/mysql-generic/templates/mysql-server.yaml deleted file mode 100644 index d59e0db..0000000 --- a/tests/db-operator/mysql-generic/templates/mysql-server.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if .Values.mysql }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.mysql.serviceName }} -spec: - ports: - - port: 3306 - selector: - app: mysql - role: test - type: ClusterIP ---- -apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 -kind: Deployment -metadata: - name: {{ .Values.mysql.serviceName }} -spec: - replicas: 1 - selector: - matchLabels: - app: mysql - role: test - strategy: - type: Recreate - template: - metadata: - labels: - app: mysql - role: test - spec: - containers: - - image: {{ .Values.mysql.image }} - name: mysql - env: - # Use secret in real usage - - name: MYSQL_ROOT_PASSWORD - value: {{ .Values.mysql.adminPassword }} -{{- end }} \ No newline at end of file diff --git a/tests/db-operator/mysql-generic/templates/test/test.yaml b/tests/db-operator/mysql-generic/templates/test/test.yaml deleted file mode 100644 index 0a0c1a6..0000000 --- a/tests/db-operator/mysql-generic/templates/test/test.yaml +++ /dev/null @@ -1,95 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: {{ .Values.db.name }}-tester-app-{{ randAlphaNum 5 | lower }} - annotations: - "helm.sh/hook": test-success - labels: - app: mysql - role: tester -spec: - containers: - - name: mysql-writer - image: imega/mysql-client - command: - - sh - - -c - - exec sh /app/write.sh - env: - - name: MYSQL_PASSWORD_FILE - value: /run/secrets/mysql/PASSWORD - - name: MYSQL_USERNAME - valueFrom: - secretKeyRef: - name: {{ .Values.db.name }}-credentials - key: USER - - name: MYSQL_DB - valueFrom: - secretKeyRef: - name: {{ .Values.db.name }}-credentials - key: DB - - name: MYSQL_HOST - valueFrom: - configMapKeyRef: - name: {{ .Values.db.name }}-credentials - key: DB_CONN - volumeMounts: - - name: db-secret - mountPath: /run/secrets/mysql/ - readOnly: true - - name: script - mountPath: /app/ - - name: shared-data - mountPath: /tmp - imagePullPolicy: IfNotPresent - resources: - limits: - cpu: 100m - memory: 128Mi - - name: mysql-reader - image: imega/mysql-client - command: - - sh - - -c - - exec sh /app/read.sh - env: - - name: MYSQL_PASSWORD_FILE - value: /run/secrets/mysql/PASSWORD - - name: MYSQL_USERNAME - valueFrom: - secretKeyRef: - name: {{ .Values.db.name }}-credentials - key: USER - - name: MYSQL_DB - valueFrom: - secretKeyRef: - name: {{ .Values.db.name }}-credentials - key: DB - - name: MYSQL_HOST - valueFrom: - configMapKeyRef: - name: {{ .Values.db.name }}-credentials - key: DB_CONN - volumeMounts: - - name: db-secret - mountPath: /run/secrets/mysql/ - readOnly: true - - name: script - mountPath: /app/ - - name: shared-data - mountPath: /tmp - imagePullPolicy: IfNotPresent - resources: - limits: - cpu: 100m - memory: 128Mi - restartPolicy: Never - volumes: - - name: db-secret - secret: - secretName: {{ .Values.db.name }}-credentials - - name: script - configMap: - name: {{ .Values.db.name }}-test-script - - name: shared-data - emptyDir: {} \ No newline at end of file diff --git a/tests/db-operator/mysql-generic/templates/testscript.yaml b/tests/db-operator/mysql-generic/templates/testscript.yaml deleted file mode 100644 index c58e699..0000000 --- a/tests/db-operator/mysql-generic/templates/testscript.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Values.db.name }}-test-script -data: - write.sh: | -{{ .Files.Get "scripts/test_write.sh" | indent 4}} - read.sh: | -{{ .Files.Get "scripts/test_read.sh" | indent 4}} \ No newline at end of file diff --git a/tests/db-operator/mysql-generic/values.yaml b/tests/db-operator/mysql-generic/values.yaml deleted file mode 100644 index 739e861..0000000 --- a/tests/db-operator/mysql-generic/values.yaml +++ /dev/null @@ -1,11 +0,0 @@ -mysql: - serviceName: my-generic-server - adminUser: root - adminPassword: test1234 - image: mysql:5.7 - -instance: - name: my-generic-instance - -db: - name: my-generic-db \ No newline at end of file diff --git a/tests/db-operator/postgres-generic/Chart.yaml b/tests/db-operator/postgres-generic/Chart.yaml deleted file mode 100644 index 418e78f..0000000 --- a/tests/db-operator/postgres-generic/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: Integration test for db operator postgres -name: test-postgres-db-operator -version: 0.1.0 diff --git a/tests/db-operator/postgres-generic/templates/db.yaml b/tests/db-operator/postgres-generic/templates/db.yaml deleted file mode 100644 index c8d8d56..0000000 --- a/tests/db-operator/postgres-generic/templates/db.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: "kinda.rocks/v1beta1" -kind: "Database" -metadata: - name: pg-generic-db - labels: - env: test -spec: - secretName: pg-generic-db-credentials # where to save db name user, password for application - instance: pg-generic-instance - backup: - enable: false - cron: "" - deletionProtected: false diff --git a/tests/db-operator/postgres-generic/templates/instance.yaml b/tests/db-operator/postgres-generic/templates/instance.yaml deleted file mode 100644 index 5205015..0000000 --- a/tests/db-operator/postgres-generic/templates/instance.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: kinda.rocks/v1beta1 -kind: DbInstance -metadata: - name: pg-generic-instance -spec: - adminSecretRef: - Namespace: {{ .Release.Namespace }} - Name: pg-generic-admin-secret - engine: postgres - generic: - host: {{ .Values.postgres.serviceName }}.{{ .Release.Namespace }} - port: 5432 - backupHost: {{ .Values.postgres.serviceName }}.{{ .Release.Namespace }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: pg-generic-admin-secret -type: Opaque -data: - password: {{ .Values.postgres.adminPassword | b64enc }} - user: {{ .Values.postgres.adminUser | b64enc }} diff --git a/tests/db-operator/postgres-generic/templates/postgres-server.yaml b/tests/db-operator/postgres-generic/templates/postgres-server.yaml deleted file mode 100644 index a6c684c..0000000 --- a/tests/db-operator/postgres-generic/templates/postgres-server.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if .Values.postgres }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ .Values.postgres.serviceName }} -spec: - ports: - - port: 5432 - selector: - app: postgres - role: test - type: ClusterIP ---- -apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 -kind: Deployment -metadata: - name: {{ .Values.postgres.serviceName }} -spec: - replicas: 1 - selector: - matchLabels: - app: postgres - role: test - strategy: - type: Recreate - template: - metadata: - labels: - app: postgres - role: test - spec: - containers: - - name: postgres - image: {{ .Values.postgres.image }} - env: - - name: POSTGRES_PASSWORD - value: {{ .Values.postgres.adminPassword }} -{{- end }} \ No newline at end of file diff --git a/tests/db-operator/postgres-generic/templates/test/test.yaml b/tests/db-operator/postgres-generic/templates/test/test.yaml deleted file mode 100644 index 6db06ba..0000000 --- a/tests/db-operator/postgres-generic/templates/test/test.yaml +++ /dev/null @@ -1,95 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: pg-tester-app-{{ randAlphaNum 5 | lower }} - annotations: - "helm.sh/hook": test-success - labels: - app: postgres - role: tester -spec: - containers: - - name: postgres-writer - image: postgres:10.4 - command: - - sh - - -c - - exec sh /app/write.sh - env: - - name: POSTGRES_PASSWORD_FILE - value: /run/secrets/postgres/POSTGRES_PASSWORD - - name: POSTGRES_USERNAME - valueFrom: - secretKeyRef: - name: pg-generic-db-credentials - key: POSTGRES_USER - - name: POSTGRES_DB - valueFrom: - secretKeyRef: - name: pg-generic-db-credentials - key: POSTGRES_DB - - name: POSTGRES_HOST - valueFrom: - configMapKeyRef: - name: pg-generic-db-credentials - key: DB_CONN - volumeMounts: - - name: db-secret - mountPath: /run/secrets/postgres/ - readOnly: true - - name: script - mountPath: /app/ - - name: shared-data - mountPath: /tmp - imagePullPolicy: IfNotPresent - resources: - limits: - cpu: 100m - memory: 128Mi - - name: postgres-reader - image: postgres:10.4 - command: - - sh - - -c - - exec sh /app/read.sh - env: - - name: POSTGRES_PASSWORD_FILE - value: /run/secrets/postgres/POSTGRES_PASSWORD - - name: POSTGRES_USERNAME - valueFrom: - secretKeyRef: - name: pg-generic-db-credentials - key: POSTGRES_USER - - name: POSTGRES_DB - valueFrom: - secretKeyRef: - name: pg-generic-db-credentials - key: POSTGRES_DB - - name: POSTGRES_HOST - valueFrom: - configMapKeyRef: - name: pg-generic-db-credentials - key: DB_CONN - volumeMounts: - - name: db-secret - mountPath: /run/secrets/postgres/ - readOnly: true - - name: script - mountPath: /app/ - - name: shared-data - mountPath: /tmp - imagePullPolicy: IfNotPresent - resources: - limits: - cpu: 100m - memory: 128Mi - restartPolicy: Never - volumes: - - name: db-secret - secret: - secretName: pg-generic-db-credentials - - name: script - configMap: - name: postgres-test-script - - name: shared-data - emptyDir: {} diff --git a/tests/db-operator/postgres-generic/templates/testscript.yaml b/tests/db-operator/postgres-generic/templates/testscript.yaml deleted file mode 100644 index 9182e91..0000000 --- a/tests/db-operator/postgres-generic/templates/testscript.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: postgres-test-script -data: - read.sh: | -{{ .Files.Get "scripts/test_read.sh" | indent 4}} - write.sh: | -{{ .Files.Get "scripts/test_write.sh" | indent 4}} \ No newline at end of file diff --git a/tests/db-operator/postgres-generic/values.yaml b/tests/db-operator/postgres-generic/values.yaml deleted file mode 100644 index 885d0fa..0000000 --- a/tests/db-operator/postgres-generic/values.yaml +++ /dev/null @@ -1,5 +0,0 @@ -postgres: - serviceName: pg-test-db - adminUser: postgres - adminPassword: test1234 - image: postgres:11-alpine \ No newline at end of file diff --git a/tests/db-operator/postgres-gsql/Chart.yaml b/tests/db-operator/postgres-gsql/Chart.yaml deleted file mode 100644 index 2323ee0..0000000 --- a/tests/db-operator/postgres-gsql/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: Gsql instance for integration test -name: test-gsql-db-operator -version: 0.1.0 diff --git a/tests/db-operator/postgres-gsql/templates/config.yaml b/tests/db-operator/postgres-gsql/templates/config.yaml deleted file mode 100644 index fcfffaf..0000000 --- a/tests/db-operator/postgres-gsql/templates/config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: pg-gsql-instance-config -data: - config: | -{{ .Values.instanceConfig.data | indent 4 }} \ No newline at end of file diff --git a/tests/db-operator/postgres-gsql/templates/instance.yaml b/tests/db-operator/postgres-gsql/templates/instance.yaml deleted file mode 100644 index 104b9a8..0000000 --- a/tests/db-operator/postgres-gsql/templates/instance.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: kinda.rocks/v1beta1 -kind: DbInstance -metadata: - name: pg-gsql-instance -spec: - adminSecretRef: - Name: pg-gsql-instance-admin-secret - Namespace: {{ .Release.Namespace }} - engine: postgres - google: - configmapRef: - Name: pg-gsql-instance-config - Namespace: {{ .Release.Namespace }} - clientSecretRef: - Name: pg-gsql-instance-client-secret - Namespace: {{ .Release.Namespace }} - instance: gsql-local-postgres - apiEndpoint: {{ .Values.googleApiEndpoint }} - monitoring: - enabled: true ---- -apiVersion: v1 -kind: Secret -metadata: - name: pg-gsql-instance-admin-secret -type: Opaque -data: - password: {{ .Values.adminPassword | b64enc }} - user: {{ .Values.adminUser | b64enc }} diff --git a/tests/db-operator/postgres-gsql/values.yaml b/tests/db-operator/postgres-gsql/values.yaml deleted file mode 100644 index 70ca985..0000000 --- a/tests/db-operator/postgres-gsql/values.yaml +++ /dev/null @@ -1,29 +0,0 @@ -adminUser: postgres -adminPassword: Passw0rd - -googleApiEndpoint: http://mock-google-api - -instanceConfig: - data: | - { - "databaseVersion": "POSTGRES_11", - "settings": { - "tier": "db-f1-micro", - "availabilityType": "ZONAL", - "pricingPlan": "PER_USE", - "replicationType": "SYNCHRONOUS", - "activationPolicy": "ALWAYS", - "ipConfiguration": { - "authorizedNetworks": [], - "ipv4Enabled": true - }, - "dataDiskType": "PD_SSD", - "backupConfiguration": { - "enabled": false - }, - "storageAutoResizeLimit": "0", - "storageAutoResize": true - }, - "backendType": "SECOND_GEN", - "region": "somewhere" - }