upjet icon indicating copy to clipboard operation
upjet copied to clipboard

Updates in secrets referenced by sensitive fields don't trigger resource reconciliation

Open take-five opened this issue 1 year ago • 0 comments

What happened?

Hi, I attempted to generate a Crossplane provider with Upjet for PostgreSQL Terraform provider, but discovered that generated controllers do not watch referenced resources.

Take, for example, postgresql_role resource, which has sensitive attribute password. The generated CRD contains the following:

// Sets the role's password. A password is only of use
// for roles having the login attribute set to true.
// Sets the role's password
// +kubebuilder:validation:Optional
PasswordSecretRef *v1.SecretKeySelector `json:"passwordSecretRef,omitempty" tf:"-"`

I was able to create a Role resource and it successfully reconciled, but when I changed the contents of the secret referenced from passwordSecretRef field, nothing happened.

The reason is that the following code in the generated controller doesn't specify that reconciliation should trigger whenever an associated secret is changed:

return ctrl.NewControllerManagedBy(mgr).
	Named(name).
	WithOptions(o.ForControllerRuntime()).
	WithEventFilter(xpresource.DesiredStateChanged()).
	Watches(&v1alpha1.Database{}, eventHandler).
	Complete(ratelimiter.NewReconciler(name, r, o.GlobalRateLimiter))

KubeBuilder book describes how to watch externally managed resources (such as secrets) in controllers: https://book.kubebuilder.io/reference/watching-resources/externally-managed

Perhaps Upjet could generate all necessary boilerplate code to watch externally managed secrets (and maybe all referenced resources as well?).

How can we reproduce it?

I followed the "Generating a Crossplane provider" guide from this repository and generated a Crossplane provider for PostgreSQL Terraform provider with "postgresql_role" resource.

Here's my config/role/config.go file

package role

import (
	"github.com/crossplane/upjet/pkg/config"
)

// Configure configures individual resources by adding custom ResourceConfigurators.
func Configure(p *config.Provider) {
	p.AddResourceConfigurator("postgresql_role", func(r *config.Resource) {
		r.ShortGroup = "postgresql"
		r.ExternalName = config.NameAsIdentifier
	})
}

I generated CRDs and controller using make generate and then ran it against local Kind cluster using make run. After initial reconciliation, I changed the contents of a secret which I referenced from my Role custom resource.

I used upjet 1.3.0.

take-five avatar Apr 30 '24 08:04 take-five