Skip to content

Commit 8cbfcc3

Browse files
committed
Update direction
1 parent 64b4bf7 commit 8cbfcc3

File tree

6 files changed

+57
-60
lines changed

6 files changed

+57
-60
lines changed

cmd/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func newConfigCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
2323
func newConfigProfileCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
2424
return &cobra.Command{
2525
Use: "profile",
26-
Short: "Set up the LocalStack AWS profile",
26+
Short: "Deprecated: use 'lstk setup aws' instead",
2727
PreRunE: initConfig,
2828
RunE: commandWithTelemetry("config profile", tel, func(cmd *cobra.Command, args []string) error {
2929
appConfig, err := config.Get()

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func NewRootCmd(cfg *env.Env, tel *telemetry.Client, logger log.Logger) *cobra.C
5959
newLogoutCmd(cfg, tel, logger),
6060
newStatusCmd(cfg, tel),
6161
newLogsCmd(cfg, tel),
62+
newSetupCmd(cfg, tel),
6263
newConfigCmd(cfg, tel),
6364
newUpdateCmd(cfg, tel),
6465
)

cmd/setup.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/localstack/lstk/internal/config"
7+
"github.com/localstack/lstk/internal/env"
8+
"github.com/localstack/lstk/internal/telemetry"
9+
"github.com/localstack/lstk/internal/ui"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
func newSetupCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
14+
cmd := &cobra.Command{
15+
Use: "setup",
16+
Short: "Set up emulator CLI integration",
17+
Long: "Set up emulator CLI integration (e.g., AWS profile, Azure config).",
18+
}
19+
cmd.AddCommand(newSetupAWSCmd(cfg, tel))
20+
return cmd
21+
}
22+
23+
func newSetupAWSCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
24+
return &cobra.Command{
25+
Use: "aws",
26+
Short: "Set up the LocalStack AWS profile",
27+
Long: "Set up the LocalStack AWS profile in ~/.aws/config and ~/.aws/credentials for use with AWS CLI and SDKs.",
28+
PreRunE: initConfig,
29+
RunE: commandWithTelemetry("setup aws", tel, func(cmd *cobra.Command, args []string) error {
30+
appConfig, err := config.Get()
31+
if err != nil {
32+
return fmt.Errorf("failed to get config: %w", err)
33+
}
34+
35+
if !isInteractiveMode(cfg) {
36+
return fmt.Errorf("setup aws requires an interactive terminal")
37+
}
38+
39+
return ui.RunConfigProfile(cmd.Context(), appConfig.Containers, cfg.LocalStackHost)
40+
}),
41+
}
42+
}

internal/awsconfig/awsconfig.go

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"gopkg.in/ini.v1"
1313

14-
"github.com/localstack/lstk/internal/config"
1514
"github.com/localstack/lstk/internal/endpoint"
1615
"github.com/localstack/lstk/internal/output"
1716
)
@@ -221,9 +220,10 @@ func profilePresence() (configOK, credsOK bool, err error) {
221220
return configOK, credsOK, nil
222221
}
223222

224-
// NotifyIfMissing checks for the LocalStack AWS profile and emits a note when it is incomplete.
223+
// EnsureProfile checks for the LocalStack AWS profile and either emits a note when it is incomplete
224+
// or triggers the interactive setup flow.
225225
// resolvedHost must be a host:port string (e.g. "localhost.localstack.cloud:4566").
226-
func NotifyIfMissing(ctx context.Context, sink output.Sink, interactive bool, resolvedHost string) error {
226+
func EnsureProfile(ctx context.Context, sink output.Sink, interactive bool, resolvedHost string) error {
227227
status, err := needsProfileSetup(resolvedHost)
228228
if err != nil {
229229
output.EmitWarning(sink, fmt.Sprintf("could not check AWS profile: %v", err))
@@ -246,27 +246,6 @@ func NotifyIfMissing(ctx context.Context, sink output.Sink, interactive bool, re
246246
return nil
247247
}
248248

249-
// RunProfileSetup runs the AWS profile setup flow: resolves the host, checks DNS,
250-
// verifies interactive mode, and runs the TUI if all checks pass.
251-
// Returns an error if no AWS container is configured or if not running in interactive mode.
252-
func RunProfileSetup(ctx context.Context, sink output.Sink, containers []config.ContainerConfig, localStackHost string, interactive bool) error {
253-
awsContainer := config.GetAWSContainer(containers)
254-
if awsContainer == nil {
255-
return fmt.Errorf("no aws emulator configured")
256-
}
257-
258-
resolvedHost, dnsOK := endpoint.ResolveHost(awsContainer.Port, localStackHost)
259-
if !dnsOK {
260-
output.EmitNote(sink, `Could not resolve "localhost.localstack.cloud" - your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`)
261-
}
262-
263-
if !interactive {
264-
return fmt.Errorf("config profile requires an interactive terminal")
265-
}
266-
267-
return Setup(ctx, sink, resolvedHost)
268-
}
269-
270249
// Setup checks for the localstack AWS profile and prompts to create or update it if needed.
271250
// resolvedHost must be a host:port string (e.g. "localhost.localstack.cloud:4566").
272251
func Setup(ctx context.Context, sink output.Sink, resolvedHost string) error {

internal/container/start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func Start(ctx context.Context, rt runtime.Runtime, sink output.Sink, opts Start
184184
// Maps emulator types to their post-start setup functions.
185185
// Add an entry here to run setup for a new emulator type (e.g. Azure, Snowflake).
186186
setups := map[config.EmulatorType]postStartSetupFunc{
187-
config.EmulatorAWS: awsconfig.NotifyIfMissing,
187+
config.EmulatorAWS: awsconfig.EnsureProfile,
188188
}
189189
return runPostStartSetups(ctx, sink, opts.Containers, interactive, opts.LocalStackHost, opts.WebAppURL, setups)
190190
}

internal/ui/run_awsconfig.go

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,29 @@ package ui
33
import (
44
"context"
55
"errors"
6+
"fmt"
67
"os"
78

89
tea "github.com/charmbracelet/bubbletea"
910
"github.com/localstack/lstk/internal/awsconfig"
1011
"github.com/localstack/lstk/internal/config"
12+
"github.com/localstack/lstk/internal/endpoint"
1113
"github.com/localstack/lstk/internal/output"
1214
)
1315

1416
// RunConfigProfile runs the AWS profile setup flow with TUI output.
1517
// It resolves the host from the AWS container config and runs the setup.
1618
func RunConfigProfile(parentCtx context.Context, containers []config.ContainerConfig, localStackHost string) error {
17-
ctx, cancel := context.WithCancel(parentCtx)
18-
defer cancel()
19-
20-
app := NewApp("", "", "", cancel, withoutHeader())
21-
p := tea.NewProgram(app, tea.WithInput(os.Stdin), tea.WithOutput(os.Stdout))
22-
runErrCh := make(chan error, 1)
23-
24-
go func() {
25-
err := awsconfig.RunProfileSetup(ctx, output.NewTUISink(programSender{p: p}), containers, localStackHost, true)
26-
runErrCh <- err
27-
if err != nil && !errors.Is(err, context.Canceled) {
28-
p.Send(runErrMsg{err: err})
29-
return
30-
}
31-
p.Send(runDoneMsg{})
32-
}()
33-
34-
model, err := p.Run()
35-
if err != nil {
36-
return err
19+
awsContainer := config.GetAWSContainer(containers)
20+
if awsContainer == nil {
21+
return fmt.Errorf("no aws emulator configured")
3722
}
3823

39-
if app, ok := model.(App); ok && app.Err() != nil {
40-
return output.NewSilentError(app.Err())
24+
resolvedHost, dnsOK := endpoint.ResolveHost(awsContainer.Port, localStackHost)
25+
if !dnsOK {
26+
output.EmitNote(output.NewTUISink(programSender{}), `Could not resolve "localhost.localstack.cloud" - your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`)
4127
}
4228

43-
runErr := <-runErrCh
44-
if runErr != nil && !errors.Is(runErr, context.Canceled) {
45-
return runErr
46-
}
47-
48-
return nil
49-
}
50-
51-
// RunAWSProfileSetup runs the AWS profile setup flow with TUI output.
52-
// resolvedHost must be a host:port string (e.g. "localhost.localstack.cloud:4566").
53-
// Deprecated: Use RunConfigProfile instead, which accepts container config and resolves the host.
54-
func RunAWSProfileSetup(parentCtx context.Context, resolvedHost string) error {
5529
ctx, cancel := context.WithCancel(parentCtx)
5630
defer cancel()
5731

@@ -85,3 +59,4 @@ func RunAWSProfileSetup(parentCtx context.Context, resolvedHost string) error {
8559

8660
return nil
8761
}
62+

0 commit comments

Comments
 (0)