diff --git a/CHANGELOG.md b/CHANGELOG.md index 8051ecf81d..7e11638e65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,14 @@ Adding a new version? You'll need three changes: inconsistent Service annotations. Previously this issue prevented the controller from applying configuration until corrected. [#2988](https://github.com/Kong/kubernetes-ingress-controller/pull/2988) +- Gateway API has been updated to 0.5.1. That version brought in some changes + in the conformance tests logic. Now, when the TLS config of a listener + references a non-existing secret, the listener ResolvedRefs condition reason + is set to InvalidCertificateRef. In addition, if a TLS config references a + secret in another namespace, and no ReferenceGrant allows that + reference, the listener ResolvedRefs condition reason is set to + RefNotPermitted. + [#3024](https://github.com/Kong/kubernetes-ingress-controller/pull/3024) ## [2.7.0] diff --git a/go.mod b/go.mod index 72561c39e6..84250bfeae 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( knative.dev/networking v0.0.0-20220302134042-e8b2eb995165 knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77 sigs.k8s.io/controller-runtime v0.13.0 - sigs.k8s.io/gateway-api v0.5.0 + sigs.k8s.io/gateway-api v0.5.1 sigs.k8s.io/kustomize/api v0.12.1 sigs.k8s.io/kustomize/kyaml v0.13.9 sigs.k8s.io/yaml v1.3.0 diff --git a/go.sum b/go.sum index 1259eb80ea..329394c215 100644 --- a/go.sum +++ b/go.sum @@ -1465,8 +1465,8 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= -sigs.k8s.io/gateway-api v0.5.0 h1:ze+k9fJqvmL8s1t3e4q1ST8RnN+f09dEv+gfacahlAE= -sigs.k8s.io/gateway-api v0.5.0/go.mod h1:x0AP6gugkFV8fC/oTlnOMU0pnmuzIR8LfIPRVUjxSqA= +sigs.k8s.io/gateway-api v0.5.1 h1:EqzgOKhChzyve9rmeXXbceBYB6xiM50vDfq0kK5qpdw= +sigs.k8s.io/gateway-api v0.5.1/go.mod h1:x0AP6gugkFV8fC/oTlnOMU0pnmuzIR8LfIPRVUjxSqA= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.16.0 h1:GFXyyxtPnHFKqXr3ZG8/X0+0K9sl69lejStlPn2WQyM= diff --git a/internal/controllers/gateway/gateway_controller.go b/internal/controllers/gateway/gateway_controller.go index 851fd58278..b8a7764000 100644 --- a/internal/controllers/gateway/gateway_controller.go +++ b/internal/controllers/gateway/gateway_controller.go @@ -423,7 +423,10 @@ func (r *GatewayReconciler) reconcileUnmanagedGateway(ctx context.Context, log l // a single set of shared listens. We lack knowledge of whether this is compatible with user intent, and it may // be incompatible with the spec, so we should consider evaluating cross-Gateway compatibility and raising error // conditions in the event of a problem - listenerStatuses := getListenerStatus(gateway, kongListeners, referenceGrantList.Items) + listenerStatuses, err := r.getListenerStatus(ctx, gateway, kongListeners, referenceGrantList.Items) + if err != nil { + return ctrl.Result{}, err + } // once specification matches the reference Service, all that's left to do is ensure that the // Gateway status reflects the spec. As the status is simply a mirror of the Service, this is diff --git a/internal/controllers/gateway/gateway_controller_test.go b/internal/controllers/gateway/gateway_controller_test.go index 5b5c5c8fac..9ec9321bfb 100644 --- a/internal/controllers/gateway/gateway_controller_test.go +++ b/internal/controllers/gateway/gateway_controller_test.go @@ -597,7 +597,7 @@ func TestGetReferenceGrantConditionReason(t *testing.T) { }, }, }, - expectedReason: string(gatewayv1alpha2.ListenerReasonInvalidCertificateRef), + expectedReason: string(gatewayv1alpha2.ListenerReasonRefNotPermitted), }, { name: "reference granted, secret name not specified", diff --git a/internal/controllers/gateway/gateway_utils.go b/internal/controllers/gateway/gateway_utils.go index 119fe6fb43..4d33a42cab 100644 --- a/internal/controllers/gateway/gateway_utils.go +++ b/internal/controllers/gateway/gateway_utils.go @@ -1,12 +1,15 @@ package gateway import ( + "context" "fmt" "reflect" "sort" "strings" "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -229,11 +232,12 @@ func canSharePort(requested, existing ProtocolType) bool { } } -func getListenerStatus( +func (r *GatewayReconciler) getListenerStatus( + ctx context.Context, gateway *Gateway, kongListens []Listener, referenceGrants []gatewayv1alpha2.ReferenceGrant, -) []ListenerStatus { +) ([]ListenerStatus, error) { statuses := make(map[SectionName]ListenerStatus, len(gateway.Spec.Listeners)) portToProtocol, portToHostname, listenerToAttached := initializeListenerMaps(gateway) kongProtocolsToPort := buildKongPortMap(kongListens) @@ -398,21 +402,32 @@ func getListenerStatus( if listener.TLS != nil { resolvedRefReason = string(gatewayv1alpha2.ListenerReasonResolvedRefs) for _, certRef := range listener.TLS.CertificateRefs { + // if the certificate is in the same namespace of the gateway, no ReferenceGrant is needed + if certRef.Namespace != nil && *certRef.Namespace != (Namespace)(gateway.Namespace) { + // get the result of the certificate reference. If the returned reason is not successful, the loop + // must be broken because the secret reference isn't granted + resolvedRefReason = getReferenceGrantConditionReason(gateway.Namespace, certRef, referenceGrants) + if resolvedRefReason != string(gatewayv1alpha2.ListenerReasonResolvedRefs) { + break + } + } + // only secrets are supported as certificate references if (certRef.Group != nil && (*certRef.Group != "core" && *certRef.Group != "")) || (certRef.Kind != nil && *certRef.Kind != "Secret") { resolvedRefReason = string(gatewayv1alpha2.ListenerReasonInvalidCertificateRef) break } - // if the certificate is in the same namespace of the gateway, no ReferenceGrant is needed - if certRef.Namespace == nil || *certRef.Namespace == (Namespace)(gateway.Namespace) { - continue + secret := &corev1.Secret{} + secretNamespace := gateway.Namespace + if certRef.Namespace != nil { + secretNamespace = string(*certRef.Namespace) } - // get the result of the certificate reference. If the returned reason is not successful, the loop - // must be broken because a secret reference isn't granted - resolvedRefReason = getReferenceGrantConditionReason(gateway.Namespace, certRef, referenceGrants) - if resolvedRefReason != string(gatewayv1alpha2.ListenerReasonResolvedRefs) { - break + if err := r.Client.Get(ctx, types.NamespacedName{Namespace: secretNamespace, Name: string(certRef.Name)}, secret); err != nil { + if !k8serrors.IsNotFound(err) { + return nil, err + } + resolvedRefReason = string(gatewayv1alpha2.ListenerReasonInvalidCertificateRef) } } } @@ -494,7 +509,7 @@ func getListenerStatus( statusArray = append(statusArray, status) } - return statusArray + return statusArray, nil } // getReferenceGrantConditionReason gets a certRef belonging to a specific listener and a slice of referenceGrants. @@ -534,7 +549,7 @@ func getReferenceGrantConditionReason( } } // if no grants have been found for the reference, return an "InvalidCertificateRef" reason - return string(gatewayv1alpha2.ListenerReasonInvalidCertificateRef) + return string(gatewayv1alpha2.ListenerReasonRefNotPermitted) } // ----------------------------------------------------------------------------- diff --git a/test/consts/zz_generated_gateway.go b/test/consts/zz_generated_gateway.go index 586b85ebe9..962de0cf9d 100644 --- a/test/consts/zz_generated_gateway.go +++ b/test/consts/zz_generated_gateway.go @@ -3,7 +3,7 @@ package consts const ( - GatewayStandardCRDsKustomizeURL = "github.com/kubernetes-sigs/gateway-api/config/crd/?ref=v0.5.0" - GatewayExperimentalCRDsKustomizeURL = "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.5.0" - GatewayRawRepoURL = "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.0" + GatewayStandardCRDsKustomizeURL = "github.com/kubernetes-sigs/gateway-api/config/crd/?ref=v0.5.1" + GatewayExperimentalCRDsKustomizeURL = "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.5.1" + GatewayRawRepoURL = "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1" ) diff --git a/test/integration/tlsroute_test.go b/test/integration/tlsroute_test.go index a6df00f514..f15843cd8b 100644 --- a/test/integration/tlsroute_test.go +++ b/test/integration/tlsroute_test.go @@ -615,7 +615,7 @@ func TestTLSRouteReferenceGrant(t *testing.T) { if ok := util.CheckCondition( status.Conditions, util.ConditionType(gatewayv1alpha2.ListenerConditionResolvedRefs), - util.ConditionReason(gatewayv1alpha2.ListenerReasonInvalidCertificateRef), + util.ConditionReason(gatewayv1alpha2.ListenerReasonRefNotPermitted), metav1.ConditionFalse, gateway.Generation, ); ok {