2023-02-04 01:14:06 +00:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
|
|
|
// get-authkey allocates an authkey using an OAuth API client
|
2023-03-13 19:33:16 +00:00
|
|
|
// https://tailscale.com/s/oauth-clients and prints it
|
2023-02-04 01:14:06 +00:00
|
|
|
// to stdout for scripts to capture and use.
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"golang.org/x/oauth2/clientcredentials"
|
|
|
|
"tailscale.com/client/tailscale"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
// Required to use our client API. We're fine with the instability since the
|
|
|
|
// client lives in the same repo as this code.
|
|
|
|
tailscale.I_Acknowledge_This_API_Is_Unstable = true
|
|
|
|
|
|
|
|
reusable := flag.Bool("reusable", false, "allocate a reusable authkey")
|
|
|
|
ephemeral := flag.Bool("ephemeral", false, "allocate an ephemeral authkey")
|
|
|
|
preauth := flag.Bool("preauth", true, "set the authkey as pre-authorized")
|
|
|
|
tags := flag.String("tags", "", "comma-separated list of tags to apply to the authkey")
|
|
|
|
flag.Parse()
|
|
|
|
|
2023-04-26 19:34:28 +01:00
|
|
|
clientID := os.Getenv("TS_API_CLIENT_ID")
|
2023-02-04 01:14:06 +00:00
|
|
|
clientSecret := os.Getenv("TS_API_CLIENT_SECRET")
|
2023-04-26 19:34:28 +01:00
|
|
|
if clientID == "" || clientSecret == "" {
|
2023-02-04 01:14:06 +00:00
|
|
|
log.Fatal("TS_API_CLIENT_ID and TS_API_CLIENT_SECRET must be set")
|
|
|
|
}
|
|
|
|
|
2023-02-09 00:06:48 +00:00
|
|
|
if *tags == "" {
|
|
|
|
log.Fatal("at least one tag must be specified")
|
|
|
|
}
|
|
|
|
|
2023-04-26 19:34:28 +01:00
|
|
|
baseURL := os.Getenv("TS_BASE_URL")
|
|
|
|
if baseURL == "" {
|
|
|
|
baseURL = "https://api.tailscale.com"
|
2023-02-04 01:14:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
credentials := clientcredentials.Config{
|
2023-04-26 19:34:28 +01:00
|
|
|
ClientID: clientID,
|
2023-02-04 01:14:06 +00:00
|
|
|
ClientSecret: clientSecret,
|
2023-04-26 19:34:28 +01:00
|
|
|
TokenURL: baseURL + "/api/v2/oauth/token",
|
2023-02-04 01:14:06 +00:00
|
|
|
Scopes: []string{"device"},
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
tsClient := tailscale.NewClient("-", nil)
|
|
|
|
tsClient.HTTPClient = credentials.Client(ctx)
|
2023-04-26 19:34:28 +01:00
|
|
|
tsClient.BaseURL = baseURL
|
2023-02-04 01:14:06 +00:00
|
|
|
|
|
|
|
caps := tailscale.KeyCapabilities{
|
|
|
|
Devices: tailscale.KeyDeviceCapabilities{
|
|
|
|
Create: tailscale.KeyDeviceCreateCapabilities{
|
|
|
|
Reusable: *reusable,
|
|
|
|
Ephemeral: *ephemeral,
|
|
|
|
Preauthorized: *preauth,
|
|
|
|
Tags: strings.Split(*tags, ","),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-12 06:05:18 +01:00
|
|
|
authkey, _, err := tsClient.CreateKey(ctx, caps, 0)
|
2023-02-04 01:14:06 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(authkey)
|
|
|
|
}
|