diff --git a/.github/workflows/pull_request-helm.yaml b/.github/workflows/pull_request-helm.yaml index 7639c2c38..0a31f4ef7 100644 --- a/.github/workflows/pull_request-helm.yaml +++ b/.github/workflows/pull_request-helm.yaml @@ -73,7 +73,7 @@ jobs: - name: Get version for chart from helm repo id: chart_eval run: | - current_chart_version=$(helm search repo stakater/reloader | tail -n 1 | awk '{print $2}') + current_chart_version=$(helm search repo stakater/reloader-v2 | tail -n 1 | awk '{print $2}') echo "CURRENT_CHART_VERSION=$(echo ${current_chart_version})" >> $GITHUB_OUTPUT - name: Get Updated Chart version from Chart.yaml @@ -82,7 +82,10 @@ jobs: with: cmd: yq e '.version' deployments/kubernetes/chart/reloader/Chart.yaml + # Skip the version-increase gate on first publish, when no reloader-v2 + # chart exists yet in the repo (CURRENT_CHART_VERSION is empty). - name: Check Version + if: steps.chart_eval.outputs.CURRENT_CHART_VERSION != '' uses: aleoyakas/check-semver-increased-action@415c9c60054c2442c03478b6dd96a195deac6695 # v1 id: check-version with: @@ -90,7 +93,7 @@ jobs: previous-version: ${{ steps.chart_eval.outputs.CURRENT_CHART_VERSION }} - name: Fail if Helm Chart version isnt updated - if: steps.check-version.outputs.is-version-increased != 'true' + if: steps.chart_eval.outputs.CURRENT_CHART_VERSION != '' && steps.check-version.outputs.is-version-increased != 'true' run: | echo "Helm Chart Version wasnt updated" exit 1 diff --git a/.github/workflows/push-helm-chart.yaml b/.github/workflows/push-helm-chart.yaml index 0f54f73bb..6c937a220 100644 --- a/.github/workflows/push-helm-chart.yaml +++ b/.github/workflows/push-helm-chart.yaml @@ -54,7 +54,7 @@ jobs: - name: Get version for chart from helm repo id: chart_eval run: | - current_chart_version=$(helm search repo stakater/reloader | tail -n 1 | awk '{print $2}') + current_chart_version=$(helm search repo stakater/reloader-v2 | tail -n 1 | awk '{print $2}') echo "CURRENT_CHART_VERSION=$(echo ${current_chart_version})" >> $GITHUB_OUTPUT - name: Get Updated Chart version from Chart.yaml @@ -63,7 +63,10 @@ jobs: with: cmd: yq e '.version' deployments/kubernetes/chart/reloader/Chart.yaml + # Skip the version-increase gate on first publish, when no reloader-v2 + # chart exists yet in the repo (CURRENT_CHART_VERSION is empty). - name: Check Version + if: steps.chart_eval.outputs.CURRENT_CHART_VERSION != '' uses: aleoyakas/check-semver-increased-action@415c9c60054c2442c03478b6dd96a195deac6695 # v1 id: check-version with: @@ -71,7 +74,7 @@ jobs: previous-version: ${{ steps.chart_eval.outputs.CURRENT_CHART_VERSION }} - name: Fail if Helm Chart version isnt updated - if: steps.check-version.outputs.is-version-increased != 'true' + if: steps.chart_eval.outputs.CURRENT_CHART_VERSION != '' && steps.check-version.outputs.is-version-increased != 'true' run: | echo "Helm Chart Version wasnt updated" exit 1 @@ -88,12 +91,15 @@ jobs: - name: Publish Helm chart to ghcr.io run: | + # Pull the enterprise subchart from private GHCR (uses the login above); + # the vendored charts/*.tgz is gitignored, so it isn't present on the runner. + helm dependency build ./deployments/kubernetes/chart/reloader helm package ./deployments/kubernetes/chart/reloader --destination ./packaged-chart helm push ./packaged-chart/*.tgz oci://ghcr.io/stakater/charts rm -rf ./packaged-chart - name: Sign artifacts with Cosign - run: cosign sign --yes ghcr.io/stakater/charts/reloader:${{ steps.new_chart_version.outputs.result }} + run: cosign sign --yes ghcr.io/stakater/charts/reloader-v2:${{ steps.new_chart_version.outputs.result }} - name: Publish Helm chart to gh-pages uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0 @@ -114,7 +120,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.PUBLISH_TOKEN }} WITH_V: false - CUSTOM_TAG: chart-v${{ steps.new_chart_version.outputs.result }} + CUSTOM_TAG: reloader-v2-chart-v${{ steps.new_chart_version.outputs.result }} - name: Notify Slack uses: 8398a7/action-slack@77eaa4f1c608a7d68b38af4e3f739dcd8cba273e # v3 diff --git a/.github/workflows/release-helm-chart.yaml b/.github/workflows/release-helm-chart.yaml index afc39ee53..31e7b34cd 100644 --- a/.github/workflows/release-helm-chart.yaml +++ b/.github/workflows/release-helm-chart.yaml @@ -3,7 +3,7 @@ name: Release Helm chart on: push: tags: - - "chart-v*" + - "reloader-v2-chart-v*" permissions: contents: write @@ -26,7 +26,7 @@ jobs: run: | gh release create "$tag" \ --repo="$GITHUB_REPOSITORY" \ - --title="Helm chart ${tag#chart-}" \ + --title="Helm chart reloader-v2 ${tag#reloader-v2-chart-v}" \ --generate-notes - name: Notify Slack diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ee1154b69..5d9989170 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -147,7 +147,8 @@ jobs: run: | echo GHCR_IMAGE_REPOSITORY=${{env.REGISTRY}}/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV - # tag this image as latest as it will be used in plain manifests + # v2 branch: publish a floating `v2` tag instead of `latest` so v2 + # releases never overwrite the v1 `latest` tag used by plain manifests. - name: Build and Push Docker Image to ghcr registry uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: @@ -157,7 +158,7 @@ jobs: push: true platforms: linux/amd64,linux/arm,linux/arm64 tags: | - ${{ env.GHCR_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.RELEASE_VERSION }},${{ env.GHCR_IMAGE_REPOSITORY }}:latest + ${{ env.GHCR_IMAGE_REPOSITORY }}:${{ steps.generate_tag.outputs.RELEASE_VERSION }},${{ env.GHCR_IMAGE_REPOSITORY }}:v2 build-args: | VERSION=${{ steps.generate_tag.outputs.RELEASE_VERSION }} COMMIT=${{ github.sha }} diff --git a/deployments/kubernetes/chart/reloader/Chart.yaml b/deployments/kubernetes/chart/reloader/Chart.yaml index ee8bae069..2e11cd6c0 100644 --- a/deployments/kubernetes/chart/reloader/Chart.yaml +++ b/deployments/kubernetes/chart/reloader/Chart.yaml @@ -1,8 +1,8 @@ -apiVersion: v1 -name: reloader +apiVersion: v2 +name: reloader-v2 description: Reloader chart that runs on kubernetes -version: 2.2.12 -appVersion: v1.4.17 +version: 2.0.0 +appVersion: v2.0.0 keywords: - Reloader - kubernetes @@ -17,3 +17,9 @@ maintainers: email: rasheed@stakater.com - name: faizanahmad055 email: faizan@stakater.com +dependencies: + - name: reloader-enterprise + alias: enterprise + version: 0.1.0 + repository: oci://ghcr.io/stakater/charts + condition: enterprise.enabled diff --git a/deployments/kubernetes/chart/reloader/README.md b/deployments/kubernetes/chart/reloader/README.md index 6eb65d216..05e860762 100644 --- a/deployments/kubernetes/chart/reloader/README.md +++ b/deployments/kubernetes/chart/reloader/README.md @@ -10,13 +10,13 @@ helm repo add stakater https://stakater.github.io/stakater-charts helm repo update -helm install stakater/reloader # For helm3 add --generate-name flag or set the release name +helm install stakater/reloader-v2 # For helm3 add --generate-name flag or set the release name -helm install {{RELEASE_NAME}} stakater/reloader -n {{NAMESPACE}} --set reloader.watchGlobally=false # By default, Reloader watches in all namespaces. To watch in single namespace, set watchGlobally=false +helm install {{RELEASE_NAME}} stakater/reloader-v2 -n {{NAMESPACE}} --set reloader.watchGlobally=false # By default, Reloader watches in all namespaces. To watch in single namespace, set watchGlobally=false -helm install stakater/reloader --set reloader.watchGlobally=false --namespace test --generate-name # Install Reloader in `test` namespace which will only watch `Deployments`, `Daemonsets` `Statefulsets` and `Rollouts` in `test` namespace. +helm install stakater/reloader-v2 --set reloader.watchGlobally=false --namespace test --generate-name # Install Reloader in `test` namespace which will only watch `Deployments`, `Daemonsets` `Statefulsets` and `Rollouts` in `test` namespace. -helm install stakater/reloader --set reloader.ignoreJobs=true --set reloader.ignoreCronJobs=true --generate-name # Install Reloader ignoring Jobs and CronJobs from reload monitoring +helm install stakater/reloader-v2 --set reloader.ignoreJobs=true --set reloader.ignoreCronJobs=true --generate-name # Install Reloader ignoring Jobs and CronJobs from reload monitoring ``` ## Uninstalling @@ -170,6 +170,62 @@ helm uninstall {{RELEASE_NAME}} -n {{NAMESPACE}} ### Deprecation Notice - `serviceMonitor` will be removed in future releases in favor of `PodMonitor` +## Enterprise mode + +Reloader Enterprise adds a console, gateway, and cache (dragonfly) alongside the +operator. It ships as an optional subchart gated by `enterprise.enabled`. + +Enabling it requires **four** changes, because the operator image is swapped manually: + +1. Turn on the subchart and set the component hostnames: + + ```yaml + enterprise: + enabled: true + global: + consoleHost: reloader-enterprise-console.apps.example.com + gatewayHost: reloader-enterprise-gateway.apps.example.com + ``` + +2. Swap the operator image to the enterprise image: + + ```yaml + image: + repository: ghcr.io/stakater/reloader-enterprise + tag: v0.0.43 # enterprise operator image tag (v-prefixed); use the latest release + ``` + + > **Version note:** three different numbers are in play here, don't mix them up: + > - `image.tag` above is the **enterprise operator image** tag (e.g. `v0.0.43`). + > - the `reloader-enterprise` **subchart** version (`0.1.0`, in `Chart.yaml` + > dependencies) is the Helm chart version, not an image tag. + > - the console and gateway images have their own tags again, set under + > `enterprise.console.*` / `enterprise.gateway.*`. + +3. Provide an image pull secret — the enterprise operator, console, and gateway + images are in **private GHCR**: + + ```bash + kubectl create secret docker-registry saap-dockerconfigjson \ + --docker-server=ghcr.io \ + --docker-username= --docker-password= \ + -n + ``` + + ```yaml + global: + imagePullSecrets: + - name: saap-dockerconfigjson + ``` + +4. Deeper enterprise component settings pass through under `enterprise.console.*`, + `enterprise.gateway.*`, and `enterprise.dragonfly.*` (see the reloader-enterprise + chart values for the full list). Values you do not override fall back to the + subchart defaults. + +When `enterprise.enabled=false` (the default) none of the enterprise components are +rendered and the operator uses the community image. + ## Release Process _Helm chart versioning_: The Reloader Helm chart is maintained in this repository. The Helm chart has its own semantic versioning. Helm charts and code releases are separate artifacts and separately versioned. Manifest making strategy relies on Kustomize. The Reloader Helm chart manages the two artifacts with these two fields: diff --git a/deployments/kubernetes/chart/reloader/templates/NOTES.txt b/deployments/kubernetes/chart/reloader/templates/NOTES.txt index d437a4f2b..be10fd610 100644 --- a/deployments/kubernetes/chart/reloader/templates/NOTES.txt +++ b/deployments/kubernetes/chart/reloader/templates/NOTES.txt @@ -5,3 +5,13 @@ {{ .Values.reloader.custom_annotations.secret | default "secret.reloader.stakater.com/reload" }}: "foo-secret" - After successful installation, your pods will get rolling updates when a change in data of configmap or secret will happen. +{{- if .Values.enterprise.enabled }} +{{- $usingCommunityImage := ternary (eq .Values.image.name "stakater/reloader") (eq .Values.image.repository "ghcr.io/stakater/reloader") (not (empty .Values.global.imageRegistry)) }} +{{- if $usingCommunityImage }} + + WARNING: enterprise.enabled=true but the operator image still points at the + community image. The operator will run, but without enterprise features. To use + the enterprise operator, override {{ if .Values.global.imageRegistry }}image.name{{ else }}image.repository{{ end }}/image.tag — see the + chart README "Enterprise mode". +{{- end }} +{{- end }} diff --git a/deployments/kubernetes/chart/reloader/tests/enterprise_test.yaml b/deployments/kubernetes/chart/reloader/tests/enterprise_test.yaml new file mode 100644 index 000000000..cdfc6a5de --- /dev/null +++ b/deployments/kubernetes/chart/reloader/tests/enterprise_test.yaml @@ -0,0 +1,28 @@ +suite: Enterprise image swap +templates: + - deployment.yaml +tests: + - it: uses the community image by default + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: ghcr.io/stakater/reloader:v2.0.0 + # The operator image is swapped manually via image.*; enterprise.enabled only + # toggles the subchart and must NOT change the operator image on its own. + - it: enterprise.enabled alone does not change the operator image + set: + enterprise: + enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: ghcr.io/stakater/reloader:v2.0.0 + - it: uses the enterprise image when the image block is overridden + set: + image: + repository: ghcr.io/stakater/reloader-enterprise + tag: test-tag + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: ghcr.io/stakater/reloader-enterprise:test-tag diff --git a/deployments/kubernetes/chart/reloader/tests/namespaces_rbac_test.yaml b/deployments/kubernetes/chart/reloader/tests/namespaces_rbac_test.yaml index 0585cdebb..47b0c02f1 100644 --- a/deployments/kubernetes/chart/reloader/tests/namespaces_rbac_test.yaml +++ b/deployments/kubernetes/chart/reloader/tests/namespaces_rbac_test.yaml @@ -82,7 +82,7 @@ tests: of: RoleBinding - equal: path: roleRef.name - value: reloader-reloader-role + value: reloader-reloader-v2-role - equal: path: subjects[0].namespace value: reloader-ns @@ -97,7 +97,7 @@ tests: template: role.yaml documentSelector: path: metadata.name - value: reloader-reloader-metadata-role + value: reloader-reloader-v2-metadata-role asserts: - equal: path: metadata.namespace @@ -119,7 +119,7 @@ tests: template: role.yaml documentSelector: path: metadata.name - value: reloader-reloader-metadata-role + value: reloader-reloader-v2-metadata-role asserts: - contains: path: rules @@ -143,7 +143,7 @@ tests: template: role.yaml documentSelector: path: metadata.name - value: reloader-reloader-metadata-role + value: reloader-reloader-v2-metadata-role asserts: - notContains: path: rules @@ -194,7 +194,7 @@ tests: template: role.yaml - equal: path: metadata.name - value: reloader-reloader-metadata-role + value: reloader-reloader-v2-metadata-role template: role.yaml documentIndex: 0 diff --git a/deployments/kubernetes/chart/reloader/values.yaml b/deployments/kubernetes/chart/reloader/values.yaml index 119bc8e33..3d0e47eb1 100644 --- a/deployments/kubernetes/chart/reloader/values.yaml +++ b/deployments/kubernetes/chart/reloader/values.yaml @@ -10,6 +10,11 @@ global: #imagePullSecrets: # - my-pull-secret + ## Required when enterprise.enabled=true (shared with the enterprise subchart) + consoleHost: "" + gatewayHost: "" + gatewayScheme: https + kubernetes: host: https://kubernetes.default @@ -19,10 +24,42 @@ fullnameOverride: "" image: name: stakater/reloader repository: ghcr.io/stakater/reloader - tag: v1.4.19 + tag: v2.0.0 # digest: sha256:1234567 pullPolicy: IfNotPresent +# Reloader Enterprise components (console + gateway + dragonfly cache). +# When enabled, ALSO swap the operator image to the enterprise image and provide +# global.imagePullSecrets — see the chart README "Enterprise mode". +# NOTE: if global.imageRegistry is set, the operator image resolves from +# global.imageRegistry + image.name (image.repository is ignored); in that mode +# override image.name, not image.repository. +enterprise: + enabled: false + console: + enabled: true + # deployment: + # image: + # tag: "" + # OpenShift: router auto-creates a Route from the Ingress; this annotation + # sets edge TLS termination on that Route. + # ingress: + # annotations: + # route.openshift.io/termination: edge + gateway: + enabled: true + dragonfly: + enabled: true + # deployment: + # image: + # Gateway images are published v-prefixed (WITH_V: true); latest is v0.0.23. + # tag: "" + # ingress: + # annotations: + # route.openshift.io/termination: edge + dragonfly: + fullnameOverride: reloader-enterprise-dragonfly + reloader: autoReloadAll: false isArgoRollouts: false