// Copyright 2020-2023 Project Capsule Authors. // SPDX-License-Identifier: Apache-2.0 package e2e import ( "context" "fmt" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" networkingv1 "k8s.io/api/networking/v1" networkingv1beta1 "k8s.io/api/networking/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2" "github.com/projectcapsule/capsule/pkg/utils" ) var _ = Describe("creating an Ingress with a wildcard when it is denied for the Tenant", Label("tenant"), func() { tnt := &capsulev1beta2.Tenant{ ObjectMeta: metav1.ObjectMeta{ Name: "denied-ingress-wildcard", Annotations: map[string]string{ "capsule.clastix.io/deny-wildcard": "true", }, }, Spec: capsulev1beta2.TenantSpec{ Owners: capsulev1beta2.OwnerListSpec{ { Name: "scott", Kind: "User", }, }, }, } JustBeforeEach(func() { EventuallyCreation(func() error { tnt.ResourceVersion = "" return k8sClient.Create(context.TODO(), tnt) }).Should(Succeed()) }) JustAfterEach(func() { Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed()) }) It("should fail creating an extensions/v1beta1 Ingress with a wildcard hostname", func() { if err := k8sClient.List(context.Background(), &extensionsv1beta1.IngressList{}); err != nil { if utils.IsUnsupportedAPI(err) { Skip(fmt.Sprintf("Running test due to unsupported API kind: %s", err.Error())) } } ns := NewNamespace("") NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) ok := &extensionsv1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ok", Namespace: ns.GetName(), }, Spec: extensionsv1beta1.IngressSpec{ Rules: []extensionsv1beta1.IngressRule{ { Host: "clastix.io", IngressRuleValue: extensionsv1beta1.IngressRuleValue{ HTTP: &extensionsv1beta1.HTTPIngressRuleValue{ Paths: []extensionsv1beta1.HTTPIngressPath{ { Path: "/", PathType: func(v extensionsv1beta1.PathType) *extensionsv1beta1.PathType { return &v }(extensionsv1beta1.PathTypeExact), Backend: extensionsv1beta1.IngressBackend{ ServiceName: "foo", ServicePort: intstr.FromInt(8080), }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ok) }).Should(Succeed()) ko := &extensionsv1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ko", Namespace: ns.GetName(), }, Spec: extensionsv1beta1.IngressSpec{ Rules: []extensionsv1beta1.IngressRule{ { Host: "*.clastix.io", IngressRuleValue: extensionsv1beta1.IngressRuleValue{ HTTP: &extensionsv1beta1.HTTPIngressRuleValue{ Paths: []extensionsv1beta1.HTTPIngressPath{ { Path: "/", PathType: func(v extensionsv1beta1.PathType) *extensionsv1beta1.PathType { return &v }(extensionsv1beta1.PathTypeExact), Backend: extensionsv1beta1.IngressBackend{ ServiceName: "foo", ServicePort: intstr.FromInt(8080), }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ko) }).ShouldNot(Succeed()) }) It("should fail creating an networking.k8s.io/v1beta1 Ingress with a wildcard hostname", func() { if err := k8sClient.List(context.Background(), &networkingv1beta1.IngressList{}); err != nil { if utils.IsUnsupportedAPI(err) { Skip(fmt.Sprintf("Running test due to unsupported API kind: %s", err.Error())) } } ns := NewNamespace("") NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) ok := &networkingv1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ok", Namespace: ns.GetName(), }, Spec: networkingv1beta1.IngressSpec{ Rules: []networkingv1beta1.IngressRule{ { Host: "clastix.io", IngressRuleValue: networkingv1beta1.IngressRuleValue{ HTTP: &networkingv1beta1.HTTPIngressRuleValue{ Paths: []networkingv1beta1.HTTPIngressPath{ { Path: "/", PathType: func(v networkingv1beta1.PathType) *networkingv1beta1.PathType { return &v }(networkingv1beta1.PathTypeExact), Backend: networkingv1beta1.IngressBackend{ ServiceName: "foo", ServicePort: intstr.FromInt(8080), }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ok) }).Should(Succeed()) ko := &extensionsv1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ko", Namespace: ns.GetName(), }, Spec: extensionsv1beta1.IngressSpec{ Rules: []extensionsv1beta1.IngressRule{ { Host: "*.clastix.io", IngressRuleValue: extensionsv1beta1.IngressRuleValue{ HTTP: &extensionsv1beta1.HTTPIngressRuleValue{ Paths: []extensionsv1beta1.HTTPIngressPath{ { Path: "/", PathType: func(v extensionsv1beta1.PathType) *extensionsv1beta1.PathType { return &v }(extensionsv1beta1.PathTypeExact), Backend: extensionsv1beta1.IngressBackend{ ServiceName: "foo", ServicePort: intstr.FromInt(8080), }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ko) }).ShouldNot(Succeed()) }) It("should fail creating an networking.k8s.io/v1 Ingress with a wildcard hostname", func() { if err := k8sClient.List(context.Background(), &networkingv1.IngressList{}); err != nil { if utils.IsUnsupportedAPI(err) { Skip(fmt.Sprintf("Running test due to unsupported API kind: %s", err.Error())) } } ns := NewNamespace("") NamespaceCreation(ns, tnt.Spec.Owners[0], defaultTimeoutInterval).Should(Succeed()) ok := &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ok", Namespace: ns.GetName(), }, Spec: networkingv1.IngressSpec{ Rules: []networkingv1.IngressRule{ { Host: "clastix.io", IngressRuleValue: networkingv1.IngressRuleValue{ HTTP: &networkingv1.HTTPIngressRuleValue{ Paths: []networkingv1.HTTPIngressPath{ { Path: "/", PathType: func(v networkingv1.PathType) *networkingv1.PathType { return &v }(networkingv1.PathTypeExact), Backend: networkingv1.IngressBackend{ Service: &networkingv1.IngressServiceBackend{ Name: "foo", Port: networkingv1.ServiceBackendPort{ Number: 8080, }, }, }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ok) }).Should(Succeed()) ko := &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "ingress-ko", Namespace: ns.GetName(), }, Spec: networkingv1.IngressSpec{ Rules: []networkingv1.IngressRule{ { Host: "*.clastix.io", IngressRuleValue: networkingv1.IngressRuleValue{ HTTP: &networkingv1.HTTPIngressRuleValue{ Paths: []networkingv1.HTTPIngressPath{ { Path: "/", PathType: func(v networkingv1.PathType) *networkingv1.PathType { return &v }(networkingv1.PathTypeExact), Backend: networkingv1.IngressBackend{ Service: &networkingv1.IngressServiceBackend{ Name: "foo", Port: networkingv1.ServiceBackendPort{ Number: 8080, }, }, }, }, }, }, }, }, }, }, } EventuallyCreation(func() error { return k8sClient.Create(context.Background(), ko) }).ShouldNot(Succeed()) }) })