cmd/k8s-operator: put Tailscale IPs in Service ingress status

Updates #502

Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
This commit is contained in:
Mike Beaumont
2023-08-09 01:03:08 +02:00
committed by Maisem Ali
parent ce4bf41dcf
commit 3451b89e5f
7 changed files with 67 additions and 22 deletions

View File

@ -194,7 +194,7 @@ func (a *IngressReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
return fmt.Errorf("failed to provision: %w", err)
}
_, tsHost, err := a.ssr.DeviceInfo(ctx, crl)
_, tsHost, _, err := a.ssr.DeviceInfo(ctx, crl)
if err != nil {
return fmt.Errorf("failed to get device ID: %w", err)
}

View File

@ -80,6 +80,7 @@ func TestLoadBalancerClass(t *testing.T) {
}
s.Data["device_id"] = []byte("ts-id-1234")
s.Data["device_fqdn"] = []byte("tailscale.device.name.")
s.Data["device_ips"] = []byte(`["100.99.98.97", "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf"]`)
})
expectReconciled(t, sr, "default", "test")
want := &corev1.Service{
@ -104,6 +105,12 @@ func TestLoadBalancerClass(t *testing.T) {
{
Hostname: "tailscale.device.name",
},
{
IP: "100.99.98.97",
},
{
IP: "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf",
},
},
},
},
@ -306,6 +313,7 @@ func TestAnnotationIntoLB(t *testing.T) {
}
s.Data["device_id"] = []byte("ts-id-1234")
s.Data["device_fqdn"] = []byte("tailscale.device.name.")
s.Data["device_ips"] = []byte(`["100.99.98.97", "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf"]`)
})
expectReconciled(t, sr, "default", "test")
want := &corev1.Service{
@ -364,6 +372,12 @@ func TestAnnotationIntoLB(t *testing.T) {
{
Hostname: "tailscale.device.name",
},
{
IP: "100.99.98.97",
},
{
IP: "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf",
},
},
},
},
@ -425,6 +439,7 @@ func TestLBIntoAnnotation(t *testing.T) {
}
s.Data["device_id"] = []byte("ts-id-1234")
s.Data["device_fqdn"] = []byte("tailscale.device.name.")
s.Data["device_ips"] = []byte(`["100.99.98.97", "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf"]`)
})
expectReconciled(t, sr, "default", "test")
want := &corev1.Service{
@ -449,6 +464,12 @@ func TestLBIntoAnnotation(t *testing.T) {
{
Hostname: "tailscale.device.name",
},
{
IP: "100.99.98.97",
},
{
IP: "2c0a:8083:94d4:2012:3165:34a5:3616:5fdf",
},
},
},
},

View File

@ -122,7 +122,7 @@ func (a *tailscaleSTSReconciler) Cleanup(ctx context.Context, logger *zap.Sugare
return false, nil
}
id, _, err := a.DeviceInfo(ctx, labels)
id, _, _, err := a.DeviceInfo(ctx, labels)
if err != nil {
return false, fmt.Errorf("getting device info: %w", err)
}
@ -232,25 +232,31 @@ func (a *tailscaleSTSReconciler) createOrGetSecret(ctx context.Context, logger *
// DeviceInfo returns the device ID and hostname for the Tailscale device
// associated with the given labels.
func (a *tailscaleSTSReconciler) DeviceInfo(ctx context.Context, childLabels map[string]string) (id tailcfg.StableNodeID, hostname string, err error) {
func (a *tailscaleSTSReconciler) DeviceInfo(ctx context.Context, childLabels map[string]string) (id tailcfg.StableNodeID, hostname string, ips []string, err error) {
sec, err := getSingleObject[corev1.Secret](ctx, a.Client, a.operatorNamespace, childLabels)
if err != nil {
return "", "", err
return "", "", nil, err
}
if sec == nil {
return "", "", nil
return "", "", nil, nil
}
id = tailcfg.StableNodeID(sec.Data["device_id"])
if id == "" {
return "", "", nil
return "", "", nil, nil
}
// Kubernetes chokes on well-formed FQDNs with the trailing dot, so we have
// to remove it.
hostname = strings.TrimSuffix(string(sec.Data["device_fqdn"]), ".")
if hostname == "" {
return "", "", nil
return "", "", nil, nil
}
return id, hostname, nil
if rawDeviceIPs, ok := sec.Data["device_ips"]; ok {
if err := json.Unmarshal(rawDeviceIPs, &ips); err != nil {
return "", "", nil, err
}
}
return id, hostname, ips, nil
}
func (a *tailscaleSTSReconciler) newAuthKey(ctx context.Context, tags []string) (string, error) {

View File

@ -139,7 +139,7 @@ func (a *ServiceReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
return nil
}
_, tsHost, err := a.ssr.DeviceInfo(ctx, crl)
_, tsHost, tsIPs, err := a.ssr.DeviceInfo(ctx, crl)
if err != nil {
return fmt.Errorf("failed to get device ID: %w", err)
}
@ -153,12 +153,14 @@ func (a *ServiceReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
return nil
}
logger.Debugf("setting ingress hostname to %q", tsHost)
svc.Status.LoadBalancer.Ingress = []corev1.LoadBalancerIngress{
{
Hostname: tsHost,
},
logger.Debugf("setting ingress to %q, %s", tsHost, strings.Join(tsIPs, ", "))
ingress := []corev1.LoadBalancerIngress{
{Hostname: tsHost},
}
for _, ip := range tsIPs {
ingress = append(ingress, corev1.LoadBalancerIngress{IP: ip})
}
svc.Status.LoadBalancer.Ingress = ingress
if err := a.Status().Update(ctx, svc); err != nil {
return fmt.Errorf("failed to update service status: %w", err)
}