From 4f0222388ade008603567846fae3f4a35b168502 Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Fri, 7 Feb 2025 09:09:36 -0600 Subject: [PATCH] cmd,tsnet,internal/client: create internal shim to deprecated control plane API Even after we remove the deprecated API, we will want to maintain a minimal API for internal use, in order to avoid importing the external tailscale.com/client/tailscale/v2 package. This shim exposes only the necessary parts of the deprecated API for internal use, which gains us the following: 1. It removes deprecation warnings for internal use of the API. 2. It gives us an inventory of which parts we will want to keep for internal use. Updates tailscale/corp#22748 Signed-off-by: Percy Wegmann --- cmd/get-authkey/main.go | 6 +--- cmd/k8s-operator/depaware.txt | 1 + cmd/k8s-operator/e2e/main_test.go | 3 +- cmd/k8s-operator/tsclient.go | 2 +- cmd/tailscale/cli/up.go | 8 +---- cmd/tailscale/depaware.txt | 1 + internal/client/tailscale/tailscale.go | 48 ++++++++++++++++++++++++++ tsnet/tsnet.go | 3 ++ 8 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 internal/client/tailscale/tailscale.go diff --git a/cmd/get-authkey/main.go b/cmd/get-authkey/main.go index 95c930756..ec7ab5d2c 100644 --- a/cmd/get-authkey/main.go +++ b/cmd/get-authkey/main.go @@ -16,14 +16,10 @@ import ( "strings" "golang.org/x/oauth2/clientcredentials" - "tailscale.com/client/tailscale" + "tailscale.com/internal/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") diff --git a/cmd/k8s-operator/depaware.txt b/cmd/k8s-operator/depaware.txt index 2e96f03d0..520595bf6 100644 --- a/cmd/k8s-operator/depaware.txt +++ b/cmd/k8s-operator/depaware.txt @@ -811,6 +811,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/ tailscale.com/health from tailscale.com/control/controlclient+ tailscale.com/health/healthmsg from tailscale.com/ipn/ipnlocal tailscale.com/hostinfo from tailscale.com/client/web+ + tailscale.com/internal/client/tailscale from tailscale.com/cmd/k8s-operator tailscale.com/internal/noiseconn from tailscale.com/control/controlclient tailscale.com/ipn from tailscale.com/client/local+ tailscale.com/ipn/conffile from tailscale.com/ipn/ipnlocal+ diff --git a/cmd/k8s-operator/e2e/main_test.go b/cmd/k8s-operator/e2e/main_test.go index ae23c939c..5a1364e09 100644 --- a/cmd/k8s-operator/e2e/main_test.go +++ b/cmd/k8s-operator/e2e/main_test.go @@ -21,7 +21,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" kzap "sigs.k8s.io/controller-runtime/pkg/log/zap" - "tailscale.com/client/tailscale" + "tailscale.com/internal/client/tailscale" ) const ( @@ -64,7 +64,6 @@ func TestMain(m *testing.M) { func runTests(m *testing.M) (int, error) { zlog := kzap.NewRaw([]kzap.Opts{kzap.UseDevMode(true), kzap.Level(zapcore.DebugLevel)}...).Sugar() logf.SetLogger(zapr.NewLogger(zlog.Desugar())) - tailscale.I_Acknowledge_This_API_Is_Unstable = true if clientID := os.Getenv("TS_API_CLIENT_ID"); clientID != "" { cleanup, err := setupClientAndACLs() diff --git a/cmd/k8s-operator/tsclient.go b/cmd/k8s-operator/tsclient.go index 2381438b2..acbc96520 100644 --- a/cmd/k8s-operator/tsclient.go +++ b/cmd/k8s-operator/tsclient.go @@ -16,7 +16,7 @@ import ( "os" "golang.org/x/oauth2/clientcredentials" - "tailscale.com/client/tailscale" + "tailscale.com/internal/client/tailscale" "tailscale.com/tailcfg" "tailscale.com/util/httpm" ) diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go index da3780e39..31f7eb956 100644 --- a/cmd/tailscale/cli/up.go +++ b/cmd/tailscale/cli/up.go @@ -27,8 +27,8 @@ import ( "github.com/peterbourgon/ff/v3/ffcli" qrcode "github.com/skip2/go-qrcode" "golang.org/x/oauth2/clientcredentials" - "tailscale.com/client/tailscale" "tailscale.com/health/healthmsg" + "tailscale.com/internal/client/tailscale" "tailscale.com/ipn" "tailscale.com/ipn/ipnstate" "tailscale.com/net/netutil" @@ -1097,12 +1097,6 @@ func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netip.Addr) { return } -func init() { - // 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 -} - // resolveAuthKey either returns v unchanged (in the common case) or, if it // starts with "tskey-client-" (as Tailscale OAuth secrets do) parses it like // diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index ad2e40611..8c972aa69 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -93,6 +93,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/health from tailscale.com/net/tlsdial+ tailscale.com/health/healthmsg from tailscale.com/cmd/tailscale/cli tailscale.com/hostinfo from tailscale.com/client/web+ + tailscale.com/internal/client/tailscale from tailscale.com/cmd/tailscale/cli tailscale.com/internal/noiseconn from tailscale.com/cmd/tailscale/cli tailscale.com/ipn from tailscale.com/client/local+ tailscale.com/ipn/ipnstate from tailscale.com/client/local+ diff --git a/internal/client/tailscale/tailscale.go b/internal/client/tailscale/tailscale.go new file mode 100644 index 000000000..4745bef64 --- /dev/null +++ b/internal/client/tailscale/tailscale.go @@ -0,0 +1,48 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package tailscale provides a minimal control plane API client for internal +// use. A full client for 3rd party use is available at +// tailscale.com/client/tailscale/v2. The internal client is provided to avoid +// having to import that whole package. +package tailscale + +import ( + tsclient "tailscale.com/client/tailscale" +) + +func init() { + tsclient.I_Acknowledge_This_API_Is_Unstable = true +} + +// Client is an alias to tailscale.com/client/tailscale. +type Client = tsclient.Client + +// AuthMethod is an alias to tailscale.com/client/tailscale. +type AuthMethod = tsclient.AuthMethod + +// Device is an alias to tailscale.com/client/tailscale. +type Device = tsclient.Device + +// DeviceFieldsOpts is an alias to tailscale.com/client/tailscale. +type DeviceFieldsOpts = tsclient.DeviceFieldsOpts + +// Key is an alias to tailscale.com/client/tailscale. +type Key = tsclient.Key + +// KeyCapabilities is an alias to tailscale.com/client/tailscale. +type KeyCapabilities = tsclient.KeyCapabilities + +// KeyDeviceCapabilities is an alias to tailscale.com/client/tailscale. +type KeyDeviceCapabilities = tsclient.KeyDeviceCapabilities + +// KeyDeviceCreateCapabilities is an alias to tailscale.com/client/tailscale. +type KeyDeviceCreateCapabilities = tsclient.KeyDeviceCreateCapabilities + +// ErrResponse is an alias to tailscale.com/client/tailscale. +type ErrResponse = tsclient.ErrResponse + +// NewClient is an alias to tailscale.com/client/tailscale. +func NewClient(tailnet string, auth AuthMethod) *Client { + return tsclient.NewClient(tailnet, auth) +} diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go index 8d5b89f84..f5fcd416f 100644 --- a/tsnet/tsnet.go +++ b/tsnet/tsnet.go @@ -930,6 +930,9 @@ func getTSNetDir(logf logger.Logf, confDir, prog string) (string, error) { // APIClient returns a tailscale.Client that can be used to make authenticated // requests to the Tailscale control server. // It requires the user to set tailscale.I_Acknowledge_This_API_Is_Unstable. +// +// TODO: (percy) provide a way to use Noise for the official API at +// tailscale.com/client/tailscale/v2. func (s *Server) APIClient() (*tailscale.Client, error) { if !tailscale.I_Acknowledge_This_API_Is_Unstable { return nil, errors.New("use of Client without setting I_Acknowledge_This_API_Is_Unstable")