crossplane / crossplane/upjet

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

Open
#395 0 comments 3 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
481
Forks
131
Avg merge
2d 1h
Merged PRs (30d)
11

Description

### What happened?

Hi,
I attempted to generate a Crossplane provider with Upjet for [PostgreSQL Terraform provider](https://registry.terraform.io/providers/cyrilgdn/postgresql/latest), but discovered that generated controllers do not watch referenced resources.

Take, for example, [postgresql_role](https://registry.terraform.io/providers/cyrilgdn/postgresql/latest/docs/resources/postgresql_role) resource, which has sensitive attribute `password`. The generated CRD contains the following:
```go
// 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:
```go
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](https://github.com/crossplane/upjet/blob/main/docs/generating-a-provider.md)" guide from this repository and generated a Crossplane provider for [PostgreSQL Terraform provider](https://registry.terraform.io/providers/cyrilgdn/postgresql/latest) with "postgresql_role" resource.

Here's my `config/role/config.go` file
```go
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.

Contributor guide

Open the contributing guide

Research direction

Use config/role/config.go and the provider-generation guide to reproduce the issue with the postgresql_role resource, then run make generate and make run. Inspect the generated controller setup shown in the report and determine how referenced Secrets are watched; done means changing passwordSecretRef causes resource reconciliation.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes, postgresql, terraform
Domain
devops, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.