mirror of
https://github.com/tailscale/tailscale.git
synced 2026-02-09 09:41:49 +01:00
cmd/containerboot: handle v6 pod ips that are missing square brackets (#18519)
This commit fixes an issue within containerboot that arose from the kubernetes operator. When users enable metrics on custom resources that are running on dual stack or ipv6 only clusters, they end up with an error as we pass the hostport combintation using $(POD_IP):PORT. In go, `netip.ParseAddrPort` expects square brackets `[]` to wrap the host portion of an ipv6 address and would naturally, crash. When loading the containerboot configuration from the environment we now check if the `TS_LOCAL_ADDR_PORT` value contains the pod's v6 ip address. If it does & does not already contain brackets, we add the brackets in. Closes: #15762 Closes: #15467 Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit is contained in:
parent
ae95d8d222
commit
f2b4d7065d
@ -126,6 +126,7 @@ func configFromEnv() (*settings, error) {
|
||||
IngressProxiesCfgPath: defaultEnv("TS_INGRESS_PROXIES_CONFIG_PATH", ""),
|
||||
PodUID: defaultEnv("POD_UID", ""),
|
||||
}
|
||||
|
||||
podIPs, ok := os.LookupEnv("POD_IPS")
|
||||
if ok {
|
||||
ips := strings.Split(podIPs, ",")
|
||||
@ -144,6 +145,7 @@ func configFromEnv() (*settings, error) {
|
||||
cfg.PodIPv6 = parsed.String()
|
||||
}
|
||||
}
|
||||
|
||||
// If cert share is enabled, set the replica as read or write. Only 0th
|
||||
// replica should be able to write.
|
||||
isInCertShareMode := defaultBool("TS_EXPERIMENTAL_CERT_SHARE", false)
|
||||
@ -165,9 +167,19 @@ func configFromEnv() (*settings, error) {
|
||||
cfg.AcceptDNS = &acceptDNSNew
|
||||
}
|
||||
|
||||
// In Kubernetes clusters, people like to use the "$(POD_IP):PORT" combination to configure the TS_LOCAL_ADDR_PORT
|
||||
// environment variable (we even do this by default in the operator when enabling metrics), leading to a v6 address
|
||||
// and port combo we cannot parse, as netip.ParseAddrPort expects the host segment to be enclosed in square brackets.
|
||||
// We perform a check here to see if TS_LOCAL_ADDR_PORT is using the pod's IPv6 address and is not using brackets,
|
||||
// adding the brackets in if need be.
|
||||
if cfg.PodIPv6 != "" && strings.Contains(cfg.LocalAddrPort, cfg.PodIPv6) && !strings.ContainsAny(cfg.LocalAddrPort, "[]") {
|
||||
cfg.LocalAddrPort = strings.Replace(cfg.LocalAddrPort, cfg.PodIPv6, "["+cfg.PodIPv6+"]", 1)
|
||||
}
|
||||
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, fmt.Errorf("invalid configuration: %v", err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@ -226,3 +227,30 @@ func TestValidateAuthMethods(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlesKubeIPV6(t *testing.T) {
|
||||
t.Setenv("TS_LOCAL_ADDR_PORT", "fd7a:115c:a1e0::6c34:352:9002")
|
||||
t.Setenv("POD_IPS", "fd7a:115c:a1e0::6c34:352")
|
||||
|
||||
cfg, err := configFromEnv()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.LocalAddrPort != "[fd7a:115c:a1e0::6c34:352]:9002" {
|
||||
t.Errorf("LocalAddrPort is not set correctly")
|
||||
}
|
||||
|
||||
parsed, err := netip.ParseAddrPort(cfg.LocalAddrPort)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !parsed.Addr().Is6() {
|
||||
t.Errorf("expected v6 address but got %s", parsed)
|
||||
}
|
||||
|
||||
if parsed.Port() != 9002 {
|
||||
t.Errorf("expected port 9002 but got %d", parsed.Port())
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user