cmd/k8s-operator,kube/kubetypes,k8s-operator/apis: reconcile L3 HA Services (#15961)

This reconciler allows users to make applications highly available at L3 by
leveraging Tailscale Virtual Services. Many Kubernetes Service's
(irrespective of the cluster they reside in) can be mapped to a
Tailscale Virtual Service, allowing access to these Services at L3.

Updates #15895

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
Tom Meadows
2025-05-19 12:58:32 +01:00
committed by GitHub
parent d89aa29081
commit df8d51023e
13 changed files with 1431 additions and 21 deletions

View File

@@ -38,6 +38,10 @@ import (
"tailscale.com/util/mak"
)
const (
vipTestIP = "5.6.7.8"
)
// confgOpts contains configuration options for creating cluster resources for
// Tailscale proxies.
type configOpts struct {
@@ -561,6 +565,23 @@ func expectedSecret(t *testing.T, cl client.Client, opts configOpts) *corev1.Sec
return s
}
func findNoGenName(t *testing.T, client client.Client, ns, name, typ string) {
t.Helper()
labels := map[string]string{
kubetypes.LabelManaged: "true",
LabelParentName: name,
LabelParentNamespace: ns,
LabelParentType: typ,
}
s, err := getSingleObject[corev1.Secret](context.Background(), client, "operator-ns", labels)
if err != nil {
t.Fatalf("finding secrets for %q: %v", name, err)
}
if s != nil {
t.Fatalf("found unexpected secret with name %q", s.GetName())
}
}
func findGenName(t *testing.T, client client.Client, ns, name, typ string) (full, noSuffix string) {
t.Helper()
labels := map[string]string{
@@ -889,12 +910,26 @@ func (c *fakeTSClient) GetVIPService(ctx context.Context, name tailcfg.ServiceNa
return svc, nil
}
func (c *fakeTSClient) ListVIPServices(ctx context.Context) (map[tailcfg.ServiceName]*tailscale.VIPService, error) {
c.Lock()
defer c.Unlock()
if c.vipServices == nil {
return nil, &tailscale.ErrResponse{Status: http.StatusNotFound}
}
return c.vipServices, nil
}
func (c *fakeTSClient) CreateOrUpdateVIPService(ctx context.Context, svc *tailscale.VIPService) error {
c.Lock()
defer c.Unlock()
if c.vipServices == nil {
c.vipServices = make(map[tailcfg.ServiceName]*tailscale.VIPService)
}
if svc.Addrs == nil {
svc.Addrs = []string{vipTestIP}
}
c.vipServices[svc.Name] = svc
return nil
}