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>
pull/18352/head
Alex Valiushko 2 days ago committed by GitHub
parent a662c541ab
commit 4c3cf8bb11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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/clientmetric from tailscale.com/cmd/k8s-operator+
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+
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
💣 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/clientmetric from tailscale.com/appc+
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/dnsname from tailscale.com/appc+
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/clientmetric from tailscale.com/appc+
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/ctxkey from tailscale.com/client/tailscale/apitype+
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/clientmetric from tailscale.com/control/controlclient+
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/ctxkey from tailscale.com/ipn/ipnlocal+
💣 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/clientmetric from tailscale.com/appc+
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+
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
💣 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/clientmetric from tailscale.com/appc+
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+
tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+
💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting

@ -3,7 +3,8 @@
//go:build !(ios || android || js)
package magicsock
// Package cloudinfo provides cloud metadata utilities.
package cloudinfo
import (
"context"
@ -24,7 +25,8 @@ import (
const maxCloudInfoWait = 2 * time.Second
type cloudInfo struct {
// CloudInfo holds state used in querying instance metadata (IMDS) endpoints.
type CloudInfo struct {
client http.Client
logf logger.Logf
@ -34,7 +36,8 @@ type cloudInfo struct {
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 {
return nil
}
@ -45,7 +48,7 @@ func newCloudInfo(logf logger.Logf) *cloudInfo {
}).Dial,
}
return &cloudInfo{
return &CloudInfo{
client: http.Client{Transport: tr},
logf: logf,
cloud: cloudenv.Get(),
@ -56,7 +59,9 @@ func newCloudInfo(logf logger.Logf) *cloudInfo {
// 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
// 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 {
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
// path, authenticating with the provided IMDSv2 token. The returned metadata
// 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)
if err != nil {
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.
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)
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
// SPDX-License-Identifier: BSD-3-Clause
package magicsock
package cloudinfo
import (
"context"
@ -44,7 +44,7 @@ func TestCloudInfo_AWS(t *testing.T) {
srv := httptest.NewServer(fake)
defer srv.Close()
ci := newCloudInfo(t.Logf)
ci := New(t.Logf)
ci.cloud = cloudenv.AWS
ci.endpoint = srv.URL
@ -76,7 +76,7 @@ func TestCloudInfo_AWSNotPublic(t *testing.T) {
srv := httptest.NewServer(returns404)
defer srv.Close()
ci := newCloudInfo(t.Logf)
ci := New(t.Logf)
ci.cloud = cloudenv.AWS
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/views"
"tailscale.com/util/clientmetric"
"tailscale.com/util/cloudinfo"
"tailscale.com/util/eventbus"
"tailscale.com/util/mak"
"tailscale.com/util/ringlog"
@ -213,7 +214,7 @@ type Conn struct {
bind *connBind
// cloudInfo is used to query cloud metadata services.
cloudInfo *cloudInfo
cloudInfo *cloudinfo.CloudInfo
// ============================================================
// 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),
peerMap: newPeerMap(),
discoInfo: make(map[key.DiscoPublic]*discoInfo),
cloudInfo: newCloudInfo(logf),
cloudInfo: cloudinfo.New(logf),
}
c.discoAtomic.Set(discoPrivate)
c.bind = &connBind{Conn: c, closed: true}

Loading…
Cancel
Save