kubernetes-sigs/controller-tools

CRD: Structs in Type Def with Self referential slices don't work post make generate and make manifest (Always wants items:{} to be non empty)

kkasbi opened this issue · 1 comments

Tool Versions
CONTROLLER_TOOLS_VERSION ?= v0.15.0

This is my currect CRD definition structure,

// RateLimitConfigSpec defines the desired state of RateLimitConfig
type RateLimitConfigSpec struct {
    // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    // Important: Run "make" to regenerate code after modifying this file

    // Version is a hash of the EnvoyResources field
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    Version string `json:"version"`

    // RateLimitInfo is the rate limit configuration
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    RateLimitConfig RateLimitInfo `json:"rate_limit_config,omitempty" yaml:"rateLimitConfig"`
}

type RateLimitInfo struct {
    // Name of the rate limit configuration. This should be unique for each configuration.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    Name string `json:"name" yaml:"name"`
    // Domain name for the rate limit configuration.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    Domain string `json:"domain,omitempty" yaml:"domain"`
    // List of rate limit configuration descriptors.
    // +kubebuilder:validation:Optional
    // +nullable
    Descriptors *Descriptors `json:"descriptors,omitempty" yaml:"descriptors"`
}

// +kubebuilder:validation:Optional
// +nullable
// +kubebuilder:validation:MinItems=0
type Descriptors []RateLimitDescriptor

type RateLimitDescriptor struct {
    // Key of the descriptor.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    Key string `json:"key" yaml:"key"`
    // Optional value of the descriptor.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    Value string `json:"value,omitempty" yaml:"value"`
    // Rate limit policy of the descriptor.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    RateLimit *RateLimitPolicy `json:"rate_limit,omitempty" yaml:"rateLimit"`
    // List of sub rate limit descriptors.
    // +kubebuilder:validation:Optional
    // +nullable
    SubDescriptors *Descriptors `json:"descriptors,omitempty" yaml:"descriptors"`
    // Mark the descriptor as shadow. When the values is true, rate limit service allow requests to the backend.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    ShadowMode bool `json:"shadow_mode,omitempty" yaml:"shadowMode"`
    // Setting the `detailed_metric: true` for a descriptor will extend the metrics that are produced.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    DetailedMetric bool `json:"detailed_metric,omitempty"`
}

type RateLimitPolicy struct {
    // Optional name for the rate limit policy. Name the policy, if it should be replaced (dropped evaluation) by
    // another policy.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    Name string `json:"name,omitempty" yaml:"name"`
    // Unit of time for the rate limit.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    Unit RateLimitUnit `json:"unit" yaml:"unit"`
    // Number of requests allowed in the policy within `unit` time.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    RequestsPerUnit uint32 `json:"requests_per_unit" yaml:"requestsPerUnit"`
    // Mark the rate limit policy as unlimited. All requests are allowed to the backend.
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    Unlimited bool `json:"unlimited" yaml:"unlimited"`
    // List of rate limit policies, this rate limit policy will replace (drop evaluation)
    // For more information: https://github.com/envoyproxy/ratelimit/tree/0b2f4d5fb04bf55e1873e2c5e2bb28da67c0643f#replaces
    // Example: https://github.com/envoyproxy/ratelimit/tree/0b2f4d5fb04bf55e1873e2c5e2bb28da67c0643f#example-7
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    Replaces []*RateLimitReplace `json:"replaces,omitempty" yaml:"replaces"`
}

// Replace specifies the rate limit policy that should be replaced (dropped evaluation).
// For more information: https://github.com/envoyproxy/ratelimit/tree/0b2f4d5fb04bf55e1873e2c5e2bb28da67c0643f#replaces
type RateLimitReplace struct {
    // Name of the rate limit policy, that is being replaced (dropped evaluation).
    // +operator-sdk:csv:customresourcedefinitions:type=spec
    // +optional
    Name string `json:"name,omitempty" yaml:"name"`
}

// Identifies the unit of of time for rate limit.
type RateLimitUnit int32

const (
    // The time unit is not known.
    RateLimitUnit_UNKNOWN RateLimitUnit = 0
    // The time unit representing a second.
    RateLimitUnit_SECOND RateLimitUnit = 1
    // The time unit representing a minute.
    RateLimitUnit_MINUTE RateLimitUnit = 2
    // The time unit representing an hour.
    RateLimitUnit_HOUR RateLimitUnit = 3
    // The time unit representing a day.
    RateLimitUnit_DAY RateLimitUnit = 4
)

Ideally, the make generate and make manifests run fine, but the moment I deploy the crd definition on K8S for the first time it give the below error.
Basically the RateLimitDescriptor struct has a field []RateLimitDescriptor, which is causing the issue.

The generated crd definition is as below,

          spec:
            description: RateLimitConfigSpec defines the desired state of RateLimitConfig
            properties:
              rate_limit_config:
                description: RateLimitInfo is the rate limit configuration
                properties:
                  descriptors:
                    default: {}
                    description: List of rate limit configuration descriptors.
                    items:
                      properties:
                        descriptors:
                          default: {}
                          description: List of sub rate limit descriptors.
                          nullable: true

Why is this error coming? What I am missing here?

The CustomResourceDefinition "ratelimitconfigs.domain.group.com" is invalid: spec.validation.openAPIV3Schema.properties[spec].properties[rate_limit_config].properties[descriptors].items.properties[descriptors].type: Required value: must not be empty for specified object fields make: *** [install] Error 1