diff --git a/.gitignore b/.gitignore
index 60ad705f84..82137583f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,3 +54,4 @@ inference-extension-conformance-test-report.yaml
site/.cursorrules
/.cursor
.worktrees/
+tools/tmp/
diff --git a/Makefile b/Makefile
index ae82600d75..660c2498ab 100644
--- a/Makefile
+++ b/Makefile
@@ -52,6 +52,12 @@ lint: ## This runs the linter on the codebase.
@echo "actionlint => ./..."
@$(GO_TOOL) actionlint -shellcheck="" # Disabling shellcheck as it requires additional host dependencies.
+.PHONY: lint-api
+lint-api: ## Run kube-api-linter on API directories to validate CRDs against Kubernetes API conventions.
+ @echo "kube-api-linter => ./api/..."
+ @test -f tools/tmp/bin/golangci-kube-api-linter || (cd tools && go tool -modfile go.mod golangci-lint custom)
+ @tools/tmp/bin/golangci-kube-api-linter run --config tools/.golangci-kal.yml ./api/...
+
.PHONY: spellcheck
spellcheck: ## Spell check the codebase.
@echo "misspell => ./..."
diff --git a/api/v1alpha1/status.go b/api/v1alpha1/status.go
index 4874d1b9b8..e05fe84659 100644
--- a/api/v1alpha1/status.go
+++ b/api/v1alpha1/status.go
@@ -16,47 +16,71 @@ const (
ConditionTypeNotAccepted = "NotAccepted"
)
+// Condition contains details for one aspect of the current state of this API Resource.
+type Condition struct {
+ // type of condition in CamelCase or in foo.example.com/CamelCase.
+ //
+ // +kubebuilder:validation:Enum=Accepted;NotAccepted
+ // +kubebuilder:validation:MaxLength=316
+ Type string `json:"type"`
+
+ // status of the condition, one of True, False, Unknown.
+ //
+ // +kubebuilder:validation:Enum=True;False;Unknown
+ Status metav1.ConditionStatus `json:"status"`
+
+ // observedGeneration represents the .metadata.generation that the condition was set based upon.
+ //
+ // +kubebuilder:validation:Minimum=0
+ // +optional
+ ObservedGeneration int64 `json:"observedGeneration,omitempty"`
+
+ // lastTransitionTime is the last time the condition transitioned from one status to another.
+ LastTransitionTime metav1.Time `json:"lastTransitionTime"`
+
+ // reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ //
+ // +kubebuilder:validation:MaxLength=1024
+ // +kubebuilder:validation:MinLength=1
+ Reason string `json:"reason"`
+
+ // message is a human readable message indicating details about the transition.
+ //
+ // +kubebuilder:validation:MaxLength=32768
+ Message string `json:"message"`
+}
+
// AIGatewayRouteStatus contains the conditions by the reconciliation result.
type AIGatewayRouteStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// AIServiceBackendStatus contains the conditions by the reconciliation result.
type AIServiceBackendStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// BackendSecurityPolicyStatus contains the conditions by the reconciliation result.
type BackendSecurityPolicyStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// MCPRouteStatus contains the conditions by the reconciliation result.
type MCPRouteStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// QuotaPolicyStatus contains the conditions by the reconciliation result.
type QuotaPolicyStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 3c44727050..29152bc3be 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -247,7 +247,7 @@ func (in *AIGatewayRouteStatus) DeepCopyInto(out *AIGatewayRouteStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -355,7 +355,7 @@ func (in *AIServiceBackendStatus) DeepCopyInto(out *AIServiceBackendStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -689,7 +689,7 @@ func (in *BackendSecurityPolicyStatus) DeepCopyInto(out *BackendSecurityPolicySt
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -706,6 +706,22 @@ func (in *BackendSecurityPolicyStatus) DeepCopy() *BackendSecurityPolicyStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Condition) DeepCopyInto(out *Condition) {
+ *out = *in
+ in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
+func (in *Condition) DeepCopy() *Condition {
+ if in == nil {
+ return nil
+ }
+ out := new(Condition)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GCPCredentialsFile) DeepCopyInto(out *GCPCredentialsFile) {
*out = *in
@@ -1558,7 +1574,7 @@ func (in *MCPRouteStatus) DeepCopyInto(out *MCPRouteStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1791,7 +1807,7 @@ func (in *QuotaPolicyStatus) DeepCopyInto(out *QuotaPolicyStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
diff --git a/api/v1beta1/status.go b/api/v1beta1/status.go
index 09dafe7376..3b15743b3a 100644
--- a/api/v1beta1/status.go
+++ b/api/v1beta1/status.go
@@ -16,38 +16,64 @@ const (
ConditionTypeNotAccepted = "NotAccepted"
)
+// Condition contains details for one aspect of the current state of this API Resource.
+type Condition struct {
+ // type of condition in CamelCase or in foo.example.com/CamelCase.
+ //
+ // +kubebuilder:validation:Enum=Accepted;NotAccepted
+ // +kubebuilder:validation:MaxLength=316
+ Type string `json:"type"`
+
+ // status of the condition, one of True, False, Unknown.
+ //
+ // +kubebuilder:validation:Enum=True;False;Unknown
+ Status metav1.ConditionStatus `json:"status"`
+
+ // observedGeneration represents the .metadata.generation that the condition was set based upon.
+ //
+ // +kubebuilder:validation:Minimum=0
+ // +optional
+ ObservedGeneration int64 `json:"observedGeneration,omitempty"`
+
+ // lastTransitionTime is the last time the condition transitioned from one status to another.
+ LastTransitionTime metav1.Time `json:"lastTransitionTime"`
+
+ // reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ //
+ // +kubebuilder:validation:MaxLength=1024
+ // +kubebuilder:validation:MinLength=1
+ Reason string `json:"reason"`
+
+ // message is a human readable message indicating details about the transition.
+ //
+ // +kubebuilder:validation:MaxLength=32768
+ Message string `json:"message"`
+}
+
// AIGatewayRouteStatus contains the conditions by the reconciliation result.
type AIGatewayRouteStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// AIServiceBackendStatus contains the conditions by the reconciliation result.
type AIServiceBackendStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// BackendSecurityPolicyStatus contains the conditions by the reconciliation result.
type BackendSecurityPolicyStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
// MCPRouteStatus contains the conditions by the reconciliation result.
type MCPRouteStatus struct {
// Conditions is the list of conditions by the reconciliation result.
// Currently, at most one condition is set.
- //
- // Known .status.conditions.type are: "Accepted", "NotAccepted".
- Conditions []metav1.Condition `json:"conditions,omitempty"`
+ Conditions []Condition `json:"conditions"`
}
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 10823978cf..0ee3acd3df 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -247,7 +247,7 @@ func (in *AIGatewayRouteStatus) DeepCopyInto(out *AIGatewayRouteStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -362,7 +362,7 @@ func (in *AIServiceBackendStatus) DeepCopyInto(out *AIServiceBackendStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -726,7 +726,7 @@ func (in *BackendSecurityPolicyStatus) DeepCopyInto(out *BackendSecurityPolicySt
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -743,6 +743,22 @@ func (in *BackendSecurityPolicyStatus) DeepCopy() *BackendSecurityPolicyStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Condition) DeepCopyInto(out *Condition) {
+ *out = *in
+ in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
+func (in *Condition) DeepCopy() *Condition {
+ if in == nil {
+ return nil
+ }
+ out := new(Condition)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialOverrideFromDynamicMetadata) DeepCopyInto(out *CredentialOverrideFromDynamicMetadata) {
*out = *in
@@ -1715,7 +1731,7 @@ func (in *MCPRouteStatus) DeepCopyInto(out *MCPRouteStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]metav1.Condition, len(*in))
+ *out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
diff --git a/internal/controller/controller.go b/internal/controller/controller.go
index 70ba755ed4..23f2d3e43c 100644
--- a/internal/controller/controller.go
+++ b/internal/controller/controller.go
@@ -548,8 +548,8 @@ func referenceGrantToTargetKindIndexFunc(o client.Object) []string {
//
// Currently, we only set one condition at a time either "Accepted" or "NotAccepted".
// In the future, if we can have multiple conditions like multiple errors, we can make changes here.
-func newConditions(conditionType, message string) []metav1.Condition {
- condition := metav1.Condition{Message: message, LastTransitionTime: metav1.Now()}
+func newConditions(conditionType, message string) []aigv1b1.Condition {
+ condition := aigv1b1.Condition{Message: message, LastTransitionTime: metav1.Now()}
// Note: we use the fixed reason for now since the message is enough to describe the error and
// reason doesn't fit the entire message.
switch conditionType {
@@ -562,7 +562,23 @@ func newConditions(conditionType, message string) []metav1.Condition {
condition.Status = metav1.ConditionFalse
condition.Reason = "ReconciliationFailed"
}
- return []metav1.Condition{condition}
+ return []aigv1b1.Condition{condition}
+}
+
+// newConditionsV1Alpha1 creates new conditions for v1alpha1 resources.
+func newConditionsV1Alpha1(conditionType, message string) []aigv1a1.Condition {
+ condition := aigv1a1.Condition{Message: message, LastTransitionTime: metav1.Now()}
+ switch conditionType {
+ case aigv1a1.ConditionTypeAccepted:
+ condition.Type = aigv1a1.ConditionTypeAccepted
+ condition.Status = metav1.ConditionTrue
+ condition.Reason = "ReconciliationSucceeded"
+ case aigv1a1.ConditionTypeNotAccepted:
+ condition.Type = aigv1a1.ConditionTypeNotAccepted
+ condition.Status = metav1.ConditionFalse
+ condition.Reason = "ReconciliationFailed"
+ }
+ return []aigv1a1.Condition{condition}
}
// aiGatewayControllerFinalizer is the name of the finalizer added to various AI Gateway resources.
diff --git a/internal/controller/quota_policy.go b/internal/controller/quota_policy.go
index 9be168e842..012ea4e52c 100644
--- a/internal/controller/quota_policy.go
+++ b/internal/controller/quota_policy.go
@@ -257,7 +257,7 @@ func (c *QuotaPolicyController) updateQuotaPolicyStatus(ctx context.Context, pol
}
return err
}
- policy.Status.Conditions = newConditions(conditionType, message)
+ policy.Status.Conditions = newConditionsV1Alpha1(conditionType, message)
return c.client.Status().Update(ctx, policy)
})
if err != nil {
diff --git a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aigatewayroutes.yaml b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aigatewayroutes.yaml
index b31f78108c..44e9b8252b 100644
--- a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aigatewayroutes.yaml
+++ b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aigatewayroutes.yaml
@@ -888,42 +888,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -934,8 +923,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -945,6 +936,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
@@ -1817,42 +1810,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -1863,8 +1845,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -1874,6 +1858,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
diff --git a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aiservicebackends.yaml b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aiservicebackends.yaml
index 64a3fa17c1..e7a4ebc2ab 100644
--- a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aiservicebackends.yaml
+++ b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_aiservicebackends.yaml
@@ -376,42 +376,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -422,8 +411,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -433,6 +424,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
@@ -851,42 +844,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -897,8 +879,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -908,6 +892,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
diff --git a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_backendsecuritypolicies.yaml b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_backendsecuritypolicies.yaml
index e1dc2d6f41..a2ef4e253a 100644
--- a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_backendsecuritypolicies.yaml
+++ b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_backendsecuritypolicies.yaml
@@ -6397,42 +6397,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -6443,8 +6432,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -6454,6 +6445,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
@@ -12916,42 +12909,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -12962,8 +12944,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -12973,6 +12957,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
diff --git a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_mcproutes.yaml b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_mcproutes.yaml
index 9129059b5b..42642da1e3 100644
--- a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_mcproutes.yaml
+++ b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_mcproutes.yaml
@@ -6128,42 +6128,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -6174,8 +6163,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -6185,6 +6176,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
@@ -12386,42 +12379,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -12432,8 +12414,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -12443,6 +12427,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
diff --git a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_quotapolicies.yaml b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_quotapolicies.yaml
index 6250bd161e..c6ab81d847 100644
--- a/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_quotapolicies.yaml
+++ b/manifests/charts/ai-gateway-crds-helm/templates/aigateway.envoyproxy.io_quotapolicies.yaml
@@ -453,42 +453,31 @@ spec:
description: |-
Conditions is the list of conditions by the reconciliation result.
Currently, at most one condition is set.
-
- Known .status.conditions.type are: "Accepted", "NotAccepted".
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
- description: |-
- lastTransitionTime is the last time the condition transitioned from one status to another.
- This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another.
format: date-time
type: string
message:
- description: |-
- message is a human readable message indicating details about the transition.
- This may be an empty string.
+ description: message is a human readable message indicating
+ details about the transition.
maxLength: 32768
type: string
observedGeneration:
- description: |-
- observedGeneration represents the .metadata.generation that the condition was set based upon.
- For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
- with respect to the current state of the instance.
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
- description: |-
- reason contains a programmatic identifier indicating the reason for the condition's last transition.
- Producers of specific condition types may define expected values and meanings for this field,
- and whether the values are considered a guaranteed API.
- The value should be a CamelCase string.
- This field may not be empty.
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition.
maxLength: 1024
minLength: 1
- pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
@@ -499,8 +488,10 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ enum:
+ - Accepted
+ - NotAccepted
maxLength: 316
- pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
@@ -510,6 +501,8 @@ spec:
- type
type: object
type: array
+ required:
+ - conditions
type: object
type: object
served: true
diff --git a/site/docs/api/api.mdx b/site/docs/api/api.mdx
index b559cebd54..798ed6cb2a 100644
--- a/site/docs/api/api.mdx
+++ b/site/docs/api/api.mdx
@@ -579,6 +579,7 @@ QuotaPolicyList contains a list of QuotaPolicy
- [BackendSecurityPolicySpec](#github-com-envoyproxy-ai-gateway-api-v1alpha1-backendsecuritypolicyspec)
- [BackendSecurityPolicyStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-backendsecuritypolicystatus)
- [BackendSecurityPolicyType](#github-com-envoyproxy-ai-gateway-api-v1alpha1-backendsecuritypolicytype)
+- [Condition](#github-com-envoyproxy-ai-gateway-api-v1alpha1-condition)
- [GCPCredentialsFile](#github-com-envoyproxy-ai-gateway-api-v1alpha1-gcpcredentialsfile)
- [GCPOIDCExchangeToken](#github-com-envoyproxy-ai-gateway-api-v1alpha1-gcpoidcexchangetoken)
- [GCPServiceAccountImpersonationConfig](#github-com-envoyproxy-ai-gateway-api-v1alpha1-gcpserviceaccountimpersonationconfig)
@@ -812,9 +813,9 @@ AIGatewayRouteStatus contains the conditions by the reconciliation result.
@@ -869,9 +870,9 @@ AIServiceBackendStatus contains the conditions by the reconciliation result.
@@ -1326,9 +1327,9 @@ BackendSecurityPolicyStatus contains the conditions by the reconciliation result
@@ -1376,6 +1377,56 @@ BackendSecurityPolicyType specifies the type of auth mechanism used to access a
required="false"
description=""
/>
+#### Condition
+
+
+
+**Appears in:**
+- [AIGatewayRouteStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-aigatewayroutestatus)
+- [AIServiceBackendStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-aiservicebackendstatus)
+- [BackendSecurityPolicyStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-backendsecuritypolicystatus)
+- [MCPRouteStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-mcproutestatus)
+- [QuotaPolicyStatus](#github-com-envoyproxy-ai-gateway-api-v1alpha1-quotapolicystatus)
+
+Condition contains details for one aspect of the current state of this API Resource.
+
+##### Fields
+
+
+
+
+
+
#### GCPCredentialsFile
@@ -2286,9 +2337,9 @@ MCPRouteStatus contains the conditions by the reconciliation result.
@@ -2509,9 +2560,9 @@ QuotaPolicyStatus contains the conditions by the reconciliation result.
@@ -3150,6 +3201,7 @@ MCPRouteList contains a list of MCPRoute.
- [BackendSecurityPolicySpec](#github-com-envoyproxy-ai-gateway-api-v1beta1-backendsecuritypolicyspec)
- [BackendSecurityPolicyStatus](#github-com-envoyproxy-ai-gateway-api-v1beta1-backendsecuritypolicystatus)
- [BackendSecurityPolicyType](#github-com-envoyproxy-ai-gateway-api-v1beta1-backendsecuritypolicytype)
+- [Condition](#github-com-envoyproxy-ai-gateway-api-v1beta1-condition)
- [CredentialOverrideFromDynamicMetadata](#github-com-envoyproxy-ai-gateway-api-v1beta1-credentialoverridefromdynamicmetadata)
- [CredentialOverrideFromRequestHeaders](#github-com-envoyproxy-ai-gateway-api-v1beta1-credentialoverridefromrequestheaders)
- [GCPCredentialsFile](#github-com-envoyproxy-ai-gateway-api-v1beta1-gcpcredentialsfile)
@@ -3382,9 +3434,9 @@ AIGatewayRouteStatus contains the conditions by the reconciliation result.
@@ -3444,9 +3496,9 @@ AIServiceBackendStatus contains the conditions by the reconciliation result.
@@ -3939,9 +3991,9 @@ BackendSecurityPolicyStatus contains the conditions by the reconciliation result
@@ -3989,6 +4041,55 @@ BackendSecurityPolicyType specifies the type of auth mechanism used to access a
required="false"
description=""
/>
+#### Condition
+
+
+
+**Appears in:**
+- [AIGatewayRouteStatus](#github-com-envoyproxy-ai-gateway-api-v1beta1-aigatewayroutestatus)
+- [AIServiceBackendStatus](#github-com-envoyproxy-ai-gateway-api-v1beta1-aiservicebackendstatus)
+- [BackendSecurityPolicyStatus](#github-com-envoyproxy-ai-gateway-api-v1beta1-backendsecuritypolicystatus)
+- [MCPRouteStatus](#github-com-envoyproxy-ai-gateway-api-v1beta1-mcproutestatus)
+
+Condition contains details for one aspect of the current state of this API Resource.
+
+##### Fields
+
+
+
+
+
+
#### CredentialOverrideFromDynamicMetadata
@@ -5144,9 +5245,9 @@ MCPRouteStatus contains the conditions by the reconciliation result.
diff --git a/tools/.custom-gcl.yaml b/tools/.custom-gcl.yaml
new file mode 100644
index 0000000000..2a25837b21
--- /dev/null
+++ b/tools/.custom-gcl.yaml
@@ -0,0 +1,16 @@
+# Copyright Envoy AI Gateway Authors
+# SPDX-License-Identifier: Apache-2.0
+# The full text of the Apache license is available in the LICENSE file at
+# the root of the repo.
+
+# Custom golangci-lint build configuration for kube-api-linter.
+#
+# This builds a custom golangci-lint binary that includes the kube-api-linter
+# plugin. The custom binary is used to lint CRDs for Kubernetes API convention
+# compliance without affecting the main golangci-lint version used elsewhere.
+version: v2.13.2
+name: golangci-kube-api-linter
+destination: ./tmp/bin/
+plugins:
+ - module: "sigs.k8s.io/kube-api-linter"
+ version: v0.0.0-20260716143926-092fe0c72997
diff --git a/tools/.golangci-kal.yml b/tools/.golangci-kal.yml
new file mode 100644
index 0000000000..9a10c8bbbb
--- /dev/null
+++ b/tools/.golangci-kal.yml
@@ -0,0 +1,71 @@
+# Copyright Envoy AI Gateway Authors
+# SPDX-License-Identifier: Apache-2.0
+# The full text of the Apache license is available in the LICENSE file at
+# the root of the repo.
+
+# This file holds the Kube-API-Linter (KAL) configuration.
+# KAL ensures that our Custom Resource Definitions meet the Kubernetes API
+# conventions (as much as possible).
+#
+# The linters documentation is at
+# https://github.com/kubernetes-sigs/kube-api-linter/blob/main/docs/linters.md
+version: "2"
+run:
+ go: "1.27"
+ allow-parallel-runners: true
+linters:
+ default: none
+ enable:
+ - kubeapilinter
+ settings:
+ custom:
+ kubeapilinter:
+ type: module
+ description: KAL is the Kube-API-Linter and lints Custom Resource Definitions (CRDs) based on API conventions and best practices.
+ settings:
+ linters:
+ # We configure the list of enabled linters explicitly.
+ # Whenever a new linter is added, it should not break the backward
+ # compatibility of existing APIs (at least for v1 APIs).
+ enable:
+ - "conflictingmarkers"
+ - "duplicatemarkers"
+ - "nofloats"
+ - "uniquemarkers"
+ - "nophase"
+ - "nonullable"
+ - "forbiddenmarkers"
+ - "nomaps"
+ disable:
+ - "*"
+ lintersConfig:
+ conflictingmarkers:
+ conflicts:
+ - name: "default_vs_required"
+ sets:
+ - ["default", "kubebuilder:default"]
+ - [
+ "required",
+ "kubebuilder:validation:Required",
+ "k8s:required",
+ ]
+ description: "A field with a default value cannot be required"
+ forbiddenmarkers:
+ markers:
+ - identifier: "+kubebuilder:pruning:PreserveUnknownFields"
+ - identifier: "+kubebuilder:validation:XPreserveUnknownFields"
+ - identifier: "+kubebuilder:validation:items:XPreserveUnknownFields"
+ - identifier: "+kubebuilder:validation:EmbeddedResource"
+ - identifier: "+kubebuilder:validation:XEmbeddedResource"
+ - identifier: "+kubebuilder:validation:items:XEmbeddedResource"
+ exclusions:
+ generated: strict
+ paths:
+ # Exclude test files and generated code.
+ - _test\.go
+ - zz_generated.*\.go$
+ rules:
+ # KAL only validates the API folders for CRD client generation.
+ - path-except: "api/.*"
+ linters:
+ - kubeapilinter
diff --git a/tools/go.mod b/tools/go.mod
index 44bdf56b76..df4323aee6 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -31,6 +31,7 @@ tool (
sigs.k8s.io/controller-runtime/tools/setup-envtest
sigs.k8s.io/controller-tools/cmd/controller-gen
sigs.k8s.io/kind
+ sigs.k8s.io/kube-api-linter/cmd/golangci-lint-kube-api-linter
)
require github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
@@ -395,6 +396,7 @@ require (
sigs.k8s.io/controller-tools v0.20.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/kind v0.33.0 // indirect
+ sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997 // indirect
sigs.k8s.io/kustomize/api v0.20.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
diff --git a/tools/go.sum b/tools/go.sum
index 9c5768046c..ae4e54e393 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -1044,6 +1044,8 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5E
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kind v0.33.0 h1:AjvDv3vOygb/VKLVQW87lfktIBzkxR8Ump9DjxC8+Lk=
sigs.k8s.io/kind v0.33.0/go.mod h1:FSqriGaoTPruiXWfRnUXNykF8r2t+fHtK0P0m1AbGF8=
+sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997 h1:u5/qbXZq7YIrurEE6HiJKtjQ9ILcFPJJSHNY0Q1ZRhU=
+sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997/go.mod h1:5mP60UakkCye+eOcZ5p98VnV2O49qreW1gq9TdsUf7Q=
sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=