From 9d8b7a738311068af054326f3fc910357c3c9bbd Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Thu, 23 Mar 2023 11:35:09 -0700 Subject: [PATCH] ipn/store/kubestore: handle "/" in ipn.StateKeys Kubernetes doesn't allow slashes as keys in secrets, replace them with "__". This shows up in the kubernetes-operator now that tsnet sets resets the ServeConfig at startup. Fixes #7662 Signed-off-by: Maisem Ali --- ipn/store/kubestore/store_kube.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ipn/store/kubestore/store_kube.go b/ipn/store/kubestore/store_kube.go index 0d3a01f7b..b82d041ff 100644 --- a/ipn/store/kubestore/store_kube.go +++ b/ipn/store/kubestore/store_kube.go @@ -7,6 +7,7 @@ import ( "context" + "strings" "time" "tailscale.com/ipn" @@ -46,13 +47,24 @@ func (s *Store) ReadState(id ipn.StateKey) ([]byte, error) { } return nil, err } - b, ok := secret.Data[string(id)] + b, ok := secret.Data[sanitizeKey(id)] if !ok { return nil, ipn.ErrStateNotExist } return b, nil } +func sanitizeKey(k ipn.StateKey) string { + // The only valid characters in a Kubernetes secret key are alphanumeric, -, + // _, and . + return strings.Map(func(r rune) rune { + if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_' || r == '.' { + return r + } + return '_' + }, string(k)) +} + // WriteState implements the StateStore interface. func (s *Store) WriteState(id ipn.StateKey, bs []byte) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) @@ -70,13 +82,13 @@ func (s *Store) WriteState(id ipn.StateKey, bs []byte) error { Name: s.secretName, }, Data: map[string][]byte{ - string(id): bs, + sanitizeKey(id): bs, }, }) } return err } - secret.Data[string(id)] = bs + secret.Data[sanitizeKey(id)] = bs if err := s.client.UpdateSecret(ctx, secret); err != nil { return err }