diff --git a/e2e/localstack/localstack-deployment.yaml b/e2e/localstack/localstack-deployment.yaml index 667f44f2..904ef96a 100644 --- a/e2e/localstack/localstack-deployment.yaml +++ b/e2e/localstack/localstack-deployment.yaml @@ -56,7 +56,27 @@ apiVersion: v1 kind: Secret metadata: namespace: crossplane-system - name: localstack + name: localstack-a +type: Opaque +data: + access_key: "RHVtbXk=" + secret_key: "RHVtbXk=" +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: crossplane-system + name: localstack-b +type: Opaque +data: + access_key: "RHVtbXk=" + secret_key: "RHVtbXk=" +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: crossplane-system + name: localstack-c type: Opaque data: access_key: "RHVtbXk=" diff --git a/e2e/localstack/localstack-provider-cfg.yaml b/e2e/localstack/localstack-provider-cfg.yaml index e72e0009..9edb25c3 100644 --- a/e2e/localstack/localstack-provider-cfg.yaml +++ b/e2e/localstack/localstack-provider-cfg.yaml @@ -8,7 +8,7 @@ spec: source: Secret secretRef: namespace: crossplane-system - name: localstack + name: localstack-a key: credentials disableHealthCheck: false healthCheckIntervalSeconds: 5 @@ -23,7 +23,7 @@ spec: source: Secret secretRef: namespace: crossplane-system - name: localstack + name: localstack-b key: credentials disableHealthCheck: false healthCheckIntervalSeconds: 5 @@ -38,7 +38,7 @@ spec: source: Secret secretRef: namespace: crossplane-system - name: localstack + name: localstack-c key: credentials disableHealthCheck: false healthCheckIntervalSeconds: 5 diff --git a/internal/controller/providerconfig/backendmonitor/backendmonitor.go b/internal/controller/providerconfig/backendmonitor/backendmonitor.go index 0671292d..b8415f2e 100644 --- a/internal/controller/providerconfig/backendmonitor/backendmonitor.go +++ b/internal/controller/providerconfig/backendmonitor/backendmonitor.go @@ -7,8 +7,10 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/reconciler/providerconfig" apisv1alpha1 "github.com/linode/provider-ceph/apis/v1alpha1" "github.com/linode/provider-ceph/internal/backendstore" + corev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" ) type Controller struct { @@ -54,5 +56,6 @@ func WithS3Timeout(t time.Duration) func(*Controller) { func (c *Controller) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&apisv1alpha1.ProviderConfig{}). + Watches(&corev1.Secret{}, &handler.EnqueueRequestForObject{}). Complete(c) } diff --git a/internal/controller/providerconfig/backendmonitor/backendmonitor_controller.go b/internal/controller/providerconfig/backendmonitor/backendmonitor_controller.go index 03bccb74..0fc2c9be 100644 --- a/internal/controller/providerconfig/backendmonitor/backendmonitor_controller.go +++ b/internal/controller/providerconfig/backendmonitor/backendmonitor_controller.go @@ -21,10 +21,14 @@ import ( v1 "github.com/crossplane/crossplane-runtime/apis/common/v1" "github.com/crossplane/crossplane-runtime/pkg/errors" + "github.com/crossplane/crossplane-runtime/pkg/meta" + "go.opentelemetry.io/otel" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" + apimachinerymetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -35,10 +39,12 @@ import ( ) const ( - errCreateS3Client = "failed create s3 client" - errCreateSTSClient = "failed create sts client" + errCreateS3Client = "failed to create s3 client" + errCreateSTSClient = "failed to create sts client" + errAddCtrlRef = "failed to add controller reference" errGetProviderConfig = "failed to get ProviderConfig" errGetSecret = "failed to get Secret" + errUpdateSecret = "failed to update Secret" ) func (c *Controller) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { @@ -87,6 +93,17 @@ func (c *Controller) addOrUpdateBackend(ctx context.Context, pc *apisv1alpha1.Pr return errors.Wrap(err, errCreateSTSClient) } + // Set the ProviderConfig as an owner of the Secret so that any change to the Secret + // will trigger a reconcile of the ProviderConfig. This ensures new clients will + // be created if the Secret's data (SK/AK pair) are changed. + if !apimachinerymetav1.IsControlledBy(secret, pc) { + if err := meta.AddControllerReference(secret, meta.AsController(meta.TypedReferenceTo(pc, pc.GroupVersionKind()))); err != nil { + return errors.Wrap(err, errAddCtrlRef) + } + if err := c.kubeClient.Update(ctx, secret); err != nil { + return errors.Wrap(err, errUpdateSecret) + } + } readyCondition := pc.Status.GetCondition(v1.TypeReady) c.backendStore.AddOrUpdateBackend(pc.Name, s3Client, stsClient, true, utils.MapConditionToHealthStatus(readyCondition))