mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 14:57:49 +00:00
client/tailscale/apitype: move local API types to new apitype package
They were scattered/duplicated in misc places before. It can't be in the client package itself for circular dep reasons. This new package is basically tailcfg but for localhost communications, instead of to control. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
1b9d8771dc
commit
db5e269463
29
client/tailscale/apitype/apitype.go
Normal file
29
client/tailscale/apitype/apitype.go
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package apitype contains types for the Tailscale local API.
|
||||
package apitype
|
||||
|
||||
import "tailscale.com/tailcfg"
|
||||
|
||||
// WhoIsResponse is the JSON type returned by tailscaled debug server's /whois?ip=$IP handler.
|
||||
type WhoIsResponse struct {
|
||||
Node *tailcfg.Node
|
||||
UserProfile *tailcfg.UserProfile
|
||||
}
|
||||
|
||||
// FileTarget is a node to which files can be sent, and the PeerAPI
|
||||
// URL base to do so via.
|
||||
type FileTarget struct {
|
||||
Node *tailcfg.Node
|
||||
|
||||
// PeerAPI is the http://ip:port URL base of the node's peer API,
|
||||
// without any path (not even a single slash).
|
||||
PeerAPIURL string
|
||||
}
|
||||
|
||||
type WaitingFile struct {
|
||||
Name string
|
||||
Size int64
|
||||
}
|
@ -19,11 +19,11 @@
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/paths"
|
||||
"tailscale.com/safesocket"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
// TailscaledSocket is the tailscaled Unix socket.
|
||||
@ -91,12 +91,12 @@ func get200(ctx context.Context, path string) ([]byte, error) {
|
||||
}
|
||||
|
||||
// WhoIs returns the owner of the remoteAddr, which must be an IP or IP:port.
|
||||
func WhoIs(ctx context.Context, remoteAddr string) (*tailcfg.WhoIsResponse, error) {
|
||||
func WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsResponse, error) {
|
||||
body, err := get200(ctx, "/localapi/v0/whois?addr="+url.QueryEscape(remoteAddr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := new(tailcfg.WhoIsResponse)
|
||||
r := new(apitype.WhoIsResponse)
|
||||
if err := json.Unmarshal(body, r); err != nil {
|
||||
if max := 200; len(body) > max {
|
||||
body = append(body[:max], "..."...)
|
||||
@ -142,17 +142,12 @@ func status(ctx context.Context, queryString string) (*ipnstate.Status, error) {
|
||||
return st, nil
|
||||
}
|
||||
|
||||
type WaitingFile struct {
|
||||
Name string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func WaitingFiles(ctx context.Context) ([]WaitingFile, error) {
|
||||
func WaitingFiles(ctx context.Context) ([]apitype.WaitingFile, error) {
|
||||
body, err := get200(ctx, "/localapi/v0/files/")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var wfs []WaitingFile
|
||||
var wfs []apitype.WaitingFile
|
||||
if err := json.Unmarshal(body, &wfs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -185,6 +180,18 @@ func GetWaitingFile(ctx context.Context, baseName string) (rc io.ReadCloser, siz
|
||||
return res.Body, res.ContentLength, nil
|
||||
}
|
||||
|
||||
func FileTargets(ctx context.Context) ([]apitype.FileTarget, error) {
|
||||
body, err := get200(ctx, "/localapi/v0/file-targets")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var fts []apitype.FileTarget
|
||||
if err := json.Unmarshal(body, &fts); err != nil {
|
||||
return nil, fmt.Errorf("invalid JSON: %w", err)
|
||||
}
|
||||
return fts, nil
|
||||
}
|
||||
|
||||
func CheckIPForwarding(ctx context.Context) error {
|
||||
body, err := get200(ctx, "/localapi/v0/check-ip-forwarding")
|
||||
if err != nil {
|
||||
|
@ -18,7 +18,7 @@
|
||||
"strings"
|
||||
|
||||
"tailscale.com/client/tailscale"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -107,7 +107,7 @@ type tmplData struct {
|
||||
IP string // "100.2.3.4"
|
||||
}
|
||||
|
||||
func tailscaleIP(who *tailcfg.WhoIsResponse) string {
|
||||
func tailscaleIP(who *apitype.WhoIsResponse) string {
|
||||
if who == nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
rsc.io/goversion/version from tailscale.com/version
|
||||
tailscale.com/atomicfile from tailscale.com/ipn
|
||||
tailscale.com/client/tailscale from tailscale.com/cmd/tailscale/cli
|
||||
tailscale.com/client/tailscale/apitype from tailscale.com/client/tailscale
|
||||
tailscale.com/cmd/tailscale/cli from tailscale.com/cmd/tailscale
|
||||
tailscale.com/derp from tailscale.com/derp/derphttp
|
||||
tailscale.com/derp/derphttp from tailscale.com/net/netcheck
|
||||
|
@ -71,6 +71,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
inet.af/peercred from tailscale.com/ipn/ipnserver
|
||||
rsc.io/goversion/version from tailscale.com/version
|
||||
tailscale.com/atomicfile from tailscale.com/ipn+
|
||||
tailscale.com/client/tailscale/apitype from tailscale.com/ipn/ipnlocal+
|
||||
tailscale.com/control/controlclient from tailscale.com/ipn/ipnlocal+
|
||||
tailscale.com/derp from tailscale.com/derp/derphttp+
|
||||
tailscale.com/derp/derphttp from tailscale.com/net/netcheck+
|
||||
|
@ -25,6 +25,7 @@
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/internal/deepprint"
|
||||
@ -2173,7 +2174,7 @@ func (b *LocalBackend) TestOnlyPublicKeys() (machineKey tailcfg.MachineKey, node
|
||||
return tailcfg.MachineKey(mk), tailcfg.NodeKey(nk)
|
||||
}
|
||||
|
||||
func (b *LocalBackend) WaitingFiles() ([]WaitingFile, error) {
|
||||
func (b *LocalBackend) WaitingFiles() ([]apitype.WaitingFile, error) {
|
||||
b.mu.Lock()
|
||||
apiSrv := b.peerAPIServer
|
||||
b.mu.Unlock()
|
||||
@ -2203,19 +2204,9 @@ func (b *LocalBackend) OpenFile(name string) (rc io.ReadCloser, size int64, err
|
||||
return apiSrv.OpenFile(name)
|
||||
}
|
||||
|
||||
// FileTarget is a node to which files can be sent, and the PeerAPI
|
||||
// URL base to do so via.
|
||||
type FileTarget struct {
|
||||
Node *tailcfg.Node
|
||||
|
||||
// PeerAPI is the http://ip:port URL base of the node's peer API,
|
||||
// without any path (not even a single slash).
|
||||
PeerAPIURL string
|
||||
}
|
||||
|
||||
// FileTargets lists nodes that the current node can send files to.
|
||||
func (b *LocalBackend) FileTargets() ([]*FileTarget, error) {
|
||||
var ret []*FileTarget
|
||||
func (b *LocalBackend) FileTargets() ([]*apitype.FileTarget, error) {
|
||||
var ret []*apitype.FileTarget
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
@ -2232,7 +2223,7 @@ func (b *LocalBackend) FileTargets() ([]*FileTarget, error) {
|
||||
continue
|
||||
|
||||
}
|
||||
ret = append(ret, &FileTarget{
|
||||
ret = append(ret, &apitype.FileTarget{
|
||||
Node: p,
|
||||
PeerAPIURL: peerAPI,
|
||||
})
|
||||
|
@ -24,6 +24,7 @@
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/syncs"
|
||||
@ -99,14 +100,7 @@ func (s *peerAPIServer) hasFilesWaiting() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// WaitingFile is a JSON-marshaled struct sent by the localapi to pick
|
||||
// up queued files.
|
||||
type WaitingFile struct {
|
||||
Name string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func (s *peerAPIServer) WaitingFiles() (ret []WaitingFile, err error) {
|
||||
func (s *peerAPIServer) WaitingFiles() (ret []apitype.WaitingFile, err error) {
|
||||
if s.rootDir == "" {
|
||||
return nil, errors.New("peerapi disabled; no storage configured")
|
||||
}
|
||||
@ -130,7 +124,7 @@ func (s *peerAPIServer) WaitingFiles() (ret []WaitingFile, err error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, WaitingFile{
|
||||
ret = append(ret, apitype.WaitingFile{
|
||||
Name: filepath.Base(name),
|
||||
Size: fi.Size(),
|
||||
})
|
||||
|
@ -23,6 +23,7 @@
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
@ -143,7 +144,7 @@ func (h *Handler) serveWhoIs(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "no match for IP:port", 404)
|
||||
return
|
||||
}
|
||||
res := &tailcfg.WhoIsResponse{
|
||||
res := &apitype.WhoIsResponse{
|
||||
Node: n,
|
||||
UserProfile: &u,
|
||||
}
|
||||
@ -340,7 +341,7 @@ func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
stableID, filenameEscaped := tailcfg.StableNodeID(upath[:slash]), upath[slash+1:]
|
||||
|
||||
var ft *ipnlocal.FileTarget
|
||||
var ft *apitype.FileTarget
|
||||
for _, x := range fts {
|
||||
if x.Node.StableID == stableID {
|
||||
ft = x
|
||||
|
@ -1050,12 +1050,6 @@ func eqTimePtr(a, b *time.Time) bool {
|
||||
return ((a == nil) == (b == nil)) && (a == nil || a.Equal(*b))
|
||||
}
|
||||
|
||||
// WhoIsResponse is the JSON type returned by tailscaled debug server's /whois?ip=$IP handler.
|
||||
type WhoIsResponse struct {
|
||||
Node *Node
|
||||
UserProfile *UserProfile
|
||||
}
|
||||
|
||||
// Oauth2Token is a copy of golang.org/x/oauth2.Token, to avoid the
|
||||
// go.mod dependency on App Engine and grpc, which was causing problems.
|
||||
// All we actually needed was this struct on the client side.
|
||||
|
Loading…
x
Reference in New Issue
Block a user