github.com/cilium/cilium@v1.16.2/operator/pkg/ingress/annotations/annotations_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package annotations 5 6 import ( 7 "reflect" 8 "testing" 9 "time" 10 11 networkingv1 "k8s.io/api/networking/v1" 12 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 14 "github.com/cilium/cilium/operator/pkg/model" 15 ) 16 17 func TestGetAnnotationServiceType(t *testing.T) { 18 type args struct { 19 ingress *networkingv1.Ingress 20 } 21 tests := []struct { 22 name string 23 args args 24 want string 25 }{ 26 { 27 name: "no service type annotation", 28 args: args{ 29 ingress: &networkingv1.Ingress{}, 30 }, 31 want: "LoadBalancer", 32 }, 33 { 34 name: "service type annotation as LoadBalancer", 35 args: args{ 36 ingress: &networkingv1.Ingress{ 37 ObjectMeta: metav1.ObjectMeta{ 38 Annotations: map[string]string{ 39 "ingress.cilium.io/service-type": "LoadBalancer", 40 }, 41 }, 42 }, 43 }, 44 want: "LoadBalancer", 45 }, 46 { 47 name: "service type annotation as NodePort", 48 args: args{ 49 ingress: &networkingv1.Ingress{ 50 ObjectMeta: metav1.ObjectMeta{ 51 Annotations: map[string]string{ 52 "ingress.cilium.io/service-type": "NodePort", 53 }, 54 }, 55 }, 56 }, 57 want: "NodePort", 58 }, 59 } 60 for _, tt := range tests { 61 t.Run(tt.name, func(t *testing.T) { 62 if got := GetAnnotationServiceType(tt.args.ingress); got != tt.want { 63 t.Errorf("GetAnnotationServiceType() = %v, want %v", got, tt.want) 64 } 65 }) 66 } 67 } 68 69 func TestGetAnnotationServiceExternalTrafficPolicy(t *testing.T) { 70 type args struct { 71 ingress *networkingv1.Ingress 72 } 73 tests := []struct { 74 name string 75 args args 76 want string 77 wantErr bool 78 }{ 79 { 80 name: "no externalTrafficPolicy annotation", 81 args: args{ 82 ingress: &networkingv1.Ingress{}, 83 }, 84 want: "Cluster", 85 }, 86 { 87 name: "externalTrafficPolicy as Cluster", 88 args: args{ 89 ingress: &networkingv1.Ingress{ 90 ObjectMeta: metav1.ObjectMeta{ 91 Annotations: map[string]string{ 92 "ingress.cilium.io/service-external-traffic-policy": "Cluster", 93 }, 94 }, 95 }, 96 }, 97 want: "Cluster", 98 }, 99 { 100 name: "externalTrafficPolicy as Local", 101 args: args{ 102 ingress: &networkingv1.Ingress{ 103 ObjectMeta: metav1.ObjectMeta{ 104 Annotations: map[string]string{ 105 "ingress.cilium.io/service-external-traffic-policy": "Local", 106 }, 107 }, 108 }, 109 }, 110 want: "Local", 111 }, 112 { 113 name: "externalTrafficPolicy set to invalid value", 114 args: args{ 115 ingress: &networkingv1.Ingress{ 116 ObjectMeta: metav1.ObjectMeta{ 117 Annotations: map[string]string{ 118 "ingress.cilium.io/service-external-traffic-policy": "invalid-value", 119 }, 120 }, 121 }, 122 }, 123 want: "Cluster", 124 wantErr: true, 125 }, 126 } 127 for _, tt := range tests { 128 t.Run(tt.name, func(t *testing.T) { 129 got, err := GetAnnotationServiceExternalTrafficPolicy(tt.args.ingress) 130 if (err != nil) != tt.wantErr { 131 t.Errorf("GetAnnotationServiceExternalTrafficPolicy() error = %v, wantErr %v", err, tt.wantErr) 132 return 133 } 134 if !reflect.DeepEqual(got, tt.want) { 135 t.Errorf("GetAnnotationServiceExternalTrafficPolicy() got = %v, want %v", got, tt.want) 136 } 137 }) 138 } 139 } 140 141 func TestGetAnnotationRequestTimeout(t *testing.T) { 142 type args struct { 143 ingress *networkingv1.Ingress 144 } 145 146 tests := []struct { 147 name string 148 args args 149 want *time.Duration 150 wantErr bool 151 }{ 152 { 153 name: "no request timeout annotation", 154 args: args{ 155 ingress: &networkingv1.Ingress{}, 156 }, 157 want: nil, 158 }, 159 { 160 name: "request timeout annotation with valid value", 161 args: args{ 162 ingress: &networkingv1.Ingress{ 163 ObjectMeta: metav1.ObjectMeta{ 164 Annotations: map[string]string{ 165 RequestTimeoutAnnotation: "10s", 166 }, 167 }, 168 }, 169 }, 170 want: model.AddressOf(time.Second * 10), 171 }, 172 { 173 name: "request timeout annotation with invalid value", 174 args: args{ 175 ingress: &networkingv1.Ingress{ 176 ObjectMeta: metav1.ObjectMeta{ 177 Annotations: map[string]string{ 178 RequestTimeoutAnnotation: "invalid", 179 }, 180 }, 181 }, 182 }, 183 want: nil, 184 wantErr: true, 185 }, 186 } 187 188 for _, tt := range tests { 189 t.Run(tt.name, func(t *testing.T) { 190 got, err := GetAnnotationRequestTimeout(tt.args.ingress) 191 if (err != nil) != tt.wantErr { 192 t.Errorf("GetAnnotationRequestTimeout() error = %v, wantErr %v", err, tt.wantErr) 193 return 194 } 195 196 if !reflect.DeepEqual(got, tt.want) { 197 t.Errorf("GetAnnotationRequestTimeout() got = %v, want %v", got, tt.want) 198 } 199 }) 200 } 201 } 202 203 func TestGetAnnotationSecureNodePort(t *testing.T) { 204 type args struct { 205 ingress *networkingv1.Ingress 206 } 207 tests := []struct { 208 name string 209 args args 210 want *uint32 211 wantErr bool 212 }{ 213 { 214 name: "no secure node port annotation", 215 args: args{ 216 ingress: &networkingv1.Ingress{}, 217 }, 218 want: nil, 219 }, 220 { 221 name: "secure node port annotation with valid value", 222 args: args{ 223 ingress: &networkingv1.Ingress{ 224 ObjectMeta: metav1.ObjectMeta{ 225 Annotations: map[string]string{ 226 "ingress.cilium.io/secure-node-port": "1000", 227 }, 228 }, 229 }, 230 }, 231 want: uint32p(1000), 232 }, 233 { 234 name: "secure node port annotation with invalid value", 235 args: args{ 236 ingress: &networkingv1.Ingress{ 237 ObjectMeta: metav1.ObjectMeta{ 238 Annotations: map[string]string{ 239 "ingress.cilium.io/secure-node-port": "invalid-numeric-value", 240 }, 241 }, 242 }, 243 }, 244 want: nil, 245 wantErr: true, 246 }, 247 } 248 249 for _, tt := range tests { 250 t.Run(tt.name, func(t *testing.T) { 251 got, err := GetAnnotationSecureNodePort(tt.args.ingress) 252 if (err != nil) != tt.wantErr { 253 t.Errorf("GetAnnotationSecureNodePort() error = %v, wantErr %v", err, tt.wantErr) 254 return 255 } 256 if !reflect.DeepEqual(got, tt.want) { 257 t.Errorf("GetAnnotationSecureNodePort() got = %v, want %v", got, tt.want) 258 } 259 }) 260 } 261 } 262 263 func TestGetAnnotationInsecureNodePort(t *testing.T) { 264 type args struct { 265 ingress *networkingv1.Ingress 266 } 267 tests := []struct { 268 name string 269 args args 270 want *uint32 271 wantErr bool 272 }{ 273 { 274 name: "no insecure node port annotation", 275 args: args{ 276 ingress: &networkingv1.Ingress{}, 277 }, 278 want: nil, 279 }, 280 { 281 name: "insecure node port annotation with valid value", 282 args: args{ 283 ingress: &networkingv1.Ingress{ 284 ObjectMeta: metav1.ObjectMeta{ 285 Annotations: map[string]string{ 286 "ingress.cilium.io/insecure-node-port": "1000", 287 }, 288 }, 289 }, 290 }, 291 want: uint32p(1000), 292 }, 293 { 294 name: "insecure node port annotation with invalid value", 295 args: args{ 296 ingress: &networkingv1.Ingress{ 297 ObjectMeta: metav1.ObjectMeta{ 298 Annotations: map[string]string{ 299 "ingress.cilium.io/insecure-node-port": "invalid-numeric-value", 300 }, 301 }, 302 }, 303 }, 304 want: nil, 305 wantErr: true, 306 }, 307 } 308 for _, tt := range tests { 309 t.Run(tt.name, func(t *testing.T) { 310 got, err := GetAnnotationInsecureNodePort(tt.args.ingress) 311 if (err != nil) != tt.wantErr { 312 t.Errorf("GetAnnotationSecureNodePort() error = %v, wantErr %v", err, tt.wantErr) 313 return 314 } 315 if !reflect.DeepEqual(got, tt.want) { 316 t.Errorf("GetAnnotationSecureNodePort() got = %v, want %v", got, tt.want) 317 } 318 }) 319 } 320 } 321 322 func TestGetAnnotationHostListenerPort(t *testing.T) { 323 type args struct { 324 ingress *networkingv1.Ingress 325 } 326 tests := []struct { 327 name string 328 args args 329 want *uint32 330 wantErr bool 331 }{ 332 { 333 name: "no host listener port annotation", 334 args: args{ 335 ingress: &networkingv1.Ingress{}, 336 }, 337 want: nil, 338 }, 339 { 340 name: "host listener port annotation with valid value", 341 args: args{ 342 ingress: &networkingv1.Ingress{ 343 ObjectMeta: metav1.ObjectMeta{ 344 Annotations: map[string]string{ 345 "ingress.cilium.io/host-listener-port": "1000", 346 }, 347 }, 348 }, 349 }, 350 want: uint32p(1000), 351 }, 352 { 353 name: "host listener port annotation with invalid non-numeric value", 354 args: args{ 355 ingress: &networkingv1.Ingress{ 356 ObjectMeta: metav1.ObjectMeta{ 357 Annotations: map[string]string{ 358 "ingress.cilium.io/host-listener-port": "invalid-numeric-value", 359 }, 360 }, 361 }, 362 }, 363 want: nil, 364 wantErr: true, 365 }, 366 } 367 368 for _, tt := range tests { 369 t.Run(tt.name, func(t *testing.T) { 370 got, err := GetAnnotationHostListenerPort(tt.args.ingress) 371 if (err != nil) != tt.wantErr { 372 t.Errorf("GetAnnotationHostListenerPort() error = %v, wantErr %v", err, tt.wantErr) 373 return 374 } 375 if !reflect.DeepEqual(got, tt.want) { 376 t.Errorf("GetAnnotationHostListenerPort() got = %v, want %v", got, tt.want) 377 } 378 }) 379 } 380 } 381 382 func TestGetAnnotationSSLPassthrough(t *testing.T) { 383 type args struct { 384 ingress *networkingv1.Ingress 385 } 386 tests := []struct { 387 name string 388 args args 389 want bool 390 }{ 391 { 392 name: "no SSL Passthrough port annotation", 393 args: args{ 394 ingress: &networkingv1.Ingress{}, 395 }, 396 want: false, 397 }, 398 { 399 name: "SSL Passthrough annotation present and enabled", 400 args: args{ 401 ingress: &networkingv1.Ingress{ 402 ObjectMeta: metav1.ObjectMeta{ 403 Annotations: map[string]string{ 404 "ingress.cilium.io/tls-passthrough": "enabled", 405 }, 406 }, 407 }, 408 }, 409 want: true, 410 }, 411 { 412 name: "SSL Passthrough annotation present and disabled", 413 args: args{ 414 ingress: &networkingv1.Ingress{ 415 ObjectMeta: metav1.ObjectMeta{ 416 Annotations: map[string]string{ 417 "ingress.cilium.io/tls-passthrough": "disabled", 418 }, 419 }, 420 }, 421 }, 422 want: false, 423 }, 424 { 425 name: "SSL Passthrough annotation present and true", 426 args: args{ 427 ingress: &networkingv1.Ingress{ 428 ObjectMeta: metav1.ObjectMeta{ 429 Annotations: map[string]string{ 430 "ingress.cilium.io/tls-passthrough": "true", 431 }, 432 }, 433 }, 434 }, 435 want: true, 436 }, 437 { 438 name: "SSL Passthrough annotation present and false", 439 args: args{ 440 ingress: &networkingv1.Ingress{ 441 ObjectMeta: metav1.ObjectMeta{ 442 Annotations: map[string]string{ 443 "ingress.cilium.io/tls-passthrough": "false", 444 }, 445 }, 446 }, 447 }, 448 want: false, 449 }, 450 { 451 name: "SSL Passthrough annotation present and invalid", 452 args: args{ 453 ingress: &networkingv1.Ingress{ 454 ObjectMeta: metav1.ObjectMeta{ 455 Annotations: map[string]string{ 456 "ingress.cilium.io/tls-passthrough": "invalid", 457 }, 458 }, 459 }, 460 }, 461 want: false, 462 }, 463 } 464 for _, tt := range tests { 465 t.Run(tt.name, func(t *testing.T) { 466 got := GetAnnotationTLSPassthroughEnabled(tt.args.ingress) 467 468 if !reflect.DeepEqual(got, tt.want) { 469 t.Errorf("GetAnnotationSecureNodePort() got = %v, want %v", got, tt.want) 470 } 471 }) 472 } 473 } 474 475 func TestGetAnnotationEnforceHTTPSEnabled(t *testing.T) { 476 type args struct { 477 ingress *networkingv1.Ingress 478 } 479 480 tests := []struct { 481 name string 482 args args 483 want *bool 484 }{ 485 { 486 name: "no SSL Passthrough port annotation", 487 args: args{ 488 ingress: &networkingv1.Ingress{}, 489 }, 490 want: nil, 491 }, 492 { 493 name: "SSL Passthrough annotation present and enabled", 494 args: args{ 495 ingress: &networkingv1.Ingress{ 496 ObjectMeta: metav1.ObjectMeta{ 497 Annotations: map[string]string{ 498 "ingress.cilium.io/force-https": "enabled", 499 }, 500 }, 501 }, 502 }, 503 want: model.AddressOf(true), 504 }, 505 { 506 name: "SSL Passthrough annotation present and disabled", 507 args: args{ 508 ingress: &networkingv1.Ingress{ 509 ObjectMeta: metav1.ObjectMeta{ 510 Annotations: map[string]string{ 511 "ingress.cilium.io/force-https": "disabled", 512 }, 513 }, 514 }, 515 }, 516 want: model.AddressOf(false), 517 }, 518 { 519 name: "SSL Passthrough annotation present and true", 520 args: args{ 521 ingress: &networkingv1.Ingress{ 522 ObjectMeta: metav1.ObjectMeta{ 523 Annotations: map[string]string{ 524 "ingress.cilium.io/force-https": "true", 525 }, 526 }, 527 }, 528 }, 529 want: model.AddressOf(true), 530 }, 531 { 532 name: "SSL Passthrough annotation present and false", 533 args: args{ 534 ingress: &networkingv1.Ingress{ 535 ObjectMeta: metav1.ObjectMeta{ 536 Annotations: map[string]string{ 537 "ingress.cilium.io/force-https": "false", 538 }, 539 }, 540 }, 541 }, 542 want: model.AddressOf(false), 543 }, 544 { 545 name: "SSL Passthrough annotation present and invalid", 546 args: args{ 547 ingress: &networkingv1.Ingress{ 548 ObjectMeta: metav1.ObjectMeta{ 549 Annotations: map[string]string{ 550 "ingress.cilium.io/force-https": "invalid", 551 }, 552 }, 553 }, 554 }, 555 want: nil, 556 }, 557 } 558 for _, tt := range tests { 559 t.Run(tt.name, func(t *testing.T) { 560 got := GetAnnotationForceHTTPSEnabled(tt.args.ingress) 561 if !reflect.DeepEqual(got, tt.want) { 562 t.Errorf("GetAnnotationForceHTTPSEnabled() got = %v, want %v", got, tt.want) 563 } 564 }) 565 } 566 } 567 568 func TestGetAnnotationLoadBalancerClass(t *testing.T) { 569 type args struct { 570 ingress *networkingv1.Ingress 571 } 572 tests := []struct { 573 name string 574 args args 575 want *string 576 }{ 577 { 578 name: "no load balancer class annotation", 579 args: args{ 580 ingress: &networkingv1.Ingress{}, 581 }, 582 want: nil, 583 }, 584 { 585 name: "load balancer class annotation present", 586 args: args{ 587 ingress: &networkingv1.Ingress{ 588 ObjectMeta: metav1.ObjectMeta{ 589 Annotations: map[string]string{ 590 "ingress.cilium.io/loadbalancer-class": "foo", 591 }, 592 }, 593 }, 594 }, 595 want: stringp("foo"), 596 }, 597 } 598 for _, tt := range tests { 599 t.Run(tt.name, func(t *testing.T) { 600 got := GetAnnotationLoadBalancerClass(tt.args.ingress) 601 if !isStringpEqual(got, tt.want) { 602 t.Errorf("GetAnnotationLoadBalancerClass() = %v, want %v", got, tt.want) 603 } 604 }) 605 } 606 } 607 608 func uint32p(u uint32) *uint32 { 609 return &u 610 } 611 612 func stringp(s string) *string { 613 return &s 614 } 615 616 func isStringpEqual(a, b *string) bool { 617 if a == nil && b == nil { 618 return true 619 } 620 if a == nil || b == nil { 621 return false 622 } 623 return *a == *b 624 }