cmd/{k8s-operator,containerboot},k8s-operator: remove support for proxies below capver 95. (#13986)

Updates tailscale/tailscale#13984

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
pull/14076/head
Irbe Krumina 2 weeks ago committed by GitHub
parent e38522c081
commit cf41cec5a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -102,7 +102,6 @@ import (
"net/netip" "net/netip"
"os" "os"
"os/signal" "os/signal"
"path"
"path/filepath" "path/filepath"
"slices" "slices"
"strings" "strings"
@ -731,7 +730,6 @@ func tailscaledConfigFilePath() string {
} }
cv, err := kubeutils.CapVerFromFileName(e.Name()) cv, err := kubeutils.CapVerFromFileName(e.Name())
if err != nil { if err != nil {
log.Printf("skipping file %q in tailscaled config directory %q: %v", e.Name(), dir, err)
continue continue
} }
if cv > maxCompatVer && cv <= tailcfg.CurrentCapabilityVersion { if cv > maxCompatVer && cv <= tailcfg.CurrentCapabilityVersion {
@ -739,8 +737,9 @@ func tailscaledConfigFilePath() string {
} }
} }
if maxCompatVer == -1 { if maxCompatVer == -1 {
log.Fatalf("no tailscaled config file found in %q for current capability version %q", dir, tailcfg.CurrentCapabilityVersion) log.Fatalf("no tailscaled config file found in %q for current capability version %d", dir, tailcfg.CurrentCapabilityVersion)
} }
log.Printf("Using tailscaled config file %q for capability version %q", maxCompatVer, tailcfg.CurrentCapabilityVersion) filePath := filepath.Join(dir, kubeutils.TailscaledConfigFileName(maxCompatVer))
return path.Join(dir, kubeutils.TailscaledConfigFileName(maxCompatVer)) log.Printf("Using tailscaled config file %q to match current capability version %d", filePath, tailcfg.CurrentCapabilityVersion)
return filePath
} }

@ -1388,7 +1388,7 @@ func TestTailscaledConfigfileHash(t *testing.T) {
parentType: "svc", parentType: "svc",
hostname: "default-test", hostname: "default-test",
clusterTargetIP: "10.20.30.40", clusterTargetIP: "10.20.30.40",
confFileHash: "362360188dac62bca8013c8134929fed8efd84b1f410c00873d14a05709b5647", confFileHash: "a67b5ad3ff605531c822327e8f1a23dd0846e1075b722c13402f7d5d0ba32ba2",
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSTS(t, fc, o), nil) expectEqual(t, fc, expectedSTS(t, fc, o), nil)
@ -1399,7 +1399,7 @@ func TestTailscaledConfigfileHash(t *testing.T) {
mak.Set(&svc.Annotations, AnnotationHostname, "another-test") mak.Set(&svc.Annotations, AnnotationHostname, "another-test")
}) })
o.hostname = "another-test" o.hostname = "another-test"
o.confFileHash = "20db57cfabc3fc6490f6bb1dc85994e61d255cdfa2a56abb0141736e59f263ef" o.confFileHash = "888a993ebee20ad6be99623b45015339de117946850cf1252bede0b570e04293"
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, o), nil) expectEqual(t, fc, expectedSTS(t, fc, o), nil)
} }

@ -521,11 +521,6 @@ func (a *tailscaleSTSReconciler) reconcileSTS(ctx context.Context, logger *zap.S
Name: "TS_KUBE_SECRET", Name: "TS_KUBE_SECRET",
Value: proxySecret, Value: proxySecret,
}, },
corev1.EnvVar{
// Old tailscaled config key is still used for backwards compatibility.
Name: "EXPERIMENTAL_TS_CONFIGFILE_PATH",
Value: "/etc/tsconfig/tailscaled",
},
corev1.EnvVar{ corev1.EnvVar{
// New style is in the form of cap-<capability-version>.hujson. // New style is in the form of cap-<capability-version>.hujson.
Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR", Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR",
@ -789,15 +784,9 @@ func readAuthKey(secret *corev1.Secret, key string) (*string, error) {
return origConf.AuthKey, nil return origConf.AuthKey, nil
} }
// tailscaledConfig takes a proxy config, a newly generated auth key if // tailscaledConfig takes a proxy config, a newly generated auth key if generated and a Secret with the previous proxy
// generated and a Secret with the previous proxy state and auth key and // state and auth key and returns tailscaled config files for currently supported proxy versions and a hash of that
// returns tailscaled configuration and a hash of that configuration. // configuration.
//
// As of 2024-05-09 it also returns legacy tailscaled config without the
// later added NoStatefulFilter field to support proxies older than cap95.
// TODO (irbekrm): remove the legacy config once we no longer need to support
// versions older than cap94,
// https://tailscale.com/kb/1236/kubernetes-operator#operator-and-proxies
func tailscaledConfig(stsC *tailscaleSTSConfig, newAuthkey string, oldSecret *corev1.Secret) (tailscaledConfigs, error) { func tailscaledConfig(stsC *tailscaleSTSConfig, newAuthkey string, oldSecret *corev1.Secret) (tailscaledConfigs, error) {
conf := &ipn.ConfigVAlpha{ conf := &ipn.ConfigVAlpha{
Version: "alpha0", Version: "alpha0",
@ -846,10 +835,6 @@ func tailscaledConfig(stsC *tailscaleSTSConfig, newAuthkey string, oldSecret *co
// AppConnector config option is only understood by clients of capver 107 and newer. // AppConnector config option is only understood by clients of capver 107 and newer.
conf.AppConnector = nil conf.AppConnector = nil
capVerConfigs[95] = *conf capVerConfigs[95] = *conf
// StatefulFiltering is only understood by clients of capver 95 and newer.
conf.NoStatefulFiltering.Clear()
capVerConfigs[94] = *conf
return capVerConfigs, nil return capVerConfigs, nil
} }

@ -71,7 +71,6 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef
{Name: "TS_USERSPACE", Value: "false"}, {Name: "TS_USERSPACE", Value: "false"},
{Name: "POD_IP", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "", FieldPath: "status.podIP"}, ResourceFieldRef: nil, ConfigMapKeyRef: nil, SecretKeyRef: nil}}, {Name: "POD_IP", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "", FieldPath: "status.podIP"}, ResourceFieldRef: nil, ConfigMapKeyRef: nil, SecretKeyRef: nil}},
{Name: "TS_KUBE_SECRET", Value: opts.secretName}, {Name: "TS_KUBE_SECRET", Value: opts.secretName},
{Name: "EXPERIMENTAL_TS_CONFIGFILE_PATH", Value: "/etc/tsconfig/tailscaled"},
{Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR", Value: "/etc/tsconfig"}, {Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR", Value: "/etc/tsconfig"},
}, },
SecurityContext: &corev1.SecurityContext{ SecurityContext: &corev1.SecurityContext{
@ -230,7 +229,6 @@ func expectedSTSUserspace(t *testing.T, cl client.Client, opts configOpts) *apps
{Name: "TS_USERSPACE", Value: "true"}, {Name: "TS_USERSPACE", Value: "true"},
{Name: "POD_IP", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "", FieldPath: "status.podIP"}, ResourceFieldRef: nil, ConfigMapKeyRef: nil, SecretKeyRef: nil}}, {Name: "POD_IP", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "", FieldPath: "status.podIP"}, ResourceFieldRef: nil, ConfigMapKeyRef: nil, SecretKeyRef: nil}},
{Name: "TS_KUBE_SECRET", Value: opts.secretName}, {Name: "TS_KUBE_SECRET", Value: opts.secretName},
{Name: "EXPERIMENTAL_TS_CONFIGFILE_PATH", Value: "/etc/tsconfig/tailscaled"},
{Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR", Value: "/etc/tsconfig"}, {Name: "TS_EXPERIMENTAL_VERSIONED_CONFIG_DIR", Value: "/etc/tsconfig"},
{Name: "TS_SERVE_CONFIG", Value: "/etc/tailscaled/serve-config"}, {Name: "TS_SERVE_CONFIG", Value: "/etc/tailscaled/serve-config"},
{Name: "TS_INTERNAL_APP", Value: opts.app}, {Name: "TS_INTERNAL_APP", Value: opts.app},
@ -404,12 +402,6 @@ func expectedSecret(t *testing.T, cl client.Client, opts configOpts) *corev1.Sec
if err != nil { if err != nil {
t.Fatalf("error marshalling tailscaled config") t.Fatalf("error marshalling tailscaled config")
} }
conf.NoStatefulFiltering.Clear()
b, err := json.Marshal(conf)
if err != nil {
t.Fatalf("error marshalling tailscaled config")
}
mak.Set(&s.StringData, "tailscaled", string(b))
mak.Set(&s.StringData, "cap-95.hujson", string(bn)) mak.Set(&s.StringData, "cap-95.hujson", string(bn))
mak.Set(&s.StringData, "cap-107.hujson", string(bnn)) mak.Set(&s.StringData, "cap-107.hujson", string(bnn))
labels := map[string]string{ labels := map[string]string{
@ -662,18 +654,6 @@ func removeTargetPortsFromSvc(svc *corev1.Service) {
func removeAuthKeyIfExistsModifier(t *testing.T) func(s *corev1.Secret) { func removeAuthKeyIfExistsModifier(t *testing.T) func(s *corev1.Secret) {
return func(secret *corev1.Secret) { return func(secret *corev1.Secret) {
t.Helper() t.Helper()
if len(secret.StringData["tailscaled"]) != 0 {
conf := &ipn.ConfigVAlpha{}
if err := json.Unmarshal([]byte(secret.StringData["tailscaled"]), conf); err != nil {
t.Fatalf("error unmarshalling 'tailscaled' contents: %v", err)
}
conf.AuthKey = nil
b, err := json.Marshal(conf)
if err != nil {
t.Fatalf("error marshalling updated 'tailscaled' config: %v", err)
}
mak.Set(&secret.StringData, "tailscaled", string(b))
}
if len(secret.StringData["cap-95.hujson"]) != 0 { if len(secret.StringData["cap-95.hujson"]) != 0 {
conf := &ipn.ConfigVAlpha{} conf := &ipn.ConfigVAlpha{}
if err := json.Unmarshal([]byte(secret.StringData["cap-95.hujson"]), conf); err != nil { if err := json.Unmarshal([]byte(secret.StringData["cap-95.hujson"]), conf); err != nil {

@ -32,9 +32,6 @@ type Records struct {
// TailscaledConfigFileName returns a tailscaled config file name in // TailscaledConfigFileName returns a tailscaled config file name in
// format expected by containerboot for the given CapVer. // format expected by containerboot for the given CapVer.
func TailscaledConfigFileName(cap tailcfg.CapabilityVersion) string { func TailscaledConfigFileName(cap tailcfg.CapabilityVersion) string {
if cap < 95 {
return "tailscaled"
}
return fmt.Sprintf("cap-%v.hujson", cap) return fmt.Sprintf("cap-%v.hujson", cap)
} }

Loading…
Cancel
Save