wgengine/magicsock: extract IMDS utilities into a standalone package (#18334)
Moves magicksock.cloudInfo into util/cloudinfo with minimal changes. Updates #17796 Change-Id: I83f32473b9180074d5cdbf00fa31e5b3f579f189 Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
This commit is contained in:
@@ -856,6 +856,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/cmd/k8s-operator+
|
tailscale.com/util/clientmetric from tailscale.com/cmd/k8s-operator+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
||||||
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
||||||
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/appc+
|
tailscale.com/util/clientmetric from tailscale.com/appc+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
||||||
tailscale.com/util/dnsname from tailscale.com/appc+
|
tailscale.com/util/dnsname from tailscale.com/appc+
|
||||||
tailscale.com/util/eventbus from tailscale.com/control/controlclient+
|
tailscale.com/util/eventbus from tailscale.com/control/controlclient+
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/appc+
|
tailscale.com/util/clientmetric from tailscale.com/appc+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/util/cmpver from tailscale.com/clientupdate
|
tailscale.com/util/cmpver from tailscale.com/clientupdate
|
||||||
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
||||||
tailscale.com/util/dnsname from tailscale.com/appc+
|
tailscale.com/util/dnsname from tailscale.com/appc+
|
||||||
|
|||||||
@@ -422,6 +422,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/control/controlclient+
|
tailscale.com/util/clientmetric from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/net/dns/resolver+
|
tailscale.com/util/cloudenv from tailscale.com/net/dns/resolver+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/util/cmpver from tailscale.com/net/dns+
|
tailscale.com/util/cmpver from tailscale.com/net/dns+
|
||||||
tailscale.com/util/ctxkey from tailscale.com/ipn/ipnlocal+
|
tailscale.com/util/ctxkey from tailscale.com/ipn/ipnlocal+
|
||||||
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/appc+
|
tailscale.com/util/clientmetric from tailscale.com/appc+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
||||||
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
||||||
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
tailscale.com/util/cibuild from tailscale.com/health+
|
tailscale.com/util/cibuild from tailscale.com/health+
|
||||||
tailscale.com/util/clientmetric from tailscale.com/appc+
|
tailscale.com/util/clientmetric from tailscale.com/appc+
|
||||||
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
tailscale.com/util/cloudenv from tailscale.com/hostinfo+
|
||||||
|
tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock
|
||||||
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
LW tailscale.com/util/cmpver from tailscale.com/net/dns+
|
||||||
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
|
||||||
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
//go:build !(ios || android || js)
|
//go:build !(ios || android || js)
|
||||||
|
|
||||||
package magicsock
|
// Package cloudinfo provides cloud metadata utilities.
|
||||||
|
package cloudinfo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -24,7 +25,8 @@ import (
|
|||||||
|
|
||||||
const maxCloudInfoWait = 2 * time.Second
|
const maxCloudInfoWait = 2 * time.Second
|
||||||
|
|
||||||
type cloudInfo struct {
|
// CloudInfo holds state used in querying instance metadata (IMDS) endpoints.
|
||||||
|
type CloudInfo struct {
|
||||||
client http.Client
|
client http.Client
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
|
|
||||||
@@ -34,7 +36,8 @@ type cloudInfo struct {
|
|||||||
endpoint string
|
endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCloudInfo(logf logger.Logf) *cloudInfo {
|
// New constructs a new [*CloudInfo] that will log to the provided logger instance.
|
||||||
|
func New(logf logger.Logf) *CloudInfo {
|
||||||
if !buildfeatures.HasCloud {
|
if !buildfeatures.HasCloud {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -45,7 +48,7 @@ func newCloudInfo(logf logger.Logf) *cloudInfo {
|
|||||||
}).Dial,
|
}).Dial,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cloudInfo{
|
return &CloudInfo{
|
||||||
client: http.Client{Transport: tr},
|
client: http.Client{Transport: tr},
|
||||||
logf: logf,
|
logf: logf,
|
||||||
cloud: cloudenv.Get(),
|
cloud: cloudenv.Get(),
|
||||||
@@ -56,7 +59,9 @@ func newCloudInfo(logf logger.Logf) *cloudInfo {
|
|||||||
// GetPublicIPs returns any public IPs attached to the current cloud instance,
|
// GetPublicIPs returns any public IPs attached to the current cloud instance,
|
||||||
// if the tailscaled process is running in a known cloud and there are any such
|
// if the tailscaled process is running in a known cloud and there are any such
|
||||||
// IPs present.
|
// IPs present.
|
||||||
func (ci *cloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) {
|
//
|
||||||
|
// Currently supports only AWS.
|
||||||
|
func (ci *CloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) {
|
||||||
if !buildfeatures.HasCloud {
|
if !buildfeatures.HasCloud {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -73,7 +78,7 @@ func (ci *cloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) {
|
|||||||
// getAWSMetadata makes a request to the AWS metadata service at the given
|
// getAWSMetadata makes a request to the AWS metadata service at the given
|
||||||
// path, authenticating with the provided IMDSv2 token. The returned metadata
|
// path, authenticating with the provided IMDSv2 token. The returned metadata
|
||||||
// is split by newline and returned as a slice.
|
// is split by newline and returned as a slice.
|
||||||
func (ci *cloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([]string, error) {
|
func (ci *CloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([]string, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, "GET", ci.endpoint+path, nil)
|
req, err := http.NewRequestWithContext(ctx, "GET", ci.endpoint+path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating request to %q: %w", path, err)
|
return nil, fmt.Errorf("creating request to %q: %w", path, err)
|
||||||
@@ -105,7 +110,7 @@ func (ci *cloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([]
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getAWS returns all public IPv4 and IPv6 addresses present in the AWS instance metadata.
|
// getAWS returns all public IPv4 and IPv6 addresses present in the AWS instance metadata.
|
||||||
func (ci *cloudInfo) getAWS(ctx context.Context) ([]netip.Addr, error) {
|
func (ci *CloudInfo) getAWS(ctx context.Context) ([]netip.Addr, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, maxCloudInfoWait)
|
ctx, cancel := context.WithTimeout(ctx, maxCloudInfoWait)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build ios || android || js
|
||||||
|
|
||||||
|
package cloudinfo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"tailscale.com/types/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CloudInfo is not available in mobile and JS targets.
|
||||||
|
type CloudInfo struct{}
|
||||||
|
|
||||||
|
// New construct a no-op CloudInfo stub.
|
||||||
|
func New(_ logger.Logf) *CloudInfo {
|
||||||
|
return &CloudInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPublicIPs always returns nil slice and error.
|
||||||
|
func (ci *CloudInfo) GetPublicIPs(_ context.Context) ([]netip.Addr, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package magicsock
|
package cloudinfo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -44,7 +44,7 @@ func TestCloudInfo_AWS(t *testing.T) {
|
|||||||
srv := httptest.NewServer(fake)
|
srv := httptest.NewServer(fake)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
ci := newCloudInfo(t.Logf)
|
ci := New(t.Logf)
|
||||||
ci.cloud = cloudenv.AWS
|
ci.cloud = cloudenv.AWS
|
||||||
ci.endpoint = srv.URL
|
ci.endpoint = srv.URL
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ func TestCloudInfo_AWSNotPublic(t *testing.T) {
|
|||||||
srv := httptest.NewServer(returns404)
|
srv := httptest.NewServer(returns404)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
ci := newCloudInfo(t.Logf)
|
ci := New(t.Logf)
|
||||||
ci.cloud = cloudenv.AWS
|
ci.cloud = cloudenv.AWS
|
||||||
ci.endpoint = srv.URL
|
ci.endpoint = srv.URL
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
//go:build ios || android || js
|
|
||||||
|
|
||||||
package magicsock
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/netip"
|
|
||||||
|
|
||||||
"tailscale.com/types/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cloudInfo struct{}
|
|
||||||
|
|
||||||
func newCloudInfo(_ logger.Logf) *cloudInfo {
|
|
||||||
return &cloudInfo{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ci *cloudInfo) GetPublicIPs(_ context.Context) ([]netip.Addr, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
@@ -60,6 +60,7 @@ import (
|
|||||||
"tailscale.com/types/nettype"
|
"tailscale.com/types/nettype"
|
||||||
"tailscale.com/types/views"
|
"tailscale.com/types/views"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
|
"tailscale.com/util/cloudinfo"
|
||||||
"tailscale.com/util/eventbus"
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
"tailscale.com/util/ringlog"
|
"tailscale.com/util/ringlog"
|
||||||
@@ -213,7 +214,7 @@ type Conn struct {
|
|||||||
bind *connBind
|
bind *connBind
|
||||||
|
|
||||||
// cloudInfo is used to query cloud metadata services.
|
// cloudInfo is used to query cloud metadata services.
|
||||||
cloudInfo *cloudInfo
|
cloudInfo *cloudinfo.CloudInfo
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Fields that must be accessed via atomic load/stores.
|
// Fields that must be accessed via atomic load/stores.
|
||||||
@@ -597,7 +598,7 @@ func newConn(logf logger.Logf) *Conn {
|
|||||||
peerLastDerp: make(map[key.NodePublic]int),
|
peerLastDerp: make(map[key.NodePublic]int),
|
||||||
peerMap: newPeerMap(),
|
peerMap: newPeerMap(),
|
||||||
discoInfo: make(map[key.DiscoPublic]*discoInfo),
|
discoInfo: make(map[key.DiscoPublic]*discoInfo),
|
||||||
cloudInfo: newCloudInfo(logf),
|
cloudInfo: cloudinfo.New(logf),
|
||||||
}
|
}
|
||||||
c.discoAtomic.Set(discoPrivate)
|
c.discoAtomic.Set(discoPrivate)
|
||||||
c.bind = &connBind{Conn: c, closed: true}
|
c.bind = &connBind{Conn: c, closed: true}
|
||||||
|
|||||||
Reference in New Issue
Block a user