一键导入
eg-contrib-add-api
Step-by-step guide to add or extend a CRD API type in envoyproxy/gateway — type definitions, validation, code generation, and API design rules
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Step-by-step guide to add or extend a CRD API type in envoyproxy/gateway — type definitions, validation, code generation, and API design rules
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Configure client-facing traffic policies -- timeouts, connection limits, TLS settings, HTTP behavior
Production-grade Envoy Gateway setup with comprehensive security, observability, high availability, and operational best practices
Integrate Envoy Gateway with Istio ambient mesh or Cilium for unified ingress and service mesh
Envoy Gateway version information, compatibility matrix, and upgrade readiness checks
Envoy AI Gateway contribution orchestrator — interviews you about your contribution and guides you through the correct workflow using contributor skills
Envoy Gateway contribution orchestrator — interviews you about your contribution and guides you through the correct workflow using contributor skills
| name | eg-contrib-add-api |
| description | Step-by-step guide to add or extend a CRD API type in envoyproxy/gateway — type definitions, validation, code generation, and API design rules |
| arguments | [{"name":"CRDName","description":"The CRD being modified (e.g., BackendTrafficPolicy, SecurityPolicy, ClientTrafficPolicy, EnvoyExtensionPolicy, EnvoyProxy, Backend)","required":true},{"name":"FieldName","description":"Name of the new field or sub-field being added","required":true},{"name":"FieldDescription","description":"What the field does — used to generate doc comments","required":true}] |
eg-contrib-pr-guide — API changes require a separate PR from implementationeg-contrib-architecture — understand where API types fit in the pipelineMap the CRD name to its file in api/v1alpha1/:
| CRD | Types File |
|---|---|
| BackendTrafficPolicy | backendtrafficpolicy_types.go |
| ClientTrafficPolicy | clienttrafficpolicy_types.go |
| SecurityPolicy | securitypolicy_types.go |
| EnvoyExtensionPolicy | envoyextensionpolicy_types.go |
| EnvoyProxy | envoyproxy_types.go |
| EnvoyPatchPolicy | envoypatchpolicy_types.go |
| Backend | backend_types.go |
| HTTPRouteFilter | httproutefilter_types.go |
Pattern: lowercase CRD name + _types.go
Create a new struct in the appropriate types file or in shared_types.go if used across CRDs:
// MyFeatureSettings defines the settings for MyFeature.
type MyFeatureSettings struct {
// Enabled controls whether MyFeature is active.
//
// +optional
Enabled *bool `json:"enabled,omitempty"`
// Mode specifies the operating mode.
//
// +kubebuilder:validation:Enum=Strict;Permissive
// +optional
Mode *MyFeatureMode `json:"mode,omitempty"`
// Threshold sets the numeric limit.
//
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=1000
// +optional
Threshold *int32 `json:"threshold,omitempty"`
}
// MyFeatureMode defines the mode of MyFeature.
// +kubebuilder:validation:Enum=Strict;Permissive
type MyFeatureMode string
const (
MyFeatureModeStrict MyFeatureMode = "Strict"
MyFeatureModePermissive MyFeatureMode = "Permissive"
)
Add the field to the parent spec struct:
type BackendTrafficPolicySpec struct {
// ... existing fields ...
// MyFeature configures the MyFeature behavior for backend connections.
//
// +optional
MyFeature *MyFeatureSettings `json:"myFeature,omitempty"`
}
| Rule | Example |
|---|---|
| Go field names: PascalCase | MyFeature, RetryBudget |
| JSON tags: camelCase | json:"myFeature,omitempty" |
Optional fields: pointer type + // +optional | *MyFeatureSettings |
| Required fields: value type (no pointer) | MyFeatureMode (when required) |
| Enums: typed string with validation marker | +kubebuilder:validation:Enum=A;B;C |
| Numeric bounds: min/max markers | +kubebuilder:validation:Minimum=1 |
| Default values: kubebuilder default marker | +kubebuilder:default=100 |
If the type is used by multiple CRDs, place it in api/v1alpha1/shared_types.go:
// shared_types.go
// Duration is a string representing a duration (e.g., "1s", "5m").
// +kubebuilder:validation:Pattern=`^([0-9]{1,5}(h|m|s|ms)){1,4}$`
type Duration string
Existing shared types you should reuse (do not reinvent):
Duration — time durationsBackendRef — backend referencesKubernetesContainerSpec — container resource settingsKubernetesPodSpec — pod-level settingsmake generate
This runs:
controller-gen — generates zz_generated.deepcopy.go (DeepCopy methods for all types)charts/gateway-helm/crds/generated/Always verify: git diff after make generate to confirm the generated output looks correct.
Add validation rules as kubebuilder markers on the type:
// +kubebuilder:validation:XValidation:rule="!(has(self.fieldA) && has(self.fieldB))",message="fieldA and fieldB are mutually exclusive"
type MyPolicySpec struct {
// +optional
FieldA *string `json:"fieldA,omitempty"`
// +optional
FieldB *string `json:"fieldB,omitempty"`
}
For rules too complex for CEL, add Go validation in api/v1alpha1/validation/:
// validation/validate.go
func ValidateMyFeature(feature *MyFeatureSettings) error {
if feature == nil {
return nil
}
// complex validation logic
return nil
}
Add tests in test/cel-validation/:
// test/cel-validation/backendtrafficpolicy_test.go
func TestMyFeatureValidation(t *testing.T) {
tests := []struct {
name string
policy *egv1a1.BackendTrafficPolicy
wantErr bool
}{
{
name: "valid configuration",
policy: &egv1a1.BackendTrafficPolicy{
Spec: egv1a1.BackendTrafficPolicySpec{
MyFeature: &egv1a1.MyFeatureSettings{
Enabled: ptr.To(true),
},
},
},
wantErr: false,
},
{
name: "mutually exclusive fields",
policy: &egv1a1.BackendTrafficPolicy{
Spec: egv1a1.BackendTrafficPolicySpec{
MyFeature: &egv1a1.MyFeatureSettings{
FieldA: ptr.To("a"),
FieldB: ptr.To("b"),
},
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create the resource and check if it validates
})
}
}
If the new field needs to be configurable via Helm values:
charts/gateway-helm/values.yaml with the new fieldcharts/gateway-helm/templates/charts/gateway-helm/crds/generated/ are auto-updated by make generate// +optional + pointer type + omitempty tagshared_types.go before creating new typestargetRef for policy attachment, standard status conditionsEnabled *bool if the feature is disabled when the parent struct is nilinterface{} — use typed alternatives// +optionalmake generate run successfullytest/cel-validation/charts/gateway-helm/crds/generated/ updatedapi(api): add FieldName to CRDName