github.com/cilium/cilium@v1.16.2/operator/pkg/ingress/helpers_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ingress 5 6 import ( 7 "context" 8 "io" 9 "testing" 10 11 "github.com/sirupsen/logrus" 12 "github.com/stretchr/testify/require" 13 networkingv1 "k8s.io/api/networking/v1" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/apimachinery/pkg/runtime" 16 utilruntime "k8s.io/apimachinery/pkg/util/runtime" 17 clientgoscheme "k8s.io/client-go/kubernetes/scheme" 18 "sigs.k8s.io/controller-runtime/pkg/client" 19 "sigs.k8s.io/controller-runtime/pkg/client/fake" 20 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" 21 22 "github.com/cilium/cilium/operator/pkg/model" 23 ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" 24 ) 25 26 func TestIsIngressClassMarkedAsDefault(t *testing.T) { 27 testCases := []struct { 28 desc string 29 ingressClass networkingv1.IngressClass 30 isDefault bool 31 }{ 32 { 33 desc: "Is default IngressClass if annotation is present and set to true", 34 ingressClass: networkingv1.IngressClass{ 35 ObjectMeta: metav1.ObjectMeta{ 36 Namespace: "test", 37 Name: "test", 38 Annotations: map[string]string{ 39 "ingressclass.kubernetes.io/is-default-class": "true", 40 }, 41 }, 42 }, 43 isDefault: true, 44 }, 45 { 46 desc: "Isn't default IngressClass if annotation is present and set to false", 47 ingressClass: networkingv1.IngressClass{ 48 ObjectMeta: metav1.ObjectMeta{ 49 Namespace: "test", 50 Name: "test", 51 Annotations: map[string]string{ 52 "ingressclass.kubernetes.io/is-default-class": "false", 53 }, 54 }, 55 }, 56 isDefault: false, 57 }, 58 { 59 desc: "Isn't default IngressClass if annotation isn't present", 60 ingressClass: networkingv1.IngressClass{ 61 ObjectMeta: metav1.ObjectMeta{ 62 Namespace: "test", 63 Name: "test", 64 Annotations: map[string]string{}, 65 }, 66 }, 67 isDefault: false, 68 }, 69 } 70 for _, tC := range testCases { 71 t.Run(tC.desc, func(t *testing.T) { 72 isDefault, err := isIngressClassMarkedAsDefault(tC.ingressClass) 73 require.NoError(t, err) 74 require.Equal(t, tC.isDefault, isDefault) 75 }) 76 } 77 } 78 79 func TestIsCiliumManagedIngress(t *testing.T) { 80 fakeLogger := logrus.New() 81 fakeLogger.SetOutput(io.Discard) 82 83 testCases := []struct { 84 desc string 85 ingress networkingv1.Ingress 86 fixture []client.Object 87 managed bool 88 }{ 89 { 90 desc: "Marked via IngressClassName", 91 ingress: networkingv1.Ingress{ 92 ObjectMeta: metav1.ObjectMeta{ 93 Namespace: "test", 94 Name: "test", 95 }, 96 Spec: networkingv1.IngressSpec{ 97 IngressClassName: model.AddressOf("cilium"), 98 }, 99 }, 100 fixture: []client.Object{}, 101 managed: true, 102 }, 103 { 104 desc: "Marked via annotation", 105 ingress: networkingv1.Ingress{ 106 ObjectMeta: metav1.ObjectMeta{ 107 Namespace: "test", 108 Name: "test", 109 Annotations: map[string]string{ 110 "kubernetes.io/ingress.class": "cilium", 111 }, 112 }, 113 Spec: networkingv1.IngressSpec{}, 114 }, 115 fixture: []client.Object{}, 116 managed: true, 117 }, 118 { 119 desc: "Legacy ingress class annotation takes presedence over ingressClassName field", 120 ingress: networkingv1.Ingress{ 121 ObjectMeta: metav1.ObjectMeta{ 122 Namespace: "test", 123 Name: "test", 124 Annotations: map[string]string{ 125 "kubernetes.io/ingress.class": "other", 126 }, 127 }, 128 Spec: networkingv1.IngressSpec{ 129 IngressClassName: model.AddressOf("cilium"), 130 }, 131 }, 132 fixture: []client.Object{}, 133 managed: false, 134 }, 135 { 136 desc: "Cilium is default IngressClass and Ingress has no specific class set", 137 ingress: networkingv1.Ingress{ 138 ObjectMeta: metav1.ObjectMeta{ 139 Namespace: "test", 140 Name: "test", 141 }, 142 Spec: networkingv1.IngressSpec{}, 143 }, 144 fixture: []client.Object{ 145 &networkingv1.IngressClass{ 146 ObjectMeta: metav1.ObjectMeta{ 147 Name: "cilium", 148 Annotations: map[string]string{ 149 "ingressclass.kubernetes.io/is-default-class": "true", 150 }, 151 }, 152 }, 153 }, 154 managed: true, 155 }, 156 { 157 desc: "Cilium isn't IngressClass (annotation set to false) and Ingress has no specific class set", 158 ingress: networkingv1.Ingress{ 159 ObjectMeta: metav1.ObjectMeta{ 160 Namespace: "test", 161 Name: "test", 162 }, 163 Spec: networkingv1.IngressSpec{}, 164 }, 165 fixture: []client.Object{ 166 &networkingv1.IngressClass{ 167 ObjectMeta: metav1.ObjectMeta{ 168 Name: "cilium", 169 Annotations: map[string]string{ 170 "ingressclass.kubernetes.io/is-default-class": "false", 171 }, 172 }, 173 }, 174 }, 175 managed: false, 176 }, 177 { 178 desc: "Cilium isn't IngressClass (annotation missconfigured) and Ingress has no specific class set", 179 ingress: networkingv1.Ingress{ 180 ObjectMeta: metav1.ObjectMeta{ 181 Namespace: "test", 182 Name: "test", 183 }, 184 Spec: networkingv1.IngressSpec{}, 185 }, 186 fixture: []client.Object{ 187 &networkingv1.IngressClass{ 188 ObjectMeta: metav1.ObjectMeta{ 189 Name: "cilium", 190 Annotations: map[string]string{ 191 "ingressclass.kubernetes.io/is-default-class": "wrong-bool", 192 }, 193 }, 194 }, 195 }, 196 managed: false, 197 }, 198 { 199 desc: "Cilium isn't IngressClass (annotation not present) and Ingress has no specific class set", 200 ingress: networkingv1.Ingress{ 201 ObjectMeta: metav1.ObjectMeta{ 202 Namespace: "test", 203 Name: "test", 204 }, 205 Spec: networkingv1.IngressSpec{}, 206 }, 207 fixture: []client.Object{ 208 &networkingv1.IngressClass{ 209 ObjectMeta: metav1.ObjectMeta{ 210 Name: "cilium", 211 Annotations: map[string]string{}, 212 }, 213 }, 214 }, 215 managed: false, 216 }, 217 { 218 desc: "Cilium is default IngressClass but Ingress has set another specific Ingress class", 219 ingress: networkingv1.Ingress{ 220 ObjectMeta: metav1.ObjectMeta{ 221 Namespace: "test", 222 Name: "test", 223 }, 224 Spec: networkingv1.IngressSpec{ 225 IngressClassName: model.AddressOf("other"), 226 }, 227 }, 228 fixture: []client.Object{ 229 &networkingv1.IngressClass{ 230 ObjectMeta: metav1.ObjectMeta{ 231 Name: "cilium", 232 Annotations: map[string]string{ 233 "ingressclass.kubernetes.io/is-default-class": "true", 234 }, 235 }, 236 }, 237 }, 238 managed: false, 239 }, 240 } 241 for _, tC := range testCases { 242 t.Run(tC.desc, func(t *testing.T) { 243 fakeClient := fake.NewClientBuilder(). 244 WithScheme(testScheme()). 245 WithObjects(tC.fixture...). 246 Build() 247 248 isManaged := isCiliumManagedIngress(context.Background(), fakeClient, fakeLogger, tC.ingress) 249 require.Equal(t, tC.managed, isManaged) 250 }) 251 } 252 } 253 254 func testScheme() *runtime.Scheme { 255 scheme := runtime.NewScheme() 256 257 utilruntime.Must(clientgoscheme.AddToScheme(scheme)) 258 utilruntime.Must(ciliumv2.AddToScheme(scheme)) 259 utilruntime.Must(gatewayv1.AddToScheme(scheme)) 260 261 return scheme 262 }