Skip to content

fix(types): make secret reference fields optional in initProvider - #727

Open
pujitha24 wants to merge 1 commit into
crossplane:mainfrom
pujitha24:auto/issue-456
Open

fix(types): make secret reference fields optional in initProvider#727
pujitha24 wants to merge 1 commit into
crossplane:mainfrom
pujitha24:auto/issue-456

Conversation

@pujitha24

Copy link
Copy Markdown

Fixes #456

I have:

  • Read and followed Upjet's contribution process.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Extended the table-driven TestBuild cases Sensitive_Fields and Sensitive_Fields_namespaced in pkg/types/builder_test.go to assert on the generated initProvider struct, not just forProvider. Confirmed via git stash on pkg/types/field.go alone that these assertions FAIL against the pre-fix code and PASS with the fix applied:

go test ./pkg/types/... -run TestBuild -v

Also ran, all passing:

go build ./...
go vet ./pkg/...
go test ./pkg/...

AI assistance: this change was drafted with Claude Code.

Motivation: NewSensitiveField (pkg/types/field.go) only wrapped a
generated secret-reference field (e.g. *v1.SecretKeySelector) in a
pointer with an omitempty JSON tag when the underlying Terraform field
was itself Optional. When the Terraform field was Required, the
generated field stayed a non-pointer type with no omitempty tag. Since
forProvider and initProvider share the same Field.FieldType and
Field.JSONTag for secret references, this made the initProvider secret
reference required in the CRD schema too, even though initProvider
fields are always meant to be optional. Users who wanted to set a
secret only in forProvider were forced to duplicate it into
initProvider as well.

Approach: Make the pointer-wrap and omitempty tag unconditional in
NewSensitiveField, independent of the source field's Terraform
required/optional-ness. This matches how ordinary (non-sensitive)
fields already behave: scalar Go types are always pointers
(pkg/types/builder.go buildSchema), and the base JSON tag always
defaults to omitempty (pkg/types/field.go NewField); required-ness for
forProvider is enforced separately via an explicit kubebuilder marker
and a CEL validation rule, not via the Go type/tag, so forProvider's
required behavior for a required sensitive field is unchanged.

Validation: Extended the table-driven TestBuild cases Sensitive_Fields
and Sensitive_Fields_namespaced in pkg/types/builder_test.go to assert
on the generated initProvider struct, not just forProvider. Confirmed
via `git stash` on pkg/types/field.go alone that these assertions FAIL
against the pre-fix code and PASS with the fix applied:

  go test ./pkg/types/... -run TestBuild -v

Also ran, all passing:

  go build ./...
  go vet ./pkg/...
  go test ./pkg/...

Report: crossplane#456
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Sensitive secret-reference fields now generate optional pointer types with omitempty. Builder tests now validate the corresponding InitProvider output for cluster-scoped and namespaced fields.

Changes

Sensitive field reference generation

Layer / File(s) Summary
Optional sensitive field generation
pkg/types/field.go
Sensitive fields always use pointer types and omitempty JSON tags, including required Terraform schema fields.
Builder InitProvider expectations
pkg/types/builder_test.go
TestBuild now includes expected InitProvider types and optional secret-reference fields for cluster-scoped and namespaced resources.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: backport release-1.11, backport release-1.10

Suggested reviewers: erhancagirici, sergenyalcin, ulucinar

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title is descriptive, matches the secret-reference change, and is 65 characters long, below the 72-character limit.
Description check ✅ Passed The description explains the optional initProvider secret-reference fix, test coverage, and validation commands.
Linked Issues check ✅ Passed The changes make initProvider secret references optional and add tests for sensitive and namespaced fields, satisfying issue #456.
Out of Scope Changes check ✅ Passed The implementation and related test updates are limited to the secret-reference behavior described in issue #456.
Configuration Api Breaking Changes ✅ Passed The pull request changes only pkg/types/field.go and pkg/types/builder_test.go; git diff shows no changes under pkg/config or its public API.
Generated Code Manual Edits ✅ Passed The complete diff changes only pkg/types/builder_test.go and pkg/types/field.go; no path matches the zz_*.go generated-file pattern.
Template Breaking Changes ✅ Passed The commit changes only pkg/types/builder_test.go and pkg/types/field.go; no pkg/controller/external*.go template or controller behavior changes are present.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/types/builder_test.go`:
- Around line 871-875: Update the InitProvider assertion in the builder test to
fail when tc.want.initProvider is non-empty and g.InitProviderType is nil,
before calling Obj().String(). Preserve the existing cmp.Diff validation for
non-nil generated types.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f3929ed1-373b-49ca-a673-8f500339c0b3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a879 and 638c3cb.

📒 Files selected for processing (2)
  • pkg/types/builder_test.go
  • pkg/types/field.go

Comment thread pkg/types/builder_test.go
Comment on lines +871 to +875
if tc.want.initProvider != "" && g.InitProviderType != nil {
if diff := cmp.Diff(tc.want.initProvider, g.InitProviderType.Obj().String()); diff != "" {
t.Fatalf("Build(...): -want initProvider, +got initProvider: %s", diff)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fail when the generated InitProvider type is missing.

If tc.want.initProvider is non-empty but g.InitProviderType is nil, this condition skips the assertion and the test passes. Check for nil and fail before calling Obj().String().

Proposed fix
-			if tc.want.initProvider != "" && g.InitProviderType != nil {
+			if tc.want.initProvider != "" {
+				if g.InitProviderType == nil {
+					t.Fatalf("Build(...): expected initProvider type, got nil")
+				}
 				if diff := cmp.Diff(tc.want.initProvider, g.InitProviderType.Obj().String()); diff != "" {
 					t.Fatalf("Build(...): -want initProvider, +got initProvider: %s", diff)
 				}
 			}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if tc.want.initProvider != "" && g.InitProviderType != nil {
if diff := cmp.Diff(tc.want.initProvider, g.InitProviderType.Obj().String()); diff != "" {
t.Fatalf("Build(...): -want initProvider, +got initProvider: %s", diff)
}
}
if tc.want.initProvider != "" {
if g.InitProviderType == nil {
t.Fatalf("Build(...): expected initProvider type, got nil")
}
if diff := cmp.Diff(tc.want.initProvider, g.InitProviderType.Obj().String()); diff != "" {
t.Fatalf("Build(...): -want initProvider, +got initProvider: %s", diff)
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/types/builder_test.go` around lines 871 - 875, Update the InitProvider
assertion in the builder test to fail when tc.want.initProvider is non-empty and
g.InitProviderType is nil, before calling Obj().String(). Preserve the existing
cmp.Diff validation for non-nil generated types.

@pujitha24

Copy link
Copy Markdown
Author

This has been sitting green and rebased for a couple weeks now — happy to make any changes that would help move review along.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Secret in InitProvider is required but should be optional

1 participant