refactor: move instance metadata service to EC2 domain

This commit is contained in:
joshsiv-mulga
2026-10-06 12:41:12 +10:00
parent b4ca2720f6
commit 09de514ef1
35 changed files with 49 additions and 49 deletions
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"net/http"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"net/http"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"errors"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"net/http"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
// MetaDataServerIP is the standard EC2 link-local metadata address.
const MetaDataServerIP = "169.254.169.254"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"bytes"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -26,7 +26,7 @@ const tokenSweepInterval = time.Minute
const tapReconcileInterval = 15 * time.Second
// listTapsFunc enumerates the local primary-ENI IMDS taps as eniID → endpoint,
// injected (like the veth hooks) to keep handlers/imds free of a network/host
// injected (like the veth hooks) to keep domains/ec2/guestmetadata free of a network/host
// import cycle. Backed by host.ListIMDSTaps in vpcd.
type listTapsFunc func(ctx context.Context) (map[string]string, error)
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"context"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"crypto/rand"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"testing"
@@ -1,4 +1,4 @@
package handlers_imds
package guestmetadata
import (
"net/http"
+1 -1
View File
@@ -30,7 +30,7 @@ const (
// DefaultResolverQPSPerIP is AWS's 10,000 UDP queries/sec per resolver-endpoint
// IP. The per-tap 169.254.169.253 shim is our resolver-endpoint analog, so
// this is the AWS-parity ceiling above which the forwarder sheds a flood
// (handlers/imds dnsQueryRatePerTap mirrors it).
// (domains/ec2/guestmetadata dnsQueryRatePerTap mirrors it).
DefaultResolverQPSPerIP = 10_000
// MaxRecordsPerChangeRequest is the hard cap on ResourceRecord elements in one
+2 -2
View File
@@ -15,7 +15,7 @@ import (
// localVMStateReader adapts this node's on-disk instance state to IMDS's
// local-first lookup. vpcd is the composition root for both the network and
// compute planes IMDS straddles, so this adapter — not handlers/imds — is
// compute planes IMDS straddles, so this adapter — not domains/ec2/guestmetadata — is
// what knows the state lives in a daemon-owned file.
type localVMStateReader struct {
dataDir string
@@ -74,7 +74,7 @@ func (r *localVMStateReader) LocalVM(instanceID string) (*vm.VM, error) {
return r.cached.VMS[instanceID], nil
}
// recordLoader mirrors handlers/imds's own narrow instance-record accessor
// recordLoader mirrors domains/ec2/guestmetadata's own narrow instance-record accessor
// interface, so a construction failure below returns a true nil interface
// rather than a *daemon.JetStreamManager typed nil boxed into one.
type recordLoader interface {
+8 -8
View File
@@ -19,9 +19,9 @@ import (
"syscall"
"time"
"github.com/mulgadc/spinifex/spinifex/domains/ec2/guestmetadata"
"github.com/mulgadc/spinifex/spinifex/foundation/telemetry"
handlers_ec2_igw "github.com/mulgadc/spinifex/spinifex/handlers/ec2/igw"
handlers_imds "github.com/mulgadc/spinifex/spinifex/handlers/imds"
"github.com/mulgadc/spinifex/spinifex/network/external"
"github.com/mulgadc/spinifex/spinifex/network/external/dhcp"
"github.com/mulgadc/spinifex/spinifex/network/external/ocinet"
@@ -579,18 +579,18 @@ func launchService(cfg *Config) error {
return live, nil
}
// vpcd is the composition root for both planes IMDS straddles: it wires the
// on-disk VM state reader and the shared record space, so handlers/imds
// on-disk VM state reader and the shared record space, so domains/ec2/guestmetadata
// itself never needs to import the compute plane beyond vm.VM.
records, err := newInstanceRecordLoader(ctx, nc)
if err != nil {
return fmt.Errorf("open instance record space: %w", err)
}
imdsSvc, err := handlers_imds.NewIMDSServiceImpl(
imdsSvc, err := guestmetadata.NewIMDSServiceImpl(
ctx,
nc,
handlers_imds.NewNATSSTSAssumer(nc),
handlers_imds.NewNATSProfileLookup(nc),
handlers_imds.NewNATSPublicKeyLookup(nc),
guestmetadata.NewNATSSTSAssumer(nc),
guestmetadata.NewNATSProfileLookup(nc),
guestmetadata.NewNATSPublicKeyLookup(nc),
newLocalVMStateReader(cfg.DataDir),
records,
listTaps,
@@ -599,7 +599,7 @@ func launchService(cfg *Config) error {
cfg.ServicesDomain,
cfg.CACert,
cfg.ResolverNameservers,
handlers_imds.NewHostBindAddrs(cfg.IMDSHostMetaIP, cfg.IMDSHostDNSIP),
guestmetadata.NewHostBindAddrs(cfg.IMDSHostMetaIP, cfg.IMDSHostDNSIP),
)
if err != nil {
return fmt.Errorf("construct IMDS service: %w", err)
@@ -824,7 +824,7 @@ func launchService(cfg *Config) error {
// absent northstar it falls back to the upstream pool DNS.
func resolverDNSServer(cfg *Config) string {
if len(cfg.ResolverNameservers) > 0 {
return handlers_imds.VPCDNSServerIP
return guestmetadata.VPCDNSServerIP
}
return pickDNSServer(cfg.ExternalPools)
}
+3 -3
View File
@@ -8,7 +8,7 @@ import (
"testing"
"time"
handlers_imds "github.com/mulgadc/spinifex/spinifex/handlers/imds"
"github.com/mulgadc/spinifex/spinifex/domains/ec2/guestmetadata"
"github.com/mulgadc/spinifex/spinifex/network/external"
)
@@ -486,8 +486,8 @@ func TestResolverDNSServer(t *testing.T) {
ResolverNameservers: []string{"192.168.1.31", "192.168.1.32"},
ExternalPools: []external.ExternalPoolConfig{{DNSServers: []string{"8.8.8.8"}}},
}
if got := resolverDNSServer(cfg); got != handlers_imds.VPCDNSServerIP {
t.Errorf("resolverDNSServer = %q, want %q", got, handlers_imds.VPCDNSServerIP)
if got := resolverDNSServer(cfg); got != guestmetadata.VPCDNSServerIP {
t.Errorf("resolverDNSServer = %q, want %q", got, guestmetadata.VPCDNSServerIP)
}
// Without resolvers, fall back to the upstream pool DNS.
+3 -3
View File
@@ -16,7 +16,7 @@ import (
"github.com/mulgadc/spinifex/spinifex/bootstrap/config"
handlers_dns "github.com/mulgadc/spinifex/spinifex/handlers/dns"
handlers_imds "github.com/mulgadc/spinifex/spinifex/handlers/imds"
"github.com/mulgadc/spinifex/spinifex/domains/ec2/guestmetadata"
)
const (
@@ -211,9 +211,9 @@ func AssertGuestResolver(t *testing.T, target SSHTarget) {
if err != nil {
return err
}
if !slices.Contains(resolvers, handlers_imds.VPCDNSServerIP) {
if !slices.Contains(resolvers, guestmetadata.VPCDNSServerIP) {
return fmt.Errorf("guest forwards DNS to %v, want the VPC resolver %s",
resolvers, handlers_imds.VPCDNSServerIP)
resolvers, guestmetadata.VPCDNSServerIP)
}
return nil
}, 30*time.Second, 3*time.Second)
+2 -2
View File
@@ -11,7 +11,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
handlers_dns "github.com/mulgadc/spinifex/spinifex/handlers/dns"
handlers_imds "github.com/mulgadc/spinifex/spinifex/handlers/imds"
"github.com/mulgadc/spinifex/spinifex/domains/ec2/guestmetadata"
"github.com/mulgadc/spinifex/tests/e2e/harness"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -128,7 +128,7 @@ func runSGReachabilityPolicy(t *testing.T, fix *Fixture) {
region := aws.StringValue(fix.AWS.EC2Conf.Config.Region)
require.NotEmpty(t, region, "AWS region is required to build the internal EC2 name")
harness.Step(t, "assert guest uses the VPC resolver %s", handlers_imds.VPCDNSServerIP)
harness.Step(t, "assert guest uses the VPC resolver %s", guestmetadata.VPCDNSServerIP)
harness.AssertGuestResolver(t, tgt)
// Ping the instance's own private IP — local datapath sanity, no DNS