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 <maisem@tailscale.com>
pull/7670/head
Maisem Ali 2 years ago committed by Maisem Ali
parent 57a008a1e1
commit 9d8b7a7383

@ -7,6 +7,7 @@ package kubestore
import ( import (
"context" "context"
"strings"
"time" "time"
"tailscale.com/ipn" "tailscale.com/ipn"
@ -46,13 +47,24 @@ func (s *Store) ReadState(id ipn.StateKey) ([]byte, error) {
} }
return nil, err return nil, err
} }
b, ok := secret.Data[string(id)] b, ok := secret.Data[sanitizeKey(id)]
if !ok { if !ok {
return nil, ipn.ErrStateNotExist return nil, ipn.ErrStateNotExist
} }
return b, nil 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. // WriteState implements the StateStore interface.
func (s *Store) WriteState(id ipn.StateKey, bs []byte) error { func (s *Store) WriteState(id ipn.StateKey, bs []byte) error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 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, Name: s.secretName,
}, },
Data: map[string][]byte{ Data: map[string][]byte{
string(id): bs, sanitizeKey(id): bs,
}, },
}) })
} }
return err return err
} }
secret.Data[string(id)] = bs secret.Data[sanitizeKey(id)] = bs
if err := s.client.UpdateSecret(ctx, secret); err != nil { if err := s.client.UpdateSecret(ctx, secret); err != nil {
return err return err
} }

Loading…
Cancel
Save