github.com/cilium/cilium@v1.16.2/pkg/k8s/factory_functions_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package k8s 5 6 import ( 7 "fmt" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/require" 12 core_v1 "k8s.io/api/core/v1" 13 networkingv1 "k8s.io/api/networking/v1" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/client-go/tools/cache" 16 17 "github.com/cilium/cilium/api/v1/models" 18 "github.com/cilium/cilium/pkg/annotation" 19 v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" 20 slim_corev1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1" 21 slim_metav1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1" 22 "github.com/cilium/cilium/pkg/k8s/types" 23 "github.com/cilium/cilium/pkg/labels" 24 "github.com/cilium/cilium/pkg/policy/api" 25 ) 26 27 var ( 28 unknownObj = 100 29 unknownObjErr = fmt.Errorf("unknown object type %T", unknownObj) 30 ) 31 32 func Test_EqualV2CNP(t *testing.T) { 33 type args struct { 34 o1 *types.SlimCNP 35 o2 *types.SlimCNP 36 } 37 tests := []struct { 38 name string 39 args args 40 want bool 41 }{ 42 { 43 name: "CNP with the same name", 44 args: args{ 45 o1: &types.SlimCNP{ 46 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 47 ObjectMeta: metav1.ObjectMeta{ 48 Name: "rule1", 49 }, 50 }, 51 }, 52 o2: &types.SlimCNP{ 53 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 54 ObjectMeta: metav1.ObjectMeta{ 55 Name: "rule1", 56 }, 57 }, 58 }, 59 }, 60 want: true, 61 }, 62 { 63 name: "CNP with the different spec", 64 args: args{ 65 o1: &types.SlimCNP{ 66 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 67 ObjectMeta: metav1.ObjectMeta{ 68 Name: "rule1", 69 }, 70 Spec: &api.Rule{ 71 EndpointSelector: api.NewESFromLabels(labels.NewLabel("foo", "bar", labels.LabelSourceK8s)), 72 }, 73 }, 74 }, 75 o2: &types.SlimCNP{ 76 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 77 ObjectMeta: metav1.ObjectMeta{ 78 Name: "rule1", 79 }, 80 Spec: nil, 81 }, 82 }, 83 }, 84 want: false, 85 }, 86 { 87 name: "CNP with the same spec", 88 args: args{ 89 o1: &types.SlimCNP{ 90 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 91 ObjectMeta: metav1.ObjectMeta{ 92 Name: "rule1", 93 }, 94 Spec: &api.Rule{}, 95 }, 96 }, 97 o2: &types.SlimCNP{ 98 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 99 ObjectMeta: metav1.ObjectMeta{ 100 Name: "rule1", 101 }, 102 Spec: &api.Rule{}, 103 }, 104 }, 105 }, 106 want: true, 107 }, 108 { 109 name: "CNP with different last applied annotations. The are ignored so they should be equal", 110 args: args{ 111 o1: &types.SlimCNP{ 112 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 113 ObjectMeta: metav1.ObjectMeta{ 114 Name: "rule1", 115 Annotations: map[string]string{ 116 core_v1.LastAppliedConfigAnnotation: "foo", 117 }, 118 }, 119 Spec: &api.Rule{}, 120 }, 121 }, 122 o2: &types.SlimCNP{ 123 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{ 124 ObjectMeta: metav1.ObjectMeta{ 125 Name: "rule1", 126 Annotations: map[string]string{ 127 core_v1.LastAppliedConfigAnnotation: "bar", 128 }, 129 }, 130 Spec: &api.Rule{}, 131 }, 132 }, 133 }, 134 want: true, 135 }, 136 } 137 for _, tt := range tests { 138 got := tt.args.o1.DeepEqual(tt.args.o2) 139 require.Equal(t, tt.want, got, "Test Name: %s", tt.name) 140 } 141 } 142 143 func Test_EqualV1Endpoints(t *testing.T) { 144 type args struct { 145 o1 *slim_corev1.Endpoints 146 o2 *slim_corev1.Endpoints 147 } 148 tests := []struct { 149 name string 150 args args 151 want bool 152 }{ 153 { 154 name: "EPs with the same name", 155 args: args{ 156 o1: &slim_corev1.Endpoints{ 157 ObjectMeta: slim_metav1.ObjectMeta{ 158 Name: "rule1", 159 }, 160 }, 161 o2: &slim_corev1.Endpoints{ 162 ObjectMeta: slim_metav1.ObjectMeta{ 163 Name: "rule1", 164 }, 165 }, 166 }, 167 want: true, 168 }, 169 { 170 name: "EPs with the different spec", 171 args: args{ 172 o1: &slim_corev1.Endpoints{ 173 ObjectMeta: slim_metav1.ObjectMeta{ 174 Name: "rule1", 175 }, 176 Subsets: []slim_corev1.EndpointSubset{ 177 { 178 Addresses: []slim_corev1.EndpointAddress{ 179 { 180 IP: "172.0.0.1", 181 }, 182 }, 183 }, 184 }, 185 }, 186 o2: &slim_corev1.Endpoints{ 187 ObjectMeta: slim_metav1.ObjectMeta{ 188 Name: "rule1", 189 }, 190 }, 191 }, 192 want: false, 193 }, 194 { 195 name: "EPs with the same spec", 196 args: args{ 197 o1: &slim_corev1.Endpoints{ 198 ObjectMeta: slim_metav1.ObjectMeta{ 199 Name: "rule1", 200 }, 201 Subsets: []slim_corev1.EndpointSubset{ 202 { 203 Addresses: []slim_corev1.EndpointAddress{ 204 { 205 IP: "172.0.0.1", 206 }, 207 }, 208 }, 209 }, 210 }, 211 o2: &slim_corev1.Endpoints{ 212 ObjectMeta: slim_metav1.ObjectMeta{ 213 Name: "rule1", 214 }, 215 Subsets: []slim_corev1.EndpointSubset{ 216 { 217 Addresses: []slim_corev1.EndpointAddress{ 218 { 219 IP: "172.0.0.1", 220 }, 221 }, 222 }, 223 }, 224 }, 225 }, 226 want: true, 227 }, 228 { 229 name: "EPs with the same spec (multiple IPs)", 230 args: args{ 231 o1: &slim_corev1.Endpoints{ 232 ObjectMeta: slim_metav1.ObjectMeta{ 233 Name: "rule1", 234 }, 235 Subsets: []slim_corev1.EndpointSubset{ 236 { 237 Addresses: []slim_corev1.EndpointAddress{ 238 { 239 IP: "172.0.0.1", 240 }, 241 { 242 IP: "172.0.0.2", 243 }, 244 }, 245 }, 246 }, 247 }, 248 o2: &slim_corev1.Endpoints{ 249 ObjectMeta: slim_metav1.ObjectMeta{ 250 Name: "rule1", 251 }, 252 Subsets: []slim_corev1.EndpointSubset{ 253 { 254 Addresses: []slim_corev1.EndpointAddress{ 255 { 256 IP: "172.0.0.1", 257 }, 258 { 259 IP: "172.0.0.2", 260 }, 261 }, 262 }, 263 }, 264 }, 265 }, 266 want: true, 267 }, 268 } 269 for _, tt := range tests { 270 got := tt.args.o1.DeepEqual(tt.args.o2) 271 require.Equal(t, tt.want, got, "Test Name: %s", tt.name) 272 } 273 } 274 275 func Test_EqualV1Pod(t *testing.T) { 276 type args struct { 277 o1 *slim_corev1.Pod 278 o2 *slim_corev1.Pod 279 } 280 tests := []struct { 281 name string 282 args args 283 want bool 284 }{ 285 { 286 name: "Pods with the same name", 287 args: args{ 288 o1: &slim_corev1.Pod{ 289 ObjectMeta: slim_metav1.ObjectMeta{ 290 Name: "pod1", 291 }, 292 }, 293 o2: &slim_corev1.Pod{ 294 ObjectMeta: slim_metav1.ObjectMeta{ 295 Name: "pod1", 296 }, 297 }, 298 }, 299 want: true, 300 }, 301 { 302 name: "Pods with the different spec", 303 args: args{ 304 o1: &slim_corev1.Pod{ 305 ObjectMeta: slim_metav1.ObjectMeta{ 306 Name: "pod1", 307 }, 308 Status: slim_corev1.PodStatus{ 309 HostIP: "127.0.0.1", 310 PodIPs: []slim_corev1.PodIP{ 311 { 312 IP: "127.0.0.2", 313 }, 314 }, 315 }, 316 }, 317 o2: &slim_corev1.Pod{ 318 ObjectMeta: slim_metav1.ObjectMeta{ 319 Name: "pod1", 320 }, 321 Status: slim_corev1.PodStatus{ 322 HostIP: "127.0.0.1", 323 PodIPs: []slim_corev1.PodIP{ 324 { 325 IP: "127.0.0.1", 326 }, 327 }, 328 }, 329 }, 330 }, 331 want: false, 332 }, 333 { 334 name: "Pods with the same spec", 335 args: args{ 336 o1: &slim_corev1.Pod{ 337 ObjectMeta: slim_metav1.ObjectMeta{ 338 Name: "pod1", 339 }, 340 Status: slim_corev1.PodStatus{ 341 HostIP: "127.0.0.1", 342 PodIPs: []slim_corev1.PodIP{ 343 { 344 IP: "127.0.0.2", 345 }, 346 }, 347 }, 348 }, 349 o2: &slim_corev1.Pod{ 350 ObjectMeta: slim_metav1.ObjectMeta{ 351 Name: "pod1", 352 }, 353 Status: slim_corev1.PodStatus{ 354 HostIP: "127.0.0.1", 355 PodIPs: []slim_corev1.PodIP{ 356 { 357 IP: "127.0.0.2", 358 }, 359 }, 360 }, 361 }, 362 }, 363 want: true, 364 }, 365 { 366 name: "Pods with the same spec but different labels", 367 args: args{ 368 o1: &slim_corev1.Pod{ 369 ObjectMeta: slim_metav1.ObjectMeta{ 370 Name: "pod1", 371 Labels: map[string]string{ 372 "foo": "bar", 373 }, 374 }, 375 Status: slim_corev1.PodStatus{ 376 HostIP: "127.0.0.1", 377 PodIPs: []slim_corev1.PodIP{ 378 { 379 IP: "127.0.0.2", 380 }, 381 }, 382 }, 383 }, 384 o2: &slim_corev1.Pod{ 385 ObjectMeta: slim_metav1.ObjectMeta{ 386 Name: "pod1", 387 }, 388 Status: slim_corev1.PodStatus{ 389 HostIP: "127.0.0.1", 390 PodIPs: []slim_corev1.PodIP{ 391 { 392 IP: "127.0.0.2", 393 }, 394 }, 395 }, 396 }, 397 }, 398 want: false, 399 }, 400 { 401 name: "Pods with the same spec and same labels", 402 args: args{ 403 o1: &slim_corev1.Pod{ 404 ObjectMeta: slim_metav1.ObjectMeta{ 405 Name: "pod1", 406 Labels: map[string]string{ 407 "foo": "bar", 408 }, 409 }, 410 Status: slim_corev1.PodStatus{ 411 HostIP: "127.0.0.1", 412 PodIPs: []slim_corev1.PodIP{ 413 { 414 IP: "127.0.0.2", 415 }, 416 }, 417 }, 418 }, 419 o2: &slim_corev1.Pod{ 420 ObjectMeta: slim_metav1.ObjectMeta{ 421 Name: "pod1", 422 Labels: map[string]string{ 423 "foo": "bar", 424 }, 425 }, 426 Status: slim_corev1.PodStatus{ 427 HostIP: "127.0.0.1", 428 PodIPs: []slim_corev1.PodIP{ 429 { 430 IP: "127.0.0.2", 431 }, 432 }, 433 }, 434 }, 435 }, 436 want: true, 437 }, 438 { 439 name: "Pods with differing proxy-visibility annotations", 440 args: args{ 441 o1: &slim_corev1.Pod{ 442 ObjectMeta: slim_metav1.ObjectMeta{ 443 Name: "pod1", 444 Labels: map[string]string{ 445 "foo": "bar", 446 }, 447 }, 448 Status: slim_corev1.PodStatus{ 449 HostIP: "127.0.0.1", 450 PodIPs: []slim_corev1.PodIP{ 451 { 452 IP: "127.0.0.2", 453 }, 454 }, 455 }, 456 }, 457 o2: &slim_corev1.Pod{ 458 ObjectMeta: slim_metav1.ObjectMeta{ 459 Name: "pod1", 460 Labels: map[string]string{ 461 "foo": "bar", 462 }, 463 Annotations: map[string]string{ 464 annotation.ProxyVisibility: "80/HTTP", 465 }, 466 }, 467 Status: slim_corev1.PodStatus{ 468 HostIP: "127.0.0.1", 469 PodIPs: []slim_corev1.PodIP{ 470 { 471 IP: "127.0.0.2", 472 }, 473 }, 474 }, 475 }, 476 }, 477 want: false, 478 }, 479 { 480 name: "Pods with irrelevant annotations", 481 args: args{ 482 o1: &slim_corev1.Pod{ 483 ObjectMeta: slim_metav1.ObjectMeta{ 484 Name: "pod1", 485 Labels: map[string]string{ 486 "foo": "bar", 487 }, 488 }, 489 Status: slim_corev1.PodStatus{ 490 HostIP: "127.0.0.1", 491 PodIPs: []slim_corev1.PodIP{ 492 { 493 IP: "127.0.0.2", 494 }, 495 }, 496 }, 497 }, 498 o2: &slim_corev1.Pod{ 499 ObjectMeta: slim_metav1.ObjectMeta{ 500 Name: "pod1", 501 Labels: map[string]string{ 502 "foo": "bar", 503 }, 504 Annotations: map[string]string{ 505 "useless": "80/HTTP", 506 }, 507 }, 508 Status: slim_corev1.PodStatus{ 509 HostIP: "127.0.0.1", 510 PodIPs: []slim_corev1.PodIP{ 511 { 512 IP: "127.0.0.2", 513 }, 514 }, 515 }, 516 }, 517 }, 518 want: false, 519 }, 520 } 521 for _, tt := range tests { 522 got := tt.args.o1.DeepEqual(tt.args.o2) 523 require.Equal(t, tt.want, got, "Test Name: %s", tt.name) 524 } 525 } 526 527 func Test_EqualV1Node(t *testing.T) { 528 type args struct { 529 o1 *slim_corev1.Node 530 o2 *slim_corev1.Node 531 } 532 tests := []struct { 533 name string 534 args args 535 want bool 536 }{ 537 { 538 name: "Nodes with the same name", 539 args: args{ 540 o1: &slim_corev1.Node{ 541 ObjectMeta: slim_metav1.ObjectMeta{ 542 Name: "Node1", 543 }, 544 }, 545 o2: &slim_corev1.Node{ 546 ObjectMeta: slim_metav1.ObjectMeta{ 547 Name: "Node1", 548 }, 549 }, 550 }, 551 want: true, 552 }, 553 { 554 name: "Nodes with the different names", 555 args: args{ 556 o1: &slim_corev1.Node{ 557 ObjectMeta: slim_metav1.ObjectMeta{ 558 Name: "Node1", 559 }, 560 }, 561 o2: &slim_corev1.Node{ 562 ObjectMeta: slim_metav1.ObjectMeta{ 563 Name: "Node2", 564 }, 565 }, 566 }, 567 want: false, 568 }, 569 { 570 name: "Nodes with the different spec should return false", 571 args: args{ 572 o1: &slim_corev1.Node{ 573 ObjectMeta: slim_metav1.ObjectMeta{ 574 Name: "Node1", 575 }, 576 Spec: slim_corev1.NodeSpec{ 577 PodCIDR: "192.168.0.0/10", 578 }, 579 }, 580 o2: &slim_corev1.Node{ 581 ObjectMeta: slim_metav1.ObjectMeta{ 582 Name: "Node1", 583 }, 584 Spec: slim_corev1.NodeSpec{ 585 PodCIDR: "127.0.0.1/10", 586 }, 587 }, 588 }, 589 want: false, 590 }, 591 { 592 name: "Nodes with the same annotations", 593 args: args{ 594 o1: &slim_corev1.Node{ 595 ObjectMeta: slim_metav1.ObjectMeta{ 596 Name: "Node1", 597 Annotations: map[string]string{ 598 annotation.CiliumHostIP: "127.0.0.1", 599 }, 600 }, 601 }, 602 o2: &slim_corev1.Node{ 603 ObjectMeta: slim_metav1.ObjectMeta{ 604 Name: "Node1", 605 Annotations: map[string]string{ 606 annotation.CiliumHostIP: "127.0.0.1", 607 }, 608 }, 609 }, 610 }, 611 want: true, 612 }, 613 { 614 name: "Nodes with the different annotations", 615 args: args{ 616 o1: &slim_corev1.Node{ 617 ObjectMeta: slim_metav1.ObjectMeta{ 618 Name: "Node1", 619 Annotations: map[string]string{ 620 annotation.CiliumHostIP: "127.0.0.1", 621 }, 622 }, 623 }, 624 o2: &slim_corev1.Node{ 625 ObjectMeta: slim_metav1.ObjectMeta{ 626 Name: "Node1", 627 Annotations: map[string]string{ 628 annotation.CiliumHostIP: "127.0.0.2", 629 }, 630 }, 631 }, 632 }, 633 want: false, 634 }, 635 { 636 name: "Nodes with the same annotations and different specs should return false", 637 args: args{ 638 o1: &slim_corev1.Node{ 639 ObjectMeta: slim_metav1.ObjectMeta{ 640 Name: "Node1", 641 Annotations: map[string]string{ 642 annotation.CiliumHostIP: "127.0.0.1", 643 }, 644 }, 645 Spec: slim_corev1.NodeSpec{ 646 PodCIDR: "192.168.0.0/10", 647 }, 648 }, 649 o2: &slim_corev1.Node{ 650 ObjectMeta: slim_metav1.ObjectMeta{ 651 Name: "Node1", 652 Annotations: map[string]string{ 653 annotation.CiliumHostIP: "127.0.0.1", 654 }, 655 }, 656 Spec: slim_corev1.NodeSpec{ 657 PodCIDR: "127.0.0.1/10", 658 }, 659 }, 660 }, 661 want: false, 662 }, 663 { 664 name: "Nodes with the same taints and different specs should return false", 665 args: args{ 666 o1: &slim_corev1.Node{ 667 ObjectMeta: slim_metav1.ObjectMeta{ 668 Name: "Node1", 669 }, 670 Spec: slim_corev1.NodeSpec{ 671 PodCIDR: "192.168.0.0/10", 672 Taints: []slim_corev1.Taint{ 673 { 674 Key: "key", 675 Value: "value", 676 Effect: "no-effect", 677 }, 678 }, 679 }, 680 }, 681 o2: &slim_corev1.Node{ 682 ObjectMeta: slim_metav1.ObjectMeta{ 683 Name: "Node1", 684 }, 685 Spec: slim_corev1.NodeSpec{ 686 PodCIDR: "127.0.0.1/10", 687 Taints: []slim_corev1.Taint{ 688 { 689 Key: "key", 690 Value: "value", 691 Effect: "no-effect", 692 }, 693 }, 694 }, 695 }, 696 }, 697 want: false, 698 }, 699 { 700 name: "Nodes with the same taints and different specs should false", 701 args: args{ 702 o1: &slim_corev1.Node{ 703 ObjectMeta: slim_metav1.ObjectMeta{ 704 Name: "Node1", 705 }, 706 Spec: slim_corev1.NodeSpec{ 707 PodCIDR: "192.168.0.0/10", 708 Taints: []slim_corev1.Taint{ 709 { 710 Key: "key", 711 Value: "value", 712 Effect: "no-effect", 713 TimeAdded: func() *slim_metav1.Time { return &slim_metav1.Time{Time: time.Unix(1, 1)} }(), 714 }, 715 }, 716 }, 717 }, 718 o2: &slim_corev1.Node{ 719 ObjectMeta: slim_metav1.ObjectMeta{ 720 Name: "Node1", 721 }, 722 Spec: slim_corev1.NodeSpec{ 723 PodCIDR: "127.0.0.1/10", 724 Taints: []slim_corev1.Taint{ 725 { 726 Key: "key", 727 Value: "value", 728 Effect: "no-effect", 729 TimeAdded: func() *slim_metav1.Time { return &slim_metav1.Time{Time: time.Unix(1, 1)} }(), 730 }, 731 }, 732 }, 733 }, 734 }, 735 want: false, 736 }, 737 { 738 name: "Nodes with the different taints and different specs should return false", 739 args: args{ 740 o1: &slim_corev1.Node{ 741 ObjectMeta: slim_metav1.ObjectMeta{ 742 Name: "Node1", 743 }, 744 Spec: slim_corev1.NodeSpec{ 745 PodCIDR: "192.168.0.0/10", 746 Taints: []slim_corev1.Taint{ 747 { 748 Key: "key", 749 Value: "value", 750 Effect: "no-effect", 751 }, 752 }, 753 }, 754 }, 755 o2: &slim_corev1.Node{ 756 ObjectMeta: slim_metav1.ObjectMeta{ 757 Name: "Node1", 758 }, Spec: slim_corev1.NodeSpec{ 759 PodCIDR: "127.0.0.1/10", 760 Taints: []slim_corev1.Taint{ 761 { 762 Key: "key", 763 Value: "value", 764 Effect: "no-effect", 765 TimeAdded: func() *slim_metav1.Time { return &slim_metav1.Time{Time: time.Unix(1, 1)} }(), 766 }, 767 }, 768 }, 769 }, 770 }, 771 want: false, 772 }, 773 } 774 for _, tt := range tests { 775 got := tt.args.o1.DeepEqual(tt.args.o2) 776 require.Equal(t, tt.want, got, "Test Name: %s", tt.name) 777 } 778 } 779 780 func Test_EqualV1Namespace(t *testing.T) { 781 type args struct { 782 o1 *slim_corev1.Namespace 783 o2 *slim_corev1.Namespace 784 } 785 tests := []struct { 786 name string 787 args args 788 want bool 789 }{ 790 { 791 name: "Namespaces with the same name", 792 args: args{ 793 o1: &slim_corev1.Namespace{ 794 ObjectMeta: slim_metav1.ObjectMeta{ 795 Name: "Namespace1", 796 }, 797 }, 798 o2: &slim_corev1.Namespace{ 799 ObjectMeta: slim_metav1.ObjectMeta{ 800 Name: "Namespace1", 801 }, 802 }, 803 }, 804 want: true, 805 }, 806 { 807 name: "Namespaces with the different names", 808 args: args{ 809 o1: &slim_corev1.Namespace{ 810 ObjectMeta: slim_metav1.ObjectMeta{ 811 Name: "Namespace1", 812 }, 813 }, 814 o2: &slim_corev1.Namespace{ 815 ObjectMeta: slim_metav1.ObjectMeta{ 816 Name: "Namespace2", 817 }, 818 }, 819 }, 820 want: false, 821 }, 822 { 823 name: "Namespaces with the same labels", 824 args: args{ 825 o1: &slim_corev1.Namespace{ 826 ObjectMeta: slim_metav1.ObjectMeta{ 827 Name: "Namespace1", 828 Labels: map[string]string{ 829 "prod": "true", 830 }, 831 }, 832 }, 833 o2: &slim_corev1.Namespace{ 834 ObjectMeta: slim_metav1.ObjectMeta{ 835 Name: "Namespace1", 836 Labels: map[string]string{ 837 "prod": "true", 838 }, 839 }, 840 }, 841 }, 842 want: true, 843 }, 844 { 845 name: "Namespaces with the different labels", 846 args: args{ 847 o1: &slim_corev1.Namespace{ 848 ObjectMeta: slim_metav1.ObjectMeta{ 849 Name: "Namespace1", 850 Labels: map[string]string{ 851 "prod": "true", 852 }, 853 }, 854 }, 855 o2: &slim_corev1.Namespace{ 856 ObjectMeta: slim_metav1.ObjectMeta{ 857 Name: "Namespace1", 858 Labels: map[string]string{ 859 "prod": "false", 860 }, 861 }, 862 }, 863 }, 864 want: false, 865 }, 866 } 867 for _, tt := range tests { 868 got := tt.args.o1.DeepEqual(tt.args.o2) 869 require.Equal(t, tt.want, got, "Test Name: %s", tt.name) 870 } 871 } 872 873 func Test_ConvertToK8sV1ServicePorts(t *testing.T) { 874 type args struct { 875 ports []slim_corev1.ServicePort 876 } 877 tests := []struct { 878 name string 879 args args 880 want []core_v1.ServicePort 881 }{ 882 { 883 name: "empty", 884 args: args{ 885 ports: []slim_corev1.ServicePort{}, 886 }, 887 want: []core_v1.ServicePort{}, 888 }, 889 { 890 name: "non-empty", 891 args: args{ 892 ports: []slim_corev1.ServicePort{ 893 { 894 Name: "foo", 895 Port: int32(1), 896 }, 897 }, 898 }, 899 want: []core_v1.ServicePort{ 900 { 901 Name: "foo", 902 Port: int32(1), 903 }, 904 }, 905 }, 906 } 907 for _, tt := range tests { 908 got := ConvertToK8sV1ServicePorts(tt.args.ports) 909 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 910 } 911 } 912 913 func Test_ConvertToK8sV1SessionAffinityConfig(t *testing.T) { 914 ts := int32(1) 915 type args struct { 916 cfg *slim_corev1.SessionAffinityConfig 917 } 918 tests := []struct { 919 name string 920 args args 921 want *core_v1.SessionAffinityConfig 922 }{ 923 { 924 name: "empty", 925 args: args{ 926 cfg: &slim_corev1.SessionAffinityConfig{}, 927 }, 928 want: &core_v1.SessionAffinityConfig{}, 929 }, 930 { 931 name: "non-empty", 932 args: args{ 933 cfg: &slim_corev1.SessionAffinityConfig{ 934 ClientIP: &slim_corev1.ClientIPConfig{ 935 TimeoutSeconds: &ts, 936 }, 937 }, 938 }, 939 want: &core_v1.SessionAffinityConfig{ 940 ClientIP: &core_v1.ClientIPConfig{ 941 TimeoutSeconds: &ts, 942 }, 943 }, 944 }, 945 } 946 for _, tt := range tests { 947 got := ConvertToK8sV1ServiceAffinityConfig(tt.args.cfg) 948 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 949 } 950 } 951 952 func Test_ConvertToK8sV1LoadBalancerIngress(t *testing.T) { 953 type args struct { 954 ings []slim_corev1.LoadBalancerIngress 955 } 956 tests := []struct { 957 name string 958 args args 959 want []core_v1.LoadBalancerIngress 960 }{ 961 { 962 name: "empty", 963 args: args{ 964 ings: []slim_corev1.LoadBalancerIngress{}, 965 }, 966 want: []core_v1.LoadBalancerIngress{}, 967 }, 968 { 969 name: "non-empty", 970 args: args{ 971 ings: []slim_corev1.LoadBalancerIngress{ 972 { 973 IP: "1.1.1.1", 974 }, 975 }, 976 }, 977 want: []core_v1.LoadBalancerIngress{ 978 { 979 IP: "1.1.1.1", 980 Ports: nil, 981 }, 982 }, 983 }, 984 } 985 for _, tt := range tests { 986 got := ConvertToK8sV1LoadBalancerIngress(tt.args.ings) 987 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 988 } 989 } 990 991 func Test_ConvertToNetworkV1IngressLoadBalancerIngress(t *testing.T) { 992 type args struct { 993 ings []slim_corev1.LoadBalancerIngress 994 } 995 tests := []struct { 996 name string 997 args args 998 want []networkingv1.IngressLoadBalancerIngress 999 }{ 1000 { 1001 name: "empty", 1002 args: args{ 1003 ings: []slim_corev1.LoadBalancerIngress{}, 1004 }, 1005 want: []networkingv1.IngressLoadBalancerIngress{}, 1006 }, 1007 { 1008 name: "non-empty", 1009 args: args{ 1010 ings: []slim_corev1.LoadBalancerIngress{ 1011 { 1012 IP: "1.1.1.1", 1013 }, 1014 }, 1015 }, 1016 want: []networkingv1.IngressLoadBalancerIngress{ 1017 { 1018 IP: "1.1.1.1", 1019 Ports: []networkingv1.IngressPortStatus{}, 1020 }, 1021 }, 1022 }, 1023 } 1024 for _, tt := range tests { 1025 got := ConvertToNetworkV1IngressLoadBalancerIngress(tt.args.ings) 1026 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 1027 } 1028 } 1029 1030 func Test_TransformToCNP(t *testing.T) { 1031 type args struct { 1032 obj interface{} 1033 } 1034 tests := []struct { 1035 name string 1036 args args 1037 want interface{} 1038 expected bool 1039 }{ 1040 { 1041 name: "normal transformation", 1042 args: args{ 1043 obj: &v2.CiliumNetworkPolicy{}, 1044 }, 1045 want: &types.SlimCNP{ 1046 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{}, 1047 }, 1048 expected: true, 1049 }, 1050 { 1051 name: "transformation unneeded", 1052 args: args{ 1053 obj: &types.SlimCNP{}, 1054 }, 1055 want: &types.SlimCNP{}, 1056 expected: true, 1057 }, 1058 { 1059 name: "delete final state unknown transformation", 1060 args: args{ 1061 obj: cache.DeletedFinalStateUnknown{ 1062 Key: "foo", 1063 Obj: &v2.CiliumNetworkPolicy{}, 1064 }, 1065 }, 1066 want: cache.DeletedFinalStateUnknown{ 1067 Key: "foo", 1068 Obj: &types.SlimCNP{ 1069 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{}, 1070 }, 1071 }, 1072 expected: true, 1073 }, 1074 { 1075 name: "delete final state unknown transformation with SlimCNP", 1076 args: args{ 1077 obj: cache.DeletedFinalStateUnknown{ 1078 Key: "foo", 1079 Obj: &types.SlimCNP{}, 1080 }, 1081 }, 1082 want: cache.DeletedFinalStateUnknown{ 1083 Key: "foo", 1084 Obj: &types.SlimCNP{}, 1085 }, 1086 expected: true, 1087 }, 1088 { 1089 name: "unknown object type in delete final state unknown transformation", 1090 args: args{ 1091 obj: cache.DeletedFinalStateUnknown{ 1092 Key: "foo", 1093 Obj: unknownObj, 1094 }, 1095 }, 1096 want: unknownObjErr, 1097 expected: false, 1098 }, 1099 { 1100 name: "unknown object type in transformation", 1101 args: args{ 1102 obj: unknownObj, 1103 }, 1104 want: unknownObjErr, 1105 expected: false, 1106 }, 1107 } 1108 for _, tt := range tests { 1109 got, err := TransformToCNP(tt.args.obj) 1110 if tt.expected { 1111 require.Equal(t, nil, err) 1112 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 1113 } else { 1114 require.Equal(t, tt.want, err, "Test Name: %s", tt.name) 1115 } 1116 } 1117 } 1118 1119 func Test_TransformToCCNP(t *testing.T) { 1120 type args struct { 1121 obj interface{} 1122 } 1123 tests := []struct { 1124 name string 1125 args args 1126 want interface{} 1127 expected bool 1128 }{ 1129 { 1130 name: "normal transformation", 1131 args: args{ 1132 obj: &v2.CiliumClusterwideNetworkPolicy{}, 1133 }, 1134 want: &types.SlimCNP{ 1135 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{}, 1136 }, 1137 expected: true, 1138 }, 1139 { 1140 name: "transformation unneeded", 1141 args: args{ 1142 obj: &types.SlimCNP{}, 1143 }, 1144 want: &types.SlimCNP{}, 1145 expected: true, 1146 }, 1147 { 1148 name: "A CCNP where it doesn't contain neither a spec nor specs", 1149 args: args{ 1150 obj: &v2.CiliumClusterwideNetworkPolicy{}, 1151 }, 1152 want: &types.SlimCNP{ 1153 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{}, 1154 }, 1155 expected: true, 1156 }, 1157 { 1158 name: "delete final state unknown transformation", 1159 args: args{ 1160 obj: cache.DeletedFinalStateUnknown{ 1161 Key: "foo", 1162 Obj: &v2.CiliumClusterwideNetworkPolicy{}, 1163 }, 1164 }, 1165 want: cache.DeletedFinalStateUnknown{ 1166 Key: "foo", 1167 Obj: &types.SlimCNP{ 1168 CiliumNetworkPolicy: &v2.CiliumNetworkPolicy{}, 1169 }, 1170 }, 1171 expected: true, 1172 }, 1173 { 1174 name: "delete final state unknown transformation with SlimCNP", 1175 args: args{ 1176 obj: cache.DeletedFinalStateUnknown{ 1177 Key: "foo", 1178 Obj: &types.SlimCNP{}, 1179 }, 1180 }, 1181 want: cache.DeletedFinalStateUnknown{ 1182 Key: "foo", 1183 Obj: &types.SlimCNP{}, 1184 }, 1185 expected: true, 1186 }, 1187 { 1188 name: "unknown object type in delete final state unknown transformation", 1189 args: args{ 1190 obj: cache.DeletedFinalStateUnknown{ 1191 Key: "foo", 1192 Obj: unknownObj, 1193 }, 1194 }, 1195 want: unknownObjErr, 1196 expected: false, 1197 }, 1198 { 1199 name: "unknown object type in transformation", 1200 args: args{ 1201 obj: unknownObj, 1202 }, 1203 want: unknownObjErr, 1204 expected: false, 1205 }, 1206 } 1207 for _, tt := range tests { 1208 got, err := TransformToCCNP(tt.args.obj) 1209 if tt.expected { 1210 require.Equal(t, nil, err) 1211 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 1212 } else { 1213 require.Equal(t, tt.want, err, "Test Name: %s", tt.name) 1214 } 1215 } 1216 } 1217 1218 func Test_TransformToCiliumEndpoint(t *testing.T) { 1219 type args struct { 1220 obj interface{} 1221 } 1222 tests := []struct { 1223 name string 1224 args args 1225 want interface{} 1226 expected bool 1227 }{ 1228 { 1229 name: "normal transformation", 1230 args: args{ 1231 obj: &v2.CiliumEndpoint{}, 1232 }, 1233 want: &types.CiliumEndpoint{ 1234 Encryption: &v2.EncryptionSpec{}, 1235 }, 1236 expected: true, 1237 }, 1238 { 1239 name: "transformation unneeded", 1240 args: args{ 1241 obj: &types.CiliumEndpoint{}, 1242 }, 1243 want: &types.CiliumEndpoint{}, 1244 expected: true, 1245 }, 1246 { 1247 name: "delete final state unknown transformation", 1248 args: args{ 1249 obj: cache.DeletedFinalStateUnknown{ 1250 Key: "foo", 1251 Obj: &v2.CiliumEndpoint{ 1252 TypeMeta: metav1.TypeMeta{ 1253 Kind: "CiliumEndpoint", 1254 APIVersion: "v2", 1255 }, 1256 ObjectMeta: metav1.ObjectMeta{ 1257 Name: "foo", 1258 GenerateName: "generated-Foo", 1259 Namespace: "bar", 1260 UID: "fdadada-dada", 1261 ResourceVersion: "5454", 1262 Generation: 5, 1263 CreationTimestamp: metav1.Time{ 1264 Time: time.Date(2018, 01, 01, 01, 01, 01, 01, time.UTC), 1265 }, 1266 Labels: map[string]string{ 1267 "foo": "bar", 1268 }, 1269 Annotations: map[string]string{ 1270 "foo": "bar", 1271 }, 1272 OwnerReferences: []metav1.OwnerReference{ 1273 { 1274 Kind: "Pod", 1275 APIVersion: "v1", 1276 Name: "foo", 1277 UID: "65dasd54d45", 1278 Controller: nil, 1279 }, 1280 }, 1281 }, 1282 Status: v2.EndpointStatus{ 1283 ID: 0, 1284 Controllers: nil, 1285 ExternalIdentifiers: &models.EndpointIdentifiers{ 1286 ContainerID: "3290f4bc32129cb3e2f81074557ad9690240ea8fcce84bcc51a9921034875878", 1287 ContainerName: "foo", 1288 K8sNamespace: "foo", 1289 K8sPodName: "bar", 1290 PodName: "foo/bar", 1291 }, 1292 Health: &models.EndpointHealth{ 1293 Bpf: "good", 1294 Connected: false, 1295 OverallHealth: "excellent", 1296 Policy: "excellent", 1297 }, 1298 Identity: &v2.EndpointIdentity{ 1299 ID: 9654, 1300 Labels: []string{ 1301 "k8s:io.cilium.namespace=bar", 1302 }, 1303 }, 1304 Networking: &v2.EndpointNetworking{ 1305 Addressing: []*v2.AddressPair{ 1306 { 1307 IPV4: "10.0.0.1", 1308 IPV6: "fd00::1", 1309 }, 1310 }, 1311 NodeIP: "192.168.0.1", 1312 }, 1313 Encryption: v2.EncryptionSpec{ 1314 Key: 250, 1315 }, 1316 Policy: &v2.EndpointPolicy{ 1317 Ingress: &v2.EndpointPolicyDirection{ 1318 Enforcing: true, 1319 }, 1320 Egress: &v2.EndpointPolicyDirection{ 1321 Enforcing: true, 1322 }, 1323 }, 1324 State: "", 1325 NamedPorts: []*models.Port{ 1326 { 1327 Name: "foo-port", 1328 Port: 8181, 1329 Protocol: "TCP", 1330 }, 1331 }, 1332 }, 1333 }, 1334 }, 1335 }, 1336 want: cache.DeletedFinalStateUnknown{ 1337 Key: "foo", 1338 Obj: &types.CiliumEndpoint{ 1339 TypeMeta: slim_metav1.TypeMeta{ 1340 Kind: "CiliumEndpoint", 1341 APIVersion: "v2", 1342 }, 1343 ObjectMeta: slim_metav1.ObjectMeta{ 1344 Name: "foo", 1345 Namespace: "bar", 1346 UID: "fdadada-dada", 1347 ResourceVersion: "5454", 1348 // We don't need to store labels nor annotations because 1349 // they are not used by the CEP handlers. 1350 Labels: nil, 1351 Annotations: nil, 1352 }, 1353 Identity: &v2.EndpointIdentity{ 1354 ID: 9654, 1355 Labels: []string{ 1356 "k8s:io.cilium.namespace=bar", 1357 }, 1358 }, 1359 Networking: &v2.EndpointNetworking{ 1360 Addressing: []*v2.AddressPair{ 1361 { 1362 IPV4: "10.0.0.1", 1363 IPV6: "fd00::1", 1364 }, 1365 }, 1366 NodeIP: "192.168.0.1", 1367 }, 1368 Encryption: &v2.EncryptionSpec{ 1369 Key: 250, 1370 }, 1371 NamedPorts: []*models.Port{ 1372 { 1373 Name: "foo-port", 1374 Port: 8181, 1375 Protocol: "TCP", 1376 }, 1377 }, 1378 }, 1379 }, 1380 expected: true, 1381 }, 1382 { 1383 name: "unknown object type in delete final state unknown transformation", 1384 args: args{ 1385 obj: cache.DeletedFinalStateUnknown{ 1386 Key: "foo", 1387 Obj: unknownObj, 1388 }, 1389 }, 1390 want: unknownObjErr, 1391 expected: false, 1392 }, 1393 { 1394 name: "delete final state unknown transformation with a types.CiliumEndpoint", 1395 args: args{ 1396 obj: cache.DeletedFinalStateUnknown{ 1397 Key: "foo", 1398 Obj: &types.CiliumEndpoint{}, 1399 }, 1400 }, 1401 want: cache.DeletedFinalStateUnknown{ 1402 Key: "foo", 1403 Obj: &types.CiliumEndpoint{}, 1404 }, 1405 expected: true, 1406 }, 1407 { 1408 name: "unknown object type in transformation", 1409 args: args{ 1410 obj: unknownObj, 1411 }, 1412 want: unknownObjErr, 1413 expected: false, 1414 }, 1415 } 1416 for _, tt := range tests { 1417 got, err := TransformToCiliumEndpoint(tt.args.obj) 1418 if tt.expected { 1419 require.Equal(t, nil, err) 1420 require.EqualValuesf(t, tt.want, got, "Test Name: %s", tt.name) 1421 } else { 1422 require.Equal(t, tt.want, err, "Test Name: %s", tt.name) 1423 } 1424 } 1425 } 1426 1427 func Test_AnnotationsEqual(t *testing.T) { 1428 irrelevantAnnoKey := "foo" 1429 irrelevantAnnoVal := "bar" 1430 1431 relevantAnnoKey := annotation.ProxyVisibility 1432 relevantAnnoVal1 := "<Ingress/80/TCP/HTTP>" 1433 relevantAnnoVal2 := "<Ingress/80/TCP/HTTP>,<Egress/80/TCP/HTTP>" 1434 1435 // Empty returns true. 1436 require.Equal(t, true, AnnotationsEqual(nil, map[string]string{}, map[string]string{})) 1437 1438 require.True(t, AnnotationsEqual(nil, 1439 map[string]string{ 1440 irrelevantAnnoKey: irrelevantAnnoVal, 1441 relevantAnnoKey: relevantAnnoVal1, 1442 }, map[string]string{ 1443 irrelevantAnnoKey: irrelevantAnnoVal, 1444 relevantAnnoKey: relevantAnnoVal2, 1445 })) 1446 1447 // If the relevant annotation isn't in either map, return true. 1448 require.True(t, AnnotationsEqual([]string{relevantAnnoKey}, 1449 map[string]string{ 1450 irrelevantAnnoKey: irrelevantAnnoVal, 1451 }, map[string]string{ 1452 irrelevantAnnoKey: irrelevantAnnoVal, 1453 })) 1454 1455 require.False(t, AnnotationsEqual([]string{relevantAnnoKey}, 1456 map[string]string{ 1457 relevantAnnoKey: relevantAnnoVal1, 1458 }, map[string]string{ 1459 relevantAnnoKey: relevantAnnoVal2, 1460 })) 1461 }