plugin/kubernetes: Add support for dual stack ClusterIP Services (#4339)

* support dual stack clusterIPs

Signed-off-by: Chris O'Haver <cohaver@infoblox.com>

* stickler

Signed-off-by: Chris O'Haver <cohaver@infoblox.com>

* fix ClusterIPs make

Signed-off-by: Chris O'Haver <cohaver@infoblox.com>
This commit is contained in:
Chris O'Haver 2020-12-21 05:30:24 -05:00 committed by GitHub
parent 302434e392
commit 51c05679e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 204 additions and 111 deletions

View file

@ -71,17 +71,25 @@ func (APIConnServiceTest) Modified() int64 { return 0
func (APIConnServiceTest) SvcIndex(string) []*object.Service {
svcs := []*object.Service{
{
Name: "svc1",
Namespace: "testns",
ClusterIP: "10.0.0.1",
Name: "svc1",
Namespace: "testns",
ClusterIPs: []string{"10.0.0.1"},
Ports: []api.ServicePort{
{Name: "http", Protocol: "tcp", Port: 80},
},
},
{
Name: "hdls1",
Namespace: "testns",
ClusterIP: api.ClusterIPNone,
Name: "svc-dual-stack",
Namespace: "testns",
ClusterIPs: []string{"10.0.0.2", "10::2"},
Ports: []api.ServicePort{
{Name: "http", Protocol: "tcp", Port: 80},
},
},
{
Name: "hdls1",
Namespace: "testns",
ClusterIPs: []string{api.ClusterIPNone},
},
{
Name: "external",
@ -99,17 +107,25 @@ func (APIConnServiceTest) SvcIndex(string) []*object.Service {
func (APIConnServiceTest) ServiceList() []*object.Service {
svcs := []*object.Service{
{
Name: "svc1",
Namespace: "testns",
ClusterIP: "10.0.0.1",
Name: "svc1",
Namespace: "testns",
ClusterIPs: []string{"10.0.0.1"},
Ports: []api.ServicePort{
{Name: "http", Protocol: "tcp", Port: 80},
},
},
{
Name: "hdls1",
Namespace: "testns",
ClusterIP: api.ClusterIPNone,
Name: "svc-dual-stack",
Namespace: "testns",
ClusterIPs: []string{"10.0.0.2", "10::2"},
Ports: []api.ServicePort{
{Name: "http", Protocol: "tcp", Port: 80},
},
},
{
Name: "hdls1",
Namespace: "testns",
ClusterIPs: []string{api.ClusterIPNone},
},
{
Name: "external",
@ -256,19 +272,29 @@ func TestServices(t *testing.T) {
type svcTest struct {
qname string
qtype uint16
answer svcAns
answer []svcAns
}
tests := []svcTest{
// Cluster IP Services
{qname: "svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "10.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1"}},
{qname: "_http._tcp.svc1.testns.svc.interwebs.test.", qtype: dns.TypeSRV, answer: svcAns{host: "10.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1"}},
{qname: "ep1a.svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "172.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1/ep1a"}},
{qname: "svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: []svcAns{{host: "10.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1"}}},
{qname: "_http._tcp.svc1.testns.svc.interwebs.test.", qtype: dns.TypeSRV, answer: []svcAns{{host: "10.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1"}}},
{qname: "ep1a.svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: []svcAns{{host: "172.0.0.1", key: "/" + coredns + "/test/interwebs/svc/testns/svc1/ep1a"}}},
// Dual-Stack Cluster IP Service
{
qname: "_http._tcp.svc-dual-stack.testns.svc.interwebs.test.",
qtype: dns.TypeSRV,
answer: []svcAns{
{host: "10.0.0.2", key: "/" + coredns + "/test/interwebs/svc/testns/svc-dual-stack"},
{host: "10::2", key: "/" + coredns + "/test/interwebs/svc/testns/svc-dual-stack"},
},
},
// External Services
{qname: "external.testns.svc.interwebs.test.", qtype: dns.TypeCNAME, answer: svcAns{host: "coredns.io", key: "/" + coredns + "/test/interwebs/svc/testns/external"}},
{qname: "external.testns.svc.interwebs.test.", qtype: dns.TypeCNAME, answer: []svcAns{{host: "coredns.io", key: "/" + coredns + "/test/interwebs/svc/testns/external"}}},
// Headless Services
{qname: "hdls1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "172.0.0.2", key: "/" + coredns + "/test/interwebs/svc/testns/hdls1/172-0-0-2"}},
{qname: "hdls1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: []svcAns{{host: "172.0.0.2", key: "/" + coredns + "/test/interwebs/svc/testns/hdls1/172-0-0-2"}}},
}
for i, test := range tests {
@ -281,16 +307,18 @@ func TestServices(t *testing.T) {
t.Errorf("Test %d: got error '%v'", i, e)
continue
}
if len(svcs) != 1 {
t.Errorf("Test %d, expected 1 answer, got %v", i, len(svcs))
if len(svcs) != len(test.answer) {
t.Errorf("Test %d, expected %v answer, got %v", i, len(test.answer), len(svcs))
continue
}
if test.answer.host != svcs[0].Host {
t.Errorf("Test %d, expected host '%v', got '%v'", i, test.answer.host, svcs[0].Host)
}
if test.answer.key != svcs[0].Key {
t.Errorf("Test %d, expected key '%v', got '%v'", i, test.answer.key, svcs[0].Key)
for j := range svcs {
if test.answer[j].host != svcs[j].Host {
t.Errorf("Test %d, expected host '%v', got '%v'", i, test.answer[j].host, svcs[j].Host)
}
if test.answer[j].key != svcs[j].Key {
t.Errorf("Test %d, expected key '%v', got '%v'", i, test.answer[j].key, svcs[j].Key)
}
}
}
}