diff --git a/pkg/i2gw/emitters/kgateway/testing/testdata/input/golden.yaml b/pkg/i2gw/emitters/kgateway/testing/testdata/input/golden.yaml index c4561218e..3086a3f43 100644 --- a/pkg/i2gw/emitters/kgateway/testing/testdata/input/golden.yaml +++ b/pkg/i2gw/emitters/kgateway/testing/testdata/input/golden.yaml @@ -3,6 +3,7 @@ kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/client-body-buffer-size: 10m + nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/limit-rpm: "600" nginx.ingress.kubernetes.io/proxy-send-timeout: "30s" nginx.ingress.kubernetes.io/proxy-read-timeout: "45s" @@ -29,6 +30,7 @@ kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/client-body-buffer-size: 20m + nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/limit-rps: "10" nginx.ingress.kubernetes.io/proxy-send-timeout: "60" # No "s" suffix, should still be parsed correctly nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # No "s" suffix, should still be parsed correctly @@ -54,9 +56,10 @@ kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/client-body-buffer-size: 40m + nginx.ingress.kubernetes.io/proxy-body-size: "100m" + nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/limit-rps: "50" nginx.ingress.kubernetes.io/limit-burst-multiplier: "5" - nginx.ingress.kubernetes.io/proxy-body-size: "100m" nginx.ingress.kubernetes.io/proxy-send-timeout: "90s" nginx.ingress.kubernetes.io/proxy-read-timeout: "90s" nginx.ingress.kubernetes.io/proxy-connect-timeout: "120" diff --git a/pkg/i2gw/providers/ingressnginx/bodybuffer.go b/pkg/i2gw/providers/ingressnginx/bodybuffer.go index df2e6937a..e1432703f 100644 --- a/pkg/i2gw/providers/ingressnginx/bodybuffer.go +++ b/pkg/i2gw/providers/ingressnginx/bodybuffer.go @@ -27,7 +27,10 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -const clientBodyBufferSizeAnnotation = "nginx.ingress.kubernetes.io/client-body-buffer-size" +const ( + clientBodyBufferSizeAnnotation = "nginx.ingress.kubernetes.io/client-body-buffer-size" + proxyBufferingAnnotation = "nginx.ingress.kubernetes.io/proxy-buffering" +) // bufferPolicyFeature parses the "nginx.ingress.kubernetes.io/client-body-buffer-size" annotation // from Ingresses and records them as generic Policies in the ingress-nginx provider-specific IR. @@ -48,6 +51,13 @@ func bufferPolicyFeature( continue } + // Skip buffer size annotations when proxy-buffering is disabled or unset. + // Buffering is disabled by default in NGINX ingress controller. + bufferingEnabled := ing.Annotations[proxyBufferingAnnotation] + if bufferingEnabled != "on" { + continue + } + q, err := resource.ParseQuantity(val) if err != nil { errList = append(errList, field.Invalid( diff --git a/pkg/i2gw/providers/ingressnginx/bodybuffer_test.go b/pkg/i2gw/providers/ingressnginx/bodybuffer_test.go new file mode 100644 index 000000000..fcff34146 --- /dev/null +++ b/pkg/i2gw/providers/ingressnginx/bodybuffer_test.go @@ -0,0 +1,442 @@ +/* +Copyright 2026 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ingressnginx + +import ( + "testing" + + providerir "github.com/kgateway-dev/ingress2gateway/pkg/i2gw/provider_intermediate" + "github.com/kgateway-dev/ingress2gateway/pkg/i2gw/providers/common" + networkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func TestBufferPolicyFeature(t *testing.T) { + testCases := []struct { + name string + ingress networkingv1.Ingress + expectBufferSizeSet bool + expectedBufferSizeVal string + }{ + { + name: "buffer size with proxy-buffering enabled", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-buffer-enabled", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/client-body-buffer-size": "8k", + "nginx.ingress.kubernetes.io/proxy-buffering": "on", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectBufferSizeSet: true, + expectedBufferSizeVal: "8k", + }, + { + name: "buffer size ignored when proxy-buffering is off", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-buffer-off", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/client-body-buffer-size": "8k", + "nginx.ingress.kubernetes.io/proxy-buffering": "off", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectBufferSizeSet: false, + }, + { + name: "buffer size ignored when proxy-buffering is unset", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-buffer-unset", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/client-body-buffer-size": "8k", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectBufferSizeSet: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ir := providerir.ProviderIR{ + HTTPRoutes: make(map[types.NamespacedName]providerir.HTTPRouteContext), + } + + // Setup initial HTTPRoute in IR + routeKey := types.NamespacedName{ + Namespace: tc.ingress.Namespace, + Name: common.RouteName(tc.ingress.Name, "example.com"), + } + ir.HTTPRoutes[routeKey] = providerir.HTTPRouteContext{ + HTTPRoute: gatewayv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: tc.ingress.Namespace, + Name: routeKey.Name, + }, + Spec: gatewayv1.HTTPRouteSpec{ + Rules: []gatewayv1.HTTPRouteRule{ + { + BackendRefs: []gatewayv1.HTTPBackendRef{ + { + BackendRef: gatewayv1.BackendRef{ + BackendObjectReference: gatewayv1.BackendObjectReference{ + Name: "test-service", + Port: ptr.To(gatewayv1.PortNumber(80)), + }, + }, + }, + }, + }, + }, + }, + }, + RuleBackendSources: [][]providerir.BackendSource{ + { + {Ingress: &tc.ingress}, + }, + }, + ProviderSpecificIR: providerir.ProviderSpecificHTTPRouteIR{}, + } + + // Run the feature parser + errs := bufferPolicyFeature([]networkingv1.Ingress{tc.ingress}, nil, &ir) + if len(errs) > 0 { + t.Fatalf("Unexpected errors: %v", errs) + } + + // Verify results + httpCtx := ir.HTTPRoutes[routeKey] + if tc.expectBufferSizeSet { + if httpCtx.ProviderSpecificIR.IngressNginx == nil { + t.Fatal("Expected IngressNginx IR to be set") + } + policy, ok := httpCtx.ProviderSpecificIR.IngressNginx.Policies[tc.ingress.Name] + if !ok { + t.Fatal("Expected policy to be set") + } + if policy.ClientBodyBufferSize == nil { + t.Fatal("Expected ClientBodyBufferSize to be set") + } + + expectedQuantity := resource.MustParse(tc.expectedBufferSizeVal) + if !policy.ClientBodyBufferSize.Equal(expectedQuantity) { + t.Errorf("Expected buffer size %v, got %v", expectedQuantity, policy.ClientBodyBufferSize) + } + } else { + // Verify buffer size was NOT set + if httpCtx.ProviderSpecificIR.IngressNginx != nil { + if policy, ok := httpCtx.ProviderSpecificIR.IngressNginx.Policies[tc.ingress.Name]; ok { + if policy.ClientBodyBufferSize != nil { + t.Errorf("Expected ClientBodyBufferSize to NOT be set, but it was: %v", policy.ClientBodyBufferSize) + } + } + } + } + }) + } +} + +func TestProxyBodySizeFeature(t *testing.T) { + testCases := []struct { + name string + ingress networkingv1.Ingress + expectProxyBodySizeSet bool + expectedProxyBodySizeVal string + }{ + { + name: "proxy-body-size with proxy-buffering enabled", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-proxy-enabled", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/proxy-body-size": "10m", + "nginx.ingress.kubernetes.io/proxy-buffering": "on", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectProxyBodySizeSet: true, + expectedProxyBodySizeVal: "10m", + }, + { + name: "proxy-body-size ignored when proxy-buffering is off", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-proxy-off", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/proxy-body-size": "10m", + "nginx.ingress.kubernetes.io/proxy-buffering": "off", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectProxyBodySizeSet: false, + }, + { + name: "proxy-body-size ignored when proxy-buffering is unset", + ingress: networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-proxy-unset", + Namespace: "default", + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/proxy-body-size": "10m", + }, + }, + Spec: networkingv1.IngressSpec{ + Rules: []networkingv1.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: ptr.To(networkingv1.PathTypePrefix), + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "test-service", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expectProxyBodySizeSet: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ir := providerir.ProviderIR{ + HTTPRoutes: make(map[types.NamespacedName]providerir.HTTPRouteContext), + } + + // Setup initial HTTPRoute in IR + routeKey := types.NamespacedName{ + Namespace: tc.ingress.Namespace, + Name: common.RouteName(tc.ingress.Name, "example.com"), + } + ir.HTTPRoutes[routeKey] = providerir.HTTPRouteContext{ + HTTPRoute: gatewayv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: tc.ingress.Namespace, + Name: routeKey.Name, + }, + Spec: gatewayv1.HTTPRouteSpec{ + Rules: []gatewayv1.HTTPRouteRule{ + { + BackendRefs: []gatewayv1.HTTPBackendRef{ + { + BackendRef: gatewayv1.BackendRef{ + BackendObjectReference: gatewayv1.BackendObjectReference{ + Name: "test-service", + Port: ptr.To(gatewayv1.PortNumber(80)), + }, + }, + }, + }, + }, + }, + }, + }, + RuleBackendSources: [][]providerir.BackendSource{ + { + {Ingress: &tc.ingress}, + }, + }, + ProviderSpecificIR: providerir.ProviderSpecificHTTPRouteIR{}, + } + + // Run the feature parser + errs := proxyBodySizeFeature([]networkingv1.Ingress{tc.ingress}, nil, &ir) + if len(errs) > 0 { + t.Fatalf("Unexpected errors: %v", errs) + } + + // Verify results + httpCtx := ir.HTTPRoutes[routeKey] + if tc.expectProxyBodySizeSet { + if httpCtx.ProviderSpecificIR.IngressNginx == nil { + t.Fatal("Expected IngressNginx IR to be set") + } + policy, ok := httpCtx.ProviderSpecificIR.IngressNginx.Policies[tc.ingress.Name] + if !ok { + t.Fatal("Expected policy to be set") + } + if policy.ProxyBodySize == nil { + t.Fatal("Expected ProxyBodySize to be set") + } + + expectedQuantity := resource.MustParse(tc.expectedProxyBodySizeVal) + if !policy.ProxyBodySize.Equal(expectedQuantity) { + t.Errorf("Expected proxy body size %v, got %v", expectedQuantity, policy.ProxyBodySize) + } + } else { + // Verify proxy body size was NOT set + if httpCtx.ProviderSpecificIR.IngressNginx != nil { + if policy, ok := httpCtx.ProviderSpecificIR.IngressNginx.Policies[tc.ingress.Name]; ok { + if policy.ProxyBodySize != nil { + t.Errorf("Expected ProxyBodySize to NOT be set, but it was: %v", policy.ProxyBodySize) + } + } + } + } + }) + } +} diff --git a/pkg/i2gw/providers/ingressnginx/proxybodysize.go b/pkg/i2gw/providers/ingressnginx/proxybodysize.go index e693c3ee5..28ca7e3da 100644 --- a/pkg/i2gw/providers/ingressnginx/proxybodysize.go +++ b/pkg/i2gw/providers/ingressnginx/proxybodysize.go @@ -46,6 +46,13 @@ func proxyBodySizeFeature( continue } + // Skip proxy-body-size annotation when proxy-buffering is disabled or unset. + // Buffering is disabled by default in NGINX ingress controller. + bufferingEnabled := ing.Annotations[proxyBufferingAnnotation] + if bufferingEnabled != "on" { + continue + } + q, err := resource.ParseQuantity(raw) if err != nil { errs = append(errs, field.Invalid( diff --git a/test/e2e/emitters/kgateway/e2e_test.go b/test/e2e/emitters/kgateway/e2e_test.go index 125ce7e46..4df2b18b4 100644 --- a/test/e2e/emitters/kgateway/e2e_test.go +++ b/test/e2e/emitters/kgateway/e2e_test.go @@ -621,3 +621,81 @@ func TestExternalAuth(t *testing.T) { }, }) } + +func TestServiceUpstream(t *testing.T) { + _, gwAddr, host, ingressHostHeader, ingressIP := e2eTestSetup(t, "service_upstream.yaml", "service_upstream.yaml") + + // Test HTTP connectivity via Ingress + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: ingressHostHeader, + Scheme: "http", + Address: ingressIP, + Port: "", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) + + // Test HTTP connectivity via Gateway + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: host, + Scheme: "http", + Address: gwAddr, + Port: "80", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) +} + +func TestBackendProtocol(t *testing.T) { + _, gwAddr, host, ingressHostHeader, ingressIP := e2eTestSetup(t, "backend_protocol.yaml", "backend_protocol.yaml") + + // Test HTTP connectivity via Ingress + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: ingressHostHeader, + Scheme: "http", + Address: ingressIP, + Port: "", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) + + // Test HTTP connectivity via Gateway + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: host, + Scheme: "http", + Address: gwAddr, + Port: "80", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) +} + +func TestBackendTLS(t *testing.T) { + _, gwAddr, host, ingressHostHeader, ingressIP := e2eTestSetup(t, "backend_tls.yaml", "backend_tls.yaml") + + // Test HTTP connectivity via Ingress + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: ingressHostHeader, + Scheme: "http", + Address: ingressIP, + Port: "", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) + + // Test HTTP connectivity via Gateway + testutils.MakeHTTPRequestEventually(t, kubeContext, testutils.HTTPRequestConfig{ + HostHeader: host, + Scheme: "http", + Address: gwAddr, + Port: "80", + Path: "/", + ExpectedStatusCode: 200, + Timeout: 1 * time.Minute, + }) +} diff --git a/test/e2e/emitters/kgateway/testdata/input/backend_protocol.yaml b/test/e2e/emitters/kgateway/testdata/input/backend_protocol.yaml new file mode 100644 index 000000000..b06bfa376 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/input/backend_protocol.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + name: backend-protocol-test + namespace: default +spec: + ingressClassName: nginx + rules: + - host: grpc.localdev.me + http: + paths: + - backend: + service: + name: echo-backend + port: + number: 8080 + path: / + pathType: Prefix diff --git a/test/e2e/emitters/kgateway/testdata/input/backend_tls.yaml b/test/e2e/emitters/kgateway/testdata/input/backend_tls.yaml new file mode 100644 index 000000000..a642c08d3 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/input/backend_tls.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Secret +metadata: + name: backend-tls-cert + namespace: default +type: kubernetes.io/tls +stringData: + tls.crt: | + -----BEGIN CERTIFICATE----- + MIIBkTCB+wIJAKHHCgVZfULhMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBnRl + c3RjYTAeFw0yMzAxMDEwMDAwMDBaFw0yNDAxMDEwMDAwMDBaMBExDzANBgNVBAMM + BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw7Hs7hf5Z1JQ0v3F + e5z8HzF3Y0YKj2cPqR3xK5dN7rH5V8p5Y0YKj2cPqR3xK5dN7rH5V8p5Y0YKj2cP + qR3xK5dN7rH5V8p5Y0YKj2cPqR3xK5dN7rH5V8p5Y0YKj2cPqR3xK5dN7rH5V8p5 + Y0YKj2cPqR3xK5dN7rH5V8p5Y0YKj2cPqR3xK5dN7rCAwEAAaMQMA4wDAYDVR0T + BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQBWvL5S8f0H0Z8A8N3F0H0H0H0H0H0H + 0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H + 0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H + 0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H + == + -----END CERTIFICATE----- + tls.key: | + -----BEGIN PRIVATE KEY----- + MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMOx7O4X+WdSUNL9 + xXuc/B8xd2NGCo9nD6kd8SuXTe6x+VfKeWNGCo9nD6kd8SuXTe6x+VfKeWNGCo9n + D6kd8SuXTe6x+VfKeWNGCo9nD6kd8SuXTe6x+VfKeWNGCo9nD6kd8SuXTe6x+VfK + eWNGCo9nD6kd8SuXTe6x+VfKeWNGCo9nD6kd8SuXTe6xAgMBAAECgYEAwqDN+P3n + H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0 + H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0H0 + -----END PRIVATE KEY----- +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: HTTPS + nginx.ingress.kubernetes.io/proxy-ssl-secret: default/backend-tls-cert + nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on" + nginx.ingress.kubernetes.io/proxy-ssl-name: "backend-tls.example.com" + nginx.ingress.kubernetes.io/proxy-ssl-verify: "on" + name: backend-tls-test + namespace: default +spec: + ingressClassName: nginx + rules: + - host: tls.localdev.me + http: + paths: + - backend: + service: + name: echo-backend + port: + number: 8080 + path: / + pathType: Prefix diff --git a/test/e2e/emitters/kgateway/testdata/input/service_upstream.yaml b/test/e2e/emitters/kgateway/testdata/input/service_upstream.yaml new file mode 100644 index 000000000..641bb7f32 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/input/service_upstream.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/service-upstream: "true" + name: service-upstream-test + namespace: default +spec: + ingressClassName: nginx + rules: + - host: service-upstream.localdev.me + http: + paths: + - backend: + service: + name: echo-backend + port: + number: 8080 + path: / + pathType: Prefix diff --git a/test/e2e/emitters/kgateway/testdata/output/backend_protocol.yaml b/test/e2e/emitters/kgateway/testdata/output/backend_protocol.yaml new file mode 100644 index 000000000..aea467e56 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/output/backend_protocol.yaml @@ -0,0 +1,55 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: nginx + namespace: default +spec: + gatewayClassName: kgateway + listeners: + - hostname: grpc.localdev.me + name: grpc-localdev-me-http + port: 80 + protocol: HTTP +status: {} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: backend-protocol-test-grpc-localdev-me + namespace: default +spec: + hostnames: + - grpc.localdev.me + parentRefs: + - name: nginx + rules: + - backendRefs: + - group: gateway.kgateway.dev + kind: Backend + name: echo-backend-service-upstream + matches: + - path: + type: PathPrefix + value: / +status: + parents: [] +--- +apiVersion: gateway.kgateway.dev/v1alpha1 +kind: Backend +metadata: + labels: + ingress2gateway.kubernetes.io/source-ingress: backend-protocol-test + name: echo-backend-service-upstream + namespace: default +spec: + static: + appProtocol: grpc + hosts: + - host: echo-backend.default.svc.cluster.local + port: 8080 + type: Static +status: {} diff --git a/test/e2e/emitters/kgateway/testdata/output/backend_tls.yaml b/test/e2e/emitters/kgateway/testdata/output/backend_tls.yaml new file mode 100644 index 000000000..15bb2b117 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/output/backend_tls.yaml @@ -0,0 +1,55 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: nginx + namespace: default +spec: + gatewayClassName: kgateway + listeners: + - hostname: tls.localdev.me + name: tls-localdev-me-http + port: 80 + protocol: HTTP +status: {} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: backend-tls-test-tls-localdev-me + namespace: default +spec: + hostnames: + - tls.localdev.me + parentRefs: + - name: nginx + rules: + - backendRefs: + - name: echo-backend + port: 8080 + matches: + - path: + type: PathPrefix + value: / +status: + parents: [] +--- +apiVersion: gateway.kgateway.dev/v1alpha1 +kind: BackendConfigPolicy +metadata: + name: echo-backend-backend-config + namespace: default +spec: + targetRefs: + - group: "" + kind: Service + name: echo-backend + tls: + secretRef: + name: backend-tls-cert + sni: backend-tls.example.com +status: + ancestors: null diff --git a/test/e2e/emitters/kgateway/testdata/output/service_upstream.yaml b/test/e2e/emitters/kgateway/testdata/output/service_upstream.yaml new file mode 100644 index 000000000..09af23551 --- /dev/null +++ b/test/e2e/emitters/kgateway/testdata/output/service_upstream.yaml @@ -0,0 +1,54 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: nginx + namespace: default +spec: + gatewayClassName: kgateway + listeners: + - hostname: service-upstream.localdev.me + name: service-upstream-localdev-me-http + port: 80 + protocol: HTTP +status: {} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + gateway.networking.k8s.io/generator: ingress2gateway-dev + name: service-upstream-test-service-upstream-localdev-me + namespace: default +spec: + hostnames: + - service-upstream.localdev.me + parentRefs: + - name: nginx + rules: + - backendRefs: + - group: gateway.kgateway.dev + kind: Backend + name: echo-backend-service-upstream + matches: + - path: + type: PathPrefix + value: / +status: + parents: [] +--- +apiVersion: gateway.kgateway.dev/v1alpha1 +kind: Backend +metadata: + labels: + ingress2gateway.kubernetes.io/source-ingress: service-upstream-test + name: echo-backend-service-upstream + namespace: default +spec: + static: + hosts: + - host: echo-backend.default.svc.cluster.local + port: 8080 + type: Static +status: {}