fix(backups): leave the credentials Secret alone when BucketInfo has no endpoint

A BucketInfo without an endpoint differs from every credentials Secret
that has one, so the gate forced the bucket release on every throttle
window. That render cannot converge: an empty endpoint would be written
into the Secret every driver reads, and with the key absent the
template's trimPrefix fails and parks the release in Failed.

Assisted-by: LLM
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
This commit is contained in:
Alexey Artamonov committed 2026-11-08 20:18:29 +03:00
1 parent 399ccd3f4a
commit bd2b6c4b49
2 files changed
+8 -2

No files matched your search

@@ -438,7 +438,9 @@ func (g *DefaultObjectsGate) Check(ctx context.Context) ([]string, bool, error)
// writes for it. The COSI Secret being absent (the BucketAccess is being
// re-granted) leaves nothing to compare against and is not staleness, and
// neither is a source Secret the bucket chart does not render: the COSI Secret
// itself (the projector accepts one) or one without the endpoint key.
// itself (the projector accepts one) or one without the endpoint key. A
// BucketInfo without an endpoint is not a target either: rendering from it
// writes an empty endpoint, or fails the release when the key is absent.
func (g *DefaultObjectsGate) staleCredentials(ctx context.Context, src *corev1.Secret) (string, error) {
if g.CredentialsCOSISecretName == "" || g.CredentialsHelmRelease.Name == "" || g.CredentialsHelmRelease.Namespace == "" {
return "", nil
@@ -466,7 +468,7 @@ func (g *DefaultObjectsGate) staleCredentials(ctx context.Context, src *corev1.S
}
want := strings.TrimPrefix(strings.TrimPrefix(info.Spec.SecretS3.Endpoint, "https://"), "http://")
have := string(src.Data["endpoint"])
if have == want {
if want == "" || have == want {
return "", nil
}
return fmt.Sprintf("Secret/%s (endpoint %q, COSI Secret has %q)", g.Config.SourceSecretName, have, want), nil
@@ -851,6 +851,10 @@ func TestCheckCredentialsEndpointComparison(t *testing.T) {
{"bare host", "s3.example.com", false},
{"other host", "https://s3.new.example.com", true},
{"other port", "https://s3.example.com:8443", true},
// A forced render from a BucketInfo with no endpoint would write an
// empty endpoint into the Secret every driver reads (or, with the key
// absent, fail the bucket release's render), never a working one.
{"no endpoint in BucketInfo", "", false},
} {
t.Run(tc.name, func(t *testing.T) {
objs := append([]runtime.Object{helmReleaseObject(), credentialsHelmReleaseObject()}, allDefaultObjects()...)