You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+42-30Lines changed: 42 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,16 @@ See `/devel/architecture/overview.md` and the translation diagram at `/devel/arc
21
21
-**test/e2e/**: End-to-end tests using custom framework (see test/e2e/README.md)
22
22
23
23
### Plugin System
24
+
At the core kgateway translates kubernetes Gateway API resources to Envoy configuration. To add features
25
+
like policies, or backends, we use a plugin system. Each plugin *contributes* to the translation, usually by
26
+
adding a new type of CRD (most commonly a Policy CRD) that users can create to express their desired configuration.
27
+
28
+
Policy CRDs are attached to Gateway API resources via `targetRefs` or `targetSelectors`. kgateway manages the attachment
29
+
of policies to the appropriate resources during translation.
30
+
31
+
The plugin is then called in the translation process to affect the dataplane configuration.
32
+
To do this efficiently, the plugin should convert the CRD to an intermediate representation (IR) that is as close to Envoy protos as possible. This minimizes the amount of logic needed in the final translation, and allows for better status reflected back to the user if there are errors.
33
+
24
34
Plugins are **stateless across translations** but maintain state during a single gateway translation via `ProxyTranslationPass`. Each plugin:
25
35
- Provides a KRT collection of `ir.PolicyWrapper` (contains `PolicyIR` + `TargetRefs`)
IRs output by KRT collections **must** implement `Equals(other T) bool`:
37
47
-**Compare ALL fields** or mark with `// +noKrtEquals` (last line of comment)
38
48
-**Never use `reflect.DeepEqual`** (flagged by custom analyzer in `/hack/krtequals/`)
39
-
-**Always write unit tests** for Equals (test reflexivity, symmetry, transitivity)
40
49
- Use proto equality helpers: `proto.Equal()`, not `==`
41
50
42
-
Example test pattern:
43
-
```go
44
-
funcTestMyIREquals(t *testing.T) {
45
-
// Test cases: nil, same, different fields
46
-
// Test symmetry: a.Equals(b) == b.Equals(a)
47
-
// Test reflexivity: x.Equals(x) == true
48
-
// Test transitivity: a.Equals(b) && b.Equals(c) → a.Equals(c)
49
-
}
50
-
```
51
-
52
51
### Code Generation Workflow
53
52
Common targets:
54
53
-`make generate-code`: Ignores stamp files, generates all (takes around 30 seconds)
@@ -76,6 +75,8 @@ make unit # All unit tests (excludes e2e)
76
75
```
77
76
78
77
### API/CRD Development
78
+
79
+
#### Adding New CRDs
79
80
1. Create `*_types.go` in `api/v1alpha1/` with `+kubebuilder` markers. You can use `+kubebuilder:validation:AtLeastOneOf` or `+kubebuilder:validation:ExactlyOneOf` for field groups.
80
81
2.**Required fields**: Use `+required`, NO `omitempty` tag
81
82
3.**Optional fields**: Use `+optional`, pointer types (except slices/maps), `omitempty` tag
@@ -87,14 +88,22 @@ make unit # All unit tests (excludes e2e)
87
88
88
89
See `/api/README.md` for full guidelines.
89
90
90
-
#### Testing New Policy Fields
91
-
When adding fields to policies, at a minimum add yaml tests cases in `internal/kgateway/translator/gateway/gateway_translator_test.go`.
92
-
The yaml inputs go in `internal/kgateway/translator/gateway/testutils/inputs/`. DO NOT generate the outputs.
93
-
Instead, run your tests with environment variable `REFRESH_GOLDEN=true` For example: `REFRESH_GOLDEN=true go test -timeout 30s -run ^TestBasic$/^ListenerPolicy_with_proxy_protocol_on_HTTPS_listener$ github.com/kgateway-dev/kgateway/v2/internal/kgateway/translator/gateway`
94
-
It will generate the outputs for you automatically in the `internal/kgateway/translator/gateway/testutils/outputs/` folder.
95
-
Once the outputs are generated, inspect them to see they contain the changes you expect, and alert the user if that's not the case.
96
-
97
-
Consider also adding E2E tests using the framework. You can look at `test/e2e/features/cors/suite.go` as an example for an E2E test.
91
+
#### Adding fields to Policy CRDs
92
+
93
+
1. Add the field to the appropriate `Spec` struct in the CRD Go type in `api/v1alpha1/`.
94
+
2. Add validation markers as needed (e.g., `+kubebuilder:validation:MinLength=1`, `+optional`, etc.)
95
+
3. Run `make go-generate-apis` to regenerate code.
96
+
4. Update the IR struct in the plugin package (`internal/kgateway/extensions2/plugins/<plugin_name>/`) to include the new field.
97
+
5. Add yaml tests cases in `internal/kgateway/translator/gateway/gateway_translator_test.go`.
98
+
The yaml inputs go in `internal/kgateway/translator/gateway/testutils/inputs/`. DO NOT create the outputs by yourself.
99
+
Instead, run your tests with environment variable `REFRESH_GOLDEN=true`. For example: `REFRESH_GOLDEN=true go test -timeout 30s -run ^TestBasic$/^ListenerPolicy_with_proxy_protocol_on_HTTPS_listener$ github.com/kgateway-dev/kgateway/v2/internal/kgateway/translator/gateway`
100
+
It will generate the outputs for you automatically in the `internal/kgateway/translator/gateway/testutils/outputs/` folder.
101
+
Once the outputs are generated, inspect them to see they contain the changes you expect, and alert the user if that's not the case.
102
+
6. For non-trivial changes, also add unit tests.
103
+
7. Consider also adding E2E tests using the framework. You can look at `test/e2e/features/cors/suite.go` as an example for an E2E test.
104
+
When writing an E2E test, prefer to use `base.NewBaseTestingSuite` as the base suite, as it provides many useful utilities.
105
+
If you are adding a new test suite, remember to register it in `test/e2e/tests/kgateway_tests.go`.
106
+
Additionally add it to one of the test kind clusters in `.github/workflows/e2e.yaml`.
98
107
99
108
### Directory Conventions
100
109
-**Avoid "util" packages** - use descriptive names
@@ -107,30 +116,26 @@ Consider also adding E2E tests using the framework. You can look at `test/e2e/fe
107
116
### Local Development with Tilt
108
117
```bash
109
118
# Initial setup
110
-
make kind-create gw-api-crds gie-crds metallb # Or: make setup-base
make deploy-kgateway # Or: make run (setup + deploy)
134
+
# Set up complete development environment
135
+
make run # kind + CRDs + MetalLB + images + charts
131
136
132
137
# Update after code change
133
-
make kgateway-docker kind-load-kgateway kind-set-image-kgateway
138
+
make kind-reload-kgateway
134
139
```
135
140
136
141
### Running Conformance Tests
@@ -146,7 +151,7 @@ make conformance-HTTPRouteSimpleSameNamespace
146
151
147
152
## Common Gotchas
148
153
149
-
1.**IR Equals() bugs**: High-risk area. MUST compare all fields or mark `+noKrtEquals`. Always test.
154
+
1.**IR Equals() bugs**: High-risk area. MUST compare all fields or mark `+noKrtEquals`.
150
155
2.**Proto comparison**: Use `proto.Equal()`, not `==` or `reflect.DeepEqual`
151
156
3.**Codegen stamps**: `make clean-stamps` if regeneration seems stuck
152
157
4.**E2E test resources**: Never manually delete resources in specific order - let framework handle it
@@ -194,3 +199,10 @@ make generate-licenses # Update license attribution
194
199
```
195
200
196
201
Gateway API version is in `go.mod` and CRD install URL in Makefile (`CONFORMANCE_VERSION`).
202
+
203
+
## Opening Pull Requests
204
+
205
+
1. Ensure all linters pass: `make analyze`, `make verify`
206
+
2. When PR is ready to review/merge, follow this PR template: https://raw.githubusercontent.com/kgateway-dev/.github/refs/heads/main/.github/PULL_REQUEST_TEMPLATE.md
207
+
Specifically must haves are the `Description`, `# Change Type` and `# Changelog` sections.
208
+
3. Ensure tests pass in CI (unit + e2e + conformance)
0 commit comments