diff --git a/controllers/authpolicy_authconfig.go b/controllers/authpolicy_authconfig.go index 8c4265f90..fa8efd8f6 100644 --- a/controllers/authpolicy_authconfig.go +++ b/controllers/authpolicy_authconfig.go @@ -74,7 +74,7 @@ func (r *AuthPolicyReconciler) desiredAuthConfig(ctx context.Context, ap *api.Au // that do not have an authpolicy of its own, so we can generate wasm rules for those cases gw := common.GatewayWrapper{Gateway: obj} gwHostnames := gw.Hostnames() - if len(hosts) == 0 { + if len(gwHostnames) == 0 { gwHostnames = []gatewayapiv1.Hostname{"*"} } hosts = common.HostnamesToStrings(gwHostnames) diff --git a/controllers/authpolicy_controller_test.go b/controllers/authpolicy_controller_test.go index 3d1fd7d28..e25d068ed 100644 --- a/controllers/authpolicy_controller_test.go +++ b/controllers/authpolicy_controller_test.go @@ -5,6 +5,7 @@ package controllers import ( "context" "encoding/json" + "fmt" "path/filepath" "strings" "time" @@ -43,11 +44,7 @@ var _ = Describe("AuthPolicy controller", func() { err := k8sClient.Create(context.Background(), gateway) Expect(err).ToNot(HaveOccurred()) - Eventually(func() bool { - existingGateway := &gatewayapiv1.Gateway{} - err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) - return err == nil && meta.IsStatusConditionTrue(existingGateway.Status.Conditions, common.GatewayProgrammedConditionType) - }, 15*time.Second, 5*time.Second).Should(BeTrue()) + Eventually(testGatewayIsReady(gateway), 15*time.Second, 5*time.Second).Should(BeTrue()) ApplyKuadrantCR(testNamespace) }) @@ -116,7 +113,7 @@ var _ = Describe("AuthPolicy controller", func() { Eventually(func() bool { err := k8sClient.Get(context.Background(), authConfigKey, authConfig) logf.Log.V(1).Info("Fetching Authorino's AuthConfig", "key", authConfigKey.String(), "error", err) - return err == nil || authConfig.Status.Ready() + return err == nil && authConfig.Status.Ready() }, 2*time.Minute, 5*time.Second).Should(BeTrue()) logf.Log.V(1).Info("authConfig.Spec", "hosts", authConfig.Spec.Hosts, "conditions", authConfig.Spec.Conditions) Expect(authConfig.Spec.Hosts).To(Equal([]string{"*"})) @@ -132,6 +129,62 @@ var _ = Describe("AuthPolicy controller", func() { Expect(authConfig.Spec.Conditions[0].Any[0].Any[0].All[1].Value).To(Equal("/toy.*")) }) + It("Attaches policy to a Gateway with hostname in listeners", func() { + gatewayName := fmt.Sprintf("%s-with-hostnames", testGatewayName) + gateway := testBuildBasicGateway(gatewayName, testNamespace) + Expect(gateway.Spec.Listeners).To(HaveLen(1)) + // Set hostname + gateway.Spec.Listeners[0].Hostname = &[]gatewayapiv1.Hostname{"*.example.com"}[0] + err := k8sClient.Create(context.Background(), gateway) + Expect(err).ToNot(HaveOccurred()) + + Eventually(testGatewayIsReady(gateway), 15*time.Second, 5*time.Second).Should(BeTrue()) + + routeName := fmt.Sprintf("%s-with-hostnames", testHTTPRouteName) + route := testBuildBasicHttpRoute(routeName, gatewayName, testNamespace, []string{"*.api.example.com"}) + err = k8sClient.Create(context.Background(), route) + Expect(err).ToNot(HaveOccurred()) + Eventually(func() bool { + existingRoute := &gatewayapiv1.HTTPRoute{} + err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(route), existingRoute) + return err == nil && common.IsHTTPRouteAccepted(existingRoute) + }, 15*time.Second, 5*time.Second).Should(BeTrue()) + + policy := &api.AuthPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "gw-auth", + Namespace: testNamespace, + }, + Spec: api.AuthPolicySpec{ + TargetRef: gatewayapiv1alpha2.PolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: gatewayapiv1.ObjectName(gatewayName), + Namespace: ptr.To(gatewayapiv1.Namespace(testNamespace)), + }, + AuthScheme: testBasicAuthScheme(), + }, + } + + err = k8sClient.Create(context.Background(), policy) + logf.Log.V(1).Info("Creating AuthPolicy", "key", client.ObjectKeyFromObject(policy).String(), "error", err) + Expect(err).ToNot(HaveOccurred()) + + // check policy status + Eventually(testPolicyIsReady(policy), 60*time.Second, 5*time.Second).Should(BeTrue()) + + // check authorino authconfig hosts + authConfigKey := types.NamespacedName{Name: authConfigName(client.ObjectKeyFromObject(policy)), Namespace: testNamespace} + authConfig := &authorinoapi.AuthConfig{} + Eventually(func() bool { + err := k8sClient.Get(context.Background(), authConfigKey, authConfig) + logf.Log.V(1).Info("Fetching Authorino's AuthConfig", "key", authConfigKey.String(), "error", err) + return err == nil && authConfig.Status.Ready() + }, 2*time.Minute, 5*time.Second).Should(BeTrue()) + + Expect(authConfig.Spec.Hosts).To(ConsistOf("*.example.com")) + }) + It("Attaches policy to the HTTPRoute", func() { policy := &api.AuthPolicy{ ObjectMeta: metav1.ObjectMeta{ @@ -275,7 +328,7 @@ var _ = Describe("AuthPolicy controller", func() { Eventually(func() bool { err := k8sClient.Get(context.Background(), authConfigKey, authConfig) logf.Log.V(1).Info("Fetching Authorino's AuthConfig", "key", authConfigKey.String(), "error", err) - return err == nil || authConfig.Status.Ready() + return err == nil && authConfig.Status.Ready() }, 2*time.Minute, 5*time.Second).Should(BeTrue()) logf.Log.V(1).Info("authConfig.Spec", "hosts", authConfig.Spec.Hosts, "conditions", authConfig.Spec.Conditions) Expect(authConfig.Spec.Hosts).To(Equal([]string{"*"})) @@ -844,7 +897,7 @@ var _ = Describe("AuthPolicy controller", func() { Eventually(func() bool { err := k8sClient.Get(context.Background(), authConfigKey, authConfig) logf.Log.V(1).Info("Fetching Authorino's AuthConfig", "key", authConfigKey.String(), "error", err) - return err == nil || authConfig.Status.Ready() + return err == nil && authConfig.Status.Ready() }, 2*time.Minute, 5*time.Second).Should(BeTrue()) logf.Log.V(1).Info("authConfig.Spec", "hosts", authConfig.Spec.Hosts, "conditions", authConfig.Spec.Conditions) Expect(authConfig.Spec.Hosts).To(Equal([]string{"*.toystore.com", "*.admin.toystore.com"})) @@ -1246,6 +1299,14 @@ func testBasicAuthScheme() api.AuthSchemeSpec { } } +func testGatewayIsReady(gateway *gatewayapiv1.Gateway) func() bool { + return func() bool { + existingGateway := &gatewayapiv1.Gateway{} + err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(gateway), existingGateway) + return err == nil && meta.IsStatusConditionTrue(existingGateway.Status.Conditions, common.GatewayProgrammedConditionType) + } +} + func testPolicyIsReady(policy *api.AuthPolicy) func() bool { return func() bool { existingPolicy := &api.AuthPolicy{}