kubernetes: add multicluster support (#7266)

* kubernetes: add multicluster support

Add multicluster support via Multi-Cluster Services API (MCS-API) via a
new option `multiclusterZones` in the kubernetes plugin.

When some multicluster zones are passed to the kubernetes plugin, it
will start watching the ServiceImport objects and its associated
EndpointSlices.

Signed-off-by: Arthur Outhenin-Chalandre <arthur@cri.epita.fr>

* kubernetes: implement xfr support for multicluster zones

Signed-off-by: Arthur Outhenin-Chalandre <arthur@cri.epita.fr>

---------

Signed-off-by: Arthur Outhenin-Chalandre <arthur@cri.epita.fr>
This commit is contained in:
Arthur Outhenin-Chalandre
2025-05-19 07:58:16 +02:00
committed by GitHub
parent 76b199f829
commit 5c71bd0b87
23 changed files with 1634 additions and 298 deletions

View File

@@ -10,28 +10,31 @@ import (
func TestParseRequest(t *testing.T) {
tests := []struct {
query string
expected string // output from r.String()
query string
expected string // output from r.String()
multicluster bool
}{
// valid SRV request
{"_http._tcp.webs.mynamespace.svc.inter.webs.tests.", "http.tcp..webs.mynamespace.svc"},
{"_http._tcp.webs.mynamespace.svc.inter.webs.tests.", "http.tcp...webs.mynamespace.svc", false},
// A request of endpoint
{"1-2-3-4.webs.mynamespace.svc.inter.webs.tests.", "..1-2-3-4.webs.mynamespace.svc"},
{"1-2-3-4.webs.mynamespace.svc.inter.webs.tests.", "..1-2-3-4..webs.mynamespace.svc", false},
// bare zone
{"inter.webs.tests.", "....."},
{"inter.webs.tests.", "......", false},
// bare svc type
{"svc.inter.webs.tests.", "....."},
{"svc.inter.webs.tests.", "......", false},
// bare pod type
{"pod.inter.webs.tests.", "....."},
{"pod.inter.webs.tests.", "......", false},
// SRV request with empty segments
{"..webs.mynamespace.svc.inter.webs.tests.", "...webs.mynamespace.svc"},
{"..webs.mynamespace.svc.inter.webs.tests.", "....webs.mynamespace.svc", false},
// A multicluster request with a clusterid
{"1-2-3-4.cluster1.webs.mynamespace.svc.inter.webs.tests.", "..1-2-3-4.cluster1.webs.mynamespace.svc", true},
}
for i, tc := range tests {
m := new(dns.Msg)
m.SetQuestion(tc.query, dns.TypeA)
state := request.Request{Zone: zone, Req: m}
r, e := parseRequest(state.Name(), state.Zone)
r, e := parseRequest(state.Name(), state.Zone, tc.multicluster)
if e != nil {
t.Errorf("Test %d, expected no error, got '%v'.", i, e)
}
@@ -53,7 +56,7 @@ func TestParseInvalidRequest(t *testing.T) {
m.SetQuestion(query, dns.TypeA)
state := request.Request{Zone: zone, Req: m}
if _, e := parseRequest(state.Name(), state.Zone); e == nil {
if _, e := parseRequest(state.Name(), state.Zone, false); e == nil {
t.Errorf("Test %d: expected error from %s, got none", i, query)
}
}