From 2677db1a30045ca6a99665d99428064ac43c42f9 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Fri, 24 Jul 2026 14:25:15 +1200 Subject: [PATCH 1/9] A quick jump to the console from the cli --- cmd/skpr/console/command.go | 30 ++++++++++++++ cmd/skpr/main.go | 2 + internal/command/console/command.go | 63 +++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 cmd/skpr/console/command.go create mode 100644 internal/command/console/command.go diff --git a/cmd/skpr/console/command.go b/cmd/skpr/console/command.go new file mode 100644 index 0000000..1c36ddc --- /dev/null +++ b/cmd/skpr/console/command.go @@ -0,0 +1,30 @@ +package console + +import ( + "github.com/spf13/cobra" + + skprcommand "github.com/skpr/cli/internal/command" + "github.com/skpr/cli/internal/command/console" +) + +// NewCommand creates a new cobra.Command for 'console' sub command +func NewCommand() *cobra.Command { + command := console.Command{} + + cmd := &cobra.Command{ + Use: "console ", + Args: cobra.ExactArgs(1), + DisableFlagsInUseLine: true, + Short: "Open the Skpr console for an environment in browser.", + GroupID: skprcommand.GroupDebug, + RunE: func(cmd *cobra.Command, args []string) error { + command.Environment = args[0] + return command.Run(cmd.Context()) + }, + } + + cmd.Flags().BoolVarP(&command.Print, "print", "p", false, "Only display the link instead of opening it") + + return cmd +} + diff --git a/cmd/skpr/main.go b/cmd/skpr/main.go index 3b4bd6f..702a78d 100644 --- a/cmd/skpr/main.go +++ b/cmd/skpr/main.go @@ -14,6 +14,7 @@ import ( "github.com/skpr/cli/cmd/skpr/alias" "github.com/skpr/cli/cmd/skpr/backup" "github.com/skpr/cli/cmd/skpr/config" + "github.com/skpr/cli/cmd/skpr/console" "github.com/skpr/cli/cmd/skpr/create" "github.com/skpr/cli/cmd/skpr/cron" "github.com/skpr/cli/cmd/skpr/daemon" @@ -94,6 +95,7 @@ func main() { cmd.AddCommand(backup.NewCommand()) cmd.AddCommand(config.NewCommand()) cmd.AddCommand(create.NewCommand()) + cmd.AddCommand(console.NewCommand()) cmd.AddCommand(cron.NewCommand()) cmd.AddCommand(daemon.NewCommand()) cmd.AddCommand(dashboard.NewCommand()) diff --git a/internal/command/console/command.go b/internal/command/console/command.go new file mode 100644 index 0000000..eeec2be --- /dev/null +++ b/internal/command/console/command.go @@ -0,0 +1,63 @@ +package console + +import ( + "context" + "fmt" + "strings" + + "github.com/skpr/api/pb" + "github.com/skratchdot/open-golang/open" + + "github.com/skpr/cli/internal/client" + clientconfig "github.com/skpr/cli/internal/client/config" + skprcredentials "github.com/skpr/cli/internal/client/credentials" +) + +// Command for console access. +type Command struct { + Environment string + Print bool +} + +// Run the command. +func (cmd *Command) Run(ctx context.Context) error { + config, err := clientconfig.New() + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + // Build the console URL by replacing the "cluster." prefix with "console." + host := config.API.Host() + consoleHost := strings.Replace(host, "cluster.", "console.", 1) + consoleURL := fmt.Sprintf("https://%s/projects/%s/%s", consoleHost, config.Project, cmd.Environment) + + // Check if we are logged in. If so, verify the environment exists before opening. + credentials, err := skprcredentials.New(ctx, config) + if err != nil { + return fmt.Errorf("failed to check credentials: %w", err) + } + + if credentials.Username != "" || credentials.Session != "" { + ctx, skprClient, err := client.New(ctx) + if err != nil { + return err + } + + _, err = skprClient.Environment().Get(ctx, &pb.EnvironmentGetRequest{ + Name: cmd.Environment, + }) + if err != nil { + return fmt.Errorf("failed to get environment: %w", err) + } + } + + if cmd.Print { + fmt.Println(consoleURL) + return nil + } + + fmt.Println("Opening in Browser") + + return open.Run(consoleURL) +} + From 455689a41700068a2c073c515764c8656e0ff86b Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Fri, 24 Jul 2026 14:27:39 +1200 Subject: [PATCH 2/9] Bake in the /metrics for now --- internal/command/console/command.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/command/console/command.go b/internal/command/console/command.go index eeec2be..5955a1f 100644 --- a/internal/command/console/command.go +++ b/internal/command/console/command.go @@ -29,7 +29,8 @@ func (cmd *Command) Run(ctx context.Context) error { // Build the console URL by replacing the "cluster." prefix with "console." host := config.API.Host() consoleHost := strings.Replace(host, "cluster.", "console.", 1) - consoleURL := fmt.Sprintf("https://%s/projects/%s/%s", consoleHost, config.Project, cmd.Environment) + // @todo Remove the /metrics when we respond correctly in UI. + consoleURL := fmt.Sprintf("https://%s/projects/%s/%s/metrics", consoleHost, config.Project, cmd.Environment) // Check if we are logged in. If so, verify the environment exists before opening. credentials, err := skprcredentials.New(ctx, config) @@ -60,4 +61,3 @@ func (cmd *Command) Run(ctx context.Context) error { return open.Run(consoleURL) } - From d20bc34c4c0782784599f05eb43adcc2244689e0 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Fri, 24 Jul 2026 14:32:52 +1200 Subject: [PATCH 3/9] Better environment checking --- internal/command/console/command.go | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/internal/command/console/command.go b/internal/command/console/command.go index 5955a1f..9239732 100644 --- a/internal/command/console/command.go +++ b/internal/command/console/command.go @@ -10,7 +10,6 @@ import ( "github.com/skpr/cli/internal/client" clientconfig "github.com/skpr/cli/internal/client/config" - skprcredentials "github.com/skpr/cli/internal/client/credentials" ) // Command for console access. @@ -32,24 +31,16 @@ func (cmd *Command) Run(ctx context.Context) error { // @todo Remove the /metrics when we respond correctly in UI. consoleURL := fmt.Sprintf("https://%s/projects/%s/%s/metrics", consoleHost, config.Project, cmd.Environment) - // Check if we are logged in. If so, verify the environment exists before opening. - credentials, err := skprcredentials.New(ctx, config) + ctx, client, err := client.New(ctx) if err != nil { - return fmt.Errorf("failed to check credentials: %w", err) + return err } - if credentials.Username != "" || credentials.Session != "" { - ctx, skprClient, err := client.New(ctx) - if err != nil { - return err - } - - _, err = skprClient.Environment().Get(ctx, &pb.EnvironmentGetRequest{ - Name: cmd.Environment, - }) - if err != nil { - return fmt.Errorf("failed to get environment: %w", err) - } + _, err = client.Environment().Get(ctx, &pb.EnvironmentGetRequest{ + Name: cmd.Environment, + }) + if err != nil { + return fmt.Errorf("failed to get environment: %w", err) } if cmd.Print { From c8b5eed80828bd0cdffe46ee926148bf93516e05 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Fri, 24 Jul 2026 14:36:11 +1200 Subject: [PATCH 4/9] Fixing the linting issues --- cmd/skpr/console/command.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/skpr/console/command.go b/cmd/skpr/console/command.go index 1c36ddc..d6dc8fc 100644 --- a/cmd/skpr/console/command.go +++ b/cmd/skpr/console/command.go @@ -27,4 +27,3 @@ func NewCommand() *cobra.Command { return cmd } - From c98728ba3d543b3eb717aa2bed409220a86f65a4 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 14:25:20 +1200 Subject: [PATCH 5/9] Use the server to get the console URL --- go.mod | 2 +- go.sum | 4 ++-- internal/client/client.go | 5 +++++ internal/command/console/command.go | 20 ++++++++------------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 87ecd69..a2f8ef0 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/moby/patternmatcher v0.6.1 github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 github.com/pkg/errors v0.9.1 - github.com/skpr/api v1.6.0 + github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/cobra v1.10.2 diff --git a/go.sum b/go.sum index bd78e10..bc56eae 100644 --- a/go.sum +++ b/go.sum @@ -217,8 +217,8 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skpr/api v1.6.0 h1:LzbNm97wXvnWAcm+iyV1r36YKGMFWNn65y+EHhBxgqo= -github.com/skpr/api v1.6.0/go.mod h1:LMyIte2bWjGuO2e8XOA6FKNFUX10itF2qYVTckM7dwg= +github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a h1:91Mh3B7zH46CK3I1YzrQO9caCPfv3muAauRQaL5ve44= +github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a/go.mod h1:HWzGU9hY392K8N4I7xdk+anSRLoouJM2NtSjnYfIj1s= github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926 h1:g8m8qqehB6/GMeM81BaIXQOkD2LZbCQE0HPRGear9Jw= github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926/go.mod h1:Rokt2mnHteBaBmsSgiNk4P7laV0E8/BLQsSLyGUJLtk= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= diff --git a/internal/client/client.go b/internal/client/client.go index 49b8a48..2341145 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -92,6 +92,11 @@ func (c Client) Environment() pb.EnvironmentClient { return pb.NewEnvironmentClient(c.conn) } +// Cluster client operations. +func (c Client) Cluster() pb.ClusterClient { + return pb.NewClusterClient(c.conn) +} + // Config client operations. func (c Client) Config() pb.ConfigClient { return pb.NewConfigClient(c.conn) diff --git a/internal/command/console/command.go b/internal/command/console/command.go index 9239732..387de3b 100644 --- a/internal/command/console/command.go +++ b/internal/command/console/command.go @@ -3,13 +3,11 @@ package console import ( "context" "fmt" - "strings" "github.com/skpr/api/pb" "github.com/skratchdot/open-golang/open" "github.com/skpr/cli/internal/client" - clientconfig "github.com/skpr/cli/internal/client/config" ) // Command for console access. @@ -20,21 +18,19 @@ type Command struct { // Run the command. func (cmd *Command) Run(ctx context.Context) error { - config, err := clientconfig.New() + ctx, client, err := client.New(ctx) if err != nil { - return fmt.Errorf("failed to load config: %w", err) + return err } - // Build the console URL by replacing the "cluster." prefix with "console." - host := config.API.Host() - consoleHost := strings.Replace(host, "cluster.", "console.", 1) - // @todo Remove the /metrics when we respond correctly in UI. - consoleURL := fmt.Sprintf("https://%s/projects/%s/%s/metrics", consoleHost, config.Project, cmd.Environment) - - ctx, client, err := client.New(ctx) + cluster, err := client.Cluster().Get(ctx, &pb.ClusterGetRequest{}) if err != nil { - return err + return fmt.Errorf("failed to get cluster information: %w", err) + } + if cluster.Endpoints == nil || cluster.Endpoints.Console == "" { + return fmt.Errorf("cluster does not have a console domain") } + consoleURL := cluster.Endpoints.Console _, err = client.Environment().Get(ctx, &pb.EnvironmentGetRequest{ Name: cmd.Environment, From c0680753cebdbd047a4f11e5ee931920526e1c64 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 14:33:32 +1200 Subject: [PATCH 6/9] Get the project from the config --- internal/command/console/command.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/command/console/command.go b/internal/command/console/command.go index 387de3b..7200535 100644 --- a/internal/command/console/command.go +++ b/internal/command/console/command.go @@ -8,6 +8,7 @@ import ( "github.com/skratchdot/open-golang/open" "github.com/skpr/cli/internal/client" + "github.com/skpr/cli/internal/client/config" ) // Command for console access. @@ -18,6 +19,11 @@ type Command struct { // Run the command. func (cmd *Command) Run(ctx context.Context) error { + config, err := config.New() + if err != nil { + return err + } + ctx, client, err := client.New(ctx) if err != nil { return err @@ -30,7 +36,7 @@ func (cmd *Command) Run(ctx context.Context) error { if cluster.Endpoints == nil || cluster.Endpoints.Console == "" { return fmt.Errorf("cluster does not have a console domain") } - consoleURL := cluster.Endpoints.Console + consoleHost := cluster.Endpoints.Console _, err = client.Environment().Get(ctx, &pb.EnvironmentGetRequest{ Name: cmd.Environment, @@ -39,6 +45,8 @@ func (cmd *Command) Run(ctx context.Context) error { return fmt.Errorf("failed to get environment: %w", err) } + consoleURL := fmt.Sprintf("https://%s/projects/%s/%s/metrics", consoleHost, config.Project, cmd.Environment) + if cmd.Print { fmt.Println(consoleURL) return nil From 2b3288a2892734f938409a2cec796b425e9d9317 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 19:00:56 +1200 Subject: [PATCH 7/9] Adding a todo --- internal/command/console/command.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/command/console/command.go b/internal/command/console/command.go index 7200535..5fd56a0 100644 --- a/internal/command/console/command.go +++ b/internal/command/console/command.go @@ -45,6 +45,7 @@ func (cmd *Command) Run(ctx context.Context) error { return fmt.Errorf("failed to get environment: %w", err) } + // @todo Remove '/metrics' when UI supports it. consoleURL := fmt.Sprintf("https://%s/projects/%s/%s/metrics", consoleHost, config.Project, cmd.Environment) if cmd.Print { From 89bc23f6c6bf85ff7fa2c9c4a500064f2e477ac4 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 19:03:47 +1200 Subject: [PATCH 8/9] Updating skpr/api to v1.8.0 --- go.mod | 4 ++-- go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index a2f8ef0..d6e80ab 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/moby/patternmatcher v0.6.1 github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 github.com/pkg/errors v0.9.1 - github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a + github.com/skpr/api v1.8.0 github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/cobra v1.10.2 @@ -40,7 +40,7 @@ require ( golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.22.0 golang.org/x/term v0.45.0 - google.golang.org/grpc v1.82.0 + google.golang.org/grpc v1.82.1 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index bc56eae..cc9ceba 100644 --- a/go.sum +++ b/go.sum @@ -219,6 +219,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a h1:91Mh3B7zH46CK3I1YzrQO9caCPfv3muAauRQaL5ve44= github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a/go.mod h1:HWzGU9hY392K8N4I7xdk+anSRLoouJM2NtSjnYfIj1s= +github.com/skpr/api v1.8.0 h1:mOfpy6W+8THIaRG2nxIFpQ8wdtTawSoUZbwhcs0VS0M= +github.com/skpr/api v1.8.0/go.mod h1:KMGPWD5+HwbmqqX6HNtdpDylQ1lFfTS/qiSv/bolfdc= github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926 h1:g8m8qqehB6/GMeM81BaIXQOkD2LZbCQE0HPRGear9Jw= github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926/go.mod h1:Rokt2mnHteBaBmsSgiNk4P7laV0E8/BLQsSLyGUJLtk= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= @@ -292,6 +294,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= +google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From c18fb7da1aff287bb4de53002a72684289e96d6e Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 19:09:25 +1200 Subject: [PATCH 9/9] Cleaning up --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index cc9ceba..4c326ea 100644 --- a/go.sum +++ b/go.sum @@ -217,8 +217,6 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a h1:91Mh3B7zH46CK3I1YzrQO9caCPfv3muAauRQaL5ve44= -github.com/skpr/api v1.7.1-0.20260729015944-375c0b58d01a/go.mod h1:HWzGU9hY392K8N4I7xdk+anSRLoouJM2NtSjnYfIj1s= github.com/skpr/api v1.8.0 h1:mOfpy6W+8THIaRG2nxIFpQ8wdtTawSoUZbwhcs0VS0M= github.com/skpr/api v1.8.0/go.mod h1:KMGPWD5+HwbmqqX6HNtdpDylQ1lFfTS/qiSv/bolfdc= github.com/skpr/compass/tracing v0.0.0-20251208094547-dafe383c3926 h1:g8m8qqehB6/GMeM81BaIXQOkD2LZbCQE0HPRGear9Jw= @@ -292,8 +290,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1: google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= -google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=