From 44bbc8794f4fd15d15f4bfa74683e401f45acc2f Mon Sep 17 00:00:00 2001 From: v47 Date: Wed, 3 Sep 2025 01:59:49 +0200 Subject: [PATCH 1/4] enabled commentstart linter and addressed findings --- .golangci-kal.yml | 12 ++++++------ controlplane/eks/api/v1beta1/types.go | 6 +++--- controlplane/eks/api/v1beta2/types.go | 6 +++--- exp/api/v1beta1/types.go | 2 +- exp/api/v1beta2/types.go | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.golangci-kal.yml b/.golangci-kal.yml index 9a7d650a1b..69198cafe9 100644 --- a/.golangci-kal.yml +++ b/.golangci-kal.yml @@ -25,7 +25,7 @@ linters: #- "nobools" # Bools do not evolve over time, should use enums instead. #- "nofloats" # Ensure floats are not used. #- "optionalorrequired" # Every field should be marked as `+optional` or `+required`. - # - "requiredfields" # Required fields should not be pointers, and should not have `omitempty`. + - "requiredfields" # Required fields should not be pointers, and should not have `omitempty`. - "statussubresource" # All root objects that have a `status` field should have a status subresource. # Linters below this line are disabled, pending conversation on how and when to enable them. @@ -45,11 +45,11 @@ linters: # pointerPolicy: Warn | SuggestFix # Defaults to `SuggestFix`. We want our required fields to not be pointers. exclusions: - generated: strict - paths: - - zz_generated.*\.go$ - - ".*_test.go" # Exclude test files. - rules: + generated: strict + paths: + - zz_generated.*\.go$ + - ".*_test.go" # Exclude test files. + rules: # KAL should only run on API folders. - path-except: "api//*" linters: diff --git a/controlplane/eks/api/v1beta1/types.go b/controlplane/eks/api/v1beta1/types.go index b2d80277ac..4de86be1be 100644 --- a/controlplane/eks/api/v1beta1/types.go +++ b/controlplane/eks/api/v1beta1/types.go @@ -223,7 +223,7 @@ type OIDCIdentityProviderConfig struct { // This is also known as audience. The ID for the client application that makes // authentication requests to the OpenID identity provider. // +kubebuilder:validation:Required - ClientID string `json:"clientId,omitempty"` + ClientID string `json:"clientId"` // The JWT claim that the provider uses to return your groups. // +optional @@ -239,7 +239,7 @@ type OIDCIdentityProviderConfig struct { // // IdentityProviderConfigName is a required field // +kubebuilder:validation:Required - IdentityProviderConfigName string `json:"identityProviderConfigName,omitempty"` + IdentityProviderConfigName string `json:"identityProviderConfigName"` // The URL of the OpenID identity provider that allows the API server to discover // public signing keys for verifying tokens. The URL must begin with https:// @@ -250,7 +250,7 @@ type OIDCIdentityProviderConfig struct { // and must be publicly accessible over the internet. // // +kubebuilder:validation:Required - IssuerURL string `json:"issuerUrl,omitempty"` + IssuerURL string `json:"issuerUrl"` // The key value pairs that describe required claims in the identity token. // If set, each claim is verified to be present in the token with a matching diff --git a/controlplane/eks/api/v1beta2/types.go b/controlplane/eks/api/v1beta2/types.go index ba355089ef..bc4da380cd 100644 --- a/controlplane/eks/api/v1beta2/types.go +++ b/controlplane/eks/api/v1beta2/types.go @@ -227,7 +227,7 @@ type OIDCIdentityProviderConfig struct { // This is also known as audience. The ID for the client application that makes // authentication requests to the OpenID identity provider. // +kubebuilder:validation:Required - ClientID string `json:"clientId,omitempty"` + ClientID string `json:"clientId"` // The JWT claim that the provider uses to return your groups. // +optional @@ -243,7 +243,7 @@ type OIDCIdentityProviderConfig struct { // // IdentityProviderConfigName is a required field // +kubebuilder:validation:Required - IdentityProviderConfigName string `json:"identityProviderConfigName,omitempty"` + IdentityProviderConfigName string `json:"identityProviderConfigName"` // The URL of the OpenID identity provider that allows the API server to discover // public signing keys for verifying tokens. The URL must begin with https:// @@ -254,7 +254,7 @@ type OIDCIdentityProviderConfig struct { // and must be publicly accessible over the internet. // // +kubebuilder:validation:Required - IssuerURL string `json:"issuerUrl,omitempty"` + IssuerURL string `json:"issuerUrl"` // The key value pairs that describe required claims in the identity token. // If set, each claim is verified to be present in the token with a matching diff --git a/exp/api/v1beta1/types.go b/exp/api/v1beta1/types.go index f0886db879..b337340159 100644 --- a/exp/api/v1beta1/types.go +++ b/exp/api/v1beta1/types.go @@ -53,7 +53,7 @@ type EBS struct { type BlockDeviceMapping struct { // The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh). // +kubebuilder:validation:Required - DeviceName string `json:"deviceName,omitempty"` + DeviceName string `json:"deviceName"` // You can specify either VirtualName or Ebs, but not both. // +optional diff --git a/exp/api/v1beta2/types.go b/exp/api/v1beta2/types.go index b4eca931a8..9db149d9a7 100644 --- a/exp/api/v1beta2/types.go +++ b/exp/api/v1beta2/types.go @@ -52,7 +52,7 @@ type EBS struct { type BlockDeviceMapping struct { // The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh). // +kubebuilder:validation:Required - DeviceName string `json:"deviceName,omitempty"` + DeviceName string `json:"deviceName"` // You can specify either VirtualName or Ebs, but not both. // +optional From 43a07db8f49ffc974379499dde09a6333f79b782 Mon Sep 17 00:00:00 2001 From: v47 Date: Thu, 4 Sep 2025 02:27:50 +0200 Subject: [PATCH 2/4] Updated kube-api-linter version to the latest. After update relax conditions checks in .golangci-kal.yml (comment out conditions config). The older version was not picking them. --- .golangci-kal.yml | 8 ++--- api/v1beta1/awsmachine_types.go | 2 +- api/v1beta2/awsmachine_types.go | 2 +- ...ster.x-k8s.io_awsmanagedcontrolplanes.yaml | 8 +++++ ...8s.io_awsmanagedcontrolplanetemplates.yaml | 4 +++ ...ne.cluster.x-k8s.io_rosacontrolplanes.yaml | 6 ++++ ...ture.cluster.x-k8s.io_awsmachinepools.yaml | 2 ++ ...uster.x-k8s.io_awsmanagedmachinepools.yaml | 6 ++++ ...ure.cluster.x-k8s.io_rosamachinepools.yaml | 2 ++ controlplane/eks/api/v1beta1/types.go | 12 ++++--- controlplane/eks/api/v1beta2/types.go | 18 ++++++---- .../rosa/api/v1beta2/external_auth_types.go | 33 +++++++++++-------- exp/api/v1beta1/awsmachinepool_types.go | 2 +- exp/api/v1beta1/types.go | 12 ++++--- exp/api/v1beta2/awsmachinepool_types.go | 2 +- exp/api/v1beta2/rosamachinepool_types.go | 9 +++-- exp/api/v1beta2/types.go | 12 ++++--- hack/tools/.custom-gcl.yaml | 2 +- 18 files changed, 97 insertions(+), 45 deletions(-) diff --git a/.golangci-kal.yml b/.golangci-kal.yml index 69198cafe9..43e8478903 100644 --- a/.golangci-kal.yml +++ b/.golangci-kal.yml @@ -32,10 +32,10 @@ linters: disable: - "*" # We will manually enable new linters after understanding the impact. Disable all by default. lintersConfig: - conditions: - isFirstField: Warn # Require conditions to be the first field in the status struct. - usePatchStrategy: Forbid # Conditions should not use the patch strategy on CRDs. - useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required. + # conditions: + # isFirstField: Warn # Require conditions to be the first field in the status struct. + # usePatchStrategy: Forbid # Conditions should not use the patch strategy on CRDs. + # useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required. # jsonTags: # jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case. # optionalOrRequired: diff --git a/api/v1beta1/awsmachine_types.go b/api/v1beta1/awsmachine_types.go index 25a8cb4dcd..94d531c9df 100644 --- a/api/v1beta1/awsmachine_types.go +++ b/api/v1beta1/awsmachine_types.go @@ -77,7 +77,7 @@ type AWSMachineSpec struct { // InstanceType is the type of instance to create. Example: m4.xlarge // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=2 - InstanceType string `json:"instanceType"` + InstanceType string `json:"instanceType,omitempty"` // AdditionalTags is an optional set of tags to add to an instance, in addition to the ones added by default by the // AWS provider. If both the AWSCluster and the AWSMachine specify the same tag name with different values, the diff --git a/api/v1beta2/awsmachine_types.go b/api/v1beta2/awsmachine_types.go index 415457485f..ba0f05807b 100644 --- a/api/v1beta2/awsmachine_types.go +++ b/api/v1beta2/awsmachine_types.go @@ -114,7 +114,7 @@ type AWSMachineSpec struct { // InstanceType is the type of instance to create. Example: m4.xlarge // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=2 - InstanceType string `json:"instanceType"` + InstanceType string `json:"instanceType,omitempty"` // AdditionalTags is an optional set of tags to add to an instance, in addition to the ones added by default by the // AWS provider. If both the AWSCluster and the AWSMachine specify the same tag name with different values, the diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml index a69fc00a41..fb99abeccb 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -878,6 +878,7 @@ spec: description: |- This is also known as audience. The ID for the client application that makes authentication requests to the OpenID identity provider. + minLength: 1 type: string groupsClaim: description: The JWT claim that the provider uses to return your @@ -894,6 +895,7 @@ spec: The name of the OIDC provider configuration. IdentityProviderConfigName is a required field + minLength: 1 type: string issuerUrl: description: |- @@ -904,6 +906,8 @@ spec: not. Typically the URL consists of only a hostname, like https://server.example.org or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. + minLength: 1 + pattern: ^https://.+ type: string requiredClaims: additionalProperties: @@ -3050,6 +3054,7 @@ spec: description: |- This is also known as audience. The ID for the client application that makes authentication requests to the OpenID identity provider. + minLength: 1 type: string groupsClaim: description: The JWT claim that the provider uses to return your @@ -3066,6 +3071,7 @@ spec: The name of the OIDC provider configuration. IdentityProviderConfigName is a required field + minLength: 1 type: string issuerUrl: description: |- @@ -3076,6 +3082,8 @@ spec: not. Typically the URL consists of only a hostname, like https://server.example.org or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. + minLength: 1 + pattern: ^https://.+ type: string requiredClaims: additionalProperties: diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml index c92dd995e5..1fc20f13ab 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml @@ -880,6 +880,7 @@ spec: description: |- This is also known as audience. The ID for the client application that makes authentication requests to the OpenID identity provider. + minLength: 1 type: string groupsClaim: description: The JWT claim that the provider uses to return @@ -896,6 +897,7 @@ spec: The name of the OIDC provider configuration. IdentityProviderConfigName is a required field + minLength: 1 type: string issuerUrl: description: |- @@ -906,6 +908,8 @@ spec: not. Typically the URL consists of only a hostname, like https://server.example.org or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. + minLength: 1 + pattern: ^https://.+ type: string requiredClaims: additionalProperties: diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml index f00d4a97f1..0a3ef4b285 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml @@ -285,6 +285,7 @@ spec: claim: description: Claim is a JWT token claim to be used in the mapping + minLength: 1 type: string prefix: description: |- @@ -310,6 +311,7 @@ spec: claim: description: Claim is a JWT token claim to be used in the mapping + minLength: 1 type: string prefix: description: Prefix is prepended to claim to prevent @@ -417,6 +419,7 @@ spec: name: description: Name is the metadata.name of the referenced object. + minLength: 1 type: string required: - name @@ -425,6 +428,7 @@ spec: description: |- URL is the serving URL of the token issuer. Must use the https:// scheme. + minLength: 1 pattern: ^https:\/\/[^\s] type: string required: @@ -457,6 +461,7 @@ spec: name: description: Name is the metadata.name of the referenced object. + minLength: 1 type: string required: - name @@ -474,6 +479,7 @@ spec: client configuration maxLength: 63 minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string extraScopes: description: ExtraScopes is an optional set of scopes diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml index 868135f659..00ddb9c901 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml @@ -80,6 +80,7 @@ spec: awsLaunchTemplate: description: AWSLaunchTemplate specifies the launch template and version to use when an instance is launched. + minProperties: 1 properties: additionalSecurityGroups: description: |- @@ -582,6 +583,7 @@ spec: awsLaunchTemplate: description: AWSLaunchTemplate specifies the launch template and version to use when an instance is launched. + minProperties: 1 properties: additionalSecurityGroups: description: |- diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml index 29c439ddc2..e585d428ab 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml @@ -89,6 +89,7 @@ spec: AWSLaunchTemplate specifies the launch template to use to create the managed node group. If AWSLaunchTemplate is specified, certain node group configuraions outside of launch template are prohibited (https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html). + minProperties: 1 properties: additionalSecurityGroups: description: |- @@ -349,9 +350,11 @@ spec: type: string key: description: Key is the key of the taint + minLength: 1 type: string value: description: Value is the value of the taint + minLength: 1 type: string required: - effect @@ -591,6 +594,7 @@ spec: AWSLaunchTemplate specifies the launch template to use to create the managed node group. If AWSLaunchTemplate is specified, certain node group configuraions outside of launch template are prohibited (https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html). + minProperties: 1 properties: additionalSecurityGroups: description: |- @@ -1085,9 +1089,11 @@ spec: type: string key: description: Key is the key of the taint + minLength: 1 type: string value: description: Value is the value of the taint + minLength: 1 type: string required: - effect diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_rosamachinepools.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_rosamachinepools.yaml index d17d3d84b5..2163b90e7e 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_rosamachinepools.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_rosamachinepools.yaml @@ -90,6 +90,7 @@ spec: type: string instanceType: description: InstanceType specifies the AWS instance type + minLength: 1 type: string labels: additionalProperties: @@ -143,6 +144,7 @@ spec: type: string key: description: The taint key to be applied to a node. + minLength: 1 type: string value: description: The taint value corresponding to the taint key. diff --git a/controlplane/eks/api/v1beta1/types.go b/controlplane/eks/api/v1beta1/types.go index 4de86be1be..f63db752a4 100644 --- a/controlplane/eks/api/v1beta1/types.go +++ b/controlplane/eks/api/v1beta1/types.go @@ -127,7 +127,7 @@ type Addon struct { // Name is the name of the addon // +kubebuilder:validation:MinLength:=2 // +kubebuilder:validation:Required - Name string `json:"name"` + Name string `json:"name,omitempty"` // Version is the version of the addon to use Version string `json:"version"` // Configuration of the EKS addon @@ -223,7 +223,8 @@ type OIDCIdentityProviderConfig struct { // This is also known as audience. The ID for the client application that makes // authentication requests to the OpenID identity provider. // +kubebuilder:validation:Required - ClientID string `json:"clientId"` + // +kubebuilder:validation:MinLength=1 + ClientID string `json:"clientId,omitempty"` // The JWT claim that the provider uses to return your groups. // +optional @@ -239,7 +240,8 @@ type OIDCIdentityProviderConfig struct { // // IdentityProviderConfigName is a required field // +kubebuilder:validation:Required - IdentityProviderConfigName string `json:"identityProviderConfigName"` + // +kubebuilder:validation:MinLength=1 + IdentityProviderConfigName string `json:"identityProviderConfigName,omitempty"` // The URL of the OpenID identity provider that allows the API server to discover // public signing keys for verifying tokens. The URL must begin with https:// @@ -250,7 +252,9 @@ type OIDCIdentityProviderConfig struct { // and must be publicly accessible over the internet. // // +kubebuilder:validation:Required - IssuerURL string `json:"issuerUrl"` + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Pattern=`^https://.+` + IssuerURL string `json:"issuerUrl,omitempty"` // The key value pairs that describe required claims in the identity token. // If set, each claim is verified to be present in the token with a matching diff --git a/controlplane/eks/api/v1beta2/types.go b/controlplane/eks/api/v1beta2/types.go index bc4da380cd..843c72c9e2 100644 --- a/controlplane/eks/api/v1beta2/types.go +++ b/controlplane/eks/api/v1beta2/types.go @@ -107,7 +107,7 @@ type KubernetesMapping struct { // RoleMapping represents a mapping from a IAM role to Kubernetes users and groups. type RoleMapping struct { // RoleARN is the AWS ARN for the role to map - // +kubebuilder:validation:MinLength:=31 + // +kubebuilder:validation:MinLength=31 RoleARN string `json:"rolearn"` // KubernetesMapping holds the RBAC details for the mapping KubernetesMapping `json:",inline"` @@ -116,7 +116,7 @@ type RoleMapping struct { // UserMapping represents a mapping from an IAM user to Kubernetes users and groups. type UserMapping struct { // UserARN is the AWS ARN for the user to map - // +kubebuilder:validation:MinLength:=31 + // +kubebuilder:validation:MinLength=31 UserARN string `json:"userarn"` // KubernetesMapping holds the RBAC details for the mapping KubernetesMapping `json:",inline"` @@ -125,9 +125,9 @@ type UserMapping struct { // Addon represents a EKS addon. type Addon struct { // Name is the name of the addon - // +kubebuilder:validation:MinLength:=2 + // +kubebuilder:validation:MinLength=2 // +kubebuilder:validation:Required - Name string `json:"name"` + Name string `json:"name,omitempty"` // Version is the version of the addon to use Version string `json:"version"` // Configuration of the EKS addon @@ -227,7 +227,8 @@ type OIDCIdentityProviderConfig struct { // This is also known as audience. The ID for the client application that makes // authentication requests to the OpenID identity provider. // +kubebuilder:validation:Required - ClientID string `json:"clientId"` + // +kubebuilder:validation:MinLength=1 + ClientID string `json:"clientId,omitempty"` // The JWT claim that the provider uses to return your groups. // +optional @@ -243,7 +244,8 @@ type OIDCIdentityProviderConfig struct { // // IdentityProviderConfigName is a required field // +kubebuilder:validation:Required - IdentityProviderConfigName string `json:"identityProviderConfigName"` + // +kubebuilder:validation:MinLength=1 + IdentityProviderConfigName string `json:"identityProviderConfigName,omitempty"` // The URL of the OpenID identity provider that allows the API server to discover // public signing keys for verifying tokens. The URL must begin with https:// @@ -254,7 +256,9 @@ type OIDCIdentityProviderConfig struct { // and must be publicly accessible over the internet. // // +kubebuilder:validation:Required - IssuerURL string `json:"issuerUrl"` + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Pattern=`^https://.+` + IssuerURL string `json:"issuerUrl,omitempty"` // The key value pairs that describe required claims in the identity token. // If set, each claim is verified to be present in the token with a matching diff --git a/controlplane/rosa/api/v1beta2/external_auth_types.go b/controlplane/rosa/api/v1beta2/external_auth_types.go index 7bd16d4585..75de9b070f 100644 --- a/controlplane/rosa/api/v1beta2/external_auth_types.go +++ b/controlplane/rosa/api/v1beta2/external_auth_types.go @@ -4,15 +4,15 @@ package v1beta2 type ExternalAuthProvider struct { // Name of the OIDC provider // - // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 // +required - Name string `json:"name"` + Name string `json:"name,omitempty"` // Issuer describes attributes of the OIDC token issuer // // +kubebuilder:validation:Required // +required - Issuer TokenIssuer `json:"issuer"` + Issuer TokenIssuer `json:"issuer,omitzero"` // OIDCClients contains configuration for the platform's clients that // need to request tokens from the issuer @@ -46,9 +46,10 @@ type TokenIssuer struct { // Must use the https:// scheme. // // +kubebuilder:validation:Pattern=`^https:\/\/[^\s]` + // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Required // +required - URL string `json:"issuerURL"` + URL string `json:"issuerURL,omitempty"` // Audiences is an array of audiences that the token was issued for. // Valid tokens must include at least one of these values in their @@ -60,7 +61,7 @@ type TokenIssuer struct { // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=10 // +required - Audiences []TokenAudience `json:"audiences"` + Audiences []TokenAudience `json:"audiences,omitempty"` // CertificateAuthority is a reference to a config map in the // configuration namespace. The .data of the configMap must contain @@ -79,7 +80,7 @@ type OIDCClientConfig struct { // +kubebuilder:validation:MaxLength=256 // +kubebuilder:validation:Required // +required - ComponentName string `json:"componentName"` + ComponentName string `json:"componentName,omitempty"` // ComponentNamespace is the namespace of the component that is supposed to consume this // client configuration @@ -87,15 +88,16 @@ type OIDCClientConfig struct { // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=63 // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ // +required - ComponentNamespace string `json:"componentNamespace"` + ComponentNamespace string `json:"componentNamespace,omitempty"` // ClientID is the identifier of the OIDC client from the OIDC provider // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Required // +required - ClientID string `json:"clientID"` + ClientID string `json:"clientID,omitempty"` // ClientSecret refers to a secret that // contains the client secret in the `clientSecret` key of the `.data` field @@ -130,8 +132,9 @@ type PrefixedClaimMapping struct { // Claim is a JWT token claim to be used in the mapping // // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 // +required - Claim string `json:"claim"` + Claim string `json:"claim,omitempty"` // Prefix is a string to prefix the value from the token in the result of the // claim mapping. @@ -151,8 +154,9 @@ type UsernameClaimMapping struct { // Claim is a JWT token claim to be used in the mapping // // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 // +required - Claim string `json:"claim"` + Claim string `json:"claim,omitempty"` // PrefixPolicy specifies how a prefix should apply. // @@ -218,7 +222,7 @@ type TokenClaimValidationRule struct { // RequiredClaim allows configuring a required claim name and its expected value // +kubebuilder:validation:Required - RequiredClaim TokenRequiredClaim `json:"requiredClaim"` + RequiredClaim TokenRequiredClaim `json:"requiredClaim,omitzero"` } // TokenRequiredClaim allows configuring a required claim name and its expected value. @@ -229,14 +233,14 @@ type TokenRequiredClaim struct { // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Required // +required - Claim string `json:"claim"` + Claim string `json:"claim,omitempty"` // RequiredValue is the required value for the claim. // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Required // +required - RequiredValue string `json:"requiredValue"` + RequiredValue string `json:"requiredValue,omitempty"` } // LocalObjectReference references an object in the same namespace. @@ -244,6 +248,7 @@ type LocalObjectReference struct { // Name is the metadata.name of the referenced object. // // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 // +required - Name string `json:"name"` + Name string `json:"name,omitempty"` } diff --git a/exp/api/v1beta1/awsmachinepool_types.go b/exp/api/v1beta1/awsmachinepool_types.go index fc70422c03..c23b3434f9 100644 --- a/exp/api/v1beta1/awsmachinepool_types.go +++ b/exp/api/v1beta1/awsmachinepool_types.go @@ -60,7 +60,7 @@ type AWSMachinePoolSpec struct { // AWSLaunchTemplate specifies the launch template and version to use when an instance is launched. // +kubebuilder:validation:Required - AWSLaunchTemplate AWSLaunchTemplate `json:"awsLaunchTemplate"` + AWSLaunchTemplate AWSLaunchTemplate `json:"awsLaunchTemplate,omitzero"` // MixedInstancesPolicy describes how multiple instance types will be used by the ASG. MixedInstancesPolicy *MixedInstancesPolicy `json:"mixedInstancesPolicy,omitempty"` diff --git a/exp/api/v1beta1/types.go b/exp/api/v1beta1/types.go index b337340159..a458afd794 100644 --- a/exp/api/v1beta1/types.go +++ b/exp/api/v1beta1/types.go @@ -53,7 +53,8 @@ type EBS struct { type BlockDeviceMapping struct { // The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh). // +kubebuilder:validation:Required - DeviceName string `json:"deviceName"` + // +kubebuilder:validation:MinLength=1 + DeviceName string `json:"deviceName,omitempty"` // You can specify either VirtualName or Ebs, but not both. // +optional @@ -61,6 +62,7 @@ type BlockDeviceMapping struct { } // AWSLaunchTemplate defines the desired state of AWSLaunchTemplate. +// +kubebuilder:validation:MinProperties=1 type AWSLaunchTemplate struct { // The name of the launch template. Name string `json:"name,omitempty"` @@ -227,13 +229,15 @@ type Taint struct { // Effect specifies the effect for the taint // +kubebuilder:validation:Required // +kubebuilder:validation:Enum=no-schedule;no-execute;prefer-no-schedule - Effect TaintEffect `json:"effect"` + Effect TaintEffect `json:"effect,omitempty"` // Key is the key of the taint // +kubebuilder:validation:Required - Key string `json:"key"` + // +kubebuilder:validation:MinLength=1 + Key string `json:"key,omitempty"` // Value is the value of the taint // +kubebuilder:validation:Required - Value string `json:"value"` + // +kubebuilder:validation:MinLength=1 + Value string `json:"value,omitempty"` } // Equals is used to test if 2 taints are equal. diff --git a/exp/api/v1beta2/awsmachinepool_types.go b/exp/api/v1beta2/awsmachinepool_types.go index ef0a219513..248ffbd0a5 100644 --- a/exp/api/v1beta2/awsmachinepool_types.go +++ b/exp/api/v1beta2/awsmachinepool_types.go @@ -67,7 +67,7 @@ type AWSMachinePoolSpec struct { // AWSLaunchTemplate specifies the launch template and version to use when an instance is launched. // +kubebuilder:validation:Required - AWSLaunchTemplate AWSLaunchTemplate `json:"awsLaunchTemplate"` + AWSLaunchTemplate AWSLaunchTemplate `json:"awsLaunchTemplate,omitzero"` // MixedInstancesPolicy describes how multiple instance types will be used by the ASG. MixedInstancesPolicy *MixedInstancesPolicy `json:"mixedInstancesPolicy,omitempty"` diff --git a/exp/api/v1beta2/rosamachinepool_types.go b/exp/api/v1beta2/rosamachinepool_types.go index 0dc3af30ed..236f80fe92 100644 --- a/exp/api/v1beta2/rosamachinepool_types.go +++ b/exp/api/v1beta2/rosamachinepool_types.go @@ -74,7 +74,9 @@ type RosaMachinePoolSpec struct { // InstanceType specifies the AWS instance type // // +kubebuilder:validation:Required - InstanceType string `json:"instanceType"` + // +kubebuilder:validation:MinLength=1 + // +required + InstanceType string `json:"instanceType,omitempty"` // Autoscaling specifies auto scaling behaviour for this MachinePool. // required if Replicas is not configured @@ -125,7 +127,8 @@ type RosaTaint struct { // The taint key to be applied to a node. // // +kubebuilder:validation:Required - Key string `json:"key"` + // +kubebuilder:validation:MinLength=1 + Key string `json:"key,omitempty"` // The taint value corresponding to the taint key. // // +kubebuilder:validation:Pattern:=`^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$` @@ -136,7 +139,7 @@ type RosaTaint struct { // // +kubebuilder:validation:Required // +kubebuilder:validation:Enum=NoSchedule;PreferNoSchedule;NoExecute - Effect corev1.TaintEffect `json:"effect"` + Effect corev1.TaintEffect `json:"effect,omitempty"` } // RosaMachinePoolAutoScaling specifies scaling options. diff --git a/exp/api/v1beta2/types.go b/exp/api/v1beta2/types.go index 9db149d9a7..e208165dfa 100644 --- a/exp/api/v1beta2/types.go +++ b/exp/api/v1beta2/types.go @@ -52,7 +52,8 @@ type EBS struct { type BlockDeviceMapping struct { // The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh). // +kubebuilder:validation:Required - DeviceName string `json:"deviceName"` + // +kubebuilder:validation:MinLength=1 + DeviceName string `json:"deviceName,omitempty"` // You can specify either VirtualName or Ebs, but not both. // +optional @@ -60,6 +61,7 @@ type BlockDeviceMapping struct { } // AWSLaunchTemplate defines the desired state of AWSLaunchTemplate. +// +kubebuilder:validation:MinProperties=1 type AWSLaunchTemplate struct { // The name of the launch template. Name string `json:"name,omitempty"` @@ -339,13 +341,15 @@ type Taint struct { // Effect specifies the effect for the taint // +kubebuilder:validation:Required // +kubebuilder:validation:Enum=no-schedule;no-execute;prefer-no-schedule - Effect TaintEffect `json:"effect"` + Effect TaintEffect `json:"effect,omitempty"` // Key is the key of the taint // +kubebuilder:validation:Required - Key string `json:"key"` + // +kubebuilder:validation:MinLength=1 + Key string `json:"key,omitempty"` // Value is the value of the taint // +kubebuilder:validation:Required - Value string `json:"value"` + // +kubebuilder:validation:MinLength=1 + Value string `json:"value,omitempty"` } // Equals is used to test if 2 taints are equal. diff --git a/hack/tools/.custom-gcl.yaml b/hack/tools/.custom-gcl.yaml index 5253dd8852..ffc3b08319 100644 --- a/hack/tools/.custom-gcl.yaml +++ b/hack/tools/.custom-gcl.yaml @@ -3,4 +3,4 @@ name: golangci-lint-kube-api-linter destination: ./bin plugins: - module: 'sigs.k8s.io/kube-api-linter' - version: v0.0.0-20250411141643-33ef95a5ee04 + version: v0.0.0-20250902135116-ef33eac3b92b From 99178e8e7980501000eae1efc4bb4d215eefad99 Mon Sep 17 00:00:00 2001 From: v47 Date: Sat, 20 Sep 2025 01:44:02 +0200 Subject: [PATCH 3/4] use a CEL validation for URLs --- ...ntrolplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml | 6 ++++-- ...ne.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml | 3 ++- controlplane/eks/api/v1beta1/types.go | 2 +- controlplane/eks/api/v1beta2/types.go | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml index fb99abeccb..8599cc8a55 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -907,8 +907,9 @@ spec: or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. minLength: 1 - pattern: ^https://.+ type: string + x-kubernetes-validations: + - rule: isURL(self) && url(self).getScheme() == 'https' requiredClaims: additionalProperties: type: string @@ -3083,8 +3084,9 @@ spec: or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. minLength: 1 - pattern: ^https://.+ type: string + x-kubernetes-validations: + - rule: isURL(self) && url(self).getScheme() == 'https' requiredClaims: additionalProperties: type: string diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml index 1fc20f13ab..b42728706f 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml @@ -909,8 +909,9 @@ spec: or https://example.com. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet. minLength: 1 - pattern: ^https://.+ type: string + x-kubernetes-validations: + - rule: isURL(self) && url(self).getScheme() == 'https' requiredClaims: additionalProperties: type: string diff --git a/controlplane/eks/api/v1beta1/types.go b/controlplane/eks/api/v1beta1/types.go index f63db752a4..203378a8cf 100644 --- a/controlplane/eks/api/v1beta1/types.go +++ b/controlplane/eks/api/v1beta1/types.go @@ -253,7 +253,7 @@ type OIDCIdentityProviderConfig struct { // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:Pattern=`^https://.+` + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() == 'https'" IssuerURL string `json:"issuerUrl,omitempty"` // The key value pairs that describe required claims in the identity token. diff --git a/controlplane/eks/api/v1beta2/types.go b/controlplane/eks/api/v1beta2/types.go index 843c72c9e2..4cd2170ad0 100644 --- a/controlplane/eks/api/v1beta2/types.go +++ b/controlplane/eks/api/v1beta2/types.go @@ -257,7 +257,7 @@ type OIDCIdentityProviderConfig struct { // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:Pattern=`^https://.+` + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() == 'https'" IssuerURL string `json:"issuerUrl,omitempty"` // The key value pairs that describe required claims in the identity token. From 216ebdde4c9d51ee39acec0660822f23b5f206cd Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 23 Sep 2025 14:57:17 +0200 Subject: [PATCH 4/4] In awsMachinePool tests added a AWSLaunchTemplate data --- exp/controllers/awsmachinepool_controller_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exp/controllers/awsmachinepool_controller_test.go b/exp/controllers/awsmachinepool_controller_test.go index 59675a287a..71967fcdd0 100644 --- a/exp/controllers/awsmachinepool_controller_test.go +++ b/exp/controllers/awsmachinepool_controller_test.go @@ -98,6 +98,9 @@ func TestAWSMachinePoolReconciler(t *testing.T) { Spec: expinfrav1.AWSMachinePoolSpec{ MinSize: int32(0), MaxSize: int32(100), + AWSLaunchTemplate: expinfrav1.AWSLaunchTemplate{ + Name: "test", + }, MixedInstancesPolicy: &expinfrav1.MixedInstancesPolicy{ InstancesDistribution: &expinfrav1.InstancesDistribution{ OnDemandAllocationStrategy: expinfrav1.OnDemandAllocationStrategyPrioritized,