Skip to content

Commit

Permalink
fix(cli): Updating and fixing the CLI cloud commands (#3140)
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Sep 11, 2023
1 parent 7729669 commit 57a9ef2
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 157 deletions.
17 changes: 12 additions & 5 deletions agent/initialization/start.go
Expand Up @@ -10,15 +10,13 @@ import (
"github.com/kubeshop/tracetest/agent/workers"
)

// Start the agent with given configuration
func Start(ctx context.Context, config config.Config) error {
fmt.Println("Starting agent")
func NewClient(ctx context.Context, config config.Config) (*client.Client, error) {
client, err := client.Connect(ctx, config.ServerURL,
client.WithAPIKey(config.APIKey),
client.WithAgentName(config.Name),
)
if err != nil {
return err
return nil, err
}

triggerWorker := workers.NewTriggerWorker(client)
Expand All @@ -31,12 +29,21 @@ func Start(ctx context.Context, config config.Config) error {
return client.Close()
})

return client, nil
}

// Start the agent with given configuration
func Start(ctx context.Context, config config.Config) error {
client, err := NewClient(ctx, config)
if err != nil {
return err
}

err = client.Start(ctx)
if err != nil {
return err
}

fmt.Println("Agent started! Do not close the terminal.")
client.WaitUntilDisconnected()
return nil
}
19 changes: 3 additions & 16 deletions cli/cmd/dashboard_cmd.go
Expand Up @@ -2,9 +2,8 @@ package cmd

import (
"fmt"
"os/exec"
"runtime"

"github.com/kubeshop/tracetest/cli/ui"
"github.com/spf13/cobra"
)

Expand All @@ -19,7 +18,8 @@ var dashboardCmd = &cobra.Command{
return "", fmt.Errorf("missing Tracetest endpoint configuration")
}

err := openBrowser(cliConfig.URL())
ui := ui.DefaultUI
err := ui.OpenBrowser(cliConfig.URL())
if err != nil {
return "", fmt.Errorf("failed to open the dashboard url: %s", cliConfig.URL())
}
Expand All @@ -32,16 +32,3 @@ var dashboardCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(dashboardCmd)
}

func openBrowser(u string) error {
switch runtime.GOOS {
case "linux":
return exec.Command("xdg-open", u).Start()
case "windows":
return exec.Command("rundll32", "url.dll,FileProtocolHandler", u).Start()
case "darwin":
return exec.Command("open", u).Start()
default:
return fmt.Errorf("unsupported platform")
}
}
58 changes: 58 additions & 0 deletions cli/cmd/start_agent_cmd.go
@@ -0,0 +1,58 @@
package cmd

import (
"context"

"github.com/spf13/cobra"
)

var (
startAgentParams = &startAgentParameters{}
)

var startAgentCmd = &cobra.Command{
Use: "agent",
Short: "Start an Agent",
Long: "Start an Environment Agent",
PreRun: setupCommand(),
Run: WithResultHandler(WithParamsHandler(startAgentParams)(func(_ *cobra.Command, _ []string) (string, error) {
ctx := context.Background()

endpoint := cliConfig.AgentEndpoint
if startAgentParams.endpoint != "" {
endpoint = startAgentParams.endpoint
}

err := start.StartAgent(ctx, endpoint, startAgentParams.name, startAgentParams.apiKey, cliConfig.UIEndpoint)
return "", err
})),
PostRun: teardownCommand,
}

func init() {
if isCloudEnabled {
startAgentCmd.Flags().StringVarP(&startAgentParams.apiKey, "api-key", "", "", "set the agent api key")
startAgentCmd.Flags().StringVarP(&startAgentParams.endpoint, "endpoint", "", "", "set a custom server endpoint")
startAgentCmd.Flags().StringVarP(&startAgentParams.name, "name", "", "default", "set the agent name")
startCmd.AddCommand(startAgentCmd)
}
}

type startAgentParameters struct {
apiKey string
endpoint string
name string
}

func (p startAgentParameters) Validate(cmd *cobra.Command, args []string) []error {
var errors []error

if p.apiKey == "" {
errors = append(errors, paramError{
Parameter: "api-key",
Message: "The Agent API Key is required.",
})
}

return errors
}
16 changes: 9 additions & 7 deletions cli/config/config.go
@@ -1,7 +1,6 @@
package config

import (
"context"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -132,7 +131,7 @@ func ParseServerURL(serverURL string) (scheme, endpoint string, serverPath *stri
return url.Scheme, url.Host, path, nil
}

func Save(ctx context.Context, config Config) error {
func Save(config Config) error {
configPath, err := GetConfigurationPath()
if err != nil {
return fmt.Errorf("could not get configuration path: %w", err)
Expand All @@ -155,12 +154,15 @@ func Save(ctx context.Context, config Config) error {
}

func GetConfigurationPath() (string, error) {
homePath, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("could not get user home dir: %w", err)
}
configPath := "./config.yml"
if _, err := os.Stat("config.yml"); os.IsNotExist(err) {
homePath, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("could not get user home dir: %w", err)
}

configPath := path.Join(homePath, ".tracetest/config.yml")
configPath = path.Join(homePath, ".tracetest/config.yml")
}

return configPath, nil
}
30 changes: 7 additions & 23 deletions cli/config/configurator.go
Expand Up @@ -11,7 +11,7 @@ import (
cliUI "github.com/kubeshop/tracetest/cli/ui"
)

type onFinishFn func(context.Context, Config)
type onFinishFn func(context.Context, Config, Entry, Entry)

type Configurator struct {
resources *resourcemanager.Registry
Expand All @@ -21,7 +21,7 @@ type Configurator struct {

func NewConfigurator(resources *resourcemanager.Registry) Configurator {
ui := cliUI.DefaultUI
onFinish := func(_ context.Context, _ Config) {
onFinish := func(_ context.Context, _ Config, _ Entry, _ Entry) {
ui.Success("Successfully configured Tracetest CLI")
ui.Finish()
}
Expand Down Expand Up @@ -72,7 +72,7 @@ func (c Configurator) Start(ctx context.Context, prev Config, flags ConfigFlags)

serverType := version.GetType()
if serverType == "oss" {
err := Save(ctx, cfg)
err := Save(cfg)
if err != nil {
return fmt.Errorf("could not save configuration: %w", err)
}
Expand Down Expand Up @@ -111,41 +111,25 @@ func (c Configurator) onOAuthFailure(err error) {
}

func (c Configurator) ShowOrganizationSelector(ctx context.Context, cfg Config) {
cfg, err := c.organizationSelector(ctx, cfg)
cfg, org, err := c.organizationSelector(ctx, cfg)
if err != nil {
c.ui.Exit(err.Error())
return
}

cfg, err = c.environmentSelector(ctx, cfg)
cfg, env, err := c.environmentSelector(ctx, cfg)
if err != nil {
c.ui.Exit(err.Error())
return
}

err = Save(ctx, cfg)
err = Save(cfg)
if err != nil {
c.ui.Exit(err.Error())
return
}

c.onFinish(ctx, cfg)
}

func (c Configurator) ShowEnvironmentSelector(ctx context.Context, cfg Config) {
cfg, err := c.environmentSelector(ctx, cfg)
if err != nil {
c.ui.Exit(err.Error())
return
}

err = Save(ctx, cfg)
if err != nil {
c.ui.Exit(err.Error())
return
}

c.onFinish(ctx, cfg)
c.onFinish(ctx, cfg, org, env)
}

func SetupHttpClient(cfg Config) *resourcemanager.HTTPClient {
Expand Down
48 changes: 30 additions & 18 deletions cli/config/selector.go
Expand Up @@ -9,33 +9,33 @@ import (
cliUI "github.com/kubeshop/tracetest/cli/ui"
)

type entry struct {
type Entry struct {
ID string `json:"id"`
Name string `json:"name"`
}

func (c Configurator) organizationSelector(ctx context.Context, cfg Config) (Config, error) {
func (c Configurator) organizationSelector(ctx context.Context, cfg Config) (Config, Entry, error) {
resource, err := c.resources.Get("organization")
if err != nil {
return cfg, err
return cfg, Entry{}, err
}

elements, err := getElements(ctx, resource, cfg)
if err != nil {
return cfg, err
return cfg, Entry{}, err
}

if len(elements) == 1 {
cfg.OrganizationID = elements[0].ID
c.ui.Println(fmt.Sprintf("Defaulting to only available Organization: %s", elements[0].Name))
return cfg, nil
return cfg, Entry{}, nil
}

options := make([]cliUI.Option, len(elements))
for i, org := range elements {
options[i] = cliUI.Option{
Text: org.Name,
Fn: func(o entry) func(ui cliUI.UI) {
Fn: func(o Entry) func(ui cliUI.UI) {
return func(ui cliUI.UI) {
cfg.OrganizationID = o.ID
}
Expand All @@ -46,34 +46,40 @@ func (c Configurator) organizationSelector(ctx context.Context, cfg Config) (Con
option := c.ui.Select("What Organization do you want to use?", options, 0)
option.Fn(c.ui)

return cfg, nil
for _, org := range elements {
if org.ID == cfg.OrganizationID {
return cfg, org, nil
}
}

return cfg, Entry{}, nil
}

func (c Configurator) environmentSelector(ctx context.Context, cfg Config) (Config, error) {
func (c Configurator) environmentSelector(ctx context.Context, cfg Config) (Config, Entry, error) {
resource, err := c.resources.Get("env")
if err != nil {
return cfg, err
return cfg, Entry{}, err
}
resource = resource.WithOptions(resourcemanager.WithPrefixGetter(func() string {
return fmt.Sprintf("/organizations/%s/", cfg.OrganizationID)
}))

elements, err := getElements(ctx, resource, cfg)
if err != nil {
return cfg, err
return cfg, Entry{}, err
}

if len(elements) == 1 {
cfg.EnvironmentID = elements[0].ID
c.ui.Println(fmt.Sprintf("Defaulting to only available Environment: %s", elements[0].Name))
return cfg, nil
return cfg, Entry{}, nil
}

options := make([]cliUI.Option, len(elements))
for i, env := range elements {
options[i] = cliUI.Option{
Text: env.Name,
Fn: func(e entry) func(ui cliUI.UI) {
Fn: func(e Entry) func(ui cliUI.UI) {
return func(ui cliUI.UI) {
cfg.EnvironmentID = e.ID
}
Expand All @@ -83,30 +89,36 @@ func (c Configurator) environmentSelector(ctx context.Context, cfg Config) (Conf

option := c.ui.Select("What Environment do you want to use?", options, 0)
option.Fn(c.ui)
return cfg, err
for _, env := range elements {
if env.ID == cfg.EnvironmentID {
return cfg, env, nil
}
}

return cfg, Entry{}, err
}

type entryList struct {
Elements []entry `json:"elements"`
Elements []Entry `json:"elements"`
}

func getElements(ctx context.Context, resource resourcemanager.Client, cfg Config) ([]entry, error) {
func getElements(ctx context.Context, resource resourcemanager.Client, cfg Config) ([]Entry, error) {
resource = resource.WithHttpClient(SetupHttpClient(cfg))

var list entryList
resultFormat, err := resourcemanager.Formats.GetWithFallback("json", "json")
if err != nil {
return []entry{}, err
return []Entry{}, err
}

envs, err := resource.List(ctx, resourcemanager.ListOption{}, resultFormat)
if err != nil {
return []entry{}, err
return []Entry{}, err
}

err = json.Unmarshal([]byte(envs), &list)
if err != nil {
return []entry{}, err
return []Entry{}, err
}

return list.Elements, nil
Expand Down
2 changes: 1 addition & 1 deletion cli/go.mod
Expand Up @@ -11,6 +11,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/denisbrodbeck/machineid v1.0.1
github.com/goccy/go-yaml v1.11.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/goware/urlx v0.3.2
github.com/kubeshop/tracetest/agent v0.0.0-20230907210810-84198fc9f4ef
github.com/kubeshop/tracetest/server v0.0.0-20230809150857-6314696222d3
Expand Down Expand Up @@ -51,7 +52,6 @@ require (
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
Expand Down

0 comments on commit 57a9ef2

Please sign in to comment.