diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 3c80edc68b..0387f42b20 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -152,6 +152,7 @@ jobs: - version: v1.34.2 ipFamily: ipv4 profile: xds-name-scheme-v2 + gatewayApiVersion: v1.3.0 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: ./tools/github-actions/setup-deps @@ -174,6 +175,7 @@ jobs: IMAGE_PULL_POLICY: IfNotPresent IP_FAMILY: ${{ matrix.target.ipFamily }} KUBE_DEPLOY_PROFILE: ${{ matrix.target.profile }} + E2E_GATEWAY_API_VERSION: ${{ matrix.target.gatewayApiVersion }} run: make conformance e2e-test: @@ -205,6 +207,7 @@ jobs: - version: v1.34.2 ipFamily: ipv4 profile: xds-name-scheme-v2 + gatewayApiVersion: v1.3.0 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 @@ -229,6 +232,7 @@ jobs: IMAGE_PULL_POLICY: IfNotPresent IP_FAMILY: ${{ matrix.target.ipFamily }} KUBE_DEPLOY_PROFILE: ${{ matrix.target.profile }} + E2E_GATEWAY_API_VERSION: ${{ matrix.target.gatewayApiVersion }} E2E_TIMEOUT: 1h NUM_WORKERS: 2 # QPS more than 3000 may cause e2e flaky test. diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 8a65532ecf..79e2e736f4 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -78,6 +78,7 @@ type gatewayAPIReconciler struct { extBackendGVKs []schema.GroupVersionKind gatewayNamespaceMode bool + backendTLSPolicyGVK schema.GroupVersionKind backendCRDExists bool bTLSPolicyCRDExists bool btpCRDExists bool @@ -170,6 +171,10 @@ func newGatewayAPIController(ctx context.Context, mgr manager.Manager, cfg *conf extServerPolicies: extServerPoliciesGVKs, extBackendGVKs: extBackendGVKs, gatewayNamespaceMode: cfg.EnvoyGateway.GatewayNamespaceMode(), + backendTLSPolicyGVK: schema.GroupVersion{ + Group: gwapiv1.GroupVersion.Group, + Version: gwapiv1.GroupVersion.Version, + }.WithKind(resource.KindBackendTLSPolicy), } if byNamespaceSelectorEnabled(cfg.EnvoyGateway) { @@ -295,6 +300,13 @@ func isTransientError(err error) bool { errors.Is(err, context.DeadlineExceeded) } +func (r *gatewayAPIReconciler) useBackendTLSPolicyV1Alpha3() bool { + return r.backendTLSPolicyGVK.GroupVersion() == (schema.GroupVersion{ + Group: gwapiv1a3.GroupVersion.Group, + Version: gwapiv1a3.GroupVersion.Version, + }) +} + // Reconcile handles reconciling all resources in a single call. Any resource event should enqueue the // same reconcile.Request containing the gateway controller name. This allows multiple resource updates to // be handled by a single call to Reconcile. The reconcile.Request DOES NOT map to a specific resource. @@ -1880,16 +1892,12 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( func (r *gatewayAPIReconciler) processBackendTLSPolicies( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, ) error { - backendTLSPolicies := gwapiv1.BackendTLSPolicyList{} - if err := r.client.List(ctx, &backendTLSPolicies); err != nil { + backendTLSPolicies, err := r.listBackendTLSPolicies(ctx) + if err != nil { return fmt.Errorf("error listing BackendTLSPolicies: %w", err) } - for i := range backendTLSPolicies.Items { - backendTLSPolicy := &backendTLSPolicies.Items[i] - // Discard Status to reduce memory consumption in watchable - // It will be recomputed by the gateway-api layer - backendTLSPolicy.Status = gwapiv1.PolicyStatus{} + for _, backendTLSPolicy := range backendTLSPolicies { if !resourceMap.allAssociatedBackendTLSPolicies.Has(utils.NamespacedName(backendTLSPolicy).String()) { resourceMap.allAssociatedBackendTLSPolicies.Insert(utils.NamespacedName(backendTLSPolicy).String()) resourceTree.BackendTLSPolicies = append(resourceTree.BackendTLSPolicies, backendTLSPolicy) @@ -1900,6 +1908,80 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies( return r.processBackendTLSPolicyRefs(ctx, resourceTree, resourceMap) } +func (r *gatewayAPIReconciler) watchBackendTLSPolicy(mgr manager.Manager, c controller.Controller) error { + if r.useBackendTLSPolicyV1Alpha3() { + btlsPredicates := []predicate.TypedPredicate[*gwapiv1a3.BackendTLSPolicy]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a3.BackendTLSPolicy]{}, + } + if r.namespaceLabel != nil { + btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs(func(btp *gwapiv1a3.BackendTLSPolicy) bool { + return r.hasMatchingNamespaceLabels(btp) + })) + } + + return c.Watch( + source.Kind(mgr.GetCache(), &gwapiv1a3.BackendTLSPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a3.BackendTLSPolicy) []reconcile.Request { + return r.enqueueClass(ctx, btp) + }), + btlsPredicates...)) + } + + btlsPredicates := []predicate.TypedPredicate[*gwapiv1.BackendTLSPolicy]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1.BackendTLSPolicy]{}, + } + if r.namespaceLabel != nil { + btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs(func(btp *gwapiv1.BackendTLSPolicy) bool { + return r.hasMatchingNamespaceLabels(btp) + })) + } + + return c.Watch( + source.Kind(mgr.GetCache(), &gwapiv1.BackendTLSPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1.BackendTLSPolicy) []reconcile.Request { + return r.enqueueClass(ctx, btp) + }), + btlsPredicates...)) +} + +// listBackendTLSPolicies lists BackendTLSPolicy resources, handling both v1 and v1alpha3 versions to ensure compatibility. +func (r *gatewayAPIReconciler) listBackendTLSPolicies(ctx context.Context, opts ...client.ListOption) ([]*gwapiv1.BackendTLSPolicy, error) { + if !r.bTLSPolicyCRDExists { + return nil, nil + } + + if !r.useBackendTLSPolicyV1Alpha3() { + backendTLSPolicies := gwapiv1.BackendTLSPolicyList{} + if err := r.client.List(ctx, &backendTLSPolicies, opts...); err != nil { + return nil, err + } + results := make([]*gwapiv1.BackendTLSPolicy, 0, len(backendTLSPolicies.Items)) + for i := range backendTLSPolicies.Items { + backendTLSPolicy := &backendTLSPolicies.Items[i] + backendTLSPolicy.Status = gwapiv1.PolicyStatus{} + results = append(results, backendTLSPolicy) + } + return results, nil + } + + alphaList := gwapiv1a3.BackendTLSPolicyList{} + if err := r.client.List(ctx, &alphaList, opts...); err != nil { + return nil, err + } + + results := make([]*gwapiv1.BackendTLSPolicy, 0, len(alphaList.Items)) + for i := range alphaList.Items { + converted := &gwapiv1.BackendTLSPolicy{} + if err := r.client.Scheme().Convert(&alphaList.Items[i], converted, nil); err != nil { + return nil, fmt.Errorf("converting BackendTLSPolicy v1alpha3 to v1: %w", err) + } + converted.Status = gwapiv1.PolicyStatus{} + results = append(results, converted) + } + + return results, nil +} + // removeFinalizer removes the GatewayClass finalizer from the provided gc, if it exists. func (r *gatewayAPIReconciler) removeFinalizer(ctx context.Context, gc *gwapiv1.GatewayClass) error { if slice.ContainsString(gc.Finalizers, gatewayClassFinalizer) { @@ -2433,28 +2515,23 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M r.bTLSPolicyCRDExists = r.crdExists(mgr, resource.KindBackendTLSPolicy, gwapiv1.GroupVersion.String()) if !r.bTLSPolicyCRDExists { - r.log.Info("BackendTLSPolicy CRD not found, skipping BackendTLSPolicy watch") - } else { - // Watch BackendTLSPolicy - btlsPredicates := []predicate.TypedPredicate[*gwapiv1.BackendTLSPolicy]{ - predicate.TypedGenerationChangedPredicate[*gwapiv1.BackendTLSPolicy]{}, - } - if r.namespaceLabel != nil { - btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs(func(btp *gwapiv1.BackendTLSPolicy) bool { - return r.hasMatchingNamespaceLabels(btp) - })) + if r.crdExists(mgr, resource.KindBackendTLSPolicy, gwapiv1a3.GroupVersion.String()) { + r.bTLSPolicyCRDExists = true + r.backendTLSPolicyGVK = schema.GroupVersion{ + Group: gwapiv1a3.GroupVersion.Group, + Version: gwapiv1a3.GroupVersion.Version, + }.WithKind(resource.KindBackendTLSPolicy) + r.log.Info("BackendTLSPolicy v1 CRD not found, falling back to v1alpha3") + } else { + r.log.Info("BackendTLSPolicy CRD not found, skipping BackendTLSPolicy watch") } - - if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1.BackendTLSPolicy{}, - handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1.BackendTLSPolicy) []reconcile.Request { - return r.enqueueClass(ctx, btp) - }), - btlsPredicates...)); err != nil { + } + if r.bTLSPolicyCRDExists { + if err := r.watchBackendTLSPolicy(mgr, c); err != nil { return err } - if err := addBtlsIndexers(ctx, mgr); err != nil { + if err := addBtlsIndexers(ctx, mgr, r.useBackendTLSPolicyV1Alpha3()); err != nil { return err } } diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index d937be3a59..01be055199 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -1008,7 +1008,23 @@ func secretRouteFilterIndexFunc(rawObj client.Object) []string { // addBtlsIndexers adds indexing on BackendTLSPolicy, for ConfigMap and Secret objects that are // referenced in BackendTLSPolicy objects. This helps in querying for BackendTLSPolicies that are // affected by a particular ConfigMap CRUD. -func addBtlsIndexers(ctx context.Context, mgr manager.Manager) error { +func addBtlsIndexers(ctx context.Context, mgr manager.Manager, useV1Alpha3 bool) error { + if useV1Alpha3 { + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a3.BackendTLSPolicy{}, configMapBtlsIndex, configMapBtlsIndexFuncV1Alpha3); err != nil { + return err + } + + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a3.BackendTLSPolicy{}, secretBtlsIndex, secretBtlsIndexFuncV1Alpha3); err != nil { + return err + } + + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a3.BackendTLSPolicy{}, clusterTrustBundleBtlsIndex, clusterTrustBundleBtlsIndexFuncV1Alpha3); err != nil { + return err + } + + return nil + } + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.BackendTLSPolicy{}, configMapBtlsIndex, configMapBtlsIndexFunc); err != nil { return err } @@ -1071,6 +1087,53 @@ func clusterTrustBundleBtlsIndexFunc(rawObj client.Object) []string { return refs } +func configMapBtlsIndexFuncV1Alpha3(rawObj client.Object) []string { + btls := rawObj.(*gwapiv1a3.BackendTLSPolicy) + var configMapReferences []string + if btls.Spec.Validation.CACertificateRefs != nil { + for _, caCertRef := range btls.Spec.Validation.CACertificateRefs { + if string(caCertRef.Kind) == resource.KindConfigMap { + configMapReferences = append(configMapReferences, + types.NamespacedName{ + Namespace: btls.Namespace, + Name: string(caCertRef.Name), + }.String(), + ) + } + } + } + return configMapReferences +} + +func secretBtlsIndexFuncV1Alpha3(rawObj client.Object) []string { + btls := rawObj.(*gwapiv1a3.BackendTLSPolicy) + var secretReferences []string + if btls.Spec.Validation.CACertificateRefs != nil { + for _, caCertRef := range btls.Spec.Validation.CACertificateRefs { + if string(caCertRef.Kind) == resource.KindSecret { + secretReferences = append(secretReferences, + types.NamespacedName{ + Namespace: btls.Namespace, + Name: string(caCertRef.Name), + }.String(), + ) + } + } + } + return secretReferences +} + +func clusterTrustBundleBtlsIndexFuncV1Alpha3(rawObj client.Object) []string { + btls := rawObj.(*gwapiv1a3.BackendTLSPolicy) + var refs []string + for _, caCertRef := range btls.Spec.Validation.CACertificateRefs { + if string(caCertRef.Kind) == resource.KindClusterTrustBundle { + refs = append(refs, string(caCertRef.Name)) + } + } + return refs +} + // addEnvoyExtensionPolicyIndexers adds indexing on EnvoyExtensionPolicy. // - For Service objects that are referenced in EnvoyExtensionPolicy objects via // `.spec.extProc.[*].service.backendObjectReference`. This helps in querying for diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index e87dcb7815..388064a313 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -253,19 +253,15 @@ func (r *gatewayAPIReconciler) isBackendReferencingClusterTrustBundle(ctb *certi } func (r *gatewayAPIReconciler) isBackendTLSPolicyReferencingClusterTrustBundle(ctb *certificatesv1b1.ClusterTrustBundle) bool { - btlsList := &gwapiv1.BackendTLSPolicyList{} - if err := r.client.List(context.Background(), btlsList, &client.ListOptions{ + btlsList, err := r.listBackendTLSPolicies(context.Background(), &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(clusterTrustBundleBtlsIndex, ctb.Name), - }); err != nil { + }) + if err != nil { r.log.Error(err, "unable to find associated BackendTLSPolicy") return false } - if len(btlsList.Items) > 0 { - return true - } - - return false + return len(btlsList) > 0 } func (r *gatewayAPIReconciler) isHTTPRouteFilterReferencingSecret(nsName *types.NamespacedName) bool { @@ -285,19 +281,15 @@ func (r *gatewayAPIReconciler) isHTTPRouteFilterReferencingSecret(nsName *types. } func (r *gatewayAPIReconciler) isBackendTLSPolicyReferencingSecret(nsName *types.NamespacedName) bool { - btlsList := &gwapiv1.BackendTLSPolicyList{} - if err := r.client.List(context.Background(), btlsList, &client.ListOptions{ + btlsList, err := r.listBackendTLSPolicies(context.Background(), &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(secretBtlsIndex, nsName.String()), - }); err != nil { + }) + if err != nil { r.log.Error(err, "unable to find associated BackendTLSPolicy") return false } - if len(btlsList.Items) > 0 { - return true - } - - return false + return len(btlsList) > 0 } func (r *gatewayAPIReconciler) isEnvoyProxyReferencingSecret(nsName *types.NamespacedName) bool { diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 0f4d4f0769..389e51f969 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -72,6 +72,15 @@ func TestE2E(t *testing.T) { ) } + // Skip these BTLSPolicy tests since their manifests are written in v1. + // V1alpha3 are covered in the BackendTLSTest test. + if tests.IsBTLSPolicyV1alpha3() { + skipTests = append(skipTests, + tests.BackendTLSSettingsTest.ShortName, + tests.BackendClusterTrustBundleTest.ShortName, + ) + } + enabledFeatures := sets.New(features.SupportGateway) if tests.EnabledClusterTrustBundle() { tlog.Logf(t, "ClusterTrustBundle feature is enabled") diff --git a/test/e2e/testdata/backend-tls-v1alpha3.yaml b/test/e2e/testdata/backend-tls-v1alpha3.yaml new file mode 100644 index 0000000000..d9abe4001c --- /dev/null +++ b/test/e2e/testdata/backend-tls-v1alpha3.yaml @@ -0,0 +1,249 @@ +apiVersion: v1 +data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDQzCCAiugAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYDVQQKEwpFbnZv + eVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBHYXRld2F5 + IENBMCAXDTI0MDMxMDE1MzIxN1oYDzIxMjQwMzEwMTYzMjE3WjBCMRMwEQYDVQQK + EwpFbnZveVByb3h5MRAwDgYDVQQLEwdHYXRld2F5MRkwFwYDVQQDExBFbnZveSBH + YXRld2F5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7ZFmGB4e + m1KdGEohAZBfqydAEGLDHJ1YyfHWdd+vBAevdW64bZx3pggJOtgCnePuFd02rDQS + dlsJlX/6mFtoQilo6wvxDSJRfaTDbtfTjw+7k8yfd/Jsmh0RWG+UeyI7Na9sXAz7 + b57mpxsCoNowzeK5ETiOGGNWPcjENJkSnBarz5muN00xIZWBU+yN5PLJNxZvxpZJ + Ol/SSI8sno0e0PxAmp3fe7QaXiZj/TAGJPGuTJkUxrHqyZGJtYUxsS8A0dT1zBjj + izA5Dp+b5yzYo23Hh7BgpbZ7X4gsDThFuwCD6fHyepuv2zHPqvSsdqg2hAhDp91R + zrn7a9GxG2VSIwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw + AwEB/zAdBgNVHQ4EFgQUUpP1aZ1M2KIuPPWrNPDV2c5CngowDQYJKoZIhvcNAQEL + BQADggEBAGSEkAVz+Z0qS4FmA0q4SCpIIq64bsdEjiUzev7pK1LEK0/Y28QBPixV + cUXfax18VPR9pls1JgXto9qY+C0hnRZic6611QTJlWK1p6dinQ/eDdYCBC+nv5xx + ssASwmplIxMvj3S1qF6dr7sMI2ZVD5HElTWdO19UBLyhiKKZW2KxDsYj+5NRwGFe + G+JuDgq7njUM8mdyYk0NehefdBUEUUCQtnwUtW95/429XwqQROuRDteGT9kjD+Y5 + ea5mW4mfqLeuGJXZs9bdWjKKdLQPrn9IshPysWqz2Hz8dQ1f7N9/g8UWVSjd4cyx + S5EAolzVv0yB7wHCWCgfG/ckdOTUNnE= + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + name: backend-tls-ca + namespace: gateway-conformance-infra +--- +apiVersion: gateway.networking.k8s.io/v1alpha3 +kind: BackendTLSPolicy +metadata: + name: policy-btls + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: "" + kind: Service + name: tls-backend-2 + sectionName: https + validation: + caCertificateRefs: + - name: backend-tls-ca + group: "" + kind: ConfigMap + hostname: example.com +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-backend-tls + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /backend-tls + backendRefs: + - name: tls-backend-2 + port: 443 +--- +apiVersion: v1 +kind: Service +metadata: + name: tls-backend-2-no-policy + namespace: gateway-conformance-infra +spec: + selector: + app: tls-backend-2 + ports: + - protocol: TCP + port: 443 + targetPort: 8443 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-without-backend-tls + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /backend-tls-without-policy + backendRefs: + - name: tls-backend-2-no-policy + port: 443 +--- +apiVersion: gateway.networking.k8s.io/v1alpha3 +kind: BackendTLSPolicy +metadata: + name: policy-btls-trust-store + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: backend-eg-site + validation: + wellKnownCACertificates: System + hostname: gateway.envoyproxy.io +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-backend-tls-system-trust-store + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + hostnames: + - gateway.envoyproxy.io + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: backend-eg-site + group: gateway.envoyproxy.io + kind: Backend +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Backend +metadata: + name: backend-eg-site + namespace: gateway-conformance-infra +spec: + endpoints: + - fqdn: + hostname: gateway.envoyproxy.io + port: 443 +--- +apiVersion: gateway.networking.k8s.io/v1alpha3 +kind: BackendTLSPolicy +metadata: + name: policy-btls-ca-mismatch + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: backend-insecure-tls-verify + validation: + wellKnownCACertificates: System + hostname: example.com +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Backend +metadata: + name: backend-insecure-tls-verify-and-mismatch-ca + namespace: gateway-conformance-infra +spec: + endpoints: + - fqdn: + hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local + port: 443 + tls: + insecureSkipVerify: true +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-backend-insecure-skip-verify-and-mismatch-ca + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /backend-tls-skip-verify-and-mismatch-ca + backendRefs: + - name: backend-insecure-tls-verify-and-mismatch-ca + group: gateway.envoyproxy.io + kind: Backend +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Backend +metadata: + name: backend-insecure-tls-verify-without-backend-tls-policy + namespace: gateway-conformance-infra +spec: + endpoints: + - fqdn: + hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local + port: 443 + tls: + insecureSkipVerify: true +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-backend-insecure-skip-verify-without-backend-tls-policy + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /backend-tls-skip-verify-without-backend-tls-policy + backendRefs: + - name: backend-insecure-tls-verify-without-backend-tls-policy + group: gateway.envoyproxy.io + kind: Backend +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-backend-tls-auto-sni + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /backend-auto-sni + backendRefs: + - name: backend-with-auto-sni + group: gateway.envoyproxy.io + kind: Backend +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Backend +metadata: + name: backend-with-auto-sni + namespace: gateway-conformance-infra +spec: + endpoints: + - fqdn: + hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local + port: 443 + # The SNI value would be taken from the host header sent by the client and + # Envoy will validate the upstream certificate for a DNS SAN that matches SNI + tls: + caCertificateRefs: + - name: backend-tls-ca + group: "" + kind: ConfigMap diff --git a/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml b/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml index 5f410d1fb0..fda8455f08 100644 --- a/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml +++ b/test/e2e/testdata/ext-auth-grpc-securitypolicy.yaml @@ -52,7 +52,7 @@ spec: namespace: gateway-conformance-infra port: 9002 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: envoy-ext-auth-btls diff --git a/test/e2e/testdata/ext-auth-grpc-timeout-securitypolicy.yaml b/test/e2e/testdata/ext-auth-grpc-timeout-securitypolicy.yaml index 9fe5d1f0cd..046014d02c 100644 --- a/test/e2e/testdata/ext-auth-grpc-timeout-securitypolicy.yaml +++ b/test/e2e/testdata/ext-auth-grpc-timeout-securitypolicy.yaml @@ -53,7 +53,7 @@ spec: namespace: gateway-conformance-infra port: 9002 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: envoy-ext-auth-btls diff --git a/test/e2e/testdata/ext-auth-http-timeout-securitypolicy.yaml b/test/e2e/testdata/ext-auth-http-timeout-securitypolicy.yaml index 3c871450f7..d7fb85446f 100644 --- a/test/e2e/testdata/ext-auth-http-timeout-securitypolicy.yaml +++ b/test/e2e/testdata/ext-auth-http-timeout-securitypolicy.yaml @@ -55,7 +55,7 @@ spec: port: 8080 headersToBackend: ["x-current-user"] --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: envoy-ext-auth-btls diff --git a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml index c80d6518d2..52d01333bf 100644 --- a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml +++ b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml @@ -144,7 +144,7 @@ spec: namespace: gateway-conformance-infra port: 9002 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: grpc-ext-proc-btls @@ -210,7 +210,7 @@ spec: request: {} response: {} --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: policy-btls-uds-extproc diff --git a/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml b/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml index a577b66de7..b3f2f34f37 100644 --- a/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml +++ b/test/e2e/testdata/httproute-to-backend-fqdn-tls.yaml @@ -27,7 +27,7 @@ spec: hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local port: 443 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: backend-fqdn-tls-btls diff --git a/test/e2e/testdata/jwt-backend-remote-jwks.yaml b/test/e2e/testdata/jwt-backend-remote-jwks.yaml index b95caa839a..4680d101ce 100644 --- a/test/e2e/testdata/jwt-backend-remote-jwks.yaml +++ b/test/e2e/testdata/jwt-backend-remote-jwks.yaml @@ -98,7 +98,7 @@ spec: hostname: 'remote-jwks-server.gateway-conformance-infra' port: 443 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: remote-jwks-btls diff --git a/test/e2e/testdata/oidc-securitypolicy-backendcluster.yaml b/test/e2e/testdata/oidc-securitypolicy-backendcluster.yaml index 5a264f044f..3b2b64b287 100644 --- a/test/e2e/testdata/oidc-securitypolicy-backendcluster.yaml +++ b/test/e2e/testdata/oidc-securitypolicy-backendcluster.yaml @@ -95,7 +95,7 @@ spec: hostname: 'keycloak.gateway-conformance-infra' port: 443 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: policy-btls diff --git a/test/e2e/testdata/proxy-protocol-with-tls.yaml b/test/e2e/testdata/proxy-protocol-with-tls.yaml index 8272a1c522..8f129374aa 100644 --- a/test/e2e/testdata/proxy-protocol-with-tls.yaml +++ b/test/e2e/testdata/proxy-protocol-with-tls.yaml @@ -105,7 +105,7 @@ spec: hostname: envoy-gateway-conformance-infra-proxy-protocol-gtw-4aabe705.envoy-gateway-system.svc port: 443 --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: btls-proxy-protocol-backend @@ -165,4 +165,3 @@ metadata: name: example-ca namespace: gateway-conformance-infra --- - diff --git a/test/e2e/testdata/ratelimit-usage-ratelimit.yaml b/test/e2e/testdata/ratelimit-usage-ratelimit.yaml index c30323c963..94bc606df0 100644 --- a/test/e2e/testdata/ratelimit-usage-ratelimit.yaml +++ b/test/e2e/testdata/ratelimit-usage-ratelimit.yaml @@ -83,7 +83,7 @@ spec: authorization: defaultAction: Allow --- -apiVersion: gateway.networking.k8s.io/v1 +apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: grpc-ext-proc-btls diff --git a/test/e2e/tests/backend_tls.go b/test/e2e/tests/backend_tls.go index bfed66a7e1..e7300acb42 100644 --- a/test/e2e/tests/backend_tls.go +++ b/test/e2e/tests/backend_tls.go @@ -25,8 +25,13 @@ func init() { var BackendTLSTest = suite.ConformanceTest{ ShortName: "BackendTLS", Description: "Connect to backend with TLS", - Manifests: []string{"testdata/backend-tls.yaml"}, Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + if IsBTLSPolicyV1alpha3() { + suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, "testdata/backend-tls-v1alpha3.yaml", true) + } else { + suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, "testdata/backend-tls.yaml", true) + } + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ConformanceInfraNamespace} t.Run("with a backend TLS Policy", func(t *testing.T) { routeNN := types.NamespacedName{Name: "http-with-backend-tls", Namespace: ConformanceInfraNamespace} diff --git a/test/e2e/tests/utils.go b/test/e2e/tests/utils.go index f0b8dc4fdf..bf943f71f9 100644 --- a/test/e2e/tests/utils.go +++ b/test/e2e/tests/utils.go @@ -54,6 +54,7 @@ var ( IPFamily = os.Getenv("IP_FAMILY") DeployProfile = os.Getenv("KUBE_DEPLOY_PROFILE") enabledClusterTrustBundle = os.Getenv("ENABLE_CLUSTER_TRUST_BUNDLE") + gatewayAPIVersion = os.Getenv("E2E_GATEWAY_API_VERSION") SameNamespaceGateway = types.NamespacedName{Name: "same-namespace", Namespace: ConformanceInfraNamespace} SameNamespaceGatewayRef = k8sutils.NewGatewayRef(SameNamespaceGateway) @@ -751,6 +752,10 @@ func XDSNameSchemeV2() bool { return DeployProfile == "xds-name-scheme-v2" } +func IsBTLSPolicyV1alpha3() bool { + return gatewayAPIVersion == "v1.3.0" +} + func GetGatewayResourceNamespace() string { if IsGatewayNamespaceMode() { return "gateway-conformance-infra" diff --git a/tools/make/kube.mk b/tools/make/kube.mk index d9277b2fa4..9827f0b281 100644 --- a/tools/make/kube.mk +++ b/tools/make/kube.mk @@ -36,8 +36,13 @@ E2E_TIMEOUT ?= 20m # E2E_REDIRECT allow you specified a redirect when run e2e test locally, e.g. `>> test_output.out 2>&1` E2E_REDIRECT ?= E2E_TEST_ARGS ?= -v -tags e2e -timeout $(E2E_TIMEOUT) -# If you want to skip crds version check, add `--allow-crds-mismatch` to E2E_TEST_SUITE_ARGS +# If you want to skip CRD version check, add `--allow-crds-mismatch` to E2E_TEST_SUITE_ARGS. +# This flag is added automatically when E2E_GATEWAY_API_VERSION is set. E2E_TEST_SUITE_ARGS ?= --debug=true +# Add allow-crds-mismatch flag when E2E_GATEWAY_API_VERSION is set to allow testing with different Gateway API versions. +ifneq ($(strip $(E2E_GATEWAY_API_VERSION)),) +E2E_TEST_SUITE_ARGS += --allow-crds-mismatch +endif CONFORMANCE_RUN_TEST ?= CONFORMANCE_TEST_ARGS ?= -v -tags conformance -timeout $(E2E_TIMEOUT) @@ -170,7 +175,17 @@ endif .PHONY: kube-deploy kube-deploy: manifests helm-generate.gateway-helm ## Install Envoy Gateway into the Kubernetes cluster specified in ~/.kube/config. @$(LOG_TARGET) - $(GO_TOOL) helm install eg charts/gateway-helm \ + @set -e; \ + HELM_SKIP_CRDS=""; \ + if [ -n "$(strip $(E2E_GATEWAY_API_VERSION))" ]; then \ + GWAPI_VER="$(strip $(E2E_GATEWAY_API_VERSION))"; \ + GWAPI_URL="https://github.com/kubernetes-sigs/gateway-api/releases/download/$${GWAPI_VER}/experimental-install.yaml"; \ + echo "Installing Gateway API CRDs from $${GWAPI_URL}"; \ + kubectl create -f "$${GWAPI_URL}"; \ + kubectl create -f charts/gateway-helm/crds/generated; \ + HELM_SKIP_CRDS="--skip-crds"; \ + fi; \ + $(GO_TOOL) helm install $$HELM_SKIP_CRDS eg charts/gateway-helm \ --set deployment.envoyGateway.imagePullPolicy=$(IMAGE_PULL_POLICY) \ -n envoy-gateway-system --create-namespace \ --debug --timeout='$(WAIT_TIMEOUT)' \