Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ Examples:
return output.NewSilentError(fmt.Errorf("%s is not running", awsContainer.Name()))
}

host, _ := endpoint.ResolveHost(awsContainer.Port, cfg.LocalStackHost)
host, _ := endpoint.ResolveHost(cmd.Context(), awsContainer.Port, cfg.LocalStackHost)

profileExists, _ := awsconfig.ProfileExists()
profileExists, _ := awsconfig.ProfileExists(cmd.Context())
if !profileExists {
sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: "No AWS profile found, run 'lstk setup aws'"})
}
Expand Down
8 changes: 7 additions & 1 deletion internal/awsconfig/awsconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"os"
"path/filepath"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"gopkg.in/ini.v1"

"github.com/localstack/lstk/internal/endpoint"
Expand Down Expand Up @@ -138,7 +140,10 @@ func credsNeedWrite(path string) (bool, error) {

// ProfileExists reports whether the localstack profile section is present in both
// ~/.aws/config and ~/.aws/credentials.
func ProfileExists() (bool, error) {
func ProfileExists(ctx context.Context) (bool, error) {
_, span := otel.Tracer("github.com/localstack/lstk/internal/awsconfig").Start(ctx, "awsconfig.ProfileExists")
defer span.End()

configPath, credsPath, err := awsPaths()
if err != nil {
return false, err
Expand All @@ -151,6 +156,7 @@ func ProfileExists() (bool, error) {
if err != nil {
return false, err
}
span.SetAttributes(attribute.Bool("awsconfig.profile_exists", configOK && credsOK))
return configOK && credsOK, nil
}

Expand Down
5 changes: 3 additions & 2 deletions internal/awsconfig/awsconfig_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package awsconfig

import (
"context"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -50,7 +51,7 @@ func TestProfileExists(t *testing.T) {
dir := t.TempDir()
t.Setenv("HOME", dir)
tc.setup(t, dir)
ok, err := ProfileExists()
ok, err := ProfileExists(context.Background())
if err != nil {
t.Fatal(err)
}
Expand All @@ -71,7 +72,7 @@ func TestWriteProfile(t *testing.T) {
name: "creates files when absent",
setup: func(t *testing.T, dir string) {},
check: func(t *testing.T, dir string) {
ok, err := ProfileExists()
ok, err := ProfileExists(context.Background())
if err != nil {
t.Fatal(err)
}
Expand Down
10 changes: 5 additions & 5 deletions internal/container/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func runPostStartSetups(ctx context.Context, sink output.Sink, containers []conf
}
for _, t := range uniqueEmulatorTypes {
c := firstByType[t]
resolvedHost, dnsOK := endpoint.ResolveHost(c.Port, localStackHost)
resolvedHost, dnsOK := endpoint.ResolveHost(ctx, c.Port, localStackHost)
if !dnsOK {
sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: endpoint.DNSRebindNote})
}
Expand All @@ -219,9 +219,9 @@ func runPostStartSetups(ctx context.Context, sink output.Sink, containers []conf
return nil
}

func emitAlreadyRunning(sink output.Sink, c runtime.ContainerConfig, localStackHost, webAppURL string) {
func emitAlreadyRunning(ctx context.Context, sink output.Sink, c runtime.ContainerConfig, localStackHost, webAppURL string) {
sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: fmt.Sprintf("%s is already running", config.DisplayNameForType(c.EmulatorType))})
resolvedHost, dnsOK := endpoint.ResolveHost(c.Port, localStackHost)
resolvedHost, dnsOK := endpoint.ResolveHost(ctx, c.Port, localStackHost)
if !dnsOK {
sink.Emit(output.MessageEvent{Severity: output.SeverityNote, Text: endpoint.DNSRebindNote})
}
Expand Down Expand Up @@ -403,7 +403,7 @@ func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink outpu
return nil, fmt.Errorf("failed to check container status: %w", err)
}
if running {
emitAlreadyRunning(sink, c, localStackHost, webAppURL)
emitAlreadyRunning(ctx, sink, c, localStackHost, webAppURL)
continue
}

Expand Down Expand Up @@ -447,7 +447,7 @@ func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink outpu
})
return nil, output.NewSilentError(fmt.Errorf("LocalStack already running on port %s", found.BoundPort))
}
emitAlreadyRunning(sink, c, localStackHost, webAppURL)
emitAlreadyRunning(ctx, sink, c, localStackHost, webAppURL)
continue
}

Expand Down
2 changes: 1 addition & 1 deletion internal/container/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func Status(ctx context.Context, rt runtime.Runtime, containers []config.Contain
port = actualPort
}
}
host, _ := endpoint.ResolveHost(port, localStackHost)
host, _ := endpoint.ResolveHost(ctx, port, localStackHost)
if c.Type == config.EmulatorSnowflake {
if h := snowflake.Hostname(host); h != "" {
host = h
Expand Down
22 changes: 19 additions & 3 deletions internal/endpoint/endpoint.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package endpoint

import "net"
import (
"context"
"net"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)

const Hostname = "localhost.localstack.cloud"

Expand All @@ -10,20 +16,30 @@ const DNSRebindNote = "Could not resolve localhost.localstack.cloud, falling bac
// If override is non-empty it is returned as-is. Otherwise a DNS check is performed;
// if Hostname does not resolve to 127.0.0.1 (e.g. DNS rebind protection is active),
// it falls back to 127.0.0.1 directly.
func ResolveHost(port, override string) (host string, dnsOK bool) {
func ResolveHost(ctx context.Context, port, override string) (host string, dnsOK bool) {
ctx, span := otel.Tracer("github.com/localstack/lstk/internal/endpoint").Start(ctx, "endpoint.ResolveHost")
defer span.End()

if override != "" {
span.SetAttributes(attribute.String("endpoint.host", override), attribute.Bool("endpoint.override", true))
return override, true
}
// Use a "test." subdomain: *.localhost.localstack.cloud has wildcard DNS that resolves
// to 127.0.0.1, so any subdomain works as a probe without hitting the actual service.
addrs, err := net.LookupHost("test." + Hostname)
probe := "test." + Hostname
span.SetAttributes(attribute.String("endpoint.dns.probe", probe))
resolver := net.Resolver{}
addrs, err := resolver.LookupHost(ctx, probe)
if err != nil {
span.SetAttributes(attribute.Bool("endpoint.dns.ok", false))
return "127.0.0.1:" + port, false
}
for _, addr := range addrs {
if addr == "127.0.0.1" {
span.SetAttributes(attribute.Bool("endpoint.dns.ok", true), attribute.String("endpoint.host", Hostname))
return Hostname + ":" + port, true
}
}
span.SetAttributes(attribute.Bool("endpoint.dns.ok", false))
return "127.0.0.1:" + port, false
}
2 changes: 1 addition & 1 deletion internal/ui/run_awsconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func RunConfigProfile(parentCtx context.Context, containers []config.ContainerCo
return fmt.Errorf("no aws emulator configured")
}

resolvedHost, dnsOK := endpoint.ResolveHost(awsContainer.Port, localStackHost)
resolvedHost, dnsOK := endpoint.ResolveHost(parentCtx, awsContainer.Port, localStackHost)

return runWithTUI(parentCtx, withoutHeader(), func(ctx context.Context, sink output.Sink) error {
if !dnsOK {
Expand Down
Loading