Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package k8up-cli for openSUSE:Factory checked in at 2026-10-24 22:04:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/k8up-cli (Old) and /work/SRC/openSUSE:Factory/.k8up-cli.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "k8up-cli" Sat Oct 24 22:04:11 2026 rev:9 rq:1392096 version:2.16.1 Changes: -------- --- /work/SRC/openSUSE:Factory/k8up-cli/k8up-cli.changes 2026-07-20 10:01:38.964793127 +0200 +++ /work/SRC/openSUSE:Factory/.k8up-cli.new.2252680/k8up-cli.changes 2026-10-24 22:05:45.345443326 +0200 @@ -1,0 +2,19 @@ +Fri Oct 23 16:05:58 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 2.16.1: + * Update security relevant Go dependencies + * Introduce secretKeys for endpoint and bucket + * Align OWNERS.md with the Maintainer GitHub team (#1253) + * e2e: use ghcr.io/vshn/minio for the MinIO server and mc + * Use the MinIO binary from ghcr.io/vshn/minio instead of + building it + * Fix CI: Go 1.26.6, lint exclusion, MinIO from source + * Add 7 day delay for actions + * Autoformat json + * Set github action digests + * fix(scheduler): randomize @annually-random schedules + * Update vulnerable x library + * Update module github.com/restic/restic to v0.19.1 + * Bump chart version for new release + +------------------------------------------------------------------- Old: ---- k8up-cli-2.16.0.obscpio New: ---- k8up-cli-2.16.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ k8up-cli.spec ++++++ --- /var/tmp/diff_new_pack.yNaZof/_old 2026-10-24 22:05:46.403488099 +0200 +++ /var/tmp/diff_new_pack.yNaZof/_new 2026-10-24 22:05:46.404488141 +0200 @@ -19,7 +19,7 @@ %define executable_name k8up Name: k8up-cli -Version: 2.16.0 +Version: 2.16.1 Release: 0 Summary: CLI for the K8up Kubernetes and OpenShift Backup Operator License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.yNaZof/_old 2026-10-24 22:05:46.434489411 +0200 +++ /var/tmp/diff_new_pack.yNaZof/_new 2026-10-24 22:05:46.437489538 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/k8up-io/k8up.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">refs/tags/v2.16.0</param> + <param name="revision">refs/tags/v2.16.1</param> <param name="match-tag">v*</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.yNaZof/_old 2026-10-24 22:05:46.458490426 +0200 +++ /var/tmp/diff_new_pack.yNaZof/_new 2026-10-24 22:05:46.460490511 +0200 @@ -3,6 +3,6 @@ <param name="url">https://github.com/k8up-io/k8up/</param> <param name="changesrevision">0240a0613b2fa15665a71418079c1550ceb19df3</param></service><service name="tar_scm"> <param name="url">https://github.com/k8up-io/k8up.git</param> - <param name="changesrevision">343b99d1519385d75738dbb07d6ff45785c3f186</param></service></servicedata> + <param name="changesrevision">8c825c87f7fcf64cc2a3e37d914b64bc698a8b58</param></service></servicedata> (No newline at EOF) ++++++ k8up-cli-2.16.0.obscpio -> k8up-cli-2.16.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/.golangci.yml new/k8up-cli-2.16.1/.golangci.yml --- old/k8up-cli-2.16.0/.golangci.yml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/.golangci.yml 2026-10-22 16:33:00.000000000 +0200 @@ -10,7 +10,7 @@ rules: - linters: - staticcheck - text: 'k8upv1.LegacyScheduleFinalizerName is deprecated: Migrate to ScheduleFinalizerName' + text: 'LegacyScheduleFinalizerName is deprecated: Migrate to ScheduleFinalizerName' paths: - third_party$ - builtin$ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/Makefile.restic-integration.mk new/k8up-cli-2.16.1/Makefile.restic-integration.mk --- old/k8up-cli-2.16.0/Makefile.restic-integration.mk 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/Makefile.restic-integration.mk 2026-10-22 16:33:00.000000000 +0200 @@ -55,8 +55,9 @@ @while ! curl --silent "http://$(minio_address)" > /dev/null; do echo "Waiting for server http://$(minio_address) to become ready"; sleep 0.5; done $(minio_path): | $(go_bin) - curl $(curl_args) --output "$@" "$(minio_url)" - chmod +x "$@" + id=$$(docker create --platform linux/$(arch) "$(minio_image)") && \ + docker cp "$$id:/usr/bin/minio" "$@"; \ + status=$$?; docker rm "$$id" > /dev/null; exit $$status "$@" --version $(restic_path): | $(go_bin) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/Makefile.restic-integration.vars.mk new/k8up-cli-2.16.1/Makefile.restic-integration.vars.mk --- old/k8up-cli-2.16.0/Makefile.restic-integration.vars.mk 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/Makefile.restic-integration.vars.mk 2026-10-22 16:33:00.000000000 +0200 @@ -28,4 +28,6 @@ minio_root_user ?= accesskey minio_root_password ?= secretkey minio_pid ?= $(integrationtest_dir)/minio.pid -minio_url ?= https://dl.min.io/server/minio/release/$(os)-$(arch)/minio +# MinIO no longer publishes community binaries; the linux/amd64 server binary is +# copied out of VSHN's MinIO image (needs Docker, as on the CI runners). +minio_image ?= ghcr.io/vshn/minio:RELEASE.2025-09-07T16-13-09Z diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/OWNERS.md new/k8up-cli-2.16.1/OWNERS.md --- old/k8up-cli-2.16.0/OWNERS.md 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/OWNERS.md 2026-10-22 16:33:00.000000000 +0200 @@ -16,8 +16,9 @@ * Tobias Brunner <[email protected]> ([tobru](https://github.com/tobru)) * Simon Beck <[email protected]> ([Kidswiss](https://github.com/Kidswiss)) * Nicolas Bigler <[email protected]> ([TheBigLee](https://github.com/TheBigLee)) -* Łukasz Widera <[email protected]> ([wejdross](https://github.com/wejdross)) -* Gabriel Saratura <[email protected]> ([zugao](https://github.com/zugao)) +* Aarno Aukia <[email protected]> ([arska](https://github.com/arska)) +* Sebastian Widmer <[email protected]> ([bastjan](https://github.com/bastjan)) +* Liene Luksika <[email protected]> ([lieneluksika](https://github.com/lieneluksika)) We also document the list of maintainers in the [GitHub team "Maintainer"](https://github.com/orgs/k8up-io/teams/maintainer/members). @@ -27,4 +28,5 @@ ## Emeritus maintainers -As of today, we don't have any emeritus maintainers yet. +* Łukasz Widera <[email protected]> ([wejdross](https://github.com/wejdross)) +* Gabriel Saratura <[email protected]> ([zugao](https://github.com/zugao)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/api/v1/backend.go new/k8up-cli-2.16.1/api/v1/backend.go --- old/k8up-cli-2.16.0/api/v1/backend.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/api/v1/backend.go 2026-10-22 16:33:00.000000000 +0200 @@ -1,11 +1,13 @@ package v1 import ( + "context" "fmt" "reflect" "strings" corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" "github.com/k8up-io/k8up/v2/operator/cfg" ) @@ -71,6 +73,14 @@ return "" } +// ResolveSecretRefs resolves Secret-backed repository fields in place. +func (in *Backend) ResolveSecretRefs(ctx context.Context, reader client.Reader, namespace, secretName string) error { + if in == nil || in.S3 == nil { + return nil + } + return in.S3.ResolveSecretRefs(ctx, reader, namespace, secretName) +} + // IsBackendEqualTo returns true if the restic repository string is equal to the other's string. // If other is nil, it returns false. func (in *Backend) IsBackendEqualTo(other *Backend) bool { @@ -98,6 +108,14 @@ } } +func secretValue(secret *corev1.Secret, key, field string) (string, error) { + value, ok := secret.Data[key] + if !ok { + return "", fmt.Errorf("secret %s/%s has no key %q for %s", secret.Namespace, secret.Name, key, field) + } + return string(value), nil +} + type LocalSpec struct { MountPath string `json:"mountPath,omitempty"` } @@ -114,11 +132,47 @@ type S3Spec struct { Endpoint string `json:"endpoint,omitempty"` + EndpointSecretKey string `json:"endpointSecretKey,omitempty"` Bucket string `json:"bucket,omitempty"` + BucketSecretKey string `json:"bucketSecretKey,omitempty"` AccessKeyIDSecretRef *corev1.SecretKeySelector `json:"accessKeyIDSecretRef,omitempty"` SecretAccessKeySecretRef *corev1.SecretKeySelector `json:"secretAccessKeySecretRef,omitempty"` } +// ResolveSecretRefs replaces configured endpoint and bucket Secret references +// with their values before the repository string is used to create a Job. +func (in *S3Spec) ResolveSecretRefs(ctx context.Context, reader client.Reader, namespace, secretName string) error { + if in == nil || (in.EndpointSecretKey == "" && in.BucketSecretKey == "") { + return nil + } + + secret := &corev1.Secret{} + if err := reader.Get(ctx, client.ObjectKey{Namespace: namespace, Name: secretName}, secret); err != nil { + return fmt.Errorf("get repository Secret %s/%s: %w", namespace, secretName, err) + } + + endpoint := in.Endpoint + if in.EndpointSecretKey != "" { + var err error + endpoint, err = secretValue(secret, in.EndpointSecretKey, "S3 endpoint") + if err != nil { + return err + } + } + bucket := in.Bucket + if in.BucketSecretKey != "" { + var err error + bucket, err = secretValue(secret, in.BucketSecretKey, "S3 bucket") + if err != nil { + return err + } + } + + in.Endpoint = endpoint + in.Bucket = bucket + return nil +} + // EnvVars returns the env vars for this backend. func (in *S3Spec) EnvVars(vars map[string]*corev1.EnvVarSource) map[string]*corev1.EnvVarSource { addEnvVarFromSecret(vars, cfg.AwsAccessKeyIDEnvName, in.AccessKeyIDSecretRef) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/api/v1/backend_test.go new/k8up-cli-2.16.1/api/v1/backend_test.go --- old/k8up-cli-2.16.0/api/v1/backend_test.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/api/v1/backend_test.go 2026-10-22 16:33:00.000000000 +0200 @@ -1,10 +1,15 @@ package v1 import ( + "context" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/k8up-io/k8up/v2/operator/cfg" ) @@ -155,6 +160,32 @@ } } +func TestBackend_ResolveSecretRefs(t *testing.T) { + const ( + namespace = "backup" + secretName = "k8up-repo" + ) + scheme := runtime.NewScheme() + require.NoError(t, corev1.AddToScheme(scheme)) + reader := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: secretName}, + Data: map[string][]byte{ + "endpoint": []byte("https://endpoint"), + "bucket": []byte("bucket"), + }, + }).Build() + + backend := &Backend{S3: &S3Spec{ + EndpointSecretKey: "endpoint", + BucketSecretKey: "bucket", + }} + + err := backend.ResolveSecretRefs(context.Background(), reader, namespace, secretName) + + require.NoError(t, err) + assert.Equal(t, "s3:https://endpoint/bucket", backend.String()) +} + func newSecretRef(name string) *corev1.SecretKeySelector { return &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/Chart.yaml new/k8up-cli-2.16.1/charts/k8up/Chart.yaml --- old/k8up-cli-2.16.0/charts/k8up/Chart.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/Chart.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -6,7 +6,7 @@ - backup - operator - restic -version: 4.9.0 +version: 4.10.0 sources: - https://github.com/k8up-io/k8up maintainers: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/Makefile new/k8up-cli-2.16.1/charts/k8up/Makefile --- old/k8up-cli-2.16.0/charts/k8up/Makefile 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/Makefile 2026-10-22 16:33:00.000000000 +0200 @@ -19,6 +19,7 @@ @yq -i e '.metadata.name="{{ include \"k8up.fullname\" . }}-manager", del(.metadata.creationTimestamp)' $@ @yq -i e '.metadata.labels.replace="LABELS"' $@ @$(sed) -e 's/replace: LABELS/{{- include "k8up.labels" . | nindent 4 }}/g' $@ + @$(sed) -e 's/- k8up-repo/- {{ .Values.k8up.repositorySecretName | default "k8up-repo" }}/g' $@ @$(sed) -e '1s/^/{{- if .Values.rbac.create -}}\n/' $@ @$(sed) -e '$$a{{- end -}}' $@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/README.md new/k8up-cli-2.16.1/charts/k8up/README.md --- old/k8up-cli-2.16.0/charts/k8up/README.md 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/README.md 2026-10-22 16:33:00.000000000 +0200 @@ -1,6 +1,6 @@ # k8up - + Kubernetes and OpenShift Backup Operator based on restic @@ -49,7 +49,7 @@ | image.pullPolicy | string | `"IfNotPresent"` | Operator image pull policy | | image.registry | string | `"ghcr.io"` | Operator image registry | | image.repository | string | `"k8up-io/k8up"` | Operator image repository | -| image.tag | string | `"v2.15.0"` | Operator image tag (version) | +| image.tag | string | `"v2.16.0"` | Operator image tag (version) | | imagePullSecrets | list | `[]` | | | k8up.backupImage.repository | string | `""` | The backup runner image repository. Defaults to `{image.registry}/{image.repository}`. Specify an image repository including registry, e.g. `example.com/repo/image` | | k8up.backupImage.tag | string | `""` | The backup runner image tag Defaults to `{image.tag}` | @@ -61,6 +61,7 @@ | k8up.globalResources.requests.cpu | string | `""` | Global CPU resource requests applied to jobs. See [supported units][resource-units]. | | k8up.globalResources.requests.memory | string | `""` | Global Memory resource requests applied to jobs. See [supported units][resource-units]. | | k8up.operatorNamespace | string | `""` | Specifies the namespace in which K8up's `EffectiveSchedules` are stored. Defaults to release namespace if left empty. | +| k8up.repositorySecretName | string | `""` | Specifies the name of the Secret that contains repository configuration values (e.g. S3 endpoint and bucket). Defaults to `k8up-repo` if left empty. | | k8up.skipSnapshotSync | bool | `false` | Specifies whether K8up should skip synchronizing Snapshot custom resources to the cluster after backup or prune operations. When enabled, the operator passes `BACKUP_SKIP_SNAPSHOT_SYNC=true` to backup and prune job pods. Webhook notifications are still sent. | | k8up.skipWithoutAnnotation | bool | `false` | Specifies whether K8up should ignore PVCs without the backup annotation (by default, `k8up.io/backup`) | | k8up.timezone | string | `""` | Specifies the timezone K8up is using for scheduling. Empty value defaults to the timezone in which Kubernetes is deployed. Accepts `tz database` compatible entries, e.g. `Europe/Zurich` | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_archives.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_archives.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_archives.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_archives.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -383,8 +383,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -873,8 +877,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_backups.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_backups.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_backups.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_backups.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -390,8 +390,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_checks.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_checks.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_checks.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_checks.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_prunes.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_prunes.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_prunes.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_prunes.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_restores.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_restores.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_restores.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_restores.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -875,8 +879,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_schedules.yaml new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_schedules.yaml --- old/k8up-cli-2.16.0/charts/k8up/crds/k8up.io_schedules.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/crds/k8up.io_schedules.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -376,8 +376,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -868,8 +872,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -1486,8 +1494,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -1930,8 +1942,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -2950,8 +2966,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -4164,8 +4184,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -5204,8 +5228,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -5696,8 +5724,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/templates/deployment.yaml new/k8up-cli-2.16.1/charts/k8up/templates/deployment.yaml --- old/k8up-cli-2.16.0/charts/k8up/templates/deployment.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/templates/deployment.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -43,6 +43,8 @@ value: "{{ .Values.k8up.skipWithoutAnnotation }}" - name: BACKUP_GLOBAL_SKIP_SNAPSHOT_SYNC value: "{{ .Values.k8up.skipSnapshotSync }}" + - name: BACKUP_REPOSITORY_SECRET_NAME + value: "{{ .Values.k8up.repositorySecretName | default "k8up-repo" }}" - name: BACKUP_OPERATOR_NAMESPACE {{- if .Values.k8up.operatorNamespace }} value: "{{ .Values.k8up.operatorNamespace }}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/templates/operator-clusterrole.yaml new/k8up-cli-2.16.1/charts/k8up/templates/operator-clusterrole.yaml --- old/k8up-cli-2.16.0/charts/k8up/templates/operator-clusterrole.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/templates/operator-clusterrole.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -26,6 +26,14 @@ - watch - apiGroups: - "" + resourceNames: + - {{ .Values.k8up.repositorySecretName | default "k8up-repo" }} + resources: + - secrets + verbs: + - get + - apiGroups: + - "" resources: - serviceaccounts verbs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/test/deployment_test.go new/k8up-cli-2.16.1/charts/k8up/test/deployment_test.go --- old/k8up-cli-2.16.0/charts/k8up/test/deployment_test.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/test/deployment_test.go 2026-10-22 16:33:00.000000000 +0200 @@ -39,12 +39,14 @@ assert.Equal(t, wantTimezone, envs[1].Value) assert.Equal(t, "BACKUP_SKIP_WITHOUT_ANNOTATION", envs[3].Name) assert.Equal(t, "BACKUP_GLOBAL_SKIP_SNAPSHOT_SYNC", envs[4].Name) - assert.Equal(t, "BACKUP_OPERATOR_NAMESPACE", envs[5].Name) - assert.Equal(t, "metadata.namespace", envs[5].ValueFrom.FieldRef.FieldPath) - assert.Equal(t, "BACKUP_GLOBAL_CPU_REQUEST", envs[6].Name, "Deployment does not use configured Env Name") - assert.Equal(t, wantCpuRequest, envs[6].Value, "Deployment does not use configured Env Value") - assert.Equal(t, "VARIABLE", envs[7].Name, "Deployment does not use configured Env Name") - assert.Equal(t, "VALUE", envs[7].Value, "Deployment does not use configured Env Value") + assert.Equal(t, "BACKUP_REPOSITORY_SECRET_NAME", envs[5].Name) + assert.Equal(t, "k8up-repo", envs[5].Value) + assert.Equal(t, "BACKUP_OPERATOR_NAMESPACE", envs[6].Name) + assert.Equal(t, "metadata.namespace", envs[6].ValueFrom.FieldRef.FieldPath) + assert.Equal(t, "BACKUP_GLOBAL_CPU_REQUEST", envs[7].Name, "Deployment does not use configured Env Name") + assert.Equal(t, wantCpuRequest, envs[7].Value, "Deployment does not use configured Env Value") + assert.Equal(t, "VARIABLE", envs[8].Name, "Deployment does not use configured Env Name") + assert.Equal(t, "VALUE", envs[8].Value, "Deployment does not use configured Env Value") } func Test_Deployment_ShouldRender_Affinity(t *testing.T) { @@ -93,8 +95,8 @@ got := renderDeployment(t, options, false) assert.Equal(t, overrideNamespace, got.Namespace, "Deployment should use the overridden namespace") - assert.Equal(t, "BACKUP_OPERATOR_NAMESPACE", got.Spec.Template.Spec.Containers[0].Env[4].Name) - assert.Equal(t, "metadata.namespace", got.Spec.Template.Spec.Containers[0].Env[4].ValueFrom.FieldRef.FieldPath) + assert.Equal(t, "BACKUP_OPERATOR_NAMESPACE", got.Spec.Template.Spec.Containers[0].Env[5].Name) + assert.Equal(t, "metadata.namespace", got.Spec.Template.Spec.Containers[0].Env[5].ValueFrom.FieldRef.FieldPath) } func Test_Deployment_ShouldRender_Resources(t *testing.T) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/charts/k8up/values.yaml new/k8up-cli-2.16.1/charts/k8up/values.yaml --- old/k8up-cli-2.16.0/charts/k8up/values.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/charts/k8up/values.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -13,7 +13,7 @@ # -- Operator image repository repository: k8up-io/k8up # -- Operator image tag (version) - tag: v2.15.0 + tag: v2.16.0 imagePullSecrets: [] serviceAccount: @@ -60,6 +60,10 @@ # When enabled, the operator passes `BACKUP_SKIP_SNAPSHOT_SYNC=true` to backup and prune job pods. Webhook notifications are still sent. skipSnapshotSync: false + # -- Specifies the name of the Secret that contains repository configuration values (e.g. S3 endpoint and bucket). + # Defaults to `k8up-repo` if left empty. + repositorySecretName: "" + # -- Specifies the namespace in which K8up's `EffectiveSchedules` are stored. # Defaults to release namespace if left empty. operatorNamespace: "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/cmd/operator/main.go new/k8up-cli-2.16.1/cmd/operator/main.go --- old/k8up-cli-2.16.0/cmd/operator/main.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/cmd/operator/main.go 2026-10-22 16:33:00.000000000 +0200 @@ -57,6 +57,7 @@ &cli.StringFlag{Destination: &cfg.Config.GlobalRestoreS3SecretAccessKey, Name: "globalrestores3secretaccesskey", EnvVars: []string{"BACKUP_GLOBALRESTORES3SECRETACCESSKEY"}, Usage: "set the global restore S3 SecretAccessKey for restores"}, &cli.StringFlag{Destination: &cfg.Config.GlobalRepoPassword, Name: "globalrepopassword", EnvVars: []string{"BACKUP_GLOBALREPOPASSWORD"}, Usage: "set the restic repository password to be used globally"}, + &cli.StringFlag{Destination: &cfg.Config.RepositorySecretName, Name: "repository-secret-name", EnvVars: []string{"BACKUP_REPOSITORY_SECRET_NAME"}, Value: "k8up-repo", Usage: "set the name of the Secret that contains repository configuration values (e.g. S3 endpoint and bucket)"}, &cli.StringFlag{Destination: &cfg.Config.GlobalAccessKey, Name: "globalaccesskeyid", EnvVars: []string{"BACKUP_GLOBALACCESSKEYID"}, Usage: "set the S3 access key id to be used globally"}, &cli.StringFlag{Destination: &cfg.Config.GlobalSecretAccessKey, Name: "globalsecretaccesskey", EnvVars: []string{"BACKUP_GLOBALSECRETACCESSKEY"}, Usage: "set the S3 secret access key to be used globally"}, &cli.StringFlag{Destination: &cfg.Config.GlobalS3Bucket, Name: "globals3bucket", EnvVars: []string{"BACKUP_GLOBALS3BUCKET"}, Usage: "set the S3 bucket to be used globally"}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_archives.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_archives.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_archives.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_archives.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -383,8 +383,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -873,8 +877,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_backups.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_backups.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_backups.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_backups.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -390,8 +390,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_checks.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_checks.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_checks.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_checks.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_prunes.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_prunes.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_prunes.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_prunes.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_restores.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_restores.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_restores.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_restores.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -385,8 +385,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -875,8 +879,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_schedules.yaml new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_schedules.yaml --- old/k8up-cli-2.16.0/config/crd/apiextensions.k8s.io/v1/k8up.io_schedules.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/crd/apiextensions.k8s.io/v1/k8up.io_schedules.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -376,8 +376,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -868,8 +872,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -1486,8 +1494,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -1930,8 +1942,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -2950,8 +2966,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -4164,8 +4184,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -5204,8 +5228,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: @@ -5696,8 +5724,12 @@ x-kubernetes-map-type: atomic bucket: type: string + bucketSecretKey: + type: string endpoint: type: string + endpointSecretKey: + type: string secretAccessKeySecretRef: description: SecretKeySelector selects a key of a Secret. properties: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/config/rbac/role.yaml new/k8up-cli-2.16.1/config/rbac/role.yaml --- old/k8up-cli-2.16.0/config/rbac/role.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/config/rbac/role.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -23,6 +23,14 @@ - watch - apiGroups: - "" + resourceNames: + - k8up-repo + resources: + - secrets + verbs: + - get +- apiGroups: + - "" resources: - serviceaccounts verbs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/e2e/definitions/minio/helm.yaml new/k8up-cli-2.16.1/e2e/definitions/minio/helm.yaml --- old/k8up-cli-2.16.0/e2e/definitions/minio/helm.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/e2e/definitions/minio/helm.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -1,3 +1,11 @@ +# MinIO no longer publishes images on quay.io or Docker Hub. VSHN's image ships +# both the server and the mc client (with sh), so it serves as image and mcImage. +image: + repository: ghcr.io/vshn/minio + tag: RELEASE.2025-09-07T16-13-09Z +mcImage: + repository: ghcr.io/vshn/minio + tag: RELEASE.2025-09-07T16-13-09Z replicas: 1 mode: standalone resources: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/e2e/definitions/subject-dl/deployment.yaml new/k8up-cli-2.16.1/e2e/definitions/subject-dl/deployment.yaml --- old/k8up-cli-2.16.0/e2e/definitions/subject-dl/deployment.yaml 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/e2e/definitions/subject-dl/deployment.yaml 2026-10-22 16:33:00.000000000 +0200 @@ -45,7 +45,7 @@ - name: share mountPath: /mnt/share - name: minio-mc-container - image: minio/mc + image: ghcr.io/vshn/minio:RELEASE.2025-09-07T16-13-09Z imagePullPolicy: IfNotPresent command: - bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/e2e/lib/k8up.bash new/k8up-cli-2.16.1/e2e/lib/k8up.bash --- old/k8up-cli-2.16.0/e2e/lib/k8up.bash 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/e2e/lib/k8up.bash 2026-10-22 16:33:00.000000000 +0200 @@ -81,7 +81,7 @@ kubectl run "$podname" \ --restart Never \ --namespace "${DETIK_CLIENT_NAMESPACE-"k8up-system"}" \ - --image "minio/mc" \ + --image "ghcr.io/vshn/minio:RELEASE.2025-09-07T16-13-09Z" \ --image-pull-policy "IfNotPresent" \ --env "MC_HOST_minio=http://minioadmin:[email protected]:9000" \ --pod-running-timeout 60s \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/go.mod new/k8up-cli-2.16.1/go.mod --- old/k8up-cli-2.16.0/go.mod 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/go.mod 2026-10-22 16:33:00.000000000 +0200 @@ -1,6 +1,6 @@ module github.com/k8up-io/k8up/v2 -go 1.26.5 +go 1.26.10 require ( github.com/firepear/qsplit/v2 v2.5.0 @@ -8,7 +8,7 @@ github.com/go-logr/zapr v1.3.0 github.com/minio/minio-go/v7 v7.1.0 github.com/prometheus/client_golang v1.23.2 - github.com/restic/restic v0.19.0 + github.com/restic/restic v0.19.1 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.11.1 github.com/urfave/cli/v2 v2.27.7 @@ -59,7 +59,7 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -86,17 +86,17 @@ go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.52.0 // indirect + golang.org/x/crypto v0.58.0 // indirect golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect - golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/mod v0.41.0 // indirect + golang.org/x/net v0.61.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/term v0.43.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/sync v0.24.0 // indirect + golang.org/x/sys v0.49.0 // indirect + golang.org/x/term v0.47.0 // indirect + golang.org/x/text v0.43.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.44.0 // indirect + golang.org/x/tools v0.51.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/go.sum new/k8up-cli-2.16.1/go.sum --- old/k8up-cli-2.16.0/go.sum 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/go.sum 2026-10-22 16:33:00.000000000 +0200 @@ -110,8 +110,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= -github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= @@ -168,8 +168,8 @@ github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= -github.com/restic/restic v0.19.0 h1:IQugM6uMG9/lL00O0HM30P12usLmhHeeQhooPRQY/VI= -github.com/restic/restic v0.19.0/go.mod h1:hz6/aYltJIodzs8AxuBkkI7ik37c/tESlseRykLko8M= +github.com/restic/restic v0.19.1 h1:LQKkar5/gYxay1OCokAWPBNiLr1lTpt4fhdM4GWqSlY= +github.com/restic/restic v0.19.1/go.mod h1:WHXRowuv2xE5OEhd8UFLJw8czCP3LJRTvR5rcBfj1AA= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -236,29 +236,29 @@ go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.58.0 h1:COkYLr4k7nDI4r6QtMML2AfzeIswWHAJthLS6K/M/54= +golang.org/x/crypto v0.58.0/go.mod h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w= golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= +golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= +golang.org/x/net v0.61.0 h1:RR+6j/BTBCrggOLugxa+66R8FvoN6MHlzDlZIbN9YFw= +golang.org/x/net v0.61.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA= +golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= +golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= +golang.org/x/term v0.47.0 h1:cpyOwQkr2Nzxe2p6KnrTG7Ei2wtzjsuSjhpXXepZ/BM= +golang.org/x/term v0.47.0/go.mod h1:efAfAuG6RKABvg1ArGebRkvX6LXul14SM67o2e4mUCY= +golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc= +golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= -golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.51.0 h1:k4Xc/1Om9jwkBJBo4NVLMSARBoWtK10mx+W5BnXCeAI= +golang.org/x/tools v0.51.0/go.mod h1:9eEncMayCV6zRMGhR5eZEC2iBx98qWcF1HZ9Z7wJOoA= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/archivecontroller/controller.go new/k8up-cli-2.16.1/operator/archivecontroller/controller.go --- old/k8up-cli-2.16.0/operator/archivecontroller/controller.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/archivecontroller/controller.go 2026-10-22 16:33:00.000000000 +0200 @@ -2,6 +2,7 @@ import ( "context" + "fmt" "time" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" @@ -16,6 +17,8 @@ // ArchiveReconciler reconciles Archive objects type ArchiveReconciler struct { Kube client.Client + // KubeReader performs direct API reads so Secrets only require named GET permissions, not cache list/watch permissions. + KubeReader client.Reader } func (r *ArchiveReconciler) NewObject() *k8upv1.Archive { @@ -29,6 +32,17 @@ func (r *ArchiveReconciler) Provision(ctx context.Context, obj *k8upv1.Archive) (controllerruntime.Result, error) { log := controllerruntime.LoggerFrom(ctx) + if obj.Spec.Backend != nil { + if err := obj.Spec.Backend.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve backend Secret references: %w", err) + } + } + if obj.Spec.RestoreMethod != nil { + if err := obj.Spec.RestoreMethod.S3.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve restore S3 Secret references: %w", err) + } + } + repository := cfg.Config.GetGlobalRepository() if obj.Spec.Backend != nil { repository = obj.Spec.Backend.String() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/archivecontroller/executor.go new/k8up-cli-2.16.1/operator/archivecontroller/executor.go --- old/k8up-cli-2.16.0/operator/archivecontroller/executor.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/archivecontroller/executor.go 2026-10-22 16:33:00.000000000 +0200 @@ -116,8 +116,8 @@ for key, value := range archive.Spec.Backend.GetCredentialEnv() { vars.SetEnvVarSource(key, value) } - vars.SetString(cfg.ResticRepositoryEnvName, archive.Spec.Backend.String()) } + vars.SetString(cfg.ResticRepositoryEnvName, a.Repository) err := vars.Merge(executor.DefaultEnv(a.Obj.GetNamespace())) if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/archivecontroller/setup.go new/k8up-cli-2.16.1/operator/archivecontroller/setup.go --- old/k8up-cli-2.16.0/operator/archivecontroller/setup.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/archivecontroller/setup.go 2026-10-22 16:33:00.000000000 +0200 @@ -16,7 +16,8 @@ func SetupWithManager(mgr controllerruntime.Manager) error { name := "archive.k8up.io" r := reconciler.NewReconciler[*k8upv1.Archive, *k8upv1.ArchiveList](mgr.GetClient(), &ArchiveReconciler{ - Kube: mgr.GetClient(), + Kube: mgr.GetClient(), + KubeReader: mgr.GetAPIReader(), }) return controllerruntime.NewControllerManagedBy(mgr). For(&k8upv1.Archive{}). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/backupcontroller/backup_utils.go new/k8up-cli-2.16.1/operator/backupcontroller/backup_utils.go --- old/k8up-cli-2.16.0/operator/backupcontroller/backup_utils.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/backupcontroller/backup_utils.go 2026-10-22 16:33:00.000000000 +0200 @@ -183,8 +183,8 @@ for key, value := range b.backup.Spec.Backend.GetCredentialEnv() { vars.SetEnvVarSource(key, value) } - vars.SetString(cfg.ResticRepositoryEnvName, b.backup.Spec.Backend.String()) } + vars.SetString(cfg.ResticRepositoryEnvName, b.Repository) } vars.SetStringOrDefault("STATS_URL", b.backup.Spec.StatsURL, cfg.Config.GlobalStatsURL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/backupcontroller/controller.go new/k8up-cli-2.16.1/operator/backupcontroller/controller.go --- old/k8up-cli-2.16.0/operator/backupcontroller/controller.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/backupcontroller/controller.go 2026-10-22 16:33:00.000000000 +0200 @@ -19,6 +19,8 @@ // BackupReconciler reconciles a Backup object type BackupReconciler struct { Kube client.Client + // KubeReader performs direct API reads so Secrets only require named GET permissions, not cache list/watch permissions. + KubeReader client.Reader } func (r *BackupReconciler) NewObject() *k8upv1.Backup { @@ -32,6 +34,12 @@ func (r *BackupReconciler) Provision(ctx context.Context, obj *k8upv1.Backup) (reconcile.Result, error) { log := controllerruntime.LoggerFrom(ctx) + if obj.Spec.Backend != nil { + if err := obj.Spec.Backend.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return reconcile.Result{}, fmt.Errorf("resolve backend Secret references: %w", err) + } + } + repository := cfg.Config.GetGlobalRepository() if obj.Spec.Backend != nil { repository = obj.Spec.Backend.String() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/backupcontroller/setup.go new/k8up-cli-2.16.1/operator/backupcontroller/setup.go --- old/k8up-cli-2.16.0/operator/backupcontroller/setup.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/backupcontroller/setup.go 2026-10-22 16:33:00.000000000 +0200 @@ -25,7 +25,8 @@ func SetupWithManager(mgr controllerruntime.Manager) error { name := "backup.k8up.io" r := reconciler.NewReconciler[*k8upv1.Backup, *k8upv1.BackupList](mgr.GetClient(), &BackupReconciler{ - Kube: mgr.GetClient(), + Kube: mgr.GetClient(), + KubeReader: mgr.GetAPIReader(), }) return controllerruntime.NewControllerManagedBy(mgr). Named(name). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/cfg/config.go new/k8up-cli-2.16.1/operator/cfg/config.go --- old/k8up-cli-2.16.0/operator/cfg/config.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/cfg/config.go 2026-10-22 16:33:00.000000000 +0200 @@ -83,6 +83,7 @@ PromURL string ClusterName string RestartPolicy string + RepositorySecretName string SkipWithoutAnnotation bool SkipSnapshotSync bool EnableRelaxedScheduling bool diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/checkcontroller/controller.go new/k8up-cli-2.16.1/operator/checkcontroller/controller.go --- old/k8up-cli-2.16.0/operator/checkcontroller/controller.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/checkcontroller/controller.go 2026-10-22 16:33:00.000000000 +0200 @@ -2,6 +2,7 @@ import ( "context" + "fmt" "time" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" @@ -16,6 +17,8 @@ // CheckReconciler reconciles a Check object type CheckReconciler struct { Kube client.Client + // KubeReader performs direct API reads so Secrets only require named GET permissions, not cache list/watch permissions. + KubeReader client.Reader } func (r *CheckReconciler) NewObject() *k8upv1.Check { @@ -29,6 +32,12 @@ func (r *CheckReconciler) Provision(ctx context.Context, obj *k8upv1.Check) (controllerruntime.Result, error) { log := controllerruntime.LoggerFrom(ctx) + if obj.Spec.Backend != nil { + if err := obj.Spec.Backend.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve backend Secret references: %w", err) + } + } + repository := cfg.Config.GetGlobalRepository() if obj.Spec.Backend != nil { repository = obj.Spec.Backend.String() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/checkcontroller/executor.go new/k8up-cli-2.16.1/operator/checkcontroller/executor.go --- old/k8up-cli-2.16.0/operator/checkcontroller/executor.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/checkcontroller/executor.go 2026-10-22 16:33:00.000000000 +0200 @@ -91,8 +91,8 @@ for key, value := range c.check.Spec.Backend.GetCredentialEnv() { vars.SetEnvVarSource(key, value) } - vars.SetString(cfg.ResticRepositoryEnvName, c.check.Spec.Backend.String()) } + vars.SetString(cfg.ResticRepositoryEnvName, c.Repository) } vars.SetString("PROM_URL", cfg.Config.PromURL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/checkcontroller/setup.go new/k8up-cli-2.16.1/operator/checkcontroller/setup.go --- old/k8up-cli-2.16.0/operator/checkcontroller/setup.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/checkcontroller/setup.go 2026-10-22 16:33:00.000000000 +0200 @@ -16,7 +16,8 @@ func SetupWithManager(mgr ctrl.Manager) error { name := "check.k8up.io" r := reconciler.NewReconciler[*k8upv1.Check, *k8upv1.CheckList](mgr.GetClient(), &CheckReconciler{ - Kube: mgr.GetClient(), + Kube: mgr.GetClient(), + KubeReader: mgr.GetAPIReader(), }) return ctrl.NewControllerManagedBy(mgr). For(&k8upv1.Check{}). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/controllers.go new/k8up-cli-2.16.1/operator/controllers.go --- old/k8up-cli-2.16.0/operator/controllers.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/controllers.go 2026-10-22 16:33:00.000000000 +0200 @@ -2,3 +2,4 @@ // +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;create;update // +kubebuilder:rbac:groups=core,resources=events,verbs=create;patch +// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get,resourceNames=k8up-repo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/prunecontroller/controller.go new/k8up-cli-2.16.1/operator/prunecontroller/controller.go --- old/k8up-cli-2.16.0/operator/prunecontroller/controller.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/prunecontroller/controller.go 2026-10-22 16:33:00.000000000 +0200 @@ -2,6 +2,7 @@ import ( "context" + "fmt" "time" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" @@ -16,6 +17,8 @@ // PruneReconciler reconciles a Prune object type PruneReconciler struct { Kube client.Client + // KubeReader performs direct API reads so Secrets only require named GET permissions, not cache list/watch permissions. + KubeReader client.Reader } func (r *PruneReconciler) NewObject() *k8upv1.Prune { @@ -29,6 +32,12 @@ func (r *PruneReconciler) Provision(ctx context.Context, obj *k8upv1.Prune) (controllerruntime.Result, error) { log := controllerruntime.LoggerFrom(ctx) + if obj.Spec.Backend != nil { + if err := obj.Spec.Backend.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve backend Secret references: %w", err) + } + } + repository := cfg.Config.GetGlobalRepository() if obj.Spec.Backend != nil { repository = obj.Spec.Backend.String() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/prunecontroller/executor.go new/k8up-cli-2.16.1/operator/prunecontroller/executor.go --- old/k8up-cli-2.16.0/operator/prunecontroller/executor.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/prunecontroller/executor.go 2026-10-22 16:33:00.000000000 +0200 @@ -131,8 +131,8 @@ for key, value := range prune.Spec.Backend.GetCredentialEnv() { vars.SetEnvVarSource(key, value) } - vars.SetString(cfg.ResticRepositoryEnvName, prune.Spec.Backend.String()) } + vars.SetString(cfg.ResticRepositoryEnvName, p.Repository) vars.SetString("PROM_URL", cfg.Config.PromURL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/prunecontroller/setup.go new/k8up-cli-2.16.1/operator/prunecontroller/setup.go --- old/k8up-cli-2.16.0/operator/prunecontroller/setup.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/prunecontroller/setup.go 2026-10-22 16:33:00.000000000 +0200 @@ -16,7 +16,8 @@ func SetupWithManager(mgr ctrl.Manager) error { name := "prune.k8up.io" r := reconciler.NewReconciler[*k8upv1.Prune, *k8upv1.PruneList](mgr.GetClient(), &PruneReconciler{ - Kube: mgr.GetClient(), + Kube: mgr.GetClient(), + KubeReader: mgr.GetAPIReader(), }) return ctrl.NewControllerManagedBy(mgr). For(&k8upv1.Prune{}). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/restorecontroller/controller.go new/k8up-cli-2.16.1/operator/restorecontroller/controller.go --- old/k8up-cli-2.16.0/operator/restorecontroller/controller.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/restorecontroller/controller.go 2026-10-22 16:33:00.000000000 +0200 @@ -2,6 +2,7 @@ import ( "context" + "fmt" "time" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" @@ -16,6 +17,8 @@ // RestoreReconciler reconciles a Restore object type RestoreReconciler struct { Kube client.Client + // KubeReader performs direct API reads so Secrets only require named GET permissions, not cache list/watch permissions. + KubeReader client.Reader } func (r *RestoreReconciler) NewObject() *k8upv1.Restore { @@ -29,6 +32,17 @@ func (r *RestoreReconciler) Provision(ctx context.Context, obj *k8upv1.Restore) (controllerruntime.Result, error) { log := controllerruntime.LoggerFrom(ctx) + if obj.Spec.Backend != nil { + if err := obj.Spec.Backend.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve backend Secret references: %w", err) + } + } + if obj.Spec.RestoreMethod != nil { + if err := obj.Spec.RestoreMethod.S3.ResolveSecretRefs(ctx, r.KubeReader, obj.GetNamespace(), cfg.Config.RepositorySecretName); err != nil { + return controllerruntime.Result{}, fmt.Errorf("resolve restore S3 Secret references: %w", err) + } + } + repository := cfg.Config.GetGlobalRepository() if obj.Spec.Backend != nil { repository = obj.Spec.Backend.String() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/restorecontroller/executor.go new/k8up-cli-2.16.1/operator/restorecontroller/executor.go --- old/k8up-cli-2.16.0/operator/restorecontroller/executor.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/restorecontroller/executor.go 2026-10-22 16:33:00.000000000 +0200 @@ -185,8 +185,8 @@ for key, value := range restore.Spec.Backend.GetCredentialEnv() { vars.SetEnvVarSource(key, value) } - vars.SetString(cfg.ResticRepositoryEnvName, restore.Spec.Backend.String()) } + vars.SetString(cfg.ResticRepositoryEnvName, r.Repository) err := vars.Merge(executor.DefaultEnv(r.Obj.GetNamespace())) if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/restorecontroller/executor_test.go new/k8up-cli-2.16.1/operator/restorecontroller/executor_test.go --- old/k8up-cli-2.16.0/operator/restorecontroller/executor_test.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/restorecontroller/executor_test.go 2026-10-22 16:33:00.000000000 +0200 @@ -7,6 +7,7 @@ "testing" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" + "github.com/k8up-io/k8up/v2/operator/cfg" "github.com/k8up-io/k8up/v2/operator/job" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -134,7 +135,11 @@ for name, tt := range tests { t.Run(name, func(t *testing.T) { - e := NewRestoreExecutor(*newConfig()) + repository := cfg.Config.GetGlobalRepository() + if tt.GivenResource.Spec.Backend != nil { + repository = tt.GivenResource.Spec.Backend.String() + } + e := NewRestoreExecutor(job.NewConfig(nil, tt.GivenResource, repository)) envVars := e.setupEnvVars(context.TODO(), tt.GivenResource) actualEnvVars, actualSecretKeyRefs := extractVarsAndSecretRefs(envVars) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/restorecontroller/setup.go new/k8up-cli-2.16.1/operator/restorecontroller/setup.go --- old/k8up-cli-2.16.0/operator/restorecontroller/setup.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/restorecontroller/setup.go 2026-10-22 16:33:00.000000000 +0200 @@ -4,7 +4,7 @@ k8upv1 "github.com/k8up-io/k8up/v2/api/v1" "github.com/k8up-io/k8up/v2/operator/reconciler" batchv1 "k8s.io/api/batch/v1" - "sigs.k8s.io/controller-runtime" + controllerruntime "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/predicate" ) @@ -16,7 +16,8 @@ func SetupWithManager(mgr controllerruntime.Manager) error { name := "restore.k8up.io" r := reconciler.NewReconciler[*k8upv1.Restore, *k8upv1.RestoreList](mgr.GetClient(), &RestoreReconciler{ - Kube: mgr.GetClient(), + Kube: mgr.GetClient(), + KubeReader: mgr.GetAPIReader(), }) return controllerruntime.NewControllerManagedBy(mgr). For(&k8upv1.Restore{}). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/schedulecontroller/randomizer.go new/k8up-cli-2.16.1/operator/schedulecontroller/randomizer.go --- old/k8up-cli-2.16.0/operator/schedulecontroller/randomizer.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/schedulecontroller/randomizer.go 2026-10-22 16:33:00.000000000 +0200 @@ -40,8 +40,7 @@ return k8upv1.ScheduleDefinition(fmt.Sprintf("%d %d * * *", minute, hour)), nil case ScheduleMonthlyRandom: return k8upv1.ScheduleDefinition(fmt.Sprintf("%d %d %d * *", minute, hour, dayOfMonth)), nil - case ScheduleAnnuallyRandom: - case ScheduleYearlyRandom: + case ScheduleAnnuallyRandom, ScheduleYearlyRandom: month := remainderFromModulo(checksum, 12, 1) return k8upv1.ScheduleDefinition(fmt.Sprintf("%d %d %d %d *", minute, hour, dayOfMonth, month)), nil case ScheduleWeeklyRandom: @@ -50,7 +49,6 @@ default: return originalSchedule, fmt.Errorf("unrecognized random schedule: '%s'", originalSchedule) } - return originalSchedule, nil } // calculateChecksumFromSeed calculates a SHA1 hexadecimal checksum from the given seed. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/operator/schedulecontroller/randomizer_test.go new/k8up-cli-2.16.1/operator/schedulecontroller/randomizer_test.go --- old/k8up-cli-2.16.0/operator/schedulecontroller/randomizer_test.go 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/operator/schedulecontroller/randomizer_test.go 2026-10-22 16:33:00.000000000 +0200 @@ -72,6 +72,11 @@ schedule: "@yearly-random", expectedSchedule: "52 4 26 5 *", }, + "WhenScheduleRandomAnnuallyGiven_ThenReturnStableRandomizedSchedule": { + // @annually-random is documented as an alias of @yearly-random. + schedule: "@annually-random", + expectedSchedule: "52 4 26 5 *", + }, } for name, tt := range tests { t.Run(name, func(t *testing.T) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k8up-cli-2.16.0/renovate.json new/k8up-cli-2.16.1/renovate.json --- old/k8up-cli-2.16.0/renovate.json 2026-07-17 13:27:49.000000000 +0200 +++ new/k8up-cli-2.16.1/renovate.json 2026-10-22 16:33:00.000000000 +0200 @@ -2,7 +2,8 @@ "extends": [ "config:base", ":gitSignOff", - ":disableDependencyDashboard" + ":disableDependencyDashboard", + "helpers:pinGitHubActionDigests" ], "labels": [ "dependency" @@ -13,23 +14,40 @@ "packageRules": [ { "description": "Label chart dependency updates", - "matchFileNames": ["charts/**"], - "addLabels": ["area:chart", "chart:k8up"] + "matchFileNames": [ + "charts/**" + ], + "addLabels": [ + "area:chart", + "chart:k8up" + ] }, { "description": "Label operator dependency updates", - "matchFileNames": ["go.mod", "go.sum"], - "addLabels": ["area:operator"] + "matchFileNames": [ + "go.mod", + "go.sum" + ], + "addLabels": [ + "area:operator" + ] }, { "description": "Automerge GitHub Actions (CI-only, no impact on shipped code)", - "matchManagers": ["github-actions"], + "matchManagers": [ + "github-actions" + ], "automerge": true }, { "description": "Automerge Docker base image patch/minor updates", - "matchDatasources": ["docker"], - "matchUpdateTypes": ["patch", "minor"], + "matchDatasources": [ + "docker" + ], + "matchUpdateTypes": [ + "patch", + "minor" + ], "automerge": true }, { @@ -67,9 +85,18 @@ "schedule": [ "on the first day of the month" ] + }, + { + "matchManagers": [ + "github-actions" + ], + "groupName": "github actions dependencies", + "minimumReleaseAge": "7 days", + "prCreation": "not-pending", + "internalChecksFilter": "strict" } ], "prBodyNotes": [ "- [ ] PR contains the label that identifies the area, one of: `area:operator`, `area:chart`\n- [ ] If the PR is targeting a Helm chart, add the chart label, e.g. `chart:k8up`" ] -} +} \ No newline at end of file ++++++ k8up-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.yNaZof/_old 2026-10-24 22:05:46.886508539 +0200 +++ /var/tmp/diff_new_pack.yNaZof/_new 2026-10-24 22:05:46.889508666 +0200 @@ -1,5 +1,5 @@ name: k8up-cli -version: 2.16.0 -mtime: 1784287669 -commit: 343b99d1519385d75738dbb07d6ff45785c3f186 +version: 2.16.1 +mtime: 1792679580 +commit: 8c825c87f7fcf64cc2a3e37d914b64bc698a8b58 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/k8up-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.k8up-cli.new.2252680/vendor.tar.gz differ: char 152, line 1
