Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/push-helm-chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
exit 1

- name: Install Cosign
uses: sigstore/cosign-installer@v4.0.0
uses: sigstore/cosign-installer@v4.1.1

- name: Login to GHCR Registry
uses: docker/login-action@v3
Expand Down
4 changes: 2 additions & 2 deletions docs/How-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Note: Rolling upgrade also works in the same way for secrets.

### Hash Value Computation

Reloader uses SHA1 to compute hash value. SHA1 is used because it is efficient and less prone to collision.
Reloader uses SHA512 to compute hash value. SHA512 is used because it is efficient and less prone to collision.

## Monitor All Namespaces

Expand All @@ -90,4 +90,4 @@ The output file can then be used to deploy Reloader in specific namespace.

## Compatibility With Helm Install and Upgrade

Reloader has no impact on helm deployment cycle. Reloader only injects an environment variable in `deployment`, `daemonset` or `statefulset`. The environment variable contains the SHA1 value of `ConfigMaps` or `Secrets` data. So if a deployment is created using Helm and Reloader updates the deployment, then next time you upgrade the helm release, Reloader will do nothing except changing that environment variable value in `deployment` , `daemonset` or `statefulset`.
Reloader has no impact on helm deployment cycle. Reloader only injects an environment variable in `deployment`, `daemonset` or `statefulset`. The environment variable contains the SHA512 value of `ConfigMaps` or `Secrets` data. So if a deployment is created using Helm and Reloader updates the deployment, then next time you upgrade the helm release, Reloader will do nothing except changing that environment variable value in `deployment` , `daemonset` or `statefulset`.
14 changes: 7 additions & 7 deletions docs/Reloader-vs-ConfigmapController.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

Reloader is inspired from [`configmapcontroller`](https://github.com/fabric8io/configmapcontroller) but there are many ways in which it differs from `configmapcontroller`. Below is the small comparison between these two controllers.

| Reloader | ConfigMap |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Reloader can watch both `Secrets` and `ConfigMaps`. | `configmapcontroller` can only watch changes in `ConfigMaps`. It cannot detect changes in other resources like `Secrets`. |
| Reloader can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` | `configmapcontroller` can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` |
| Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any old functionality. | Currently there are not any unit test cases or end to end integration test cases in `configmap-controller`. It adds difficulties for any additional updates in `configmap-controller` and one can not know for sure whether new changes breaks any old functionality or not. |
| Reloader uses SHA1 to encode the change in `ConfigMap` or `Secret`. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is very less prone to collision. | `configmap-controller` uses `FABRICB_FOO_REVISION` environment variable to store any change in `ConfigMap` controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. |
| Reloader allows you to customize your own annotation (for both `Secrets` and `ConfigMaps`) using command line flags | `configmap-controller` restricts you to only their provided annotation |
| Reloader | ConfigMap |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Reloader can watch both `Secrets` and `ConfigMaps`. | `configmapcontroller` can only watch changes in `ConfigMaps`. It cannot detect changes in other resources like `Secrets`. |
| Reloader can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` | `configmapcontroller` can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` |
| Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any old functionality. | Currently there are not any unit test cases or end to end integration test cases in `configmap-controller`. It adds difficulties for any additional updates in `configmap-controller` and one can not know for sure whether new changes breaks any old functionality or not. |
| Reloader uses SHA512 to encode the change in `ConfigMap` or `Secret`. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is very less prone to collision. | `configmap-controller` uses `FABRICB_FOO_REVISION` environment variable to store any change in `ConfigMap` controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. |
| Reloader allows you to customize your own annotation (for both `Secrets` and `ConfigMaps`) using command line flags | `configmap-controller` restricts you to only their provided annotation |
2 changes: 1 addition & 1 deletion docs/Reloader-vs-k8s-trigger-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Reloader and k8s-trigger-controller are both built for same purpose. So there ar

- Both controllers support change detection in `ConfigMaps` and `Secrets`
- Both controllers support deployment `rollout`
- Reloader controller use SHA1 for hashing
- Reloader controller use SHA512 for hashing
- Both controllers have end to end as well as unit test cases.

## Differences
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
k8s.io/apimachinery v0.35.3
k8s.io/client-go v0.35.3
k8s.io/kubectl v0.35.3
sigs.k8s.io/secrets-store-csi-driver v1.5.5
sigs.k8s.io/secrets-store-csi-driver v1.5.6
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5E
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/secrets-store-csi-driver v1.5.5 h1:LJDpDL5TILhlP68nGvtGSlJFxSDgAD2m148NT0Ts7os=
sigs.k8s.io/secrets-store-csi-driver v1.5.5/go.mod h1:i2WqLicYH00hrTG3JAzICPMF4HL4KMEORlDt9UQoZLk=
sigs.k8s.io/secrets-store-csi-driver v1.5.6 h1:vVghX13yY7AmPEtxTEdMrZzj0uDzAu1kq9EY6mDOfXM=
sigs.k8s.io/secrets-store-csi-driver v1.5.6/go.mod h1:668UPSzWZsWpR6VOcqfx24tcw8sh0RI9LmWOMjHjETc=
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
Expand Down
16 changes: 4 additions & 12 deletions internal/pkg/crypto/sha.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package crypto

import (
"crypto/sha1"
"fmt"
"io"

"github.com/sirupsen/logrus"
"crypto/sha512"
"encoding/hex"
)

// GenerateSHA generates SHA from string
func GenerateSHA(data string) string {
hasher := sha1.New()
_, err := io.WriteString(hasher, data)
if err != nil {
logrus.Errorf("Unable to write data in hash writer %v", err)
}
sha := hasher.Sum(nil)
return fmt.Sprintf("%x", sha)
hash := sha512.Sum512_256([]byte(data))
return hex.EncodeToString(hash[:])
}
6 changes: 3 additions & 3 deletions internal/pkg/crypto/sha_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
// TestGenerateSHA generates the sha from given data and verifies whether it is correct or not
func TestGenerateSHA(t *testing.T) {
data := "www.stakater.com"
sha := "abd4ed82fb04548388a6cf3c339fd9dc84d275df"
sha := "2e9aa975331b22861b4f62b7fcc69b63e001f938361fee3b4ed888adf26a10e3"
result := GenerateSHA(data)
if result != sha {
t.Errorf("Failed to generate SHA")
Expand All @@ -18,11 +18,11 @@ func TestGenerateSHA(t *testing.T) {
// This ensures consistent behavior and avoids issues with string matching operations
func TestGenerateSHAEmptyString(t *testing.T) {
result := GenerateSHA("")
expected := "da39a3ee5e6b4b0d3255bfef95601890afd80709"
expected := "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"
if result != expected {
t.Errorf("Failed to generate SHA for empty string. Expected: %s, Got: %s", expected, result)
}
if len(result) != 40 {
if len(result) != 64 {
t.Errorf("SHA hash should be 40 characters long, got %d", len(result))
}
}
12 changes: 6 additions & 6 deletions internal/pkg/handler/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,7 @@ func TestRollingUpgradeForDeploymentWithPatchAndRetryUsingArs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"metadata":{"annotations":{"reloader.stakater.com/last-reloaded-from":`)
assert.Contains(t, string(bytes), `\"hash\":\"3c9a892aeaedc759abc3df9884a37b8be5680382\"`)
assert.Contains(t, string(bytes), `\"hash\":\"fd9e71a362056bfa864d9859e12978f893d330ce8cbf09218b25d015770ad91f\"`)
return nil
}

Expand Down Expand Up @@ -2964,7 +2964,7 @@ func TestRollingUpgradeForDaemonSetWithPatchAndRetryUsingArs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"metadata":{"annotations":{"reloader.stakater.com/last-reloaded-from":`)
assert.Contains(t, string(bytes), `\"hash\":\"314a2269170750a974d79f02b5b9ee517de7f280\"`)
assert.Contains(t, string(bytes), `\"hash\":\"43bf9e30e7c4e32a8f8673c462b86d0b1ac626cf498afdc0d0108e79ebe7ee0c\"`)
return nil
}

Expand Down Expand Up @@ -3227,7 +3227,7 @@ func TestRollingUpgradeForStatefulSetWithPatchAndRetryUsingArs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"metadata":{"annotations":{"reloader.stakater.com/last-reloaded-from":`)
assert.Contains(t, string(bytes), `\"hash\":\"f821414d40d8815fb330763f74a4ff7ab651d4fa\"`)
assert.Contains(t, string(bytes), `\"hash\":\"6aa837180bdf6a93306c71a0cf62b4a45c2d5b021578247b3b64d5baea2b84d9\"`)
return nil
}

Expand Down Expand Up @@ -3607,7 +3607,7 @@ func TestRollingUpgradeForDeploymentWithPatchAndRetryUsingErs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"spec":{"containers":[{"name":`)
assert.Contains(t, string(bytes), `"value":"3c9a892aeaedc759abc3df9884a37b8be5680382"`)
assert.Contains(t, string(bytes), `"value":"fd9e71a362056bfa864d9859e12978f893d330ce8cbf09218b25d015770ad91f"`)
return nil
}

Expand Down Expand Up @@ -4502,7 +4502,7 @@ func TestRollingUpgradeForDaemonSetWithPatchAndRetryUsingErs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"spec":{"containers":[{"name":`)
assert.Contains(t, string(bytes), `"value":"314a2269170750a974d79f02b5b9ee517de7f280"`)
assert.Contains(t, string(bytes), `"value":"43bf9e30e7c4e32a8f8673c462b86d0b1ac626cf498afdc0d0108e79ebe7ee0c"`)
return nil
}

Expand Down Expand Up @@ -4737,7 +4737,7 @@ func TestRollingUpgradeForStatefulSetWithPatchAndRetryUsingErs(t *testing.T) {
assert.Equal(t, patchtypes.StrategicMergePatchType, patchType)
assert.NotEmpty(t, bytes)
assert.Contains(t, string(bytes), `{"spec":{"template":{"spec":{"containers":[{"name":`)
assert.Contains(t, string(bytes), `"value":"f821414d40d8815fb330763f74a4ff7ab651d4fa"`)
assert.Contains(t, string(bytes), `"value":"6aa837180bdf6a93306c71a0cf62b4a45c2d5b021578247b3b64d5baea2b84d9"`)
return nil
}

Expand Down
Loading