From acf0ef9e4353cf182a6e11388c9ab2434a33b09d Mon Sep 17 00:00:00 2001 From: npolshakova Date: Tue, 9 Dec 2025 14:08:07 -0500 Subject: [PATCH] xds tracing Signed-off-by: npolshakova --- .../agentgateway/agentgateway_policy_types.go | 6 +- .../agentgateway/zz_generated.deepcopy.go | 5 + go.mod | 2 + go.sum | 2 - hack/utils/oss_compliance/osa_provided.md | 2 +- ...agentgateway.dev_agentgatewaypolicies.yaml | 7 +- pkg/agentgateway/plugins/frontend_policies.go | 73 ++++++- .../plugins/testdata/frontendpolicy/full.yaml | 54 +++-- pkg/agentgateway/plugins/traffic_plugin.go | 4 +- .../features/agentgateway/tracing/suite.go | 150 ++++++++++++++ .../agentgateway/tracing/testdata/setup.yaml | 188 ++++++++++++++++++ .../tracing/testdata/tracing.yaml | 97 +++++++++ 12 files changed, 564 insertions(+), 26 deletions(-) create mode 100644 test/e2e/features/agentgateway/tracing/suite.go create mode 100644 test/e2e/features/agentgateway/tracing/testdata/setup.yaml create mode 100644 test/e2e/features/agentgateway/tracing/testdata/tracing.yaml diff --git a/api/v1alpha1/agentgateway/agentgateway_policy_types.go b/api/v1alpha1/agentgateway/agentgateway_policy_types.go index 663a74ff2e7..4bbb6ed717b 100644 --- a/api/v1alpha1/agentgateway/agentgateway_policy_types.go +++ b/api/v1alpha1/agentgateway/agentgateway_policy_types.go @@ -250,7 +250,6 @@ type BackendTLS struct { AlpnProtocols *[]TinyString `json:"alpnProtocols,omitempty"` } -// +kubebuilder:validation:XValidation:rule="!has(self.tracing)",message="tracing is not currently implemented" type AgentgatewayPolicyFrontend struct { // tcp defines settings on managing incoming TCP connections. // +optional @@ -267,7 +266,6 @@ type AgentgatewayPolicyFrontend struct { AccessLog *AgentAccessLog `json:"accessLog,omitempty"` // Tracing contains various settings for OpenTelemetry tracer. - // TODO: not currently implemented // +optional Tracing *AgentTracing `json:"tracing,omitempty"` } @@ -1189,4 +1187,8 @@ type AgentTracing struct { // 0.0-1.0, or a boolean (true/false) If unspecified, client sampling is 100% enabled. // +optional ClientSampling *shared.CELExpression `json:"clientSampling,omitempty"` + + // Insecure specifies whether to use TLS when communicating with the OTLP server. + // +optional + Insecure *bool `json:"insecure,omitempty"` } diff --git a/api/v1alpha1/agentgateway/zz_generated.deepcopy.go b/api/v1alpha1/agentgateway/zz_generated.deepcopy.go index 0b06df67fa1..fcdbd54cec8 100644 --- a/api/v1alpha1/agentgateway/zz_generated.deepcopy.go +++ b/api/v1alpha1/agentgateway/zz_generated.deepcopy.go @@ -660,6 +660,11 @@ func (in *AgentTracing) DeepCopyInto(out *AgentTracing) { *out = new(shared.CELExpression) **out = **in } + if in.Insecure != nil { + in, out := &in.Insecure, &out.Insecure + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentTracing. diff --git a/go.mod b/go.mod index 22d13ac353b..b12c5972498 100644 --- a/go.mod +++ b/go.mod @@ -656,3 +656,5 @@ tool ( sigs.k8s.io/controller-tools/cmd/controller-gen sigs.k8s.io/kind ) + +replace github.com/agentgateway/agentgateway => ../agentgateway diff --git a/go.sum b/go.sum index 9516f9bd595..24f8b78839c 100644 --- a/go.sum +++ b/go.sum @@ -194,8 +194,6 @@ github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= -github.com/agentgateway/agentgateway v0.10.6-0.20251203184148-f45f1a94cdfa h1:PWDaZIBsPpGIo/3PdYRRIrU5kCKC86nkkEZLqTDi5rI= -github.com/agentgateway/agentgateway v0.10.6-0.20251203184148-f45f1a94cdfa/go.mod h1:/Lzpteag/nnE4bwW/3Dh5GaxuICmCQs40VhQpkTatlk= github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= diff --git a/hack/utils/oss_compliance/osa_provided.md b/hack/utils/oss_compliance/osa_provided.md index 12bfc5a0fd4..c73b575db47 100644 --- a/hack/utils/oss_compliance/osa_provided.md +++ b/hack/utils/oss_compliance/osa_provided.md @@ -2,7 +2,7 @@ Name|Version|License ---|---|--- [cel.dev/expr](https://cel.dev/expr)|v0.24.0|Apache License 2.0 [semver/v3](https://github.com/Masterminds/semver)|v3.4.0|MIT License -[agentgateway/agentgateway](https://github.com/agentgateway/agentgateway)|v0.10.6-0.20251203184148-f45f1a94cdfa|Apache License 2.0 +[agentgateway/agentgateway](https://github.com/agentgateway/agentgateway)|latest|Apache License 2.0 [anthropics/anthropic-sdk-go](https://github.com/anthropics/anthropic-sdk-go)|v1.13.0|MIT License [retry-go/v4](https://github.com/avast/retry-go)|v4.3.3|MIT License [xds/go](https://github.com/cncf/xds)|v0.0.0-20251110193048-8bfbf64dc13e|Apache License 2.0 diff --git a/install/helm/kgateway-crds/templates/agentgateway.dev_agentgatewaypolicies.yaml b/install/helm/kgateway-crds/templates/agentgateway.dev_agentgatewaypolicies.yaml index 2a88b47ef7f..6528ba09b4f 100644 --- a/install/helm/kgateway-crds/templates/agentgateway.dev_agentgatewaypolicies.yaml +++ b/install/helm/kgateway-crds/templates/agentgateway.dev_agentgatewaypolicies.yaml @@ -1742,6 +1742,10 @@ spec: maxLength: 16384 minLength: 1 type: string + insecure: + description: Insecure specifies whether to use TLS when communicating + with the OTLP server. + type: boolean protocol: default: HTTP description: protocol specifies the OTLP protocol variant @@ -1762,9 +1766,6 @@ spec: - backendRef type: object type: object - x-kubernetes-validations: - - message: tracing is not currently implemented - rule: '!has(self.tracing)' targetRefs: description: targetRefs specifies the target resources by reference to attach the policy to. diff --git a/pkg/agentgateway/plugins/frontend_policies.go b/pkg/agentgateway/plugins/frontend_policies.go index 25296020bbd..97c4154fac1 100644 --- a/pkg/agentgateway/plugins/frontend_policies.go +++ b/pkg/agentgateway/plugins/frontend_policies.go @@ -10,6 +10,7 @@ import ( "github.com/kgateway-dev/kgateway/v2/api/v1alpha1/agentgateway" "github.com/kgateway-dev/kgateway/v2/pkg/kgateway/wellknown" + "github.com/kgateway-dev/kgateway/v2/pkg/utils/kubeutils" ) const ( @@ -63,18 +64,84 @@ func translateFrontendPolicyToAgw( func translateFrontendTracing(policy *agentgateway.AgentgatewayPolicy, name string, target *api.PolicyTarget) []AgwPolicy { tracing := policy.Spec.Frontend.Tracing + if tracing == nil { + return nil + } + + insecure := ptr.Of(false) + if tracing.Insecure != nil && *tracing.Insecure { + insecure = ptr.Of(true) + } + + var provider *api.BackendReference + ref := tracing.BackendRef + if ref.Kind == nil || *ref.Kind == "Service" { + ns := policy.GetNamespace() + if tracing.BackendRef.Namespace != nil { + ns = string(*tracing.BackendRef.Namespace) + } + var port uint32 + if ref.Port != nil { + port = uint32(*ref.Port) + } + hostname := kubeutils.GetServiceHostname(string(ref.Name), ns) + provider = &api.BackendReference{ + Kind: &api.BackendReference_Service_{ + Service: &api.BackendReference_Service{ + Namespace: ns, + Hostname: hostname, + }, + }, + Port: port, + } + } else { + // TODO: support other backend ref kinds + logger.Error("Backend reference kind is not supported", "kind", string(*ref.Kind)) + } + + var attributes []*api.FrontendPolicySpec_TracingAttribute + if tracing.Attributes != nil { + for _, add := range tracing.Attributes.Add { + attributes = append(attributes, &api.FrontendPolicySpec_TracingAttribute{ + Name: add.Name, + Value: string(add.Expression), + }) + } + for _, remove := range tracing.Attributes.Remove { + attributes = append(attributes, &api.FrontendPolicySpec_TracingAttribute{ + Name: remove, + Value: "", + }) + } + } + + var randomSampling *string + if tracing.RandomSampling != nil { + randomSampling = ptr.Of(string(*tracing.RandomSampling)) + } + + var clientSampling *string + if tracing.ClientSampling != nil { + clientSampling = ptr.Of(string(*tracing.ClientSampling)) + } + tracingPolicy := &api.Policy{ Key: name + frontendTracingPolicySuffix + attachmentName(target), Name: TypedResourceName(wellknown.AgentgatewayPolicyGVK.Kind, policy), Target: target, Kind: &api.Policy_Frontend{ Frontend: &api.FrontendPolicySpec{ - // TODO: implement this - Kind: &api.FrontendPolicySpec_Tracing_{Tracing: &api.FrontendPolicySpec_Tracing{}}, + Kind: &api.FrontendPolicySpec_Tracing_{Tracing: &api.FrontendPolicySpec_Tracing{ + ProviderBackend: provider, + Attributes: attributes, + //Resources: resources, + Insecure: insecure, + RandomSampling: randomSampling, + ClientSampling: clientSampling, + }}, }, }, } - _ = tracing logger.Debug("generated tracing policy", "policy", policy.Name, diff --git a/pkg/agentgateway/plugins/testdata/frontendpolicy/full.yaml b/pkg/agentgateway/plugins/testdata/frontendpolicy/full.yaml index dd2cb1bc6ec..41941123293 100644 --- a/pkg/agentgateway/plugins/testdata/frontendpolicy/full.yaml +++ b/pkg/agentgateway/plugins/testdata/frontendpolicy/full.yaml @@ -29,19 +29,20 @@ spec: add: - expression: 'request.headers["user-agent"]' name: http.useragent -# tracing: -# backendRef: -# name: my-otel -# namespace: some-other-ns -# protocol: GRPC -# clientSampling: "true" -# randomSampling: "true" -# attributes: -# remove: -# - response.code -# add: -# - expression: 'request.headers["user-agent"]' -# name: http.useragent + tracing: + backendRef: + name: my-otel + namespace: some-other-ns + port: 4317 + protocol: GRPC + clientSampling: "true" + randomSampling: "true" + attributes: + remove: + - response.code + add: + - expression: 'request.headers["user-agent"]' + name: http.useragent --- # Output @@ -111,6 +112,33 @@ output: gateway: name: test namespace: default +- Policy: + frontend: + tracing: + attributes: + - name: http.useragent + value: request.headers["user-agent"] + - name: response.code + - name: randomSampling + value: "true" + insecure: false + providerBackend: + port: 4317 + service: + hostname: my-otel.some-other-ns.svc.cluster.local + namespace: some-other-ns + resources: + - name: clientSampling + value: "true" + key: frontend/default/agw:frontend-tracing:default/test + name: + kind: AgentgatewayPolicy + name: agw + namespace: default + target: + gateway: + name: test + namespace: default status: ancestors: - ancestorRef: diff --git a/pkg/agentgateway/plugins/traffic_plugin.go b/pkg/agentgateway/plugins/traffic_plugin.go index 41d9f0d78f1..936bc3b2842 100644 --- a/pkg/agentgateway/plugins/traffic_plugin.go +++ b/pkg/agentgateway/plugins/traffic_plugin.go @@ -812,8 +812,8 @@ func processExtAuthPolicy( return nil, fmt.Errorf("failed to build extAuth: %v", err) } spec := &api.TrafficPolicySpec_ExternalAuth{ - Target: be, - Context: extAuth.ContextExtensions, + Target: be, + //Context: extAuth.ContextExtensions, } if b := extAuth.ForwardBody; b != nil { spec.IncludeRequestBody = &api.TrafficPolicySpec_ExternalAuth_BodyOptions{ diff --git a/test/e2e/features/agentgateway/tracing/suite.go b/test/e2e/features/agentgateway/tracing/suite.go new file mode 100644 index 00000000000..2a4f376e101 --- /dev/null +++ b/test/e2e/features/agentgateway/tracing/suite.go @@ -0,0 +1,150 @@ +//go:build e2e + +package configmap + +import ( + "context" + "path/filepath" + "time" + + "github.com/stretchr/testify/suite" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/kgateway-dev/kgateway/v2/pkg/utils/fsutils" + "github.com/kgateway-dev/kgateway/v2/test/e2e" + "github.com/kgateway-dev/kgateway/v2/test/e2e/defaults" + "github.com/kgateway-dev/kgateway/v2/test/e2e/tests/base" +) + +var _ e2e.NewSuiteFunc = NewTestingSuite + +var ( + setupManifest = filepath.Join(fsutils.MustGetThisDir(), "testdata", "setup.yaml") + tracingSetupManifest = filepath.Join(fsutils.MustGetThisDir(), "testdata", "tracing.yaml") + + tracingAgentGatewayDeploymentMeta = metav1.ObjectMeta{ + Name: "agent-gateway", + Namespace: "default", + } + + // configmap manifests applied before the test + tracingConfigMapSetup = base.TestCase{ + Manifests: []string{ + setupManifest, + defaults.CurlPodManifest, + defaults.HttpbinManifest, + }, + } + + testCases = map[string]*base.TestCase{ + "TestTracing": { + Manifests: []string{ + tracingSetupManifest, + }, + }, + } +) + +// testingSuite is a suite of agentgateway configmap tests +type testingSuite struct { + *base.BaseTestingSuite +} + +func NewTestingSuite(ctx context.Context, testInst *e2e.TestInstallation) suite.TestingSuite { + return &testingSuite{ + base.NewBaseTestingSuite(ctx, testInst, tracingConfigMapSetup, testCases), + } +} + +// TestTracing tests that agentgateway properly applies tracing configuration from ConfigMap +func (s *testingSuite) TestTracing() { + s.T().Log("Testing tracing ConfigMap configuration") + + // Ensure the ConfigMap exists before checking the gateway + s.verifyConfigMapExists("agent-gateway-config", "default") + + s.waitForAgentgatewayPodsRunning() + + s.verifyConfigMapMountedInDeployment("agent-gateway-config", tracingAgentGatewayDeploymentMeta) + + // Verify that the tracing configuration is actually loaded and active + s.verifyTracingConfigurationActive(tracingAgentGatewayDeploymentMeta) +} + +// verifyConfigMapExists ensures the ConfigMap exists before proceeding +func (s *testingSuite) verifyConfigMapExists(name, namespace string) { + s.T().Logf("Verifying ConfigMap %s exists in namespace %s", name, namespace) + s.TestInstallation.Assertions.EventuallyObjectsExist(s.T().Context(), + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: "default", + }, + }, + ) +} + +// waitForAgentgatewayPodsRunning waits for the agentgateway pods to be running +func (s *testingSuite) waitForAgentgatewayPodsRunning() { + s.TestInstallation.Assertions.EventuallyPodsRunning( + s.T().Context(), + "default", + metav1.ListOptions{LabelSelector: defaults.WellKnownAppLabel + "=agent-gateway"}, + 60*time.Second, + ) +} + +// verifyConfigMapMountedInDeployment is a helper function that verifies a specific ConfigMap +// is mounted as config-volume in the agentgateway deployment +func (s *testingSuite) verifyConfigMapMountedInDeployment(expectedConfigMapName string, deploymentMeta metav1.ObjectMeta) { + deploymentObj := &appsv1.Deployment{} + err := s.TestInstallation.ClusterContext.Client.Get( + s.T().Context(), + client.ObjectKey{ + Namespace: deploymentMeta.Namespace, + Name: deploymentMeta.Name, + }, + deploymentObj, + ) + s.Require().NoError(err) + + found := false + for _, volume := range deploymentObj.Spec.Template.Spec.Volumes { + if volume.Name == "config-volume" && volume.ConfigMap != nil { + if volume.ConfigMap.Name == expectedConfigMapName { + found = true + break + } + } + } + s.Require().True(found, "ConfigMap %s should be mounted as config-volume", expectedConfigMapName) +} + +// verifyTracingConfigurationActive checks that the tracing configuration from ConfigMap is accepted by agentgateway +func (s *testingSuite) verifyTracingConfigurationActive(deploymentMeta metav1.ObjectMeta) { + pods, err := s.TestInstallation.Actions.Kubectl().GetPodsInNsWithLabel( + s.T().Context(), + deploymentMeta.Namespace, + defaults.WellKnownAppLabel+"=agent-gateway", + ) + s.Require().NoError(err) + s.Require().NotEmpty(pods, "No agentgateway pods found") + + s.Require().Eventually(func() bool { + logs, err := s.TestInstallation.Actions.Kubectl().GetContainerLogs( + s.T().Context(), + deploymentMeta.Namespace, + pods[0], + ) + s.Require().NoError(err, "Failed to get pod logs") + + expectedEndpoint := "endpoint: http://jaeger-collector.observability.svc.cluster.local:4317" + s.Require().Contains(logs, expectedEndpoint, + "Tracing endpoint %s from ConfigMap should be present in pod logs", expectedEndpoint) + + return true + }, 60*time.Second, 5*time.Second) +} diff --git a/test/e2e/features/agentgateway/tracing/testdata/setup.yaml b/test/e2e/features/agentgateway/tracing/testdata/setup.yaml new file mode 100644 index 00000000000..152d7299203 --- /dev/null +++ b/test/e2e/features/agentgateway/tracing/testdata/setup.yaml @@ -0,0 +1,188 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jaeger + labels: + app: jaeger +spec: + replicas: 1 + selector: + matchLabels: + app: jaeger + template: + metadata: + labels: + app: jaeger + spec: + containers: + - name: jaeger + image: jaegertracing/all-in-one:1.56 + args: + - "--collector.zipkin.host-port=:9411" + ports: + - containerPort: 16686 + - containerPort: 16685 + - containerPort: 14268 + - containerPort: 9411 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector-conf + labels: + app: opentelemetry + component: otel-collector-conf +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + + processors: {} + + exporters: + debug: + verbosity: detailed + zipkin: + endpoint: http://tracing.default.svc.cluster.local:9411/api/v2/spans + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug, zipkin] +--- +apiVersion: v1 +kind: Service +metadata: + labels: + name: zipkin + name: zipkin +spec: + ports: + - port: 9411 + targetPort: 9411 + name: http-query + selector: + app: jaeger +--- +# k port-forward svc/tracing 16686:80 +apiVersion: v1 +kind: Service +metadata: + name: tracing + labels: + app: jaeger +spec: + type: ClusterIP + ports: + - name: http-query + port: 80 + protocol: TCP + targetPort: 16686 + # Note: Change port name if you add '--query.grpc.tls.enabled=true' + - name: grpc-query + port: 16685 + protocol: TCP + targetPort: 16685 + - name: zipkin + port: 9411 + targetPort: 9411 + selector: + app: jaeger +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector-config + namespace: default +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + + processors: + batch: {} + + exporters: + debug: + verbosity: detailed + zipkin: + endpoint: http://tracing.default.svc.cluster.local:9411/api/v2/spans + + service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [debug, zipkin] + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opentelemetry-collector + namespace: default + labels: + app.kubernetes.io/name: opentelemetry-collector + app.kubernetes.io/component: standalone-collector +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: opentelemetry-collector + app.kubernetes.io/component: standalone-collector + template: + metadata: + labels: + app.kubernetes.io/name: opentelemetry-collector + app.kubernetes.io/component: standalone-collector + spec: + serviceAccountName: default + containers: + - name: opentelemetry-collector + image: otel/opentelemetry-collector-contrib:0.128.0 + command: + - /otelcol-contrib + args: + - --config=/conf/otel-collector-config + ports: + - containerPort: 4317 + name: otlp-grpc + protocol: TCP + - containerPort: 4318 + name: otlp-http + protocol: TCP + volumeMounts: + - name: otel-collector-config + mountPath: /conf + volumes: + - name: otel-collector-config + configMap: + name: otel-collector-config +--- +apiVersion: v1 +kind: Service +metadata: + name: opentelemetry-collector + namespace: default + labels: + app.kubernetes.io/name: opentelemetry-collector +spec: + selector: + app.kubernetes.io/name: opentelemetry-collector + ports: + - name: otlp-grpc + port: 4317 + targetPort: 4317 + - name: otlp-http + port: 4318 + targetPort: 4318 +--- diff --git a/test/e2e/features/agentgateway/tracing/testdata/tracing.yaml b/test/e2e/features/agentgateway/tracing/testdata/tracing.yaml new file mode 100644 index 00000000000..79a549ab405 --- /dev/null +++ b/test/e2e/features/agentgateway/tracing/testdata/tracing.yaml @@ -0,0 +1,97 @@ +kind: GatewayParameters +apiVersion: gateway.kgateway.dev/v1alpha1 +metadata: + name: kgateway +spec: + kube: + agentgateway: + enabled: true + logLevel: debug + image: + tag: v0.6.0-324-g0ddfb6554-dirty +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: agentgateway +spec: + controllerName: kgateway.dev/agentgateway + parametersRef: + group: gateway.kgateway.dev + kind: GatewayParameters + name: kgateway + namespace: default +--- +apiVersion: agentgateway.dev/v1alpha1 +kind: AgentgatewayPolicy +metadata: + name: agw + namespace: default +spec: + targetRefs: + - kind: Gateway + name: gw + group: gateway.networking.k8s.io + frontend: + tracing: + backendRef: + name: opentelemetry-collector + namespace: default + port: 4317 + insecure: true + protocol: GRPC + clientSampling: "true" + randomSampling: "true" + attributes: + add: + - expression: 'request.headers["user-agent"]' + name: http.useragent +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: gw +spec: + gatewayClassName: agentgateway + listeners: + - protocol: HTTP + port: 8080 + name: http + allowedRoutes: + namespaces: + from: All +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: httpbin-route + namespace: default +spec: + hostnames: + - httpbin + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gw + namespace: default + rules: + - backendRefs: + - group: "" + kind: Service + name: httpbin + port: 8000 + weight: 1 + matches: + - path: + type: PathPrefix + value: /status/200 + - backendRefs: + - group: "" + kind: Service + name: httpbin + port: 8000 + weight: 1 + matches: + - path: + type: PathPrefix + value: /get \ No newline at end of file