Skip to content

Commit

Permalink
feat(istio): support for ExternalIPs in Istio resources
Browse files Browse the repository at this point in the history
✨ Add support for ExternalIPs in Istio Gateway and VirtualService
ℹ️ This commit extends Istio Gateway and VirtualService resources
to support ExternalIPs. The changes include:
- Checking if service has ExternalIPs defined
- If yes, adding them to the list of targets
- If not, continuing with the existing process

👌 Now you can have your Istio resources use `externalIPs` too! 🎉

Not to be `ip`-percritical, but don't we all love an `ip`grade! 🎈

Signed-off-by: Karsten Siemer <karsten.siemer@sda.se>
  • Loading branch information
KarstenSiemer committed Dec 5, 2023
1 parent 832bcb5 commit 0ae597d
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 16 deletions.
5 changes: 5 additions & 0 deletions source/istio_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networ
continue
}

if len(service.Spec.ExternalIPs) > 0 {
targets = append(targets, service.Spec.ExternalIPs...)
continue
}

for _, lb := range service.Status.LoadBalancer.Ingress {
if lb.IP != "" {
targets = append(targets, lb.IP)
Expand Down
66 changes: 56 additions & 10 deletions source/istio_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
title: "no rule.host",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
config: fakeGatewayConfig{
Expand All @@ -350,8 +351,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
title: "one empty rule.host",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
config: fakeGatewayConfig{
Expand Down Expand Up @@ -447,6 +449,48 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
},
},
{
title: "one rule.host one lb.externalIP",
lbServices: []fakeIngressGatewayService{
{
externalIPs: []string{"8.8.8.8"},
},
},
config: fakeGatewayConfig{
dnsnames: [][]string{
{"foo.bar"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
{
title: "one rule.host two lb.IP, two lb.Hostname and two lb.externalIP",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
config: fakeGatewayConfig{
dnsnames: [][]string{
{"foo.bar"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.1.1.1", "2.2.2.2"},
},
},
},
} {
ti := ti
t.Run(ti.title, func(t *testing.T) {
Expand Down Expand Up @@ -1521,11 +1565,12 @@ func newTestGatewaySource(loadBalancerList []fakeIngressGatewayService, ingressL
}

type fakeIngressGatewayService struct {
ips []string
hostnames []string
namespace string
name string
selector map[string]string
ips []string
hostnames []string
namespace string
name string
selector map[string]string
externalIPs []string
}

func (ig fakeIngressGatewayService) Service() *v1.Service {
Expand All @@ -1540,7 +1585,8 @@ func (ig fakeIngressGatewayService) Service() *v1.Service {
},
},
Spec: v1.ServiceSpec{
Selector: ig.selector,
Selector: ig.selector,
ExternalIPs: ig.externalIPs,
},
}

Expand Down
5 changes: 5 additions & 0 deletions source/istio_virtualservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway
continue
}

if len(service.Spec.ExternalIPs) > 0 {
targets = append(targets, service.Spec.ExternalIPs...)
continue
}

for _, lb := range service.Status.LoadBalancer.Ingress {
if lb.IP != "" {
targets = append(targets, lb.IP)
Expand Down
137 changes: 131 additions & 6 deletions source/istio_virtualservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,29 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
},
},
{
title: "one rule.host one lb.externalIPs",
lbServices: []fakeIngressGatewayService{
{
externalIPs: []string{"8.8.8.8"},
},
},
gwconfig: fakeGatewayConfig{
name: "mygw",
dnsnames: [][]string{{"*"}},
},
vsconfig: fakeVirtualServiceConfig{
gateways: []string{"mygw"},
dnsnames: []string{"foo.bar"},
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
{
title: "one rule.host two lb.IP and two lb.Hostname",
lbServices: []fakeIngressGatewayService{
Expand Down Expand Up @@ -479,12 +502,38 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
},
},
{
title: "one rule.host two lb.IP and two lb.Hostname and two lb.externalIPs",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
gwconfig: fakeGatewayConfig{
name: "mygw",
dnsnames: [][]string{{"*"}},
},
vsconfig: fakeVirtualServiceConfig{
gateways: []string{"mygw"},
dnsnames: []string{"foo.bar"},
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.1.1.1", "2.2.2.2"},
},
},
},
{
title: "no rule.host",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
gwconfig: fakeGatewayConfig{
Expand All @@ -501,8 +550,9 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
title: "no rule.gateway",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
gwconfig: fakeGatewayConfig{
Expand All @@ -519,8 +569,9 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
title: "one empty rule.host",
lbServices: []fakeIngressGatewayService{
{
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
ips: []string{"8.8.8.8", "127.0.0.1"},
hostnames: []string{"elb.com", "alb.com"},
externalIPs: []string{"1.1.1.1", "2.2.2.2"},
},
},
gwconfig: fakeGatewayConfig{
Expand Down Expand Up @@ -844,6 +895,42 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
},
},
{
title: "one virtualservice with two gateways, one ingressgateway loadbalancer service with externalIPs",
lbServices: []fakeIngressGatewayService{
{
namespace: namespace,
externalIPs: []string{"8.8.8.8"},
},
},
gwConfigs: []fakeGatewayConfig{
{
name: "gw1",
namespace: namespace,
dnsnames: [][]string{{"*"}},
},
{
name: "gw2",
namespace: namespace,
dnsnames: [][]string{{"*"}},
},
},
vsConfigs: []fakeVirtualServiceConfig{
{
name: "vs",
namespace: namespace,
gateways: []string{"gw1", "gw2"},
dnsnames: []string{"example.org"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
{
title: "two simple virtualservices on different namespaces with the same target gateway, one ingressgateway loadbalancer service",
lbServices: []fakeIngressGatewayService{
Expand Down Expand Up @@ -941,6 +1028,44 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
},
},
{
title: "two simple virtualservices with one gateway on different namespaces and a target namespace, one ingressgateway loadbalancer service with externalIPs",
targetNamespace: "testing1",
lbServices: []fakeIngressGatewayService{
{
externalIPs: []string{"8.8.8.8"},
namespace: "testing1",
},
},
gwConfigs: []fakeGatewayConfig{
{
name: "fake1",
namespace: "testing1",
dnsnames: [][]string{{"*"}},
},
},
vsConfigs: []fakeVirtualServiceConfig{
{
name: "vs1",
namespace: "testing1",
gateways: []string{"testing1/fake1"},
dnsnames: []string{"example.org"},
},
{
name: "vs2",
namespace: "testing2",
gateways: []string{"testing1/fake1"},
dnsnames: []string{"new.org"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
{
title: "two simple virtualservices with one gateway on different namespaces and a target namespace, one ingress",
targetNamespace: "testing1",
Expand Down

0 comments on commit 0ae597d

Please sign in to comment.