conformance: add Zentinel v0.6.1 report for Gateway API v1.4.1#4711
conformance: add Zentinel v0.6.1 report for Gateway API v1.4.1#4711raffaelschneider wants to merge 1 commit intokubernetes-sigs:mainfrom
Conversation
Add conformance report for Zentinel, a security-first reverse proxy built on Pingora. Passes all 33 core GATEWAY-HTTP profile tests. Signed-off-by: Raffael Schneider <raffael@zentinelproxy.io>
|
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: raffaelschneider The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @raffaelschneider. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
|
||
| ```shell | ||
| git clone https://github.com/zentinelproxy/zentinel.git && cd zentinel | ||
| ./scripts/conformance-test.sh --report |
There was a problem hiding this comment.
the fact the test is setting GATEWAY_ADDRESS=127.0.0.1 makes me think the test script is not really passing the tests in good faith and instead just an AI taking the shortest path to getting a green checkmark on the test. Which is not the intention of the conformance program.
There was a problem hiding this comment.
GATEWAY_ADDRESS is an env var override only used for kind testing, in production, the controller discovers the address from the proxy Service LoadBalancer IP. The kind cluster maps 127.0.0.1:80 → NodePort 30080 → proxy pod port 8080, so the full data plane path is exercised. This is the same pattern used by other implementations testing on kind (e.g. the conformance suite 's own WaitForGatewayAddress reads from status.addresses). Happy to add a comment in the README clarifying this.
There was a problem hiding this comment.
Good question. PR #4687 was opened prematurely. At that point only 31/33 tests passed (HTTPRouteHTTPSListener and HTTPRouteServiceTypes were failing). We closed it and fixed the underlying bugs:
HTTPRouteServiceTypes: The controller had no EndpointSlice watcher, so headless service pod IPs were not picked up when endpoints appeared after the HTTPRoute. Also missing RBAC for discovery.k8s.io/endpointslices.
HTTPRouteHTTPSListener: Multiple issues. Pingora's TLS stack did not support dynamic cert resolution (we added TlsSettings::from_server_config() to our fork), the translator was dropping HTTPS listeners sharing a port instead of merging SNI certs, the KDL config writer was not emitting SNI blocks, and wildcard listeners (no hostname) incorrectly filtered route hostnames.
The fixes span the gateway controller, proxy, Helm RBAC, and our Pingora fork. All are on main. You are right that the v0.6.1 tag is missing, we will push it before this merges.
There was a problem hiding this comment.
Thanks for the review! The GATEWAY_ADDRESS=127.0.0.1 is not a shortcut, it's an env var override for kind-based testing that tells the controller what IP to report in the Gateway's status.addresses. This is only used in the conformance test script (scripts/conformance-test.sh), not in production.
In production, the controller discovers the address from the proxy Service's LoadBalancer/ExternalIP:
// gateway.rs:162-169
async fn get_gateway_addresses(&self, _namespace: &str) -> Vec<serde_json::Value> {
// Check for override via environment variable (for kind/test environments)
if let Ok(addr) = std::env::var("GATEWAY_ADDRESS") {
return vec![json!({"type": "IPAddress", "value": addr})];
}
// Search all namespaces for our proxy Service (labeled by Helm)
let svc_api: Api<Service> = Api::all(self.client.clone());
// ... discovers from Service status.loadBalancer.ingressThe kind cluster architecture:
- Kind maps host ports 80/443 → NodePorts 30080/30443
- The proxy binds 8080/8443 inside the pod, exposed via NodePort Service
- The conformance suite reads
status.addresses[0].valuefrom the Gateway (which is127.0.0.1) andspec.listeners[].port(80/443) - Requests flow:
127.0.0.1:80→ kind port mapping → NodePort 30080 → proxy 8080
The conformance suite itself validates the full request path through the data plane, routing, header modification, weighted backends, cross-namespace references, headless services, TLS termination with SNI, etc. All 33 core tests exercise real traffic through the proxy.
Happy to clarify further or adjust anything.
| organization: zentinelproxy | ||
| project: zentinel | ||
| url: https://github.com/zentinelproxy/zentinel | ||
| version: 0.6.1 |
There was a problem hiding this comment.
@raffaelschneider can you please explain how the tag v0.6.1 (which by the way does not even exist on your repo) now passes all tests when it was failing many of them in #4687?
Summary
Zentinel is a security-first reverse proxy built on Cloudflare's Pingora framework. The gateway controller (
crates/gateway/) translates Gateway API resources into Zentinel's native KDL configuration and runs alongside the proxy as a sidecar.Reproduce
Requires: Docker, kind, kubectl, helm, Go 1.22+.