Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "+kubebuilder:validation:MaxItems" marker for validating embedded structs in CRD schemas #10

Closed
ulucinar opened this issue Jun 9, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@ulucinar
Copy link
Collaborator

ulucinar commented Jun 9, 2022

What problem are you facing?

While working on #4, we have realized that Terraform represents embedded blocks always with Sets/Lists of length of most 1 (if optional, length is 0 or 1, if required, it will be always of length 1). An example is the policy_settings block in azurerm_web_application_firewall_policy. In fact, this is an optional configuration block nested in azurerm_web_application_firewall_policy block. We would normally want to represents it with a CRD schema as follows:

type WebApplicationFirewallPolicyParameters struct {
	// +kubebuilder:validation:Optional
	PolicySettings *PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
        ...

However, it looks like (probably due to HCL semantics), Terraform provider instead represents this as a list of length at most 1:

			"policy_settings": {
				Type:     pluginsdk.TypeList,
				Optional: true,
				MaxItems: 1,

Upjet CRD generation pipeline also does not allow directly embedding a pluginsdk.Resource directly under another pluginsdk.Resource as expected.

Thus, Terrajet currently generates the following instead of the above fragment:

type WebApplicationFirewallPolicyParameters struct {
	// +kubebuilder:validation:Optional
	PolicySettings []PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
        ...

Since this is a generated API that reflects the underlying Terraform resource API, I believe this is okay. But we have some room for improvement for such nested blocks (structs) by asserting a max length of 1 with kubebuilder markers.

How could Terrajet help solve your problem?

We can use the Terraform resource schema to observe the pluginsdk.Schema.MaxItems to place the appropriate kubebuilder marker on the generated field. This will provide a better UX around the generated Crossplane provider API. The resulting generated code could be something like the following for the above field:

type WebApplicationFirewallPolicyParameters struct {
	// +kubebuilder:validation:Optional
        // +kubebuilder:validation:MaxItems=1
	PolicySettings []PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
        ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants