2 Commits

Author SHA1 Message Date
0dd267a0df docs(README): add an ArgoCD application resource as an example
All checks were successful
Helm / helm-lint (push) Successful in 13s
Generate README / generate-parameters (push) Successful in 15s
Markdown linter / markdown-link-checker (push) Successful in 13s
Helm / helm-unittest (push) Successful in 15s
Markdown linter / markdown-lint (push) Successful in 9s
Release / publish-chart (push) Successful in 8s
2025-10-22 17:38:24 +02:00
d790cd3ec4 fix(secret): enforce basic auth credentials
This patch remove generation of a random string for the username and password of
the basic auth credentials.

The problem with the random generated basic auth credentials is, that this leads
to a new shasum of the secret. GitOps tools like ArgoCD detects a drift trigger
a rolling update.

To avoid this must now the basic auth credentials be defined to enable
prometheus metrics.
2025-10-22 17:14:53 +02:00
7 changed files with 97 additions and 73 deletions

108
README.md
View File

@@ -16,10 +16,7 @@ Chapter [configuration and installation](#helm-configuration-and-installation) d
and use it to deploy the exporter. It also contains further configuration examples.
Furthermore, this helm chart contains unit tests to detect regressions and stabilize the deployment. Additionally, this
helm chart is tested for deployment scenarios with **ArgoCD**, but please keep in mind, that this chart supports the
*[Automatically Roll Deployment](https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments)*
concept of Helm, which can trigger unexpected rolling releases. Further configuration instructions are described in a
separate [chapter](#argocd).
helm chart is tested for deployment scenarios with **ArgoCD**.
## Helm: configuration and installation
@@ -125,6 +122,20 @@ deployment:
secret.reloader.stakater.com/reload: "reposilite-tls"
```
If the application is rolled out using ArgoCD, a rolling update from stakater's
[reloader](https://github.com/stakater/Reloader) can lead to a drift. ArgoCD will attempt to restore the original state
with a rolling update. To avoid this, instead of a rolling update triggered by the reloader, a restart of the pod can be
initiated. Further information are available in the official
[README](https://github.com/stakater/Reloader?tab=readme-ov-file#4-%EF%B8%8F-workload-specific-rollout-strategy) of
stakater's reloader.
```diff
deployment:
annotations:
reloader.stakater.com/auto: "true"
+ reloader.stakater.com/rollout-strategy: "restart"
```
#### Network policies
Network policies can only take effect, when the used CNI plugin support network policies. The chart supports no custom
@@ -199,62 +210,51 @@ helm install --version "${CHART_VERSION}" reposilite volker.raschek/reposilite \
## ArgoCD
### Daily execution of rolling updates
### Example Application
The behavior whereby ArgoCD triggers a rolling update even though nothing appears to have changed often occurs in
connection with the helm concept `checksum/secret`, `checksum/configmap` or more generally, [Automatically Roll
Deployments](https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments). Please ensure, that no
third party application modifies the config maps or secret afterwards.
An application resource for the Helm chart is defined below. It serves as an example for your own deployment.
The problem with combining this concept with ArgoCD is that ArgoCD re-renders the Helm chart every time. Even if the
content of the config map or secret has not changed, there may be minimal differences (e.g., whitespace, chart version,
Helm render order, different timestamps).
This changes the SHA256 hash, Argo sees a drift and trigger a rolling update of the deployment. Among other things, this
can lead to unnecessary notifications from ArgoCD.
To avoid this, the annotation with the shasum can be ignored. However, this negates the mechanism of [Automatically Roll
Deployments](https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments).
Below is a diff that adds the `Application` to ignore all annotations with the prefix `checksum`.
> [!WARNING]
> Configurations of `ignoreDifferences` always refer to the determination of a drift and whether a possible sync is
> necessary. If the selected attributes should also be ignored in deployment afterwards, define
> `RespectIgnoreDifferences=true` in your `Application` resource. Further information can be found in the ArgoCD
> [documentation](https://argo-cd.readthedocs.io/en/latest/user-guide/sync-options/#respect-ignore-differences-configs).
```diff
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
+ ignoreDifferences:
+ - group: apps
+ kind: Deployment
+ jqPathExpressions:
+ - '.spec.template.metadata.annotations | with_entries(select(.key | startswith("checksum")))'
```
The definition of ignoreDifferences ensures that annotations with the prefix checksum are ignored during a diff.
> [!TIP]
> If the [reloader](https://github.com/stakater/Reloader) is configured as described in section [TLS certificate
> rotation](#tls-certificate-rotation), ensure that the shasum defined as annotation or environment variable is also
> ignored. The [reloader](https://github.com/stakater/Reloader) will modify the deployment based on his configuration
> and append additional annotations or environment variables containing the shasum. Below are some examples how to adapt
> the `ignoreDifferences` configuration to ignore only the annotations and environment variables of stakater's
> [reloader](https://github.com/stakater/Reloader).
```diff
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
destination:
server: https://kubernetes.default.svc
namespace: reposilite
ignoreDifferences:
- group: apps
kind: Deployment
jqPathExpressions:
+ - '.spec.template.metadata.annotations | with_entries(select(.key | startswith("reloader")))'
+ - '.spec.template.spec.containers[].env[] | select(.name | startswith("STAKATER_"))'
# When HPA is enabled, ensure that a modification of the replicas does not lead to a
# drift.
- '.spec.replicas'
# Ensure that changes of the annotations or environment variables added or modified by
# stakater's reloader does not lead to a drift.
- '.spec.template.metadata.annotations | with_entries(select(.key | startswith("reloader")))'
- '.spec.template.spec.containers[].env[] | select(.name | startswith("STAKATER_"))'
sources:
- repoURL: https://charts.cryptic.systems/volker.raschek
chart: reposilite
targetRevision: '0.*'
helm:
valueFiles:
- $values/values.yaml
releaseName: reposilite
syncPolicy:
automated:
prune: true
selfHeal: true
managedNamespaceMetadata:
annotations: {}
labels: {}
syncOptions:
- ApplyOutOfSyncOnly=true
- CreateNamespace=true
- FailOnSharedResource=false
- Replace=false
- RespectIgnoreDifferences=false
- ServerSideApply=true
- Validate=true
```
## Parameters

View File

@@ -14,6 +14,6 @@ metadata:
name: {{ include "reposilite.secrets.prometheusBasicAuth.name" . }}
namespace: {{ .Release.Namespace }}
stringData:
password: {{ default (randAlphaNum 16) .Values.prometheus.metrics.secret.new.basicAuthPassword }}
username: {{ default (randAlphaNum 16) .Values.prometheus.metrics.secret.new.basicAuthUsername }}
password: {{ required "Password for basic auth is required!" .Values.prometheus.metrics.secret.new.basicAuthPassword }}
username: {{ required "Username for basic auth is required!" .Values.prometheus.metrics.secret.new.basicAuthUsername }}
{{- end }}

View File

@@ -13,6 +13,8 @@ tests:
set:
prometheus.metrics.enabled: true
prometheus.metrics.podMonitor.enabled: true
prometheus.metrics.secret.new.basicAuthPassword: "my-password"
prometheus.metrics.secret.new.basicAuthUsername: "my-username"
asserts:
- exists:
path: spec.template.metadata.annotations.checksum/secret-reposilite-unittest-basic-auth-credentials

View File

@@ -13,6 +13,8 @@ tests:
set:
prometheus.metrics.enabled: true
prometheus.metrics.serviceMonitor.enabled: true
prometheus.metrics.secret.new.basicAuthPassword: "my-password"
prometheus.metrics.secret.new.basicAuthUsername: "my-username"
asserts:
- exists:
path: spec.template.metadata.annotations.checksum/secret-reposilite-unittest-basic-auth-credentials

View File

@@ -13,9 +13,29 @@ tests:
- hasDocuments:
count: 0
- it: Throw error for missing basic auth password
set:
prometheus.metrics.enabled: true
# prometheus.metrics.secret.new.basicAuthPassword: "my-password"
prometheus.metrics.secret.new.basicAuthUsername: "my-username"
asserts:
- failedTemplate:
errorMessage: "Password for basic auth is required!"
- it: Throw error for missing basic auth username
set:
prometheus.metrics.enabled: true
prometheus.metrics.secret.new.basicAuthPassword: "my-password"
# prometheus.metrics.secret.new.basicAuthUsername: "my-username"
asserts:
- failedTemplate:
errorMessage: "Username for basic auth is required!"
- it: Rendering secret with default values.
set:
prometheus.metrics.enabled: true
prometheus.metrics.secret.new.basicAuthPassword: "my-password"
prometheus.metrics.secret.new.basicAuthUsername: "my-username"
asserts:
- hasDocuments:
count: 1
@@ -51,13 +71,13 @@ tests:
asserts:
- hasDocuments:
count: 1
- exists:
- isSubset:
path: metadata.annotations
value:
content:
foo: bar
- exists:
- isSubset:
path: metadata.labels
value:
content:
bar: foo
- equal:
path: metadata.name

View File

@@ -53,13 +53,13 @@ tests:
asserts:
- hasDocuments:
count: 1
- exists:
- isSubset:
path: metadata.annotations
value:
content:
foo: bar
- exists:
- isSubset:
path: metadata.labels
value:
content:
bar: foo
- equal:
path: metadata.name

View File

@@ -92,7 +92,7 @@ tests:
service.scheme: ""
asserts:
- failedTemplate:
errorMessage: No service scheme defined!
errorMessage: The scheme of the serviceMonitor is not defined!
- it: Require sessionAffinity.
set: