sigs.k8s.io/external-dns@v0.14.1/source/istio_gateway_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package source 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/pkg/errors" 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 "github.com/stretchr/testify/suite" 27 networkingv1alpha3api "istio.io/api/networking/v1alpha3" 28 networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" 29 istiofake "istio.io/client-go/pkg/clientset/versioned/fake" 30 v1 "k8s.io/api/core/v1" 31 networkv1 "k8s.io/api/networking/v1" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 "k8s.io/client-go/kubernetes/fake" 34 35 "sigs.k8s.io/external-dns/endpoint" 36 ) 37 38 // This is a compile-time validation that gatewaySource is a Source. 39 var _ Source = &gatewaySource{} 40 41 type GatewaySuite struct { 42 suite.Suite 43 source Source 44 lbServices []*v1.Service 45 ingresses []*networkv1.Ingress 46 } 47 48 func (suite *GatewaySuite) SetupTest() { 49 fakeKubernetesClient := fake.NewSimpleClientset() 50 fakeIstioClient := istiofake.NewSimpleClientset() 51 var err error 52 53 suite.lbServices = []*v1.Service{ 54 (fakeIngressGatewayService{ 55 ips: []string{"8.8.8.8"}, 56 hostnames: []string{"v1"}, 57 namespace: "istio-system", 58 name: "istio-gateway1", 59 }).Service(), 60 (fakeIngressGatewayService{ 61 ips: []string{"1.1.1.1"}, 62 hostnames: []string{"v42"}, 63 namespace: "istio-other", 64 name: "istio-gateway2", 65 }).Service(), 66 } 67 68 for _, service := range suite.lbServices { 69 _, err = fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(context.Background(), service, metav1.CreateOptions{}) 70 suite.NoError(err, "should succeed") 71 } 72 73 suite.ingresses = []*networkv1.Ingress{ 74 (fakeIngress{ 75 ips: []string{"2.2.2.2"}, 76 hostnames: []string{"v2"}, 77 namespace: "istio-system", 78 name: "istio-ingress", 79 }).Ingress(), 80 (fakeIngress{ 81 ips: []string{"3.3.3.3"}, 82 hostnames: []string{"v62"}, 83 namespace: "istio-system", 84 name: "istio-ingress2", 85 }).Ingress(), 86 } 87 88 for _, ingress := range suite.ingresses { 89 _, err = fakeKubernetesClient.NetworkingV1().Ingresses(ingress.Namespace).Create(context.Background(), ingress, metav1.CreateOptions{}) 90 suite.NoError(err, "should succeed") 91 } 92 93 suite.source, err = NewIstioGatewaySource( 94 context.TODO(), 95 fakeKubernetesClient, 96 fakeIstioClient, 97 "", 98 "", 99 "{{.Name}}", 100 false, 101 false, 102 ) 103 suite.NoError(err, "should initialize gateway source") 104 suite.NoError(err, "should succeed") 105 } 106 107 func (suite *GatewaySuite) TestResourceLabelIsSet() { 108 endpoints, _ := suite.source.Endpoints(context.Background()) 109 for _, ep := range endpoints { 110 suite.Equal("gateway/default/foo-gateway-with-targets", ep.Labels[endpoint.ResourceLabelKey], "should set correct resource label") 111 } 112 } 113 114 func TestGateway(t *testing.T) { 115 t.Parallel() 116 117 suite.Run(t, new(GatewaySuite)) 118 t.Run("endpointsFromGatewayConfig", testEndpointsFromGatewayConfig) 119 t.Run("Endpoints", testGatewayEndpoints) 120 } 121 122 func TestNewIstioGatewaySource(t *testing.T) { 123 t.Parallel() 124 125 for _, ti := range []struct { 126 title string 127 annotationFilter string 128 fqdnTemplate string 129 combineFQDNAndAnnotation bool 130 expectError bool 131 }{ 132 { 133 title: "invalid template", 134 expectError: true, 135 fqdnTemplate: "{{.Name", 136 }, 137 { 138 title: "valid empty template", 139 expectError: false, 140 }, 141 { 142 title: "valid template", 143 expectError: false, 144 fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com", 145 }, 146 { 147 title: "valid template", 148 expectError: false, 149 fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com, {{.Name}}-{{.Namespace}}.ext-dna.test.com", 150 }, 151 { 152 title: "valid template", 153 expectError: false, 154 fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com, {{.Name}}-{{.Namespace}}.ext-dna.test.com", 155 combineFQDNAndAnnotation: true, 156 }, 157 { 158 title: "non-empty annotation filter label", 159 expectError: false, 160 annotationFilter: "kubernetes.io/gateway.class=nginx", 161 }, 162 } { 163 ti := ti 164 t.Run(ti.title, func(t *testing.T) { 165 t.Parallel() 166 167 _, err := NewIstioGatewaySource( 168 context.TODO(), 169 fake.NewSimpleClientset(), 170 istiofake.NewSimpleClientset(), 171 "", 172 ti.annotationFilter, 173 ti.fqdnTemplate, 174 ti.combineFQDNAndAnnotation, 175 false, 176 ) 177 if ti.expectError { 178 assert.Error(t, err) 179 } else { 180 assert.NoError(t, err) 181 } 182 }) 183 } 184 } 185 186 func testEndpointsFromGatewayConfig(t *testing.T) { 187 t.Parallel() 188 189 for _, ti := range []struct { 190 title string 191 lbServices []fakeIngressGatewayService 192 ingresses []fakeIngress 193 config fakeGatewayConfig 194 expected []*endpoint.Endpoint 195 }{ 196 { 197 title: "one rule.host one lb.hostname", 198 lbServices: []fakeIngressGatewayService{ 199 { 200 hostnames: []string{"lb.com"}, // Kubernetes omits the trailing dot 201 }, 202 }, 203 config: fakeGatewayConfig{ 204 dnsnames: [][]string{ 205 {"foo.bar"}, // Kubernetes requires removal of trailing dot 206 }, 207 }, 208 expected: []*endpoint.Endpoint{ 209 { 210 DNSName: "foo.bar", 211 RecordType: endpoint.RecordTypeCNAME, 212 Targets: endpoint.Targets{"lb.com"}, 213 }, 214 }, 215 }, 216 { 217 title: "one namespaced rule.host one lb.hostname", 218 lbServices: []fakeIngressGatewayService{ 219 { 220 hostnames: []string{"lb.com"}, // Kubernetes omits the trailing dot 221 }, 222 }, 223 config: fakeGatewayConfig{ 224 dnsnames: [][]string{ 225 {"my-namespace/foo.bar"}, // Kubernetes requires removal of trailing dot 226 }, 227 }, 228 expected: []*endpoint.Endpoint{ 229 { 230 DNSName: "foo.bar", 231 RecordType: endpoint.RecordTypeCNAME, 232 Targets: endpoint.Targets{"lb.com"}, 233 }, 234 }, 235 }, 236 { 237 title: "one rule.host one lb.IP", 238 lbServices: []fakeIngressGatewayService{ 239 { 240 ips: []string{"8.8.8.8"}, 241 }, 242 }, 243 config: fakeGatewayConfig{ 244 dnsnames: [][]string{ 245 {"foo.bar"}, 246 }, 247 }, 248 expected: []*endpoint.Endpoint{ 249 { 250 DNSName: "foo.bar", 251 RecordType: endpoint.RecordTypeA, 252 Targets: endpoint.Targets{"8.8.8.8"}, 253 }, 254 }, 255 }, 256 { 257 title: "one rule.host one ingress.IP", 258 ingresses: []fakeIngress{ 259 { 260 name: "ingress1", 261 ips: []string{"8.8.8.8"}, 262 }, 263 }, 264 config: fakeGatewayConfig{ 265 annotations: map[string]string{ 266 IstioGatewayIngressSource: "ingress1", 267 }, 268 dnsnames: [][]string{ 269 {"foo.bar"}, 270 }, 271 }, 272 expected: []*endpoint.Endpoint{ 273 { 274 DNSName: "foo.bar", 275 RecordType: endpoint.RecordTypeA, 276 Targets: endpoint.Targets{"8.8.8.8"}, 277 }, 278 }, 279 }, 280 { 281 title: "one rule.host two lb.IP and two lb.Hostname", 282 lbServices: []fakeIngressGatewayService{ 283 { 284 ips: []string{"8.8.8.8", "127.0.0.1"}, 285 hostnames: []string{"elb.com", "alb.com"}, 286 }, 287 }, 288 config: fakeGatewayConfig{ 289 dnsnames: [][]string{ 290 {"foo.bar"}, 291 }, 292 }, 293 expected: []*endpoint.Endpoint{ 294 { 295 DNSName: "foo.bar", 296 RecordType: endpoint.RecordTypeA, 297 Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"}, 298 }, 299 { 300 DNSName: "foo.bar", 301 RecordType: endpoint.RecordTypeCNAME, 302 Targets: endpoint.Targets{"elb.com", "alb.com"}, 303 }, 304 }, 305 }, 306 { 307 title: "one rule.host two ingress.IP and two ingress.Hostname", 308 ingresses: []fakeIngress{ 309 { 310 name: "ingress1", 311 ips: []string{"8.8.8.8", "127.0.0.1"}, 312 hostnames: []string{"elb.com", "alb.com"}, 313 }, 314 }, 315 config: fakeGatewayConfig{ 316 annotations: map[string]string{ 317 IstioGatewayIngressSource: "ingress1", 318 }, 319 dnsnames: [][]string{ 320 {"foo.bar"}, 321 }, 322 }, 323 expected: []*endpoint.Endpoint{ 324 { 325 DNSName: "foo.bar", 326 RecordType: endpoint.RecordTypeA, 327 Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"}, 328 }, 329 { 330 DNSName: "foo.bar", 331 RecordType: endpoint.RecordTypeCNAME, 332 Targets: endpoint.Targets{"elb.com", "alb.com"}, 333 }, 334 }, 335 }, 336 { 337 title: "no rule.host", 338 lbServices: []fakeIngressGatewayService{ 339 { 340 ips: []string{"8.8.8.8", "127.0.0.1"}, 341 hostnames: []string{"elb.com", "alb.com"}, 342 externalIPs: []string{"1.1.1.1", "2.2.2.2"}, 343 }, 344 }, 345 config: fakeGatewayConfig{ 346 dnsnames: [][]string{}, 347 }, 348 expected: []*endpoint.Endpoint{}, 349 }, 350 { 351 title: "one empty rule.host", 352 lbServices: []fakeIngressGatewayService{ 353 { 354 ips: []string{"8.8.8.8", "127.0.0.1"}, 355 hostnames: []string{"elb.com", "alb.com"}, 356 externalIPs: []string{"1.1.1.1", "2.2.2.2"}, 357 }, 358 }, 359 config: fakeGatewayConfig{ 360 dnsnames: [][]string{ 361 {""}, 362 }, 363 }, 364 expected: []*endpoint.Endpoint{}, 365 }, 366 { 367 title: "one empty rule.host with gateway ingress annotation", 368 ingresses: []fakeIngress{ 369 { 370 name: "ingress1", 371 ips: []string{"8.8.8.8", "127.0.0.1"}, 372 hostnames: []string{"elb.com", "alb.com"}, 373 }, 374 }, 375 config: fakeGatewayConfig{ 376 annotations: map[string]string{ 377 IstioGatewayIngressSource: "ingress1", 378 }, 379 dnsnames: [][]string{ 380 {""}, 381 }, 382 }, 383 expected: []*endpoint.Endpoint{}, 384 }, 385 { 386 title: "no targets", 387 lbServices: []fakeIngressGatewayService{{}}, 388 config: fakeGatewayConfig{ 389 dnsnames: [][]string{ 390 {""}, 391 }, 392 }, 393 expected: []*endpoint.Endpoint{}, 394 }, 395 { 396 title: "one gateway, two ingressgateway loadbalancer hostnames", 397 lbServices: []fakeIngressGatewayService{ 398 { 399 hostnames: []string{"lb.com"}, 400 namespace: "istio-other", 401 name: "gateway1", 402 }, 403 { 404 hostnames: []string{"lb2.com"}, 405 namespace: "istio-other", 406 name: "gateway2", 407 }, 408 }, 409 config: fakeGatewayConfig{ 410 dnsnames: [][]string{ 411 {"foo.bar"}, // Kubernetes requires removal of trailing dot 412 }, 413 }, 414 expected: []*endpoint.Endpoint{ 415 { 416 DNSName: "foo.bar", 417 RecordType: endpoint.RecordTypeCNAME, 418 Targets: endpoint.Targets{"lb.com", "lb2.com"}, 419 }, 420 }, 421 }, 422 { 423 title: "one gateway, ingress in seperate namespace", 424 ingresses: []fakeIngress{ 425 { 426 hostnames: []string{"lb.com"}, 427 namespace: "istio-other2", 428 name: "ingress1", 429 }, 430 { 431 hostnames: []string{"lb2.com"}, 432 namespace: "istio-other", 433 name: "ingress2", 434 }, 435 }, 436 config: fakeGatewayConfig{ 437 annotations: map[string]string{ 438 IstioGatewayIngressSource: "istio-other2/ingress1", 439 }, 440 dnsnames: [][]string{ 441 {"foo.bar"}, // Kubernetes requires removal of trailing dot 442 }, 443 }, 444 expected: []*endpoint.Endpoint{ 445 { 446 DNSName: "foo.bar", 447 RecordType: endpoint.RecordTypeCNAME, 448 Targets: endpoint.Targets{"lb.com"}, 449 }, 450 }, 451 }, 452 { 453 title: "one rule.host one lb.externalIP", 454 lbServices: []fakeIngressGatewayService{ 455 { 456 externalIPs: []string{"8.8.8.8"}, 457 }, 458 }, 459 config: fakeGatewayConfig{ 460 dnsnames: [][]string{ 461 {"foo.bar"}, 462 }, 463 }, 464 expected: []*endpoint.Endpoint{ 465 { 466 DNSName: "foo.bar", 467 RecordType: endpoint.RecordTypeA, 468 Targets: endpoint.Targets{"8.8.8.8"}, 469 }, 470 }, 471 }, 472 { 473 title: "one rule.host two lb.IP, two lb.Hostname and two lb.externalIP", 474 lbServices: []fakeIngressGatewayService{ 475 { 476 ips: []string{"8.8.8.8", "127.0.0.1"}, 477 hostnames: []string{"elb.com", "alb.com"}, 478 externalIPs: []string{"1.1.1.1", "2.2.2.2"}, 479 }, 480 }, 481 config: fakeGatewayConfig{ 482 dnsnames: [][]string{ 483 {"foo.bar"}, 484 }, 485 }, 486 expected: []*endpoint.Endpoint{ 487 { 488 DNSName: "foo.bar", 489 RecordType: endpoint.RecordTypeA, 490 Targets: endpoint.Targets{"1.1.1.1", "2.2.2.2"}, 491 }, 492 }, 493 }, 494 } { 495 ti := ti 496 t.Run(ti.title, func(t *testing.T) { 497 t.Parallel() 498 499 gatewayCfg := ti.config.Config() 500 if source, err := newTestGatewaySource(ti.lbServices, ti.ingresses); err != nil { 501 require.NoError(t, err) 502 } else if hostnames, err := source.hostNamesFromGateway(gatewayCfg); err != nil { 503 require.NoError(t, err) 504 } else if endpoints, err := source.endpointsFromGateway(context.Background(), hostnames, gatewayCfg); err != nil { 505 require.NoError(t, err) 506 } else { 507 validateEndpoints(t, endpoints, ti.expected) 508 } 509 }) 510 } 511 } 512 513 func testGatewayEndpoints(t *testing.T) { 514 t.Parallel() 515 516 for _, ti := range []struct { 517 title string 518 targetNamespace string 519 annotationFilter string 520 lbServices []fakeIngressGatewayService 521 ingresses []fakeIngress 522 configItems []fakeGatewayConfig 523 expected []*endpoint.Endpoint 524 expectError bool 525 fqdnTemplate string 526 combineFQDNAndAnnotation bool 527 ignoreHostnameAnnotation bool 528 }{ 529 { 530 title: "no gateway", 531 targetNamespace: "", 532 }, 533 { 534 title: "two simple gateways, one ingressgateway loadbalancer service", 535 targetNamespace: "", 536 lbServices: []fakeIngressGatewayService{ 537 { 538 ips: []string{"8.8.8.8"}, 539 hostnames: []string{"lb.com"}, 540 }, 541 }, 542 configItems: []fakeGatewayConfig{ 543 { 544 name: "fake1", 545 namespace: "", 546 dnsnames: [][]string{{"example.org"}}, 547 }, 548 { 549 name: "fake2", 550 namespace: "", 551 dnsnames: [][]string{{"new.org"}}, 552 }, 553 }, 554 expected: []*endpoint.Endpoint{ 555 { 556 DNSName: "example.org", 557 RecordType: endpoint.RecordTypeA, 558 Targets: endpoint.Targets{"8.8.8.8"}, 559 }, 560 { 561 DNSName: "example.org", 562 RecordType: endpoint.RecordTypeCNAME, 563 Targets: endpoint.Targets{"lb.com"}, 564 }, 565 { 566 DNSName: "new.org", 567 RecordType: endpoint.RecordTypeA, 568 Targets: endpoint.Targets{"8.8.8.8"}, 569 }, 570 { 571 DNSName: "new.org", 572 RecordType: endpoint.RecordTypeCNAME, 573 Targets: endpoint.Targets{"lb.com"}, 574 }, 575 }, 576 }, 577 { 578 title: "two simple gateways on different namespaces, one ingressgateway loadbalancer service", 579 targetNamespace: "", 580 lbServices: []fakeIngressGatewayService{ 581 { 582 ips: []string{"8.8.8.8"}, 583 hostnames: []string{"lb.com"}, 584 }, 585 }, 586 configItems: []fakeGatewayConfig{ 587 { 588 name: "fake1", 589 namespace: "", 590 dnsnames: [][]string{{"example.org"}}, 591 }, 592 { 593 name: "fake2", 594 namespace: "", 595 dnsnames: [][]string{{"new.org"}}, 596 }, 597 }, 598 expected: []*endpoint.Endpoint{ 599 { 600 DNSName: "example.org", 601 RecordType: endpoint.RecordTypeA, 602 Targets: endpoint.Targets{"8.8.8.8"}, 603 }, 604 { 605 DNSName: "example.org", 606 RecordType: endpoint.RecordTypeCNAME, 607 Targets: endpoint.Targets{"lb.com"}, 608 }, 609 { 610 DNSName: "new.org", 611 RecordType: endpoint.RecordTypeA, 612 Targets: endpoint.Targets{"8.8.8.8"}, 613 }, 614 { 615 DNSName: "new.org", 616 RecordType: endpoint.RecordTypeCNAME, 617 Targets: endpoint.Targets{"lb.com"}, 618 }, 619 }, 620 }, 621 { 622 title: "two simple gateways on different namespaces and a target namespace, one ingressgateway loadbalancer service", 623 targetNamespace: "testing1", 624 lbServices: []fakeIngressGatewayService{ 625 { 626 ips: []string{"8.8.8.8"}, 627 hostnames: []string{"lb.com"}, 628 namespace: "testing1", 629 }, 630 }, 631 configItems: []fakeGatewayConfig{ 632 { 633 name: "fake1", 634 namespace: "testing1", 635 dnsnames: [][]string{{"example.org"}}, 636 }, 637 }, 638 expected: []*endpoint.Endpoint{ 639 { 640 DNSName: "example.org", 641 RecordType: endpoint.RecordTypeA, 642 Targets: endpoint.Targets{"8.8.8.8"}, 643 }, 644 { 645 DNSName: "example.org", 646 RecordType: endpoint.RecordTypeCNAME, 647 Targets: endpoint.Targets{"lb.com"}, 648 }, 649 }, 650 }, 651 { 652 title: "one simple gateways on different namespace and a target namespace, one ingress service", 653 targetNamespace: "testing1", 654 ingresses: []fakeIngress{ 655 { 656 name: "ingress1", 657 ips: []string{"8.8.8.8"}, 658 hostnames: []string{"lb.com"}, 659 namespace: "testing2", 660 }, 661 }, 662 configItems: []fakeGatewayConfig{ 663 { 664 name: "fake1", 665 namespace: "testing1", 666 dnsnames: [][]string{{"example.org"}}, 667 annotations: map[string]string{ 668 IstioGatewayIngressSource: "testing2/ingress1", 669 }, 670 }, 671 }, 672 expected: []*endpoint.Endpoint{ 673 { 674 DNSName: "example.org", 675 RecordType: endpoint.RecordTypeA, 676 Targets: endpoint.Targets{"8.8.8.8"}, 677 }, 678 { 679 DNSName: "example.org", 680 RecordType: endpoint.RecordTypeCNAME, 681 Targets: endpoint.Targets{"lb.com"}, 682 }, 683 }, 684 }, 685 { 686 title: "valid matching annotation filter expression", 687 targetNamespace: "", 688 annotationFilter: "kubernetes.io/gateway.class in (alb, nginx)", 689 lbServices: []fakeIngressGatewayService{ 690 { 691 ips: []string{"8.8.8.8"}, 692 }, 693 }, 694 configItems: []fakeGatewayConfig{ 695 { 696 name: "fake1", 697 namespace: "", 698 annotations: map[string]string{ 699 "kubernetes.io/gateway.class": "nginx", 700 }, 701 dnsnames: [][]string{{"example.org"}}, 702 }, 703 }, 704 expected: []*endpoint.Endpoint{ 705 { 706 DNSName: "example.org", 707 RecordType: endpoint.RecordTypeA, 708 Targets: endpoint.Targets{"8.8.8.8"}, 709 }, 710 }, 711 }, 712 { 713 title: "valid non-matching annotation filter expression", 714 targetNamespace: "", 715 annotationFilter: "kubernetes.io/gateway.class in (alb, nginx)", 716 lbServices: []fakeIngressGatewayService{ 717 { 718 ips: []string{"8.8.8.8"}, 719 }, 720 }, 721 configItems: []fakeGatewayConfig{ 722 { 723 name: "fake1", 724 namespace: "", 725 annotations: map[string]string{ 726 "kubernetes.io/gateway.class": "tectonic", 727 }, 728 dnsnames: [][]string{{"example.org"}}, 729 }, 730 }, 731 expected: []*endpoint.Endpoint{}, 732 }, 733 { 734 title: "invalid annotation filter expression", 735 targetNamespace: "", 736 annotationFilter: "kubernetes.io/gateway.name in (a b)", 737 lbServices: []fakeIngressGatewayService{ 738 { 739 ips: []string{"8.8.8.8"}, 740 }, 741 }, 742 configItems: []fakeGatewayConfig{ 743 { 744 name: "fake1", 745 namespace: "", 746 annotations: map[string]string{ 747 "kubernetes.io/gateway.class": "alb", 748 }, 749 dnsnames: [][]string{{"example.org"}}, 750 }, 751 }, 752 expected: []*endpoint.Endpoint{}, 753 expectError: true, 754 }, 755 { 756 title: "valid matching annotation filter label", 757 targetNamespace: "", 758 annotationFilter: "kubernetes.io/gateway.class=nginx", 759 lbServices: []fakeIngressGatewayService{ 760 { 761 ips: []string{"8.8.8.8"}, 762 }, 763 }, 764 configItems: []fakeGatewayConfig{ 765 { 766 name: "fake1", 767 namespace: "", 768 annotations: map[string]string{ 769 "kubernetes.io/gateway.class": "nginx", 770 }, 771 dnsnames: [][]string{{"example.org"}}, 772 }, 773 }, 774 expected: []*endpoint.Endpoint{ 775 { 776 DNSName: "example.org", 777 RecordType: endpoint.RecordTypeA, 778 Targets: endpoint.Targets{"8.8.8.8"}, 779 }, 780 }, 781 }, 782 { 783 title: "valid non-matching annotation filter label", 784 targetNamespace: "", 785 annotationFilter: "kubernetes.io/gateway.class=nginx", 786 lbServices: []fakeIngressGatewayService{ 787 { 788 ips: []string{"8.8.8.8"}, 789 }, 790 }, 791 configItems: []fakeGatewayConfig{ 792 { 793 name: "fake1", 794 namespace: "", 795 annotations: map[string]string{ 796 "kubernetes.io/gateway.class": "alb", 797 }, 798 dnsnames: [][]string{{"example.org"}}, 799 }, 800 }, 801 expected: []*endpoint.Endpoint{}, 802 }, 803 { 804 title: "our controller type is dns-controller", 805 targetNamespace: "", 806 lbServices: []fakeIngressGatewayService{ 807 { 808 ips: []string{"8.8.8.8"}, 809 }, 810 }, 811 configItems: []fakeGatewayConfig{ 812 { 813 name: "fake1", 814 namespace: "", 815 annotations: map[string]string{ 816 controllerAnnotationKey: controllerAnnotationValue, 817 }, 818 dnsnames: [][]string{{"example.org"}}, 819 }, 820 }, 821 expected: []*endpoint.Endpoint{ 822 { 823 DNSName: "example.org", 824 RecordType: endpoint.RecordTypeA, 825 Targets: endpoint.Targets{"8.8.8.8"}, 826 }, 827 }, 828 }, 829 { 830 title: "different controller types are ignored", 831 targetNamespace: "", 832 lbServices: []fakeIngressGatewayService{ 833 { 834 ips: []string{"8.8.8.8"}, 835 }, 836 }, 837 configItems: []fakeGatewayConfig{ 838 { 839 name: "fake1", 840 namespace: "", 841 annotations: map[string]string{ 842 controllerAnnotationKey: "some-other-tool", 843 }, 844 dnsnames: [][]string{{"example.org"}}, 845 }, 846 }, 847 expected: []*endpoint.Endpoint{}, 848 }, 849 { 850 title: "template for gateway if host is missing", 851 targetNamespace: "", 852 lbServices: []fakeIngressGatewayService{ 853 { 854 ips: []string{"8.8.8.8"}, 855 hostnames: []string{"elb.com"}, 856 }, 857 }, 858 configItems: []fakeGatewayConfig{ 859 { 860 name: "fake1", 861 namespace: "", 862 annotations: map[string]string{ 863 controllerAnnotationKey: controllerAnnotationValue, 864 }, 865 dnsnames: [][]string{}, 866 }, 867 }, 868 expected: []*endpoint.Endpoint{ 869 { 870 DNSName: "fake1.ext-dns.test.com", 871 RecordType: endpoint.RecordTypeA, 872 Targets: endpoint.Targets{"8.8.8.8"}, 873 }, 874 { 875 DNSName: "fake1.ext-dns.test.com", 876 RecordType: endpoint.RecordTypeCNAME, 877 Targets: endpoint.Targets{"elb.com"}, 878 }, 879 }, 880 fqdnTemplate: "{{.Name}}.ext-dns.test.com", 881 }, 882 { 883 title: "another controller annotation skipped even with template", 884 targetNamespace: "", 885 lbServices: []fakeIngressGatewayService{ 886 { 887 ips: []string{"8.8.8.8"}, 888 }, 889 }, 890 configItems: []fakeGatewayConfig{ 891 { 892 name: "fake1", 893 namespace: "", 894 annotations: map[string]string{ 895 controllerAnnotationKey: "other-controller", 896 }, 897 dnsnames: [][]string{}, 898 }, 899 }, 900 expected: []*endpoint.Endpoint{}, 901 fqdnTemplate: "{{.Name}}.ext-dns.test.com", 902 }, 903 { 904 title: "multiple FQDN template hostnames", 905 targetNamespace: "", 906 lbServices: []fakeIngressGatewayService{ 907 { 908 ips: []string{"8.8.8.8"}, 909 }, 910 }, 911 configItems: []fakeGatewayConfig{ 912 { 913 name: "fake1", 914 namespace: "", 915 annotations: map[string]string{}, 916 dnsnames: [][]string{}, 917 }, 918 }, 919 expected: []*endpoint.Endpoint{ 920 { 921 DNSName: "fake1.ext-dns.test.com", 922 Targets: endpoint.Targets{"8.8.8.8"}, 923 RecordType: endpoint.RecordTypeA, 924 }, 925 { 926 DNSName: "fake1.ext-dna.test.com", 927 Targets: endpoint.Targets{"8.8.8.8"}, 928 RecordType: endpoint.RecordTypeA, 929 }, 930 }, 931 fqdnTemplate: "{{.Name}}.ext-dns.test.com, {{.Name}}.ext-dna.test.com", 932 }, 933 { 934 title: "multiple FQDN template hostnames", 935 targetNamespace: "", 936 lbServices: []fakeIngressGatewayService{ 937 { 938 ips: []string{"8.8.8.8"}, 939 }, 940 }, 941 configItems: []fakeGatewayConfig{ 942 { 943 name: "fake1", 944 namespace: "", 945 annotations: map[string]string{}, 946 dnsnames: [][]string{}, 947 }, 948 { 949 name: "fake2", 950 namespace: "", 951 annotations: map[string]string{ 952 targetAnnotationKey: "gateway-target.com", 953 }, 954 dnsnames: [][]string{{"example.org"}}, 955 }, 956 }, 957 expected: []*endpoint.Endpoint{ 958 { 959 DNSName: "fake1.ext-dns.test.com", 960 Targets: endpoint.Targets{"8.8.8.8"}, 961 RecordType: endpoint.RecordTypeA, 962 }, 963 { 964 DNSName: "fake1.ext-dna.test.com", 965 Targets: endpoint.Targets{"8.8.8.8"}, 966 RecordType: endpoint.RecordTypeA, 967 }, 968 { 969 DNSName: "example.org", 970 Targets: endpoint.Targets{"gateway-target.com"}, 971 RecordType: endpoint.RecordTypeCNAME, 972 }, 973 { 974 DNSName: "fake2.ext-dns.test.com", 975 Targets: endpoint.Targets{"gateway-target.com"}, 976 RecordType: endpoint.RecordTypeCNAME, 977 }, 978 { 979 DNSName: "fake2.ext-dna.test.com", 980 Targets: endpoint.Targets{"gateway-target.com"}, 981 RecordType: endpoint.RecordTypeCNAME, 982 }, 983 }, 984 fqdnTemplate: "{{.Name}}.ext-dns.test.com, {{.Name}}.ext-dna.test.com", 985 combineFQDNAndAnnotation: true, 986 }, 987 { 988 title: "gateway rules with annotation", 989 targetNamespace: "", 990 lbServices: []fakeIngressGatewayService{ 991 { 992 ips: []string{"8.8.8.8"}, 993 }, 994 }, 995 configItems: []fakeGatewayConfig{ 996 { 997 name: "fake1", 998 namespace: "", 999 annotations: map[string]string{ 1000 targetAnnotationKey: "gateway-target.com", 1001 }, 1002 dnsnames: [][]string{{"example.org"}}, 1003 }, 1004 { 1005 name: "fake2", 1006 namespace: "", 1007 annotations: map[string]string{ 1008 targetAnnotationKey: "gateway-target.com", 1009 }, 1010 dnsnames: [][]string{{"example2.org"}}, 1011 }, 1012 { 1013 name: "fake3", 1014 namespace: "", 1015 annotations: map[string]string{ 1016 IstioGatewayIngressSource: "not-real/ingress1", 1017 targetAnnotationKey: "1.2.3.4", 1018 }, 1019 dnsnames: [][]string{{"example3.org"}}, 1020 }, 1021 }, 1022 expected: []*endpoint.Endpoint{ 1023 { 1024 DNSName: "example.org", 1025 Targets: endpoint.Targets{"gateway-target.com"}, 1026 RecordType: endpoint.RecordTypeCNAME, 1027 }, 1028 { 1029 DNSName: "example2.org", 1030 Targets: endpoint.Targets{"gateway-target.com"}, 1031 RecordType: endpoint.RecordTypeCNAME, 1032 }, 1033 { 1034 DNSName: "example3.org", 1035 Targets: endpoint.Targets{"1.2.3.4"}, 1036 RecordType: endpoint.RecordTypeA, 1037 }, 1038 }, 1039 }, 1040 { 1041 title: "gateway rules with hostname annotation", 1042 targetNamespace: "", 1043 lbServices: []fakeIngressGatewayService{ 1044 { 1045 ips: []string{"1.2.3.4"}, 1046 }, 1047 }, 1048 configItems: []fakeGatewayConfig{ 1049 { 1050 name: "fake1", 1051 namespace: "", 1052 annotations: map[string]string{ 1053 hostnameAnnotationKey: "dns-through-hostname.com", 1054 }, 1055 dnsnames: [][]string{{"example.org"}}, 1056 }, 1057 }, 1058 expected: []*endpoint.Endpoint{ 1059 { 1060 DNSName: "example.org", 1061 Targets: endpoint.Targets{"1.2.3.4"}, 1062 RecordType: endpoint.RecordTypeA, 1063 }, 1064 { 1065 DNSName: "dns-through-hostname.com", 1066 Targets: endpoint.Targets{"1.2.3.4"}, 1067 RecordType: endpoint.RecordTypeA, 1068 }, 1069 }, 1070 }, 1071 { 1072 title: "gateway rules with hostname annotation having multiple hostnames", 1073 targetNamespace: "", 1074 lbServices: []fakeIngressGatewayService{ 1075 { 1076 ips: []string{"1.2.3.4"}, 1077 }, 1078 }, 1079 configItems: []fakeGatewayConfig{ 1080 { 1081 name: "fake1", 1082 namespace: "", 1083 annotations: map[string]string{ 1084 hostnameAnnotationKey: "dns-through-hostname.com, another-dns-through-hostname.com", 1085 }, 1086 dnsnames: [][]string{{"example.org"}}, 1087 }, 1088 }, 1089 expected: []*endpoint.Endpoint{ 1090 { 1091 DNSName: "example.org", 1092 Targets: endpoint.Targets{"1.2.3.4"}, 1093 RecordType: endpoint.RecordTypeA, 1094 }, 1095 { 1096 DNSName: "dns-through-hostname.com", 1097 Targets: endpoint.Targets{"1.2.3.4"}, 1098 RecordType: endpoint.RecordTypeA, 1099 }, 1100 { 1101 DNSName: "another-dns-through-hostname.com", 1102 Targets: endpoint.Targets{"1.2.3.4"}, 1103 RecordType: endpoint.RecordTypeA, 1104 }, 1105 }, 1106 }, 1107 { 1108 title: "gateway rules with hostname and target annotation", 1109 targetNamespace: "", 1110 lbServices: []fakeIngressGatewayService{ 1111 { 1112 ips: []string{}, 1113 }, 1114 }, 1115 configItems: []fakeGatewayConfig{ 1116 { 1117 name: "fake1", 1118 namespace: "", 1119 annotations: map[string]string{ 1120 hostnameAnnotationKey: "dns-through-hostname.com", 1121 targetAnnotationKey: "gateway-target.com", 1122 }, 1123 dnsnames: [][]string{{"example.org"}}, 1124 }, 1125 }, 1126 expected: []*endpoint.Endpoint{ 1127 { 1128 DNSName: "example.org", 1129 Targets: endpoint.Targets{"gateway-target.com"}, 1130 RecordType: endpoint.RecordTypeCNAME, 1131 }, 1132 { 1133 DNSName: "dns-through-hostname.com", 1134 Targets: endpoint.Targets{"gateway-target.com"}, 1135 RecordType: endpoint.RecordTypeCNAME, 1136 }, 1137 }, 1138 }, 1139 { 1140 title: "gateway rules with hostname, target and ingress annotation", 1141 targetNamespace: "", 1142 lbServices: []fakeIngressGatewayService{ 1143 { 1144 ips: []string{}, 1145 }, 1146 }, 1147 ingresses: []fakeIngress{ 1148 { 1149 name: "ingress1", 1150 ips: []string{}, 1151 }, 1152 }, 1153 configItems: []fakeGatewayConfig{ 1154 { 1155 name: "fake1", 1156 namespace: "", 1157 annotations: map[string]string{ 1158 IstioGatewayIngressSource: "ingress1", 1159 hostnameAnnotationKey: "dns-through-hostname.com", 1160 targetAnnotationKey: "gateway-target.com", 1161 }, 1162 dnsnames: [][]string{{"example.org"}}, 1163 }, 1164 }, 1165 expected: []*endpoint.Endpoint{ 1166 { 1167 DNSName: "example.org", 1168 Targets: endpoint.Targets{"gateway-target.com"}, 1169 RecordType: endpoint.RecordTypeCNAME, 1170 }, 1171 { 1172 DNSName: "dns-through-hostname.com", 1173 Targets: endpoint.Targets{"gateway-target.com"}, 1174 RecordType: endpoint.RecordTypeCNAME, 1175 }, 1176 }, 1177 }, 1178 { 1179 title: "gateway rules with annotation and custom TTL", 1180 targetNamespace: "", 1181 lbServices: []fakeIngressGatewayService{ 1182 { 1183 ips: []string{"8.8.8.8"}, 1184 }, 1185 }, 1186 configItems: []fakeGatewayConfig{ 1187 { 1188 name: "fake1", 1189 namespace: "", 1190 annotations: map[string]string{ 1191 targetAnnotationKey: "gateway-target.com", 1192 ttlAnnotationKey: "6", 1193 }, 1194 dnsnames: [][]string{{"example.org"}}, 1195 }, 1196 { 1197 name: "fake2", 1198 namespace: "", 1199 annotations: map[string]string{ 1200 targetAnnotationKey: "gateway-target.com", 1201 ttlAnnotationKey: "1", 1202 }, 1203 dnsnames: [][]string{{"example2.org"}}, 1204 }, 1205 { 1206 name: "fake3", 1207 namespace: "", 1208 annotations: map[string]string{ 1209 targetAnnotationKey: "gateway-target.com", 1210 ttlAnnotationKey: "10s", 1211 }, 1212 dnsnames: [][]string{{"example3.org"}}, 1213 }, 1214 }, 1215 expected: []*endpoint.Endpoint{ 1216 { 1217 DNSName: "example.org", 1218 RecordType: endpoint.RecordTypeCNAME, 1219 Targets: endpoint.Targets{"gateway-target.com"}, 1220 RecordTTL: endpoint.TTL(6), 1221 }, 1222 { 1223 DNSName: "example2.org", 1224 RecordType: endpoint.RecordTypeCNAME, 1225 Targets: endpoint.Targets{"gateway-target.com"}, 1226 RecordTTL: endpoint.TTL(1), 1227 }, 1228 { 1229 DNSName: "example3.org", 1230 RecordType: endpoint.RecordTypeCNAME, 1231 Targets: endpoint.Targets{"gateway-target.com"}, 1232 RecordTTL: endpoint.TTL(10), 1233 }, 1234 }, 1235 }, 1236 { 1237 title: "template for gateway with annotation", 1238 targetNamespace: "", 1239 lbServices: []fakeIngressGatewayService{ 1240 { 1241 ips: []string{}, 1242 hostnames: []string{}, 1243 }, 1244 }, 1245 configItems: []fakeGatewayConfig{ 1246 { 1247 name: "fake1", 1248 namespace: "", 1249 annotations: map[string]string{ 1250 targetAnnotationKey: "gateway-target.com", 1251 }, 1252 dnsnames: [][]string{}, 1253 }, 1254 { 1255 name: "fake2", 1256 namespace: "", 1257 annotations: map[string]string{ 1258 targetAnnotationKey: "gateway-target.com", 1259 }, 1260 dnsnames: [][]string{}, 1261 }, 1262 { 1263 name: "fake3", 1264 namespace: "", 1265 annotations: map[string]string{ 1266 targetAnnotationKey: "1.2.3.4", 1267 }, 1268 dnsnames: [][]string{}, 1269 }, 1270 }, 1271 expected: []*endpoint.Endpoint{ 1272 { 1273 DNSName: "fake1.ext-dns.test.com", 1274 Targets: endpoint.Targets{"gateway-target.com"}, 1275 RecordType: endpoint.RecordTypeCNAME, 1276 }, 1277 { 1278 DNSName: "fake2.ext-dns.test.com", 1279 Targets: endpoint.Targets{"gateway-target.com"}, 1280 RecordType: endpoint.RecordTypeCNAME, 1281 }, 1282 { 1283 DNSName: "fake3.ext-dns.test.com", 1284 Targets: endpoint.Targets{"1.2.3.4"}, 1285 RecordType: endpoint.RecordTypeA, 1286 }, 1287 }, 1288 fqdnTemplate: "{{.Name}}.ext-dns.test.com", 1289 }, 1290 { 1291 title: "Ingress with empty annotation", 1292 targetNamespace: "", 1293 lbServices: []fakeIngressGatewayService{ 1294 { 1295 ips: []string{}, 1296 hostnames: []string{}, 1297 }, 1298 }, 1299 configItems: []fakeGatewayConfig{ 1300 { 1301 name: "fake1", 1302 namespace: "", 1303 annotations: map[string]string{ 1304 targetAnnotationKey: "", 1305 }, 1306 dnsnames: [][]string{}, 1307 }, 1308 }, 1309 expected: []*endpoint.Endpoint{}, 1310 fqdnTemplate: "{{.Name}}.ext-dns.test.com", 1311 }, 1312 { 1313 title: "Gateway with empty ingress annotation", 1314 targetNamespace: "", 1315 lbServices: []fakeIngressGatewayService{ 1316 { 1317 ips: []string{}, 1318 hostnames: []string{}, 1319 }, 1320 }, 1321 ingresses: []fakeIngress{ 1322 { 1323 name: "ingress1", 1324 ips: []string{}, 1325 hostnames: []string{}, 1326 }, 1327 }, 1328 configItems: []fakeGatewayConfig{ 1329 { 1330 name: "fake1", 1331 namespace: "", 1332 annotations: map[string]string{ 1333 IstioGatewayIngressSource: "", 1334 }, 1335 dnsnames: [][]string{}, 1336 }, 1337 }, 1338 expected: []*endpoint.Endpoint{}, 1339 fqdnTemplate: "{{.Name}}.ext-dns.test.com", 1340 }, 1341 { 1342 title: "ignore hostname annotations", 1343 targetNamespace: "", 1344 lbServices: []fakeIngressGatewayService{ 1345 { 1346 ips: []string{"8.8.8.8"}, 1347 hostnames: []string{"lb.com"}, 1348 }, 1349 }, 1350 configItems: []fakeGatewayConfig{ 1351 { 1352 name: "fake1", 1353 namespace: "", 1354 annotations: map[string]string{ 1355 hostnameAnnotationKey: "ignore.me", 1356 }, 1357 dnsnames: [][]string{{"example.org"}}, 1358 }, 1359 { 1360 name: "fake2", 1361 namespace: "", 1362 annotations: map[string]string{ 1363 hostnameAnnotationKey: "ignore.me.too", 1364 }, 1365 dnsnames: [][]string{{"new.org"}}, 1366 }, 1367 }, 1368 expected: []*endpoint.Endpoint{ 1369 { 1370 DNSName: "example.org", 1371 RecordType: endpoint.RecordTypeA, 1372 Targets: endpoint.Targets{"8.8.8.8"}, 1373 }, 1374 { 1375 DNSName: "example.org", 1376 RecordType: endpoint.RecordTypeCNAME, 1377 Targets: endpoint.Targets{"lb.com"}, 1378 }, 1379 { 1380 DNSName: "new.org", 1381 RecordType: endpoint.RecordTypeA, 1382 Targets: endpoint.Targets{"8.8.8.8"}, 1383 }, 1384 { 1385 DNSName: "new.org", 1386 RecordType: endpoint.RecordTypeCNAME, 1387 Targets: endpoint.Targets{"lb.com"}, 1388 }, 1389 }, 1390 ignoreHostnameAnnotation: true, 1391 }, 1392 { 1393 title: "gateways with wildcard host", 1394 targetNamespace: "", 1395 lbServices: []fakeIngressGatewayService{ 1396 { 1397 ips: []string{"1.2.3.4"}, 1398 }, 1399 }, 1400 configItems: []fakeGatewayConfig{ 1401 { 1402 name: "fake1", 1403 namespace: "", 1404 dnsnames: [][]string{{"*"}}, 1405 }, 1406 { 1407 name: "fake2", 1408 namespace: "", 1409 dnsnames: [][]string{{"some-namespace/*"}}, 1410 }, 1411 }, 1412 expected: []*endpoint.Endpoint{}, 1413 }, 1414 { 1415 title: "gateways with wildcard host and hostname annotation", 1416 targetNamespace: "", 1417 lbServices: []fakeIngressGatewayService{ 1418 { 1419 ips: []string{"1.2.3.4"}, 1420 }, 1421 }, 1422 configItems: []fakeGatewayConfig{ 1423 { 1424 name: "fake1", 1425 namespace: "", 1426 annotations: map[string]string{ 1427 hostnameAnnotationKey: "fake1.dns-through-hostname.com", 1428 }, 1429 dnsnames: [][]string{{"*"}}, 1430 }, 1431 { 1432 name: "fake2", 1433 namespace: "", 1434 annotations: map[string]string{ 1435 hostnameAnnotationKey: "fake2.dns-through-hostname.com", 1436 }, 1437 dnsnames: [][]string{{"some-namespace/*"}}, 1438 }, 1439 }, 1440 expected: []*endpoint.Endpoint{ 1441 { 1442 DNSName: "fake1.dns-through-hostname.com", 1443 RecordType: endpoint.RecordTypeA, 1444 Targets: endpoint.Targets{"1.2.3.4"}, 1445 }, 1446 { 1447 DNSName: "fake2.dns-through-hostname.com", 1448 RecordType: endpoint.RecordTypeA, 1449 Targets: endpoint.Targets{"1.2.3.4"}, 1450 }, 1451 }, 1452 }, 1453 { 1454 title: "gateways with ingress annotation; ingress not found", 1455 targetNamespace: "", 1456 ingresses: []fakeIngress{ 1457 { 1458 name: "ingress1", 1459 ips: []string{"8.8.8.8"}, 1460 }, 1461 }, 1462 configItems: []fakeGatewayConfig{ 1463 { 1464 name: "fake1", 1465 namespace: "", 1466 annotations: map[string]string{ 1467 IstioGatewayIngressSource: "ingress2", 1468 }, 1469 dnsnames: [][]string{{"new.org"}}, 1470 }, 1471 }, 1472 expected: []*endpoint.Endpoint{}, 1473 expectError: true, 1474 }, 1475 } { 1476 ti := ti 1477 t.Run(ti.title, func(t *testing.T) { 1478 t.Parallel() 1479 1480 fakeKubernetesClient := fake.NewSimpleClientset() 1481 1482 for _, lb := range ti.lbServices { 1483 service := lb.Service() 1484 _, err := fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(context.Background(), service, metav1.CreateOptions{}) 1485 require.NoError(t, err) 1486 } 1487 1488 for _, ing := range ti.ingresses { 1489 ingress := ing.Ingress() 1490 _, err := fakeKubernetesClient.NetworkingV1().Ingresses(ingress.Namespace).Create(context.Background(), ingress, metav1.CreateOptions{}) 1491 require.NoError(t, err) 1492 } 1493 1494 fakeIstioClient := istiofake.NewSimpleClientset() 1495 for _, config := range ti.configItems { 1496 gatewayCfg := config.Config() 1497 _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(ti.targetNamespace).Create(context.Background(), gatewayCfg, metav1.CreateOptions{}) 1498 require.NoError(t, err) 1499 } 1500 1501 gatewaySource, err := NewIstioGatewaySource( 1502 context.TODO(), 1503 fakeKubernetesClient, 1504 fakeIstioClient, 1505 ti.targetNamespace, 1506 ti.annotationFilter, 1507 ti.fqdnTemplate, 1508 ti.combineFQDNAndAnnotation, 1509 ti.ignoreHostnameAnnotation, 1510 ) 1511 require.NoError(t, err) 1512 1513 res, err := gatewaySource.Endpoints(context.Background()) 1514 if ti.expectError { 1515 assert.Error(t, err) 1516 } else { 1517 assert.NoError(t, err) 1518 } 1519 1520 validateEndpoints(t, res, ti.expected) 1521 }) 1522 } 1523 } 1524 1525 // gateway specific helper functions 1526 func newTestGatewaySource(loadBalancerList []fakeIngressGatewayService, ingressList []fakeIngress) (*gatewaySource, error) { 1527 fakeKubernetesClient := fake.NewSimpleClientset() 1528 fakeIstioClient := istiofake.NewSimpleClientset() 1529 1530 for _, lb := range loadBalancerList { 1531 service := lb.Service() 1532 _, err := fakeKubernetesClient.CoreV1().Services(service.Namespace).Create(context.Background(), service, metav1.CreateOptions{}) 1533 if err != nil { 1534 return nil, err 1535 } 1536 } 1537 for _, ing := range ingressList { 1538 ingress := ing.Ingress() 1539 _, err := fakeKubernetesClient.NetworkingV1().Ingresses(ingress.Namespace).Create(context.Background(), ingress, metav1.CreateOptions{}) 1540 if err != nil { 1541 return nil, err 1542 } 1543 } 1544 1545 src, err := NewIstioGatewaySource( 1546 context.TODO(), 1547 fakeKubernetesClient, 1548 fakeIstioClient, 1549 "", 1550 "", 1551 "{{.Name}}", 1552 false, 1553 false, 1554 ) 1555 if err != nil { 1556 return nil, err 1557 } 1558 1559 gwsrc, ok := src.(*gatewaySource) 1560 if !ok { 1561 return nil, errors.New("underlying source type was not gateway") 1562 } 1563 1564 return gwsrc, nil 1565 } 1566 1567 type fakeIngressGatewayService struct { 1568 ips []string 1569 hostnames []string 1570 namespace string 1571 name string 1572 selector map[string]string 1573 externalIPs []string 1574 } 1575 1576 func (ig fakeIngressGatewayService) Service() *v1.Service { 1577 svc := &v1.Service{ 1578 ObjectMeta: metav1.ObjectMeta{ 1579 Namespace: ig.namespace, 1580 Name: ig.name, 1581 }, 1582 Status: v1.ServiceStatus{ 1583 LoadBalancer: v1.LoadBalancerStatus{ 1584 Ingress: []v1.LoadBalancerIngress{}, 1585 }, 1586 }, 1587 Spec: v1.ServiceSpec{ 1588 Selector: ig.selector, 1589 ExternalIPs: ig.externalIPs, 1590 }, 1591 } 1592 1593 for _, ip := range ig.ips { 1594 svc.Status.LoadBalancer.Ingress = append(svc.Status.LoadBalancer.Ingress, v1.LoadBalancerIngress{ 1595 IP: ip, 1596 }) 1597 } 1598 for _, hostname := range ig.hostnames { 1599 svc.Status.LoadBalancer.Ingress = append(svc.Status.LoadBalancer.Ingress, v1.LoadBalancerIngress{ 1600 Hostname: hostname, 1601 }) 1602 } 1603 1604 return svc 1605 } 1606 1607 type fakeGatewayConfig struct { 1608 namespace string 1609 name string 1610 annotations map[string]string 1611 dnsnames [][]string 1612 selector map[string]string 1613 } 1614 1615 func (c fakeGatewayConfig) Config() *networkingv1alpha3.Gateway { 1616 gw := &networkingv1alpha3.Gateway{ 1617 ObjectMeta: metav1.ObjectMeta{ 1618 Name: c.name, 1619 Namespace: c.namespace, 1620 Annotations: c.annotations, 1621 }, 1622 Spec: networkingv1alpha3api.Gateway{ 1623 Servers: nil, 1624 Selector: c.selector, 1625 }, 1626 } 1627 1628 var servers []*networkingv1alpha3api.Server 1629 for _, dnsnames := range c.dnsnames { 1630 servers = append(servers, &networkingv1alpha3api.Server{ 1631 Hosts: dnsnames, 1632 }) 1633 } 1634 1635 gw.Spec.Servers = servers 1636 1637 return gw 1638 }