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.
94 lines
2.1 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|