From 9b6e48658f36e347f009d819bfa69c85c08aa3cf Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Fri, 12 May 2023 06:05:18 +0100 Subject: [PATCH] client: allow the expiry time to be specified for new keys Adds a parameter for create key that allows a number of seconds (less than 90) to be specified for new keys. Fixes https://github.com/tailscale/tailscale/issues/7965 Signed-off-by: Matthew Brown --- client/tailscale/keys.go | 14 +++++++++++--- cmd/get-authkey/main.go | 2 +- cmd/k8s-operator/operator.go | 10 +++++++--- cmd/k8s-operator/operator_test.go | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/client/tailscale/keys.go b/client/tailscale/keys.go index 05a29be50..38b37e38f 100644 --- a/client/tailscale/keys.go +++ b/client/tailscale/keys.go @@ -70,10 +70,18 @@ func (c *Client) Keys(ctx context.Context) ([]string, error) { // CreateKey creates a new key for the current user. Currently, only auth keys // can be created. Returns the key itself, which cannot be retrieved again // later, and the key metadata. -func (c *Client) CreateKey(ctx context.Context, caps KeyCapabilities) (string, *Key, error) { +func (c *Client) CreateKey(ctx context.Context, caps KeyCapabilities, expiry time.Duration) (string, *Key, error) { + + // convert expirySeconds to an int64 (seconds) + expirySeconds := int64(expiry.Seconds()) + if expirySeconds < 0 { + return "", nil, fmt.Errorf("expiry must be positive") + } + keyRequest := struct { - Capabilities KeyCapabilities `json:"capabilities"` - }{caps} + Capabilities KeyCapabilities `json:"capabilities"` + ExpirySeconds int64 `json:"expirySeconds,omitempty"` + }{caps, int64(expirySeconds)} bs, err := json.Marshal(keyRequest) if err != nil { return "", nil, err diff --git a/cmd/get-authkey/main.go b/cmd/get-authkey/main.go index 5f5e85186..196f45908 100644 --- a/cmd/get-authkey/main.go +++ b/cmd/get-authkey/main.go @@ -67,7 +67,7 @@ func main() { }, } - authkey, _, err := tsClient.CreateKey(ctx, caps) + authkey, _, err := tsClient.CreateKey(ctx, caps, 0) if err != nil { log.Fatal(err.Error()) } diff --git a/cmd/k8s-operator/operator.go b/cmd/k8s-operator/operator.go index 4398c21cc..fef99e2d5 100644 --- a/cmd/k8s-operator/operator.go +++ b/cmd/k8s-operator/operator.go @@ -153,7 +153,9 @@ waitOnline: }, }, } - authkey, _, err := tsClient.CreateKey(ctx, caps) + // zeroSeconds adopts the default expiration time. + zeroSeconds := time.Duration(0 * time.Second) + authkey, _, err := tsClient.CreateKey(ctx, caps, zeroSeconds) if err != nil { startlog.Fatalf("creating operator authkey: %v", err) } @@ -287,7 +289,7 @@ type ServiceReconciler struct { } type tsClient interface { - CreateKey(ctx context.Context, caps tailscale.KeyCapabilities) (string, *tailscale.Key, error) + CreateKey(ctx context.Context, caps tailscale.KeyCapabilities, expiry time.Duration) (string, *tailscale.Key, error) DeleteDevice(ctx context.Context, id string) error } @@ -593,7 +595,9 @@ func (a *ServiceReconciler) newAuthKey(ctx context.Context, tags []string) (stri }, }, } - key, _, err := a.tsClient.CreateKey(ctx, caps) + + zeroDuration := time.Duration(0) + key, _, err := a.tsClient.CreateKey(ctx, caps, zeroDuration) if err != nil { return "", err } diff --git a/cmd/k8s-operator/operator_test.go b/cmd/k8s-operator/operator_test.go index 25167961c..001d890f2 100644 --- a/cmd/k8s-operator/operator_test.go +++ b/cmd/k8s-operator/operator_test.go @@ -807,14 +807,14 @@ type fakeTSClient struct { deleted []string } -func (c *fakeTSClient) CreateKey(ctx context.Context, caps tailscale.KeyCapabilities) (string, *tailscale.Key, error) { +func (c *fakeTSClient) CreateKey(ctx context.Context, caps tailscale.KeyCapabilities, expiry time.Duration) (string, *tailscale.Key, error) { c.Lock() defer c.Unlock() c.keyRequests = append(c.keyRequests, caps) k := &tailscale.Key{ ID: "key", Created: time.Now(), - Expires: time.Now().Add(24 * time.Hour), + Expires: time.Now().Add(expiry), Capabilities: caps, } return "secret-authkey", k, nil