Files
dokku/plugins/scheduler-k3s/functions_test.go
Jose Diaz-Gonzalez ef9bdc0379 fix: split env config and image pull secret into separate helm releases
Bundling these Secrets in the app helm chart caused two bugs in the scheduler-k3s plugin: a chart rollback could delete Secrets that older ReplicaSets still referenced by exact timestamped name (`env-{app}.{ts}` and `ims-{app}.{ts}`), hard-crashing pods until manual intervention; and the strategic-merge `patchMergeKey` on `imagePullSecrets` let stale entries leak into the live Deployment until the list pointed at many nonexistent Secrets. Each Secret now lives in its own helm release with a stable name (`config-{app}` and `pull-secret-{app}`), installed before the app chart on every deploy. The deployment trigger also prunes any leaked `imagePullSecrets` entries from the live Deployment so the next deploy lands on a clean list, and the rename and destroy paths uninstall the new releases (and the previously-leaked TLS release on rename) under the old app name.
2026-04-29 12:18:03 -04:00

94 lines
2.1 KiB
Go

package scheduler_k3s
import (
"testing"
corev1 "k8s.io/api/core/v1"
)
func TestNeedsImagePullSecretsPrune(t *testing.T) {
cases := []struct {
name string
live []corev1.LocalObjectReference
keepSet map[string]struct{}
want bool
}{
{
name: "empty live, empty keep",
live: []corev1.LocalObjectReference{},
keepSet: map[string]struct{}{},
want: false,
},
{
name: "matches keep set exactly",
live: []corev1.LocalObjectReference{{Name: "pull-secret-foo"}},
keepSet: map[string]struct{}{
"pull-secret-foo": {},
},
want: false,
},
{
name: "leaked entries beyond keep set",
live: []corev1.LocalObjectReference{
{Name: "ims-foo.111"},
{Name: "ims-foo.222"},
{Name: "pull-secret-foo"},
},
keepSet: map[string]struct{}{
"pull-secret-foo": {},
},
want: true,
},
{
name: "live missing the keep entry",
live: []corev1.LocalObjectReference{
{Name: "ims-foo.111"},
},
keepSet: map[string]struct{}{
"pull-secret-foo": {},
},
want: true,
},
{
name: "live populated, keep set empty",
live: []corev1.LocalObjectReference{{Name: "ims-foo.111"}},
keepSet: map[string]struct{}{},
want: true,
},
{
name: "empty live, keep set populated",
live: []corev1.LocalObjectReference{},
keepSet: map[string]struct{}{"pull-secret-foo": {}},
want: true,
},
{
name: "user override only, no leaked entries",
live: []corev1.LocalObjectReference{{Name: "my-custom-secret"}},
keepSet: map[string]struct{}{
"my-custom-secret": {},
},
want: false,
},
{
name: "user override with leaked dokku-managed entries",
live: []corev1.LocalObjectReference{
{Name: "ims-foo.111"},
{Name: "my-custom-secret"},
},
keepSet: map[string]struct{}{
"my-custom-secret": {},
},
want: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := needsImagePullSecretsPrune(tc.live, tc.keepSet)
if got != tc.want {
t.Errorf("needsImagePullSecretsPrune() = %v, want %v", got, tc.want)
}
})
}
}