diff --git a/.github/workflows/db-instances-test.yaml b/.github/workflows/db-instances-test.yaml new file mode 100644 index 0000000..4f09f4a --- /dev/null +++ b/.github/workflows/db-instances-test.yaml @@ -0,0 +1,59 @@ +--- +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/test.yaml b/.github/workflows/test.yaml index 5a0f529..b373927 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,3 +1,4 @@ +--- name: Test on: @@ -7,13 +8,16 @@ on: pull_request: branches: - main +env: + HELM_VERSION: 3.12.1 + PYTHON_VERSION: 3.9 jobs: - get-chart: + get-chart: runs-on: ubuntu-latest outputs: changed_charts: ${{ steps.get-chart.outputs.changed_charts }} - steps: + steps: - name: Checkout uses: actions/checkout@v3 with: @@ -21,7 +25,7 @@ jobs: fetch-depth: 2 # to be able to obtain files changed in the latest commit - id: get-chart - name: 'Get modified charts' + name: "Get modified charts" run: | cd charts files_changed="$(git diff --name-only HEAD^ HEAD)" @@ -29,9 +33,9 @@ jobs: charts_dirs_changed="$(echo "$files_changed" | xargs dirname | grep -o "charts/[^/]*" | sed "s|charts/||g" | uniq | tr '\n' ' ' || true)" echo "changed:${charts_dirs_changed}" echo "::set-output name=changed_charts::${charts_dirs_changed}" - lint: + lint: runs-on: ubuntu-latest - steps: + steps: - name: Checkout uses: actions/checkout@v3 with: @@ -49,20 +53,46 @@ jobs: - 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 --chart-dirs helm --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; 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 + 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.21.6', 'v1.22.3', 'v1.23.1', 'v1.24.3'] + 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 @@ -73,17 +103,17 @@ jobs: 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/README.md b/README.md index 8e0bedf..970a0b5 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ For triggering it, change the version of Chart.yaml in the chart directory and m ## Configuring helm client ``` -$ helm repo add kloeckneri https://kloeckner-i.github.io/charts +$ helm repo add db-operator https://db-operator.github.io/charts ``` Test the helm chart repository ``` -$ helm search repo kloeckneri +$ helm search repo db-operator ``` \ No newline at end of file diff --git a/charts/db-instances/Chart.yaml b/charts/db-instances/Chart.yaml index 824db5b..5a69682 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: 1.4.0 +version: 2.1.1 diff --git a/charts/db-instances/README.md b/charts/db-instances/README.md index 1071707..0623c4d 100644 --- a/charts/db-instances/README.md +++ b/charts/db-instances/README.md @@ -4,7 +4,7 @@ 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 kloeckneri/db-instances +$ helm install --name my-release db-operator/db-instances ``` The command deploys DB Operator on Kubernetes with default configuration. diff --git a/charts/db-instances/ci/ci-1-values.yaml b/charts/db-instances/ci/ci-1-values.yaml index 5f6d33b..37ca8e2 100644 --- a/charts/db-instances/ci/ci-1-values.yaml +++ b/charts/db-instances/ci/ci-1-values.yaml @@ -1,5 +1,7 @@ dbinstances: instance1: + serviceMonitor: + enabled: true engine: postgres monitoring: enabled: true @@ -13,6 +15,3 @@ dbinstances: secrets: adminUser: adminUser adminPassword: adminAdmin - -serviceMonitor: - enabled: true diff --git a/charts/db-instances/ci/ci-test-service-monitor-values.yaml b/charts/db-instances/ci/ci-test-service-monitor-values.yaml new file mode 100644 index 0000000..d66fa31 --- /dev/null +++ b/charts/db-instances/ci/ci-test-service-monitor-values.yaml @@ -0,0 +1,18 @@ +dbinstances: + instance1: + serviceMonitor: + enabled: true + engine: postgres + monitoring: + autodiscovery: true + enabled: true + generic: + host: postgres-instance-postgresql.postgres + port: 5432 + secrets: + adminUser: postgres + adminPassword: 123123!! +tests: + serviceMonitor: + enabled: true + instance: instance1 diff --git a/charts/db-instances/ci/helmfile.yaml b/charts/db-instances/ci/helmfile.yaml new file mode 100644 index 0000000..7a9a8df --- /dev/null +++ b/charts/db-instances/ci/helmfile.yaml @@ -0,0 +1,56 @@ +repositories: + - 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: + - 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 + chart: bitnami/postgresql + needs: + - monitoring/prometheus-stack + values: + - global: + postgresql: + auth: + postgresPassword: 123123!! + - name: prometheus-stack + namespace: monitoring + createNamespace: true + disableValidationOnInstall: true + chart: prometheus-community/kube-prometheus-stack + values: + - prometheus: + prometheusSpec: + enableAdminAPI: true + podMonitorNamespaceSelector: + any: true + podMonitorSelector: {} + podMonitorSelectorNilUsesHelmValues: false + ruleNamespaceSelector: + any: true + ruleSelector: {} + ruleSelectorNilUsesHelmValues: false + serviceMonitorNamespaceSelector: + any: true + serviceMonitorSelector: {} + serviceMonitorSelectorNilUsesHelmValues: false + - name: db-operator + namespace: db-operator + createNamespace: true + chart: ../../db-operator + needs: + - cert-manager/cert-manager diff --git a/charts/db-instances/files/test_service_monitor b/charts/db-instances/files/test_service_monitor new file mode 100755 index 0000000..e6b60a0 --- /dev/null +++ b/charts/db-instances/files/test_service_monitor @@ -0,0 +1,42 @@ +#!/bin/sh +# --------------------------------------------------------------------- +# -- This test should wait for the pg_exporter to be available +# -- and then try to get the metrics from Prometheus +# --------------------------------------------------------------------- +SKIP_INSTALL_DEPS="${TEST_SKIP_INSTALL_DEPS}" +SCRAPE_INTERVAL="${TEST_SCRAPE_INTERVAL:-30}" +PROM_URL="${TEST_PROM_URL:-prometheus-operated.monitoring}" +QUERY="${TEST_QUERY:-pg_up}" +ATTEMPTS_AMOUNT="${TEST_ATTEMPTS_AMOUNT:-10}" +ATTEMPTS_PAUSE="${TEST_ATTEMPTS_PAUSE:-30}" + +if [ -n "${SKIP_INSTALL_DEPS+x}" ] +then + apk update && apk add jq +fi + +sleep "${SCRAPE_INTERVAL}" + +for x in $(seq 1 "${ATTEMPTS_AMOUNT}") +do + echo "attempt: ${x}" + QUERY_URL="http://${PROM_URL}:9090/api/v1/query?query=${QUERY}" + CURL_RES=$(curl -q "${QUERY_URL}") + STATUS=$(echo "$CURL_RES" | jq -r '.status') + if [ "$STATUS" != "success" ] + then + echo "metric doesn't have a status 'success' in the prometheus" + echo "curl output is: $CURL_RES" + fi + # -- for some reason this jq query only works with pips in the pod + METRIC_NAME=$(curl -q "${QUERY_URL}" | jq -r '.data.result | .[] | .metric.__name__') + if [ "${METRIC_NAME}" != "${QUERY}" ] + then + echo "query didn't return expected name" + echo "${METRIC_NAME}" + else + exit 0 + fi + sleep "${ATTEMPTS_PAUSE}" +done + diff --git a/charts/db-instances/templates/dbinstance.yaml b/charts/db-instances/templates/dbinstance.yaml index 936ab35..d0ee68a 100644 --- a/charts/db-instances/templates/dbinstance.yaml +++ b/charts/db-instances/templates/dbinstance.yaml @@ -3,7 +3,7 @@ {{- if .Values.dbinstances }} {{- range $name, $value := .Values.dbinstances }} --- -apiVersion: "kci.rocks/v1beta1" +apiVersion: "kinda.rocks/v1beta1" kind: "DbInstance" metadata: name: {{ $name }} @@ -13,6 +13,9 @@ metadata: {{- end }} labels: {{- include "db-instances.labels" $ | nindent 4 }} + {{- with $value.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: engine: {{ $value.engine }} {{- if $value.existingAdminSecret }} diff --git a/charts/db-instances/templates/postgres_exporter.yaml b/charts/db-instances/templates/postgres_exporter.yaml index 9dd61f6..c82b831 100644 --- a/charts/db-instances/templates/postgres_exporter.yaml +++ b/charts/db-instances/templates/postgres_exporter.yaml @@ -1,96 +1,142 @@ -{{- $root := . }} -{{- $nodeSelector := .Values.nodeSelector }} -{{- $configSha := include (print $.Template.BasePath "/postgres_exporter_query.yaml") . | sha256sum }} -{{- $exporter := .Values.exporter.postgres }} -{{- $fullName := include "db-instances.fullname" . }} -{{- if .Values.dbinstances }} -{{- range $name, $value := .Values.dbinstances }} -{{- if eq $value.engine "postgres" }} -{{- if $value.monitoring.enabled }} ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dbinstance-{{ $name }}-pgexporter -spec: - replicas: 1 - selector: - matchLabels: - {{- include "db-instances.selectorLabels" $ | nindent 6 }} - db-instance: {{ $name }} - strategy: - type: Recreate - template: - metadata: - annotations: - prometheus.io/port: "60000" - prometheus.io/scrape: "true" - checksum/config: {{ $configSha }} - labels: - {{- include "db-instances.labels" $ | nindent 8 }} - db-instance: {{ $name }} - spec: - containers: - - env: - - name: DATA_SOURCE_URI - value: {{ $value.monitoring.uri | default (printf "dbinstance-%s-svc:5432/postgres?sslmode=disable" $name) }} - - name: DATA_SOURCE_PASS_FILE - value: /run/secrets/db-secrets/{{ $value.monitoring.passwordKey | default "password" }} - - name: DATA_SOURCE_USER_FILE - value: /run/secrets/db-secrets/{{ $value.monitoring.usernameKey | default "user" }} - - name: PG_EXPORTER_WEB_LISTEN_ADDRESS - value: :60000 - - name: PG_EXPORTER_EXTEND_QUERY_PATH - value: /run/cm/queries/queries.yaml - - name: PG_EXPORTER_CONSTANT_LABELS - value: dbinstance={{ $name }} - image: {{ $exporter.image }} - imagePullPolicy: Always - name: exporter - ports: - - name: metrics - containerPort: 60000 - volumeMounts: - - mountPath: /run/secrets/db-secrets - name: db-secrets - - mountPath: /run/cm/queries/queries.yaml - name: queries - subPath: queries.yaml - nodeSelector: - {{ toYaml $nodeSelector | nindent 8 }} - volumes: - - name: db-secrets - secret: - defaultMode: 420 - {{- if $value.adminUserSecret }} - secretName: {{ $value.adminUserSecret }} - {{- else }} - secretName: {{ $name }}-admin-secret - {{- end }} - - configMap: - defaultMode: 420 - name: {{ $fullName }}-pgexporter-query - name: queries -{{- if $root.Values.serviceMonitor.enabled }} ---- -apiVersion: v1 -kind: Service -metadata: - name: dbinstance-{{ $name }}-pgexporter - labels: - {{- include "db-instances.labels" $ | nindent 4 }} -spec: - type: ClusterIP - ports: - - port: 8080 - targetPort: metrics - protocol: TCP - name: metrics - selector: - {{- include "db-instances.selectorLabels" $ | nindent 4 }} - db-instance: {{ $name }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} +{{- $root := . }} +{{- $nodeSelector := .Values.nodeSelector }} +{{- $configSha := include (print $.Template.BasePath "/postgres_exporter_query.yaml") . | sha256sum }} +{{- $exporter := .Values.exporter.postgres }} +{{- $fullName := include "db-instances.fullname" . }} +{{- if .Values.dbinstances }} +{{- range $name, $value := .Values.dbinstances }} +{{- if eq $value.engine "postgres" }} +{{- if $value.monitoring.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dbinstance-{{ $name }}-pgexporter +spec: + replicas: 1 + selector: + matchLabels: + {{- include "db-instances.selectorLabels" $ | nindent 6 }} + db-instance: {{ $name }} + strategy: + type: Recreate + template: + metadata: + annotations: + prometheus.io/port: "60000" + prometheus.io/scrape: "true" + checksum/config: {{ $configSha }} + labels: + {{- include "db-instances.labels" $ | nindent 8 }} + db-instance: {{ $name }} + spec: + containers: + - env: + - name: DATA_SOURCE_URI + value: {{ $value.monitoring.uri | default (printf "dbinstance-%s-svc:5432/postgres?sslmode=disable" $name) }} + - name: DATA_SOURCE_PASS_FILE + value: /run/secrets/db-secrets/{{ $value.monitoring.passwordKey | default "password" }} + - name: DATA_SOURCE_USER_FILE + value: /run/secrets/db-secrets/{{ $value.monitoring.usernameKey | default "user" }} + - name: PG_EXPORTER_WEB_LISTEN_ADDRESS + value: :60000 + - name: PG_EXPORTER_EXTEND_QUERY_PATH + value: /run/cm/queries/queries.yaml + - name: PG_EXPORTER_CONSTANT_LABELS + value: dbinstance={{ $name }} + {{- if $value.monitoring.autodiscovery }} + - name: PG_EXPORTER_AUTO_DISCOVERY + value: "true" + {{- end }} + image: {{ $exporter.image }} + imagePullPolicy: Always + name: exporter + ports: + - name: metrics + containerPort: 60000 + volumeMounts: + - mountPath: /run/secrets/db-secrets + name: db-secrets + - mountPath: /run/cm/queries/queries.yaml + name: queries + subPath: queries.yaml + nodeSelector: + {{ toYaml $nodeSelector | nindent 8 }} + volumes: + - name: db-secrets + secret: + defaultMode: 420 + {{- if $value.adminUserSecret }} + secretName: {{ $value.adminUserSecret }} + {{- else }} + secretName: {{ $name }}-admin-secret + {{- end }} + - configMap: + defaultMode: 420 + name: {{ $fullName }}-pgexporter-query + name: queries +{{- if $value.serviceMonitor.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: dbinstance-{{ $name }}-pgexporter + labels: + {{- include "db-instances.labels" $ | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: metrics + protocol: TCP + name: metrics + selector: + {{- include "db-instances.selectorLabels" $ | nindent 4 }} + db-instance: {{ $name }} +--- +{{- if $.Capabilities.APIVersions.Has "monitoring.coreos.com/v1" }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: dbinstance-{{ $name }}-sm + labels: + {{- include "db-instances.labels" $ | nindent 4 }} + {{- with $value.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if $value.serviceMonitor.jobLabel }} + jobLabel: {{ $value.serviceMonitor.jobLabel }} + {{- end }} + endpoints: + - port: metrics + {{- with $value.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with $value.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with $value.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- if kindIs "string" . }} + {{- tpl . $ | nindent 8 }} + {{- else }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with $value.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ $.Release.Namespace }} + selector: + matchLabels: +{{- include "db-instances.selectorLabels" $ | nindent 6 }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/db-instances/templates/postgres_exporter_query.yaml b/charts/db-instances/templates/postgres_exporter_query.yaml index e1e7b8a..9c8e87b 100644 --- a/charts/db-instances/templates/postgres_exporter_query.yaml +++ b/charts/db-instances/templates/postgres_exporter_query.yaml @@ -1,10 +1,10 @@ ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "db-instances.labels" . | nindent 4 }} - name: {{ template "db-instances.fullname" . }}-pgexporter-query -data: - queries.yaml: | - {{ .Values.exporter.postgres.query | nindent 4 }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "db-instances.labels" . | nindent 4 }} + name: {{ template "db-instances.fullname" . }}-pgexporter-query +data: + queries.yaml: | + {{- toYaml .Values.exporter.postgres.query | nindent 4 }} diff --git a/charts/db-instances/templates/servicemonitor.yaml b/charts/db-instances/templates/servicemonitor.yaml deleted file mode 100644 index 0a46380..0000000 --- a/charts/db-instances/templates/servicemonitor.yaml +++ /dev/null @@ -1,41 +0,0 @@ -{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "db-instances.smName" . }} - labels: - {{- include "db-instances.labels" . | nindent 4 }} - {{- with .Values.serviceMonitor.selector }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if .Values.serviceMonitor.jobLabel }} - jobLabel: {{ .Values.serviceMonitor.jobLabel }} - {{- end }} - endpoints: - - port: metrics - {{- with .Values.serviceMonitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - {{- with .Values.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- if kindIs "string" . }} - {{- tpl . $ | nindent 8 }} - {{- else }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- with .Values.serviceMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - selector: - matchLabels: -{{- include "db-instances.selectorLabels" . | nindent 6 }} -{{- end }} diff --git a/charts/db-instances/templates/tests/test_service_monitor.yaml b/charts/db-instances/templates/tests/test_service_monitor.yaml new file mode 100644 index 0000000..55aa7eb --- /dev/null +++ b/charts/db-instances/templates/tests/test_service_monitor.yaml @@ -0,0 +1,51 @@ +{{- if (((.Values.tests).serviceMonitor).enabled) }} +# --------------------------------------------------------------------- +# -- A config map with a script to test ServiceMonitor +# --------------------------------------------------------------------- +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "db-instances.fullname" . }}-test-prom-script + labels: + {{- include "db-instances.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + "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 }} + +--- +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "db-instances.fullname" . }}-test-prom" + labels: + {{- include "db-instances.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + volumes: + - name: test-script + configMap: + name: "{{ include "db-instances.fullname" . }}-test-prom-script" + containers: + - name: check-metrics-endpoint + image: alpine/curl + command: + - sh + volumeMounts: + - name: test-script + readOnly: true + mountPath: /test.sh + subPath: test.sh + args: + - /test.sh + restartPolicy: Never +{{- end}} diff --git a/charts/db-instances/values.yaml b/charts/db-instances/values.yaml index c3f5634..2a167c3 100644 --- a/charts/db-instances/values.yaml +++ b/charts/db-instances/values.yaml @@ -1,5 +1,3 @@ -serviceMonitorName: "" - dbinstances: {} nodeSelector: {} @@ -7,7 +5,7 @@ nodeSelector: {} exporter: postgres: image: wrouesnel/postgres_exporter:latest - query: | + query: pg_postmaster: query: "SELECT pg_postmaster_start_time as start_time_seconds from pg_postmaster_start_time()" metrics: @@ -169,8 +167,15 @@ mysql: postgresql: enabled: false -serviceMonitor: - enabled: false - # Overwrite Namespace if secrets get created and release namespace != operator ns # operatorNamespace: + +# --------------------------------------------------------------------- +# -- Internal values, used for testing, please don't set them if you +# -- don't have an intention of testing the helm chart +# --------------------------------------------------------------------- +tests: + # Test that service monitor can be created + # and metrics can be scraped by Prometheus + serviceMonitor: + enabled: false diff --git a/charts/db-operator/Chart.yaml b/charts/db-operator/Chart.yaml index 02f7100..29f650d 100644 --- a/charts/db-operator/Chart.yaml +++ b/charts/db-operator/Chart.yaml @@ -1,8 +1,29 @@ +--- apiVersion: v2 type: application -## All supported k8s versions are in the test: https://github.com/kloeckner-i/db-operator/blob/master/.github/workflows/build-and-test.yaml -kubeVersion: ">= 1.21-prerelease" -appVersion: "1.10.0" -description: A Database Operator name: db-operator -version: 1.7.0 +version: 1.15.0 +# --------------------------------------------------------------------------------- +# -- All supported k8s versions are in the test: +# -- https://github.com/db-operator/charts/blob/main/.github/workflows/test.yaml +# --------------------------------------------------------------------------------- +kubeVersion: ">= 1.22-prerelease" +appVersion: "2.0.0" +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 + - https://github.com/db-operator/pgdump-gcs + - https://github.com/db-operator/mydump-gcs +keywords: + - database + - Operator + - mysql + - postgres diff --git a/charts/db-operator/Makefile b/charts/db-operator/Makefile new file mode 100644 index 0000000..97d4272 --- /dev/null +++ b/charts/db-operator/Makefile @@ -0,0 +1,2 @@ +gen_docs: + \ No newline at end of file diff --git a/charts/db-operator/README.md b/charts/db-operator/README.md index 764085a..a91b2fb 100644 --- a/charts/db-operator/README.md +++ b/charts/db-operator/README.md @@ -1,14 +1,137 @@ # 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) + DB Operator is Kubernetes operator +The source of the operator can be found here: https://github.com/db-operator/db-operator + +## Installing Chart +To install the chart with the release name my-release: +``` +$ helm install --name my-release 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: +``` +$ helm delete my-release +``` + +## Webhooks + +You can disable webhooks if you don't need them, by providing this value +```yaml +webhook: + create: false +``` + +## Requirements + +Kubernetes: `>= 1.22-prerelease` + +If you use webhooks, you also might need to have cert-manager + +## Values -## Upgrading to `v1.10.0` -CRDs are moved to the `templates` folder, so now they are part of the release. It means that when migration you will get errors about resource ownership. 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. +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | 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 | `{}` | | +| 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.percona.proxy.image | string | `"severalnines/proxysql:2.0"` | | +| config.instance.percona.proxy.metricsPort | int | `9090` | | +| 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.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[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[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[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[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[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[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[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[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 | `{}` | | +| secrets.gsql | object | `{}` | | +| security | object | `{}` | | +| 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"` | | + +## 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.kci.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" +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: @@ -20,47 +143,4 @@ metadata: "meta.helm.sh/release-name": my-release "meta.helm.sh/release-namespace": default ``` - -## Installing Chart -To install the chart with the release name my-release: -``` -$ helm install --name my-release kloeckneri/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: -``` -$ helm delete my-release -``` - -## Parameters - -The following table lists the configurable parameters of the db-operator chart and their default values. - -| Parameter | Description | Default | -|------------------- |----------------------- |--------------- | -| `appVersion` | Application Version (DB Operator) | TODO | -| `image.repository` | Container image name | `kloeckneri/db-operator` | -| `image.tag` | Container image tag | `latest` | -| `image.pullPolicy` | Container pull policy | `Always` | -| `imagePullSecrets` | Reference to secret to be used when pulling images | "" | -| `rbac.create` | Create RBAC resources | `true` | -| `serviceAccount.create` | If `true`, create a new service account | `true` | -| `resources` | CPU/memory resource requests/limits | `{}` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `affinity` | Node affinity for pod assignment | `{}` | -| `annotations` | Annotations to add to the db-operator pod | `{}` | -| `podLabels` | Labels to add to the db-operator pod | `{}` | -| `config.instance.google.proxy.image` | Container image of db-auth-gateway | `kloeckneri/db-auth-gateway:0.1.7` | -| `config.instance.google.proxy.nodeSelector` | Node labels for google cloud proxy pod assignment | `{}` | -| `config.backup.nodeSelector` | Node labels for backup pod assignment | `{}` | -| `config.backup.resources` | Resource configuration for running backup container same as https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits | `{}` | -| `config.backup.activeDeadlineSeconds` | activeDeadlineSeconds of backup cronjob | `600` | -| `config.backup.postgres.image` | Container image of backup cronjob (only for postgres databases) | `kloeckneri/pgdump-gcs:latest` | -| `config.monitoring.nodeSelector` | Node labels for monitoring pod assignment | `{}` | -| `config.monitoring.postgres.image` | Container image of prometheus exporter (only for postgres databases) | `wrouesnel/postgres_exporter:latest` | -| `config.monitoring.postgres.queries` | Queries executed by prometheus exporter (only for postgres databases) | see `values.yaml` for defaults | -| `secrets.gsql.admin` | Service account json used by operator to create Cloud SQL instance in GCE(**Cloud SQL Admin**) | `{}` | -| `secrets.gsql.readonly` | Service account json will be used by application to access database Cloud SQL in GCE(**Cloud SQL Client** role) | `{}` | -| `serviceMonitor.enabled` | Enabling ServiceMonitor for prometheus operator monitoring | `false` | +
diff --git a/charts/db-operator/ci/ci-2-values.yaml b/charts/db-operator/ci/ci-2-values.yaml index 72b2edc..2c11cab 100644 --- a/charts/db-operator/ci/ci-2-values.yaml +++ b/charts/db-operator/ci/ci-2-values.yaml @@ -1,5 +1,5 @@ image: - repository: ghcr.io/kloeckner-i/db-operator + repository: ghcr.io/db-operator/db-operator pullPolicy: Always reconcileInterval: "60" @@ -39,7 +39,7 @@ config: google: proxy: nodeSelector: {} - image: kloeckneri/db-auth-gateway:0.1.7 + image: ghcr.io/db-operator/db-auth-gateway:latest metricsPort: 9090 generic: {} percona: diff --git a/charts/db-operator/ci/ci-3-values.yaml b/charts/db-operator/ci/ci-3-values.yaml index fe4c86d..103e74d 100644 --- a/charts/db-operator/ci/ci-3-values.yaml +++ b/charts/db-operator/ci/ci-3-values.yaml @@ -1,5 +1,5 @@ image: - repository: ghcr.io/kloeckner-i/db-operator + repository: ghcr.io/db-operator/db-operator pullPolicy: Always reconcileInterval: "60" @@ -51,7 +51,7 @@ config: proxy: nodeSelector: nodetype: database - image: kloeckneri/db-auth-gateway:0.1.7 + image: ghcr.io/db-operator/db-auth-gateway:latest metricsPort: 9090 generic: {} percona: diff --git a/charts/db-operator/ci/ci-4-values.yaml b/charts/db-operator/ci/ci-4-values.yaml index 468b389..e352a64 100644 --- a/charts/db-operator/ci/ci-4-values.yaml +++ b/charts/db-operator/ci/ci-4-values.yaml @@ -38,7 +38,7 @@ config: google: proxy: nodeSelector: {} - image: kloeckneri/db-auth-gateway:0.1.7 + image: ghcr.io/db-operator/db-auth-gateway:latest metricsPort: 9090 generic: {} percona: diff --git a/charts/db-operator/ci/ci-5-values.yaml b/charts/db-operator/ci/ci-5-values.yaml new file mode 100644 index 0000000..f3b78eb --- /dev/null +++ b/charts/db-operator/ci/ci-5-values.yaml @@ -0,0 +1,3 @@ +--- +webhook: + create: false diff --git a/charts/db-operator/ci/unit-test/values-crds-no-cert.yaml b/charts/db-operator/ci/unit-test/values-crds-no-cert.yaml new file mode 100644 index 0000000..534aebe --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-crds-no-cert.yaml @@ -0,0 +1,19 @@ +values: | + webhook: + certificate: + create: false +files: + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbinstances.kinda.rocks + - CustomResourceDefinition-dbusers.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml + - Issuer-db-operator-issuer.yml diff --git a/charts/db-operator/ci/unit-test/values-crds-no-issuer.yaml b/charts/db-operator/ci/unit-test/values-crds-no-issuer.yaml new file mode 100644 index 0000000..97872c2 --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-crds-no-issuer.yaml @@ -0,0 +1,21 @@ +values: | + webhook: + install: true + certificate: + issuer: + create: false +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbusers.kinda.rocks + - CustomResourceDefinition-dbinstances.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml diff --git a/charts/db-operator/ci/unit-test/values-crds.yaml b/charts/db-operator/ci/unit-test/values-crds.yaml new file mode 100644 index 0000000..99f6f95 --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-crds.yaml @@ -0,0 +1,19 @@ +values: | + crds: + install: true +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Issuer-db-operator-issuer.yml + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbusers.kinda.rocks + - CustomResourceDefinition-dbinstances.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml diff --git a/charts/db-operator/ci/unit-test/values-no-crds.yaml b/charts/db-operator/ci/unit-test/values-no-crds.yaml new file mode 100644 index 0000000..7a3fffb --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-no-crds.yaml @@ -0,0 +1,16 @@ +values: | + crds: + install: false +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - Issuer-db-operator-issuer.yml + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml diff --git a/charts/db-operator/ci/unit-test/values-no-rback.yaml b/charts/db-operator/ci/unit-test/values-no-rback.yaml new file mode 100644 index 0000000..d18934b --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-no-rback.yaml @@ -0,0 +1,17 @@ +values: | + rbac: + create: false +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - CustomResourceDefinition-databases.kinda.rocks + - Issuer-db-operator-issuer.yml + - Service-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - CustomResourceDefinition-dbusers.kinda.rocks + - CustomResourceDefinition-dbinstances.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml diff --git a/charts/db-operator/ci/unit-test/values-no-svcaccount.yaml b/charts/db-operator/ci/unit-test/values-no-svcaccount.yaml new file mode 100644 index 0000000..cfdaf6d --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-no-svcaccount.yaml @@ -0,0 +1,20 @@ +values: | + serviceAccount: + create: false + webhook: + serviceAccount: + create: false +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Issuer-db-operator-issuer.yml + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbinstances.kinda.rocks + - CustomResourceDefinition-dbusers.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml diff --git a/charts/db-operator/ci/unit-test/values-no-webhook.yaml b/charts/db-operator/ci/unit-test/values-no-webhook.yaml new file mode 100644 index 0000000..e4a49d7 --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-no-webhook.yaml @@ -0,0 +1,16 @@ +values: | + webhook: + enabled: false + serviceAccount: + create: false +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - ServiceAccount-db-operator.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Issuer-db-operator-issuer.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbinstances.kinda.rocks + - CustomResourceDefinition-dbusers.kinda.rocks diff --git a/charts/db-operator/ci/unit-test/values-webhook.yaml b/charts/db-operator/ci/unit-test/values-webhook.yaml new file mode 100644 index 0000000..dda08f7 --- /dev/null +++ b/charts/db-operator/ci/unit-test/values-webhook.yaml @@ -0,0 +1,21 @@ +values: | + webhook: + enabled: true + serviceAccount: + create: true +files: + - Certificate-db-operator-webhook.yml + - ConfigMap-db-operator-config.yml + - Deployment-db-operator.yml + - Deployment-db-operator-webhook.yml + - ServiceAccount-db-operator.yml + - ServiceAccount-db-operator-webhook.yml + - ClusterRoleBinding-db-operator.yml + - CustomResourceDefinition-databases.kinda.rocks + - Issuer-db-operator-issuer.yml + - Service-db-operator-webhook.yml + - ClusterRole-db-operator.yml + - CustomResourceDefinition-dbinstances.kinda.rocks + - MutatingWebhookConfiguration-db-operator-mutating-webhook-configuration.yml + - ValidatingWebhookConfiguration-db-operator-validating-webhook-configuration.yml + - CustomResourceDefinition-dbusers.kinda.rocks diff --git a/charts/db-operator/scripts/test_values b/charts/db-operator/scripts/test_values new file mode 100755 index 0000000..9a91a61 --- /dev/null +++ b/charts/db-operator/scripts/test_values @@ -0,0 +1,66 @@ +#! /usr/bin/env bash +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 +# -- which files are generated (currently) +# -- +# -- This scripts requires go-yq and helm +# ----------------------------------------------------------------------- + +function usage() { + cat <&2 + done +shift $(($OPTIND - 1)) + +if [ -z "${VALUES_PATH}" ]; then + echo VALUES_PATH is not set + usage +fi + + +CURRENT_DIR=$(pwd) +ERROR=false +for FILE in $(find $VALUES_PATH -type f); do + WORKDIR=$(mktemp -d) + echo "Checking $FILE" + cd $WORKDIR + yq '.values' "$CURRENT_DIR/$FILE" > values.yaml + 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)) + DIFF=($(echo ${ACTUAL_FILES[@]} ${EXPECTED_FILES[@]} | tr ' ' '\n' | sort | uniq -u)) + if [ ${#DIFF[@]} -eq 0 ]; then + echo "PASSED" + rm -rf "${WORKDIR}" + else + ERROR=true + echo "FAILED: Please check unexpected files -> ${DIFF[*]}" + fi +done + +if $ERROR; then + exit 1 +fi diff --git a/charts/db-operator/templates/_helpers.tpl b/charts/db-operator/templates/_helpers.tpl index 4998603..2248b16 100644 --- a/charts/db-operator/templates/_helpers.tpl +++ b/charts/db-operator/templates/_helpers.tpl @@ -25,43 +25,80 @@ If release name contains chart name it will be used as a full name. {{- end -}} {{/* -Create chart name and version as used by the chart label. +Create the name of the service account to use */}} -{{- define "db-operator.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- define "db-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "db-operator.name" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} {{- end -}} {{/* -Image version definition; +Arguments builder */}} -{{- define "db-operator.image_version" -}} -{{ default .Chart.AppVersion .Values.image.tag }} +{{- define "db-operator.args" -}} +{{- $args := list -}} +{{- if .Values.checkForChanges -}} +{{- $args = append $args "--check-for-changes" -}} +{{- end -}} +{{ join "," $args }} {{- end -}} {{/* -Image version definition using Github Packages format ('v' prefix); +Webhook templates */}} -{{- define "db-operator.github_packages_image_version" -}} -{{- printf "v%s" (default .Chart.AppVersion .Values.image.tag) }} + +{{/* +Expand the name of the chart. +*/}} +{{- define "webhook.name" -}} +{{- printf "db-operator-webhook" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "webhook.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} {{- end -}} {{/* Create the name of the service account to use */}} -{{- define "db-operator.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} -{{- printf "%s-sa" (include "db-operator.name" .) -}} +{{- define "webhook.serviceAccountName" -}} +{{- if .Values.webhook.serviceAccount.create -}} + {{ default (include "webhook.name" .) .Values.webhook.serviceAccount.name }} {{- else -}} -{{ default "default" .Values.serviceAccount.name }} + {{ default "default" .Values.webhook.serviceAccount.name }} +{{- end -}} {{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* Common labels */}} -{{- define "db-operator.labels" -}} -helm.sh/chart: {{ include "db-operator.chart" . }} -{{ include "db-operator.selectorLabels" . }} +{{- define "labels" -}} +helm.sh/chart: {{ include "chart" . }} +{{ include "selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -71,7 +108,21 @@ app.kubernetes.io/managed-by: {{ .Release.Service }} {{/* Selector labels */}} -{{- define "db-operator.selectorLabels" -}} +{{- define "selectorLabels" -}} app.kubernetes.io/name: {{ include "db-operator.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} + +{{/* +Image version definition; +*/}} +{{- define "image_version" -}} +{{ default .Chart.AppVersion .Values.image.tag }} +{{- end -}} + +{{/* +Image version definition using Github Packages format ('v' prefix); +*/}} +{{- define "github_packages_image_version" -}} +{{- printf "v%s" (default .Chart.AppVersion .Values.image.tag) }} +{{- end -}} diff --git a/charts/db-operator/templates/certificate/certificate.yaml b/charts/db-operator/templates/certificate/certificate.yaml index f3804c1..5949c10 100644 --- a/charts/db-operator/templates/certificate/certificate.yaml +++ b/charts/db-operator/templates/certificate/certificate.yaml @@ -6,8 +6,8 @@ metadata: name: {{ .Values.webhook.certificate.name }} spec: dnsNames: - - {{ .Values.webhook.serviceName }}.{{ .Release.Namespace }}.svc - - {{ .Values.webhook.serviceName }}.{{ .Release.Namespace }}.svc.cluster.local + - {{ include "webhook.name" . }}.{{ .Release.Namespace }}.svc + - {{ include "webhook.name" . }}.{{ .Release.Namespace }}.svc.cluster.local issuerRef: kind: {{ .Values.webhook.certificate.issuer.kind }} name: {{ .Values.webhook.certificate.issuer.name }} diff --git a/charts/db-operator/templates/config.yaml b/charts/db-operator/templates/controller/config.yaml similarity index 94% rename from charts/db-operator/templates/config.yaml rename to charts/db-operator/templates/controller/config.yaml index 3831d97..9423900 100644 --- a/charts/db-operator/templates/config.yaml +++ b/charts/db-operator/templates/controller/config.yaml @@ -3,7 +3,8 @@ kind: ConfigMap metadata: name: {{ template "db-operator.name" . }}-config labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" data: config.yaml: | instance: diff --git a/charts/db-operator/templates/operator.yaml b/charts/db-operator/templates/controller/deployment.yaml similarity index 82% rename from charts/db-operator/templates/operator.yaml rename to charts/db-operator/templates/controller/deployment.yaml index e1ee956..29989b0 100644 --- a/charts/db-operator/templates/operator.yaml +++ b/charts/db-operator/templates/controller/deployment.yaml @@ -4,27 +4,30 @@ kind: Deployment metadata: name: {{ template "db-operator.name" . }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" spec: replicas: 1 selector: matchLabels: - {{- include "db-operator.selectorLabels" . | nindent 6 }} + {{- include "selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: "controller" template: metadata: labels: - {{- include "db-operator.labels" . | nindent 8 }} + {{- include "labels" . | nindent 8 }} + app.kubernetes.io/component: "controller" {{- if .Values.podLabels }} {{ toYaml .Values.podLabels | trim | nindent 8 }} {{- end }} annotations: - checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/controller/config.yaml") . | sha256sum }} {{- if .Values.annotations }} {{ toYaml .Values.annotations | nindent 8 }} {{- end }} spec: {{- if .Values.serviceAccount.create }} - serviceAccountName: {{ template "db-operator.name" . }}-sa + serviceAccountName: {{ template "db-operator.serviceAccountName" . }} {{- end }} {{- if .Values.security }} securityContext: @@ -33,15 +36,18 @@ spec: {{- end }} containers: - name: operator - image: "{{ .Values.image.repository }}:{{ template "db-operator.github_packages_image_version" . }}" + image: "{{ .Values.image.repository }}:{{ template "github_packages_image_version" . }}" ports: - containerPort: 60000 name: metrics - - containerPort: 9443 - name: webhook-server - protocol: TCP command: - db-operator + {{- if (include "db-operator.args" . ) }} + args: + {{- range include "db-operator.args" $ | split "," }} + - {{ . }} + {{- end }} + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: LOG_LEVEL @@ -81,9 +87,6 @@ spec: - mountPath: /run/config/ name: config-volume readOnly: true - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true resources: {{ toYaml .Values.resources | nindent 12 }} nodeSelector: @@ -115,7 +118,3 @@ spec: - name: config-volume configMap: name: {{ template "db-operator.name" . }}-config - - name: cert - secret: - defaultMode: 420 - secretName: {{ .Values.webhook.certificate.secretName }} diff --git a/charts/db-operator/templates/gsql-secret.yaml b/charts/db-operator/templates/controller/gsql-secret.yaml similarity index 83% rename from charts/db-operator/templates/gsql-secret.yaml rename to charts/db-operator/templates/controller/gsql-secret.yaml index 40da7f5..bea9ffc 100644 --- a/charts/db-operator/templates/gsql-secret.yaml +++ b/charts/db-operator/templates/controller/gsql-secret.yaml @@ -10,7 +10,8 @@ kind: Secret metadata: name: cloudsql-admin-serviceaccount labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" type: Opaque data: credentials.json: |- @@ -26,7 +27,8 @@ kind: Secret metadata: name: cloudsql-readonly-serviceaccount labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" type: Opaque data: credentials.json: |- diff --git a/charts/db-operator/templates/rbac.yaml b/charts/db-operator/templates/controller/rbac.yaml similarity index 82% rename from charts/db-operator/templates/rbac.yaml rename to charts/db-operator/templates/controller/rbac.yaml index fbcf07d..c5e19b5 100644 --- a/charts/db-operator/templates/rbac.yaml +++ b/charts/db-operator/templates/controller/rbac.yaml @@ -5,13 +5,11 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "db-operator.name" . }} labels: - app: {{ template "db-operator.name" . }} - chart: {{ template "db-operator.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" rules: - apiGroups: - - kci.rocks + - kinda.rocks resources: - "*" verbs: @@ -87,9 +85,10 @@ rules: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: {{ template "db-operator.name" . }}-sa + name: {{ template "db-operator.name" . }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" subjects: - kind: ServiceAccount name: {{ template "db-operator.serviceAccountName" . }} diff --git a/charts/db-operator/templates/serviceaccount.yaml b/charts/db-operator/templates/controller/serviceaccount.yaml similarity index 76% rename from charts/db-operator/templates/serviceaccount.yaml rename to charts/db-operator/templates/controller/serviceaccount.yaml index 33b5838..2f7205b 100644 --- a/charts/db-operator/templates/serviceaccount.yaml +++ b/charts/db-operator/templates/controller/serviceaccount.yaml @@ -4,7 +4,8 @@ kind: ServiceAccount metadata: name: {{ template "db-operator.serviceAccountName" . }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" {{- if .Values.imagePullSecrets }} imagePullSecrets: {{ toYaml .Values.imagePullSecrets | indent 2 }} diff --git a/charts/db-operator/templates/servicemonitor.yaml b/charts/db-operator/templates/controller/servicemonitor.yaml similarity index 81% rename from charts/db-operator/templates/servicemonitor.yaml rename to charts/db-operator/templates/controller/servicemonitor.yaml index 144907e..7df04bc 100644 --- a/charts/db-operator/templates/servicemonitor.yaml +++ b/charts/db-operator/templates/controller/servicemonitor.yaml @@ -4,7 +4,8 @@ kind: Service metadata: name: {{ template "db-operator.name" . }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" {{- with .Values.service.annotations }} annotations: {{- toYaml . | nindent 4 }} @@ -20,14 +21,16 @@ spec: nodePort: {{ .Values.service.nodePort }} {{- end }} selector: - {{- include "db-operator.selectorLabels" . | nindent 4 }} + {{- include "selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: "controller" --- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: {{ template "db-operator.name" . }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "controller" {{- with .Values.serviceMonitor.selector }} {{- toYaml . | nindent 4 }} {{- end }} @@ -60,5 +63,6 @@ spec: - {{ .Release.Namespace }} selector: matchLabels: - {{- include "db-operator.selectorLabels" . | nindent 6 }} + {{- include "selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: "controller" {{- end }} diff --git a/charts/db-operator/templates/crds/kci.rocks_databases.yaml b/charts/db-operator/templates/crds/kci.rocks_databases.yaml deleted file mode 100644 index bba86bf..0000000 --- a/charts/db-operator/templates/crds/kci.rocks_databases.yaml +++ /dev/null @@ -1,643 +0,0 @@ -{{- if .Values.crds.install }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.7.0 - {{- 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 }} - creationTimestamp: null - name: databases.kci.rocks -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: {{ .Release.Namespace }} - name: {{ .Values.webhook.serviceName }} - path: /convert - conversionReviewVersions: - - v1alpha1 - - v1beta1 - group: kci.rocks - names: - kind: Database - listKind: DatabaseList - plural: databases - shortNames: - - db - singular: database - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: current db phase - jsonPath: .status.phase - name: Phase - type: string - - description: current db status - jsonPath: .status.status - name: Status - type: boolean - - description: If database is protected to not get deleted. - jsonPath: .spec.deletionProtected - name: Protected - type: boolean - - description: instance reference - jsonPath: .spec.instance - name: DBInstance - type: string - - description: time since creation of resource - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: Database is the Schema for the databases API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DatabaseSpec defines the desired state of Database - properties: - backup: - description: DatabaseBackup defines the desired state of backup and - schedule - properties: - cron: - type: string - enable: - type: boolean - required: - - cron - - enable - type: object - cleanup: - type: boolean - connectionStringTemplate: - description: 'ConnectionStringTemplate field can be used to pass a - custom template for generating a db connection string. These keywords - can be used: Protocol, DatabaseHost, DatabasePort, UserName, Password, - DatabaseName. Default template looks like this: "{{ .Protocol }}://{{ - .UserName }}:{{ .Password }}@{{ .DatabaseHost }}:{{ .DatabasePort - }}/{{ .DatabaseName }}"' - type: string - deletionProtected: - type: boolean - extensions: - items: - type: string - type: array - instance: - type: string - postgres: - description: Postgres struct should be used to provide resource that - only applicable to postgres - properties: - dropPublicSchema: - description: If set to true, the public schema will be dropped - after the database creation - type: boolean - schemas: - description: Specify schemas to be created. The user created by - db-operator will have all access on them. - items: - type: string - type: array - type: object - secretName: - type: string - secretsTemplates: - additionalProperties: - type: string - type: object - required: - - backup - - deletionProtected - - instance - - secretName - type: object - status: - description: DatabaseStatus defines the observed state of Database - properties: - database: - type: string - instanceRef: - description: DbInstance is the Schema for the dbinstances API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this - representation of an object. Servers should convert recognized - schemas to the latest internal value, and may reject unrecognized - values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource - this object represents. Servers may infer this from the endpoint - the client submits requests to. Cannot be updated. In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DbInstanceSpec defines the desired state of DbInstance - properties: - adminSecretRef: - description: NamespacedName is a fork of the kubernetes api - type of the same name. Sadly this is required because CRD - structs must have all fields json tagged and the kubernetes - type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - backup: - description: DbInstanceBackup defines name of google bucket - to use for storing database dumps for backup when backup - is enabled - properties: - bucket: - type: string - required: - - bucket - type: object - engine: - description: 'Important: Run "make generate" to regenerate - code after modifying this file' - type: string - generic: - description: GenericInstance is used when instance type is - generic and describes necessary informations to use instance - generic instance can be any backend, it must be reachable - by described address and port - properties: - backupHost: - description: BackupHost address will be used for dumping - database for backup Usually secondary address for primary-secondary - setup or cluster lb address If it's not defined, above - Host will be used as backup host address. - type: string - host: - type: string - port: - type: integer - publicIp: - type: string - required: - - host - - port - type: object - google: - description: GoogleInstance is used when instance type is - Google Cloud SQL and describes necessary informations to - use google API to create sql instances - properties: - apiEndpoint: - type: string - clientSecretRef: - description: NamespacedName is a fork of the kubernetes - api type of the same name. Sadly this is required because - CRD structs must have all fields json tagged and the - kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - configmapRef: - description: NamespacedName is a fork of the kubernetes - api type of the same name. Sadly this is required because - CRD structs must have all fields json tagged and the - kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - instance: - type: string - required: - - configmapRef - - instance - type: object - monitoring: - description: DbInstanceMonitoring defines if exporter - properties: - enabled: - type: boolean - required: - - enabled - type: object - sslConnection: - description: DbInstanceSSLConnection defines weather connection - from db-operator to instance has to be ssl or not - properties: - enabled: - type: boolean - skip-verify: - description: SkipVerity use SSL connection, but don't - check against a CA - type: boolean - required: - - enabled - - skip-verify - type: object - required: - - adminSecretRef - - engine - type: object - status: - description: DbInstanceStatus defines the observed state of DbInstance - properties: - checksums: - additionalProperties: - type: string - type: object - info: - additionalProperties: - type: string - type: object - phase: - description: 'Important: Run "make generate" to regenerate - code after modifying this file' - type: string - status: - type: boolean - required: - - phase - - status - type: object - type: object - monitorUserSecret: - type: string - phase: - description: 'Important: Run "make generate" to regenerate code after - modifying this file Add custom validation using kubebuilder tags: - https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html' - type: string - proxyStatus: - description: DatabaseProxyStatus defines whether proxy for database - is enabled or not if so, provide information - properties: - serviceName: - type: string - sqlPort: - format: int32 - type: integer - status: - type: boolean - required: - - serviceName - - sqlPort - - status - type: object - status: - type: boolean - user: - type: string - required: - - database - - instanceRef - - phase - - status - - user - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - description: current db phase - jsonPath: .status.phase - name: Phase - type: string - - description: current db status - jsonPath: .status.status - name: Status - type: boolean - - description: If database is protected to not get deleted. - jsonPath: .spec.deletionProtected - name: Protected - type: boolean - - description: instance reference - jsonPath: .spec.instance - name: DBInstance - type: string - - description: time since creation of resource - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: Database is the Schema for the databases API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DatabaseSpec defines the desired state of Database - properties: - backup: - description: DatabaseBackup defines the desired state of backup and - schedule - properties: - cron: - type: string - enable: - type: boolean - required: - - cron - - enable - type: object - cleanup: - type: boolean - deletionProtected: - type: boolean - instance: - type: string - postgres: - description: Postgres struct should be used to provide resource that - only applicable to postgres - properties: - dropPublicSchema: - description: If set to true, the public schema will be dropped - after the database creation - type: boolean - extensions: - items: - type: string - type: array - schemas: - description: Specify schemas to be created. The user created by - db-operator will have all access on them. - items: - type: string - type: array - type: object - secretName: - type: string - secretsTemplates: - additionalProperties: - type: string - type: object - required: - - backup - - deletionProtected - - instance - - secretName - type: object - status: - description: DatabaseStatus defines the observed state of Database - properties: - database: - type: string - instanceRef: - description: DbInstance is the Schema for the dbinstances API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this - representation of an object. Servers should convert recognized - schemas to the latest internal value, and may reject unrecognized - values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource - this object represents. Servers may infer this from the endpoint - the client submits requests to. Cannot be updated. In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DbInstanceSpec defines the desired state of DbInstance - properties: - adminSecretRef: - description: NamespacedName is a fork of the kubernetes api - type of the same name. Sadly this is required because CRD - structs must have all fields json tagged and the kubernetes - type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - backup: - description: DbInstanceBackup defines name of google bucket - to use for storing database dumps for backup when backup - is enabled - properties: - bucket: - type: string - required: - - bucket - type: object - engine: - description: 'Important: Run "make generate" to regenerate - code after modifying this file' - type: string - generic: - description: GenericInstance is used when instance type is - generic and describes necessary informations to use instance - generic instance can be any backend, it must be reachable - by described address and port - properties: - backupHost: - description: BackupHost address will be used for dumping - database for backup Usually secondary address for primary-secondary - setup or cluster lb address If it's not defined, above - Host will be used as backup host address. - type: string - host: - type: string - port: - type: integer - publicIp: - type: string - required: - - host - - port - type: object - google: - description: GoogleInstance is used when instance type is - Google Cloud SQL and describes necessary informations to - use google API to create sql instances - properties: - apiEndpoint: - type: string - clientSecretRef: - description: NamespacedName is a fork of the kubernetes - api type of the same name. Sadly this is required because - CRD structs must have all fields json tagged and the - kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - configmapRef: - description: NamespacedName is a fork of the kubernetes - api type of the same name. Sadly this is required because - CRD structs must have all fields json tagged and the - kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - instance: - type: string - required: - - configmapRef - - instance - type: object - monitoring: - description: DbInstanceMonitoring defines if exporter - properties: - enabled: - type: boolean - required: - - enabled - type: object - sslConnection: - description: DbInstanceSSLConnection defines weather connection - from db-operator to instance has to be ssl or not - properties: - enabled: - type: boolean - skip-verify: - description: SkipVerity use SSL connection, but don't - check against a CA - type: boolean - required: - - enabled - - skip-verify - type: object - required: - - adminSecretRef - - engine - type: object - status: - description: DbInstanceStatus defines the observed state of DbInstance - properties: - checksums: - additionalProperties: - type: string - type: object - info: - additionalProperties: - type: string - type: object - phase: - description: 'Important: Run "make generate" to regenerate - code after modifying this file' - type: string - status: - type: boolean - required: - - phase - - status - type: object - type: object - monitorUserSecret: - type: string - phase: - description: 'Important: Run "make generate" to regenerate code after - modifying this file Add custom validation using kubebuilder tags: - https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html' - type: string - proxyStatus: - description: DatabaseProxyStatus defines whether proxy for database - is enabled or not if so, provide information - properties: - serviceName: - type: string - sqlPort: - format: int32 - type: integer - status: - type: boolean - required: - - serviceName - - sqlPort - - status - type: object - status: - type: boolean - user: - type: string - required: - - database - - instanceRef - - phase - - status - - user - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] -{{- end }} diff --git a/charts/db-operator/templates/crds/kci.rocks_dbinstances.yaml b/charts/db-operator/templates/crds/kci.rocks_dbinstances.yaml deleted file mode 100644 index ff7b2e8..0000000 --- a/charts/db-operator/templates/crds/kci.rocks_dbinstances.yaml +++ /dev/null @@ -1,380 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.7.0 - {{- 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 }} - name: dbinstances.kci.rocks -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: {{ .Release.Namespace }} - name: {{ .Values.webhook.serviceName }} - path: /convert - conversionReviewVersions: - - v1alpha1 - - v1beta1 - group: kci.rocks - names: - kind: DbInstance - listKind: DbInstanceList - plural: dbinstances - shortNames: - - dbin - singular: dbinstance - scope: Cluster - versions: - - additionalPrinterColumns: - - description: current phase - jsonPath: .status.phase - name: Phase - type: string - - description: health status - jsonPath: .status.status - name: Status - type: string - name: v1alpha1 - schema: - openAPIV3Schema: - description: DbInstance is the Schema for the dbinstances API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DbInstanceSpec defines the desired state of DbInstance - properties: - adminSecretRef: - description: NamespacedName is a fork of the kubernetes api type of - the same name. Sadly this is required because CRD structs must have - all fields json tagged and the kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - backup: - description: DbInstanceBackup defines name of google bucket to use - for storing database dumps for backup when backup is enabled - properties: - bucket: - type: string - required: - - bucket - type: object - engine: - description: 'Important: Run "make generate" to regenerate code after - modifying this file' - type: string - generic: - description: GenericInstance is used when instance type is generic - and describes necessary informations to use instance generic instance - can be any backend, it must be reachable by described address and - port - properties: - backupHost: - description: BackupHost address will be used for dumping database - for backup Usually secondary address for primary-secondary setup - or cluster lb address If it's not defined, above Host will be - used as backup host address. - type: string - host: - type: string - port: - type: integer - publicIp: - type: string - required: - - host - - port - type: object - google: - description: GoogleInstance is used when instance type is Google Cloud - SQL and describes necessary informations to use google API to create - sql instances - properties: - apiEndpoint: - type: string - clientSecretRef: - description: NamespacedName is a fork of the kubernetes api type - of the same name. Sadly this is required because CRD structs - must have all fields json tagged and the kubernetes type is - not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - configmapRef: - description: NamespacedName is a fork of the kubernetes api type - of the same name. Sadly this is required because CRD structs - must have all fields json tagged and the kubernetes type is - not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - instance: - type: string - required: - - configmapRef - - instance - type: object - monitoring: - description: DbInstanceMonitoring defines if exporter - properties: - enabled: - type: boolean - required: - - enabled - type: object - sslConnection: - description: DbInstanceSSLConnection defines weather connection from - db-operator to instance has to be ssl or not - properties: - enabled: - type: boolean - skip-verify: - description: SkipVerity use SSL connection, but don't check against - a CA - type: boolean - required: - - enabled - - skip-verify - type: object - required: - - adminSecretRef - - engine - type: object - status: - description: DbInstanceStatus defines the observed state of DbInstance - properties: - checksums: - additionalProperties: - type: string - type: object - info: - additionalProperties: - type: string - type: object - phase: - description: 'Important: Run "make generate" to regenerate code after - modifying this file' - type: string - status: - type: boolean - required: - - phase - - status - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - description: current phase - jsonPath: .status.phase - name: Phase - type: string - - description: health status - jsonPath: .status.status - name: Status - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: DbInstance is the Schema for the dbinstances API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: DbInstanceSpec defines the desired state of DbInstance - properties: - adminSecretRef: - description: NamespacedName is a fork of the kubernetes api type of - the same name. Sadly this is required because CRD structs must have - all fields json tagged and the kubernetes type is not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - backup: - description: DbInstanceBackup defines name of google bucket to use - for storing database dumps for backup when backup is enabled - properties: - bucket: - type: string - required: - - bucket - type: object - engine: - description: 'Important: Run "make generate" to regenerate code after - modifying this file' - type: string - generic: - description: GenericInstance is used when instance type is generic - and describes necessary informations to use instance generic instance - can be any backend, it must be reachable by described address and - port - properties: - backupHost: - description: BackupHost address will be used for dumping database - for backup Usually secondary address for primary-secondary setup - or cluster lb address If it's not defined, above Host will be - used as backup host address. - type: string - host: - type: string - port: - type: integer - publicIp: - type: string - required: - - host - - port - type: object - google: - description: GoogleInstance is used when instance type is Google Cloud - SQL and describes necessary informations to use google API to create - sql instances - properties: - apiEndpoint: - type: string - clientSecretRef: - description: NamespacedName is a fork of the kubernetes api type - of the same name. Sadly this is required because CRD structs - must have all fields json tagged and the kubernetes type is - not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - configmapRef: - description: NamespacedName is a fork of the kubernetes api type - of the same name. Sadly this is required because CRD structs - must have all fields json tagged and the kubernetes type is - not tagged. - properties: - Name: - type: string - Namespace: - type: string - required: - - Name - - Namespace - type: object - instance: - type: string - required: - - configmapRef - - instance - type: object - monitoring: - description: DbInstanceMonitoring defines if exporter - properties: - enabled: - type: boolean - required: - - enabled - type: object - sslConnection: - description: DbInstanceSSLConnection defines weather connection from - db-operator to instance has to be ssl or not - properties: - enabled: - type: boolean - skip-verify: - description: SkipVerity use SSL connection, but don't check against - a CA - type: boolean - required: - - enabled - - skip-verify - type: object - required: - - adminSecretRef - - engine - type: object - status: - description: DbInstanceStatus defines the observed state of DbInstance - properties: - checksums: - additionalProperties: - type: string - type: object - info: - additionalProperties: - type: string - type: object - phase: - description: 'Important: Run "make generate" to regenerate code after - modifying this file' - type: string - status: - type: boolean - required: - - phase - - status - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/charts/db-operator/templates/crds/kinda.rocks_databases.yaml b/charts/db-operator/templates/crds/kinda.rocks_databases.yaml new file mode 100644 index 0000000..df08c2e --- /dev/null +++ b/charts/db-operator/templates/crds/kinda.rocks_databases.yaml @@ -0,0 +1,542 @@ +{{- if .Values.crds.install }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + 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 }} + name: databases.kinda.rocks +spec: + {{- if .Values.webhook.enabled }} + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: {{ .Release.Namespace }} + name: {{ include "webhook.name" . }} + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 + {{- end }} + group: kinda.rocks + names: + kind: Database + listKind: DatabaseList + plural: databases + shortNames: + - db + singular: database + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: current db phase + jsonPath: .status.phase + name: Phase + type: string + - description: current db status + jsonPath: .status.status + name: Status + type: boolean + - description: If database is protected to not get deleted. + jsonPath: .spec.deletionProtected + name: Protected + type: boolean + - description: instance reference + jsonPath: .spec.instance + name: DBInstance + type: string + - description: time since creation of resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Database is the Schema for the databases API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DatabaseSpec defines the desired state of Database + properties: + backup: + description: + DatabaseBackup defines the desired state of backup and + schedule + properties: + cron: + type: string + enable: + type: boolean + required: + - cron + - enable + type: object + cleanup: + type: boolean + connectionStringTemplate: + description: + 'ConnectionStringTemplate field can be used to pass a + custom template for generating a db connection string. These keywords + can be used: Protocol, DatabaseHost, DatabasePort, UserName, Password, + DatabaseName. Default template looks like this: "{{ .Protocol }}://{{ + .UserName }}:{{ .Password }}@{{ .DatabaseHost }}:{{ .DatabasePort + }}/{{ .DatabaseName }}"' + type: string + deletionProtected: + type: boolean + extensions: + items: + type: string + type: array + instance: + type: string + postgres: + description: + Postgres struct should be used to provide resource that + only applicable to postgres + properties: + dropPublicSchema: + description: + If set to true, the public schema will be dropped + after the database creation + type: boolean + schemas: + description: + Specify schemas to be created. The user created by + db-operator will have all access on them. + items: + type: string + type: array + type: object + secretName: + type: string + secretsTemplates: + additionalProperties: + type: string + type: object + required: + - backup + - deletionProtected + - instance + - secretName + type: object + status: + description: DatabaseStatus defines the observed state of Database + properties: + database: + type: string + instanceRef: + description: DbInstance is the Schema for the dbinstances API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource + this object represents. Servers may infer this from the endpoint + the client submits requests to. Cannot be updated. In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DbInstanceSpec defines the desired state of DbInstance + properties: + adminSecretRef: + description: + NamespacedName is a fork of the kubernetes api + type of the same name. Sadly this is required because CRD + structs must have all fields json tagged and the kubernetes + type is not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + backup: + description: + DbInstanceBackup defines name of google bucket + to use for storing database dumps for backup when backup + is enabled + properties: + bucket: + type: string + required: + - bucket + type: object + engine: + description: + 'Important: Run "make generate" to regenerate + code after modifying this file' + type: string + generic: + description: + GenericInstance is used when instance type is + generic and describes necessary informations to use instance + generic instance can be any backend, it must be reachable + by described address and port + properties: + backupHost: + description: + BackupHost address will be used for dumping + database for backup Usually secondary address for primary-secondary + setup or cluster lb address If it's not defined, above + Host will be used as backup host address. + type: string + host: + type: string + port: + type: integer + publicIp: + type: string + required: + - host + - port + type: object + google: + description: + GoogleInstance is used when instance type is + Google Cloud SQL and describes necessary informations to + use google API to create sql instances + properties: + apiEndpoint: + type: string + clientSecretRef: + description: + NamespacedName is a fork of the kubernetes + api type of the same name. Sadly this is required because + CRD structs must have all fields json tagged and the + kubernetes type is not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + configmapRef: + description: + NamespacedName is a fork of the kubernetes + api type of the same name. Sadly this is required because + CRD structs must have all fields json tagged and the + kubernetes type is not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + instance: + type: string + required: + - configmapRef + - instance + type: object + monitoring: + description: DbInstanceMonitoring defines if exporter + properties: + enabled: + type: boolean + required: + - enabled + type: object + sslConnection: + description: + DbInstanceSSLConnection defines weather connection + from db-operator to instance has to be ssl or not + properties: + enabled: + type: boolean + skip-verify: + description: + SkipVerity use SSL connection, but don't + check against a CA + type: boolean + required: + - enabled + - skip-verify + type: object + required: + - adminSecretRef + - engine + type: object + status: + description: DbInstanceStatus defines the observed state of DbInstance + properties: + checksums: + additionalProperties: + type: string + type: object + info: + additionalProperties: + type: string + type: object + phase: + description: + 'Important: Run "make generate" to regenerate + code after modifying this file' + type: string + status: + type: boolean + required: + - phase + - status + type: object + type: object + monitorUserSecret: + type: string + phase: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file Add custom validation using kubebuilder tags: + https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html' + type: string + proxyStatus: + description: + DatabaseProxyStatus defines whether proxy for database + is enabled or not if so, provide information + properties: + serviceName: + type: string + sqlPort: + format: int32 + type: integer + status: + type: boolean + required: + - serviceName + - sqlPort + - status + type: object + status: + type: boolean + user: + type: string + required: + - database + - instanceRef + - phase + - status + - user + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: current db phase + jsonPath: .status.phase + name: Phase + type: string + - description: current db status + jsonPath: .status.status + name: Status + type: boolean + - description: If database is protected to not get deleted. + jsonPath: .spec.deletionProtected + name: Protected + type: boolean + - description: instance reference + jsonPath: .spec.instance + name: DBInstance + type: string + - description: time since creation of resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Database is the Schema for the databases API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DatabaseSpec defines the desired state of Database + properties: + backup: + description: + DatabaseBackup defines the desired state of backup and + schedule + properties: + cron: + type: string + enable: + type: boolean + required: + - cron + - enable + type: object + cleanup: + type: boolean + credentials: + description: + "Credentials should be used to setup everything relates + to k8s secrets and configmaps TODO(@allanger): Field .spec.secretName + should be moved here in the v1beta2 version" + properties: + templates: + description: + Templates to add custom entries to ConfigMaps and + Secrets + items: + description: + Tempaltes to add custom entries to comfigmaps and + secrets + properties: + name: + type: string + secret: + type: boolean + template: + type: string + required: + - name + - secret + - template + type: object + type: array + type: object + deletionProtected: + type: boolean + instance: + type: string + postgres: + description: + Postgres struct should be used to provide resource that + only applicable to postgres + properties: + dropPublicSchema: + description: + If set to true, the public schema will be dropped + after the database creation + type: boolean + extensions: + items: + type: string + type: array + schemas: + description: + Specify schemas to be created. The user created by + db-operator will have all access on them. + items: + type: string + type: array + template: + description: Let user create database from template + type: string + type: object + secretName: + type: string + secretsTemplates: + additionalProperties: + type: string + type: object + required: + - backup + - deletionProtected + - instance + - secretName + type: object + status: + description: DatabaseStatus defines the observed state of Database + properties: + database: + type: string + engine: + type: string + monitorUserSecret: + type: string + phase: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file Add custom validation using kubebuilder tags: + https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html' + type: string + proxyStatus: + description: + DatabaseProxyStatus defines whether proxy for database + is enabled or not if so, provide information + properties: + serviceName: + type: string + sqlPort: + format: int32 + type: integer + status: + type: boolean + required: + - serviceName + - sqlPort + - status + type: object + status: + type: boolean + user: + type: string + required: + - database + - engine + - phase + - status + - user + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/charts/db-operator/templates/crds/kinda.rocks_dbinstances.yaml b/charts/db-operator/templates/crds/kinda.rocks_dbinstances.yaml new file mode 100644 index 0000000..f9f27a6 --- /dev/null +++ b/charts/db-operator/templates/crds/kinda.rocks_dbinstances.yaml @@ -0,0 +1,410 @@ +{{- if .Values.crds.install }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + 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 }} + name: dbinstances.kinda.rocks +spec: + {{- if .Values.webhook.enabled }} + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: {{ .Release.Namespace }} + name: {{ include "webhook.name" . }} + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 + {{- end }} + group: kinda.rocks + names: + kind: DbInstance + listKind: DbInstanceList + plural: dbinstances + shortNames: + - dbin + singular: dbinstance + scope: Cluster + versions: + - additionalPrinterColumns: + - description: current phase + jsonPath: .status.phase + name: Phase + type: string + - description: health status + jsonPath: .status.status + name: Status + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: DbInstance is the Schema for the dbinstances API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DbInstanceSpec defines the desired state of DbInstance + properties: + adminSecretRef: + description: + NamespacedName is a fork of the kubernetes api type of + the same name. Sadly this is required because CRD structs must have + all fields json tagged and the kubernetes type is not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + backup: + description: + DbInstanceBackup defines name of google bucket to use + for storing database dumps for backup when backup is enabled + properties: + bucket: + type: string + required: + - bucket + type: object + engine: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file' + type: string + generic: + description: + GenericInstance is used when instance type is generic + and describes necessary informations to use instance generic instance + can be any backend, it must be reachable by described address and + port + properties: + backupHost: + description: + BackupHost address will be used for dumping database + for backup Usually secondary address for primary-secondary setup + or cluster lb address If it's not defined, above Host will be + used as backup host address. + type: string + host: + type: string + port: + type: integer + publicIp: + type: string + required: + - host + - port + type: object + google: + description: + GoogleInstance is used when instance type is Google Cloud + SQL and describes necessary informations to use google API to create + sql instances + properties: + apiEndpoint: + type: string + clientSecretRef: + description: + NamespacedName is a fork of the kubernetes api type + of the same name. Sadly this is required because CRD structs + must have all fields json tagged and the kubernetes type is + not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + configmapRef: + description: + NamespacedName is a fork of the kubernetes api type + of the same name. Sadly this is required because CRD structs + must have all fields json tagged and the kubernetes type is + not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + instance: + type: string + required: + - configmapRef + - instance + type: object + monitoring: + description: DbInstanceMonitoring defines if exporter + properties: + enabled: + type: boolean + required: + - enabled + type: object + sslConnection: + description: + DbInstanceSSLConnection defines weather connection from + db-operator to instance has to be ssl or not + properties: + enabled: + type: boolean + skip-verify: + description: + SkipVerity use SSL connection, but don't check against + a CA + type: boolean + required: + - enabled + - skip-verify + type: object + required: + - adminSecretRef + - engine + type: object + status: + description: DbInstanceStatus defines the observed state of DbInstance + properties: + checksums: + additionalProperties: + type: string + type: object + info: + additionalProperties: + type: string + type: object + phase: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file' + type: string + status: + type: boolean + required: + - phase + - status + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: current phase + jsonPath: .status.phase + name: Phase + type: string + - description: health status + jsonPath: .status.status + name: Status + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: DbInstance is the Schema for the dbinstances API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DbInstanceSpec defines the desired state of DbInstance + properties: + adminSecretRef: + description: + NamespacedName is a fork of the kubernetes api type of + the same name. Sadly this is required because CRD structs must have + all fields json tagged and the kubernetes type is not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + backup: + description: + DbInstanceBackup defines name of google bucket to use + for storing database dumps for backup when backup is enabled + properties: + bucket: + type: string + required: + - bucket + type: object + engine: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file' + type: string + generic: + description: + GenericInstance is used when instance type is generic + and describes necessary informations to use instance generic instance + can be any backend, it must be reachable by described address and + port + properties: + backupHost: + description: + BackupHost address will be used for dumping database + for backup Usually secondary address for primary-secondary setup + or cluster lb address If it's not defined, above Host will be + used as backup host address. + type: string + host: + type: string + port: + type: integer + publicIp: + type: string + required: + - host + - port + type: object + google: + description: + GoogleInstance is used when instance type is Google Cloud + SQL and describes necessary informations to use google API to create + sql instances + properties: + apiEndpoint: + type: string + clientSecretRef: + description: + NamespacedName is a fork of the kubernetes api type + of the same name. Sadly this is required because CRD structs + must have all fields json tagged and the kubernetes type is + not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + configmapRef: + description: + NamespacedName is a fork of the kubernetes api type + of the same name. Sadly this is required because CRD structs + must have all fields json tagged and the kubernetes type is + not tagged. + properties: + Name: + type: string + Namespace: + type: string + required: + - Name + - Namespace + type: object + instance: + type: string + required: + - configmapRef + - instance + type: object + monitoring: + description: DbInstanceMonitoring defines if exporter + properties: + enabled: + type: boolean + required: + - enabled + type: object + sslConnection: + description: + DbInstanceSSLConnection defines weather connection from + db-operator to instance has to be ssl or not + properties: + enabled: + type: boolean + skip-verify: + description: + SkipVerity use SSL connection, but don't check against + a CA + type: boolean + required: + - enabled + - skip-verify + type: object + required: + - adminSecretRef + - engine + type: object + status: + description: DbInstanceStatus defines the observed state of DbInstance + properties: + checksums: + additionalProperties: + type: string + type: object + info: + additionalProperties: + type: string + type: object + phase: + description: + 'Important: Run "make generate" to regenerate code after + modifying this file' + type: string + status: + type: boolean + required: + - phase + - status + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/charts/db-operator/templates/crds/kinda.rocks_dbuser.yaml b/charts/db-operator/templates/crds/kinda.rocks_dbuser.yaml new file mode 100644 index 0000000..deb8dd4 --- /dev/null +++ b/charts/db-operator/templates/crds/kinda.rocks_dbuser.yaml @@ -0,0 +1,106 @@ +{{- if .Values.crds.install }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + 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 }} + name: dbusers.kinda.rocks +spec: + group: kinda.rocks + names: + kind: DbUser + listKind: DbUserList + plural: dbusers + singular: dbuser + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: current dbuser status + jsonPath: .status.status + name: Status + type: boolean + - description: To which database user should have access + jsonPath: .spec.databaseRef + name: DatabaseName + type: string + - description: A type of access the user has + jsonPath: .spec.accessType + name: AccessType + type: string + - description: time since creation of resosĀ”urce + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: DbUser is the Schema for the dbusers API + properties: + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: DbUserSpec defines the desired state of DbUser + properties: + accessType: + description: + AccessType that should be given to a user Currently only + readOnly and readWrite are supported by the operator + type: string + databaseRef: + description: + DatabaseRef should contain a name of a Database to create + a user there Database should be in the same namespace with the user + type: string + secretName: + description: SecretName name that should be used to save user's credentials + type: string + required: + - accessType + - databaseRef + - secretName + type: object + status: + description: DbUserStatus defines the observed state of DbUser + properties: + created: + description: It's required to let the operator update users + type: boolean + database: + type: string + status: + type: boolean + required: + - created + - database + - status + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/charts/db-operator/templates/webhook/deployment.yaml b/charts/db-operator/templates/webhook/deployment.yaml new file mode 100644 index 0000000..e8e18a2 --- /dev/null +++ b/charts/db-operator/templates/webhook/deployment.yaml @@ -0,0 +1,80 @@ +{{- if .Values.webhook.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "webhook.name" . }} + labels: + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" +spec: + replicas: 1 + selector: + matchLabels: + {{- include "selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: "webhook" + template: + metadata: + labels: + {{- include "labels" . | nindent 8 }} + app.kubernetes.io/component: "webhook" + {{- if .Values.podLabels }} + {{ toYaml .Values.podLabels | trim | nindent 8 }} + {{- end }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.webhook.serviceAccount.create }} + serviceAccountName: {{ template "webhook.serviceAccountName" . }} + {{- end }} + {{- if .Values.security }} + securityContext: + runAsUser: {{ .Values.security.runAsUser }} + fsGroup: {{ .Values.security.fsGroup }} + {{- end }} + containers: + - name: webhook + image: "{{ .Values.image.repository }}:{{ template "github_packages_image_version" . }}" + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + command: + - db-operator + args: ["--webhook"] + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: LOG_LEVEL + value: {{ .Values.image.logLevel }} + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + resources: + {{ toYaml .Values.resources | nindent 12 }} + nodeSelector: + {{ toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{ toYaml .Values.affinity | nindent 8 }} + tolerations: + {{ toYaml .Values.tolerations | nindent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ .Values.webhook.certificate.secretName }} +{{- end }} diff --git a/charts/db-operator/templates/webhook/mutating_webhook.yaml b/charts/db-operator/templates/webhook/mutating_webhook.yaml index 073eaf7..abd1776 100644 --- a/charts/db-operator/templates/webhook/mutating_webhook.yaml +++ b/charts/db-operator/templates/webhook/mutating_webhook.yaml @@ -1,3 +1,4 @@ +{{- if .Values.webhook.enabled }} --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration @@ -9,21 +10,22 @@ metadata: cert-manager.io/inject-ca-from-secret: {{ .Release.Namespace }}/{{ .Values.webhook.certificate.secretName}} {{- end }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" name: {{ .Values.webhook.names.mutating }} webhooks: - admissionReviewVersions: - v1 clientConfig: service: - name: {{ .Values.webhook.serviceName }} + name: {{ include "webhook.name" . }} namespace: {{ .Release.Namespace }} - path: /mutate-kci-rocks-v1beta1-database + path: /mutate-kinda-rocks-v1beta1-database failurePolicy: Fail name: mdatabase.kb.io rules: - apiGroups: - - kci.rocks + - kinda.rocks apiVersions: - v1beta1 operations: @@ -36,14 +38,14 @@ webhooks: - v1 clientConfig: service: - name: {{ .Values.webhook.serviceName }} + name: {{ include "webhook.name" . }} namespace: {{ .Release.Namespace }} - path: /mutate-kci-rocks-v1beta1-dbinstance + path: /mutate-kinda-rocks-v1beta1-dbinstance failurePolicy: Fail name: mdbinstance.kb.io rules: - apiGroups: - - kci.rocks + - kinda.rocks apiVersions: - v1beta1 operations: @@ -52,3 +54,4 @@ webhooks: resources: - dbinstances sideEffects: None +{{- end }} diff --git a/charts/db-operator/templates/webhook/service.yaml b/charts/db-operator/templates/webhook/service.yaml index 3d0ca80..4ec773a 100644 --- a/charts/db-operator/templates/webhook/service.yaml +++ b/charts/db-operator/templates/webhook/service.yaml @@ -1,13 +1,18 @@ +{{- if .Values.webhook.enabled }} --- apiVersion: v1 kind: Service metadata: - name: {{ .Values.webhook.serviceName }} - namespace: {{ .Release.Namespace }} + name: {{ include "webhook.name" . }} + labels: + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" spec: ports: - port: 443 protocol: TCP targetPort: 9443 selector: - app.kubernetes.io/name: db-operator \ No newline at end of file + {{- include "selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" +{{- end }} diff --git a/charts/db-operator/templates/webhook/serviceaccount.yaml b/charts/db-operator/templates/webhook/serviceaccount.yaml new file mode 100644 index 0000000..38f9c36 --- /dev/null +++ b/charts/db-operator/templates/webhook/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.webhook.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "webhook.serviceAccountName" . }} + labels: + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" +{{- if .Values.imagePullSecrets }} +imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/db-operator/templates/webhook/validation_webhook.yaml b/charts/db-operator/templates/webhook/validation_webhook.yaml index 7d21fa3..004eb9d 100644 --- a/charts/db-operator/templates/webhook/validation_webhook.yaml +++ b/charts/db-operator/templates/webhook/validation_webhook.yaml @@ -1,3 +1,4 @@ +{{- if .Values.webhook.enabled }} --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration @@ -9,21 +10,22 @@ metadata: cert-manager.io/inject-ca-from-secret: {{ .Release.Namespace }}/{{ .Values.webhook.certificate.secretName}} {{- end }} labels: - {{- include "db-operator.labels" . | nindent 4 }} + {{- include "labels" . | nindent 4 }} + app.kubernetes.io/component: "webhook" name: {{ .Values.webhook.names.validating }} webhooks: - admissionReviewVersions: - v1 clientConfig: service: - name: {{ .Values.webhook.serviceName }} + name: {{ include "webhook.name" . }} namespace: {{ .Release.Namespace }} - path: /validate-kci-rocks-v1beta1-database + path: /validate-kinda-rocks-v1beta1-database failurePolicy: Fail name: vdatabase.kb.io rules: - apiGroups: - - kci.rocks + - kinda.rocks apiVersions: - v1beta1 operations: @@ -36,14 +38,14 @@ webhooks: - v1 clientConfig: service: - name: {{ .Values.webhook.serviceName }} + name: {{ include "webhook.name" . }} namespace: {{ .Release.Namespace }} - path: /validate-kci-rocks-v1beta1-dbinstance + path: /validate-kinda-rocks-v1beta1-dbinstance failurePolicy: Fail name: vdbinstance.kb.io rules: - apiGroups: - - kci.rocks + - kinda.rocks apiVersions: - v1beta1 operations: @@ -52,3 +54,24 @@ webhooks: resources: - dbinstances sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "webhook.name" . }} + namespace: {{ .Release.Namespace }} + path: /validate-kinda-rocks-v1beta1-dbuser + failurePolicy: Fail + name: vdbuser.kb.io + rules: + - apiGroups: + - kinda.rocks + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - dbusers + sideEffects: None +{{- end }} diff --git a/charts/db-operator/values-stanley.yaml b/charts/db-operator/values-stanley.yaml index c1b9221..b107fcc 100644 --- a/charts/db-operator/values-stanley.yaml +++ b/charts/db-operator/values-stanley.yaml @@ -1,5 +1,5 @@ image: - repository: registry.kci.rocks/devops/db-operator + repository: registry.kinda.rocks/devops/db-operator tag: latest pullPolicy: IfNotPresent diff --git a/charts/db-operator/values.yaml b/charts/db-operator/values.yaml index f5790fc..345c324 100644 --- a/charts/db-operator/values.yaml +++ b/charts/db-operator/values.yaml @@ -1,7 +1,7 @@ nameOverride: "" image: - repository: ghcr.io/kloeckner-i/db-operator + repository: ghcr.io/db-operator/db-operator pullPolicy: Always logLevel: info @@ -11,6 +11,16 @@ image: reconcileInterval: "60" # watchNamespace value is comma-separated list of namespace names. It's necessary to set "" to watch cluster wide. watchNamespace: "" +# ------------------------------------------------------------ +# -- If set to true, db-operator will check if a Kubernetes +# -- objects were changes before running database queries. +# -- It might reduce the amount of queries, because otherwise +# -- db-operator will try to update database and users every +# -- ${RECONCILE_INTERVAL} seconds. +# ------------------------------------------------------------ +# -- NOTE: Currently, it's only working with Database Users +# ------------------------------------------------------------ +checkForChanges: false rbac: create: true @@ -24,7 +34,9 @@ crds: annotations: {} webhook: - serviceName: db-operator-webhook + enabled: true + serviceAccount: + create: true names: mutating: db-operator-mutating-webhook-configuration validating: db-operator-validating-webhook-configuration @@ -70,7 +82,7 @@ config: google: proxy: nodeSelector: {} - image: kloeckneri/db-auth-gateway:0.1.7 + image: ghcr.io/db-operator/db-auth-gateway:v0.1.10 metricsPort: 9090 generic: {} percona: diff --git a/tests/db-operator/mock-googleapi/templates/api.yaml b/tests/db-operator/mock-googleapi/templates/api.yaml index 9dd61d1..3012004 100644 --- a/tests/db-operator/mock-googleapi/templates/api.yaml +++ b/tests/db-operator/mock-googleapi/templates/api.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: api - image: ghcr.io/kloeckner-i/cloudish-sql:v1.0.0 + image: ghcr.io/db-operator/cloudish-sql:v1.0.1 ports: - containerPort: 8080 name: http diff --git a/tests/db-operator/mysql-generic/templates/db.yaml b/tests/db-operator/mysql-generic/templates/db.yaml index dea9876..d5e42f1 100644 --- a/tests/db-operator/mysql-generic/templates/db.yaml +++ b/tests/db-operator/mysql-generic/templates/db.yaml @@ -1,4 +1,4 @@ -apiVersion: "kci.rocks/v1beta1" +apiVersion: "kinda.rocks/v1beta1" kind: "Database" metadata: name: {{ .Values.db.name }} diff --git a/tests/db-operator/mysql-generic/templates/instance.yaml b/tests/db-operator/mysql-generic/templates/instance.yaml index d0d6cfc..17d3101 100644 --- a/tests/db-operator/mysql-generic/templates/instance.yaml +++ b/tests/db-operator/mysql-generic/templates/instance.yaml @@ -1,4 +1,4 @@ -apiVersion: kci.rocks/v1beta1 +apiVersion: kinda.rocks/v1beta1 kind: DbInstance metadata: name: {{ .Values.instance.name }} diff --git a/tests/db-operator/postgres-generic/templates/db.yaml b/tests/db-operator/postgres-generic/templates/db.yaml index 283479a..c8d8d56 100644 --- a/tests/db-operator/postgres-generic/templates/db.yaml +++ b/tests/db-operator/postgres-generic/templates/db.yaml @@ -1,4 +1,4 @@ -apiVersion: "kci.rocks/v1beta1" +apiVersion: "kinda.rocks/v1beta1" kind: "Database" metadata: name: pg-generic-db diff --git a/tests/db-operator/postgres-generic/templates/instance.yaml b/tests/db-operator/postgres-generic/templates/instance.yaml index e689a5d..5205015 100644 --- a/tests/db-operator/postgres-generic/templates/instance.yaml +++ b/tests/db-operator/postgres-generic/templates/instance.yaml @@ -1,4 +1,4 @@ -apiVersion: kci.rocks/v1beta1 +apiVersion: kinda.rocks/v1beta1 kind: DbInstance metadata: name: pg-generic-instance diff --git a/tests/db-operator/postgres-gsql/templates/instance.yaml b/tests/db-operator/postgres-gsql/templates/instance.yaml index b449c3c..104b9a8 100644 --- a/tests/db-operator/postgres-gsql/templates/instance.yaml +++ b/tests/db-operator/postgres-gsql/templates/instance.yaml @@ -1,4 +1,4 @@ -apiVersion: kci.rocks/v1beta1 +apiVersion: kinda.rocks/v1beta1 kind: DbInstance metadata: name: pg-gsql-instance