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 <matthew@bargrove.com>
This commit is contained in:
Matt Brown 2023-05-12 06:05:18 +01:00 committed by GitHub
parent 85215ed58a
commit 9b6e48658f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 9 deletions

View File

@ -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 // 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 // can be created. Returns the key itself, which cannot be retrieved again
// later, and the key metadata. // 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 { keyRequest := struct {
Capabilities KeyCapabilities `json:"capabilities"` Capabilities KeyCapabilities `json:"capabilities"`
}{caps} ExpirySeconds int64 `json:"expirySeconds,omitempty"`
}{caps, int64(expirySeconds)}
bs, err := json.Marshal(keyRequest) bs, err := json.Marshal(keyRequest)
if err != nil { if err != nil {
return "", nil, err return "", nil, err

View File

@ -67,7 +67,7 @@ func main() {
}, },
} }
authkey, _, err := tsClient.CreateKey(ctx, caps) authkey, _, err := tsClient.CreateKey(ctx, caps, 0)
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }

View File

@ -153,7 +153,9 @@ func main() {
}, },
}, },
} }
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 { if err != nil {
startlog.Fatalf("creating operator authkey: %v", err) startlog.Fatalf("creating operator authkey: %v", err)
} }
@ -287,7 +289,7 @@ type ServiceReconciler struct {
} }
type tsClient interface { 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 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 { if err != nil {
return "", err return "", err
} }

View File

@ -807,14 +807,14 @@ type fakeTSClient struct {
deleted []string 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() c.Lock()
defer c.Unlock() defer c.Unlock()
c.keyRequests = append(c.keyRequests, caps) c.keyRequests = append(c.keyRequests, caps)
k := &tailscale.Key{ k := &tailscale.Key{
ID: "key", ID: "key",
Created: time.Now(), Created: time.Now(),
Expires: time.Now().Add(24 * time.Hour), Expires: time.Now().Add(expiry),
Capabilities: caps, Capabilities: caps,
} }
return "secret-authkey", k, nil return "secret-authkey", k, nil