diff --git a/pkg/cmd/listen.go b/pkg/cmd/listen.go index 87da4b7..29a6829 100644 --- a/pkg/cmd/listen.go +++ b/pkg/cmd/listen.go @@ -26,9 +26,9 @@ import ( ) type listenCmd struct { - cmd *cobra.Command - wsBaseURL string - noWSS bool + cmd *cobra.Command + noWSS bool + path string } func newListenCmd() *listenCmd { @@ -75,6 +75,7 @@ func newListenCmd() *listenCmd { RunE: lc.runListenCmd, } lc.cmd.Flags().BoolVar(&lc.noWSS, "no-wss", false, "Force unencrypted ws:// protocol instead of wss://") + lc.cmd.Flags().StringVar(&lc.path, "cli-path", "", "Sets the server path of that locally running web server the events will be forwarded to") lc.cmd.SetUsageTemplate( strings.Replace( @@ -113,6 +114,7 @@ func (lc *listenCmd) runListenCmd(cmd *cobra.Command, args []string) error { } return listen.Listen(url, sourceQuery, connectionQuery, listen.Flags{ - NoWSS: lc.noWSS, + NoWSS: lc.noWSS, + CliPath: lc.path, }, &Config) } diff --git a/pkg/listen/connection.go b/pkg/listen/connection.go index f5dc02d..901b6e2 100644 --- a/pkg/listen/connection.go +++ b/pkg/listen/connection.go @@ -12,7 +12,7 @@ import ( hookdeckclient "github.com/hookdeck/hookdeck-go-sdk/client" ) -func getConnections(client *hookdeckclient.Client, sources []*hookdecksdk.Source, connectionFilterString string, isMultiSource bool) ([]*hookdecksdk.Connection, error) { +func getConnections(client *hookdeckclient.Client, sources []*hookdecksdk.Source, connectionFilterString string, isMultiSource bool, cliPath string) ([]*hookdecksdk.Connection, error) { sourceIDs := []*string{} for _, source := range sources { @@ -31,7 +31,7 @@ func getConnections(client *hookdeckclient.Client, sources []*hookdecksdk.Source return []*hookdecksdk.Connection{}, err } - connections, err = ensureConnections(client, connections, sources, isMultiSource) + connections, err = ensureConnections(client, connections, sources, isMultiSource, cliPath) if err != nil { return []*hookdecksdk.Connection{}, err } @@ -71,47 +71,55 @@ func filterConnections(connections []*hookdecksdk.Connection, connectionFilterSt // When users want to listen to a single source but there is no connection for that source, // we can help user set up a new connection for it. -func ensureConnections(client *hookdeckclient.Client, connections []*hookdecksdk.Connection, sources []*hookdecksdk.Source, isMultiSource bool) ([]*hookdecksdk.Connection, error) { +func ensureConnections(client *hookdeckclient.Client, connections []*hookdecksdk.Connection, sources []*hookdecksdk.Source, isMultiSource bool, cliPath string) ([]*hookdecksdk.Connection, error) { if len(connections) > 0 || isMultiSource { return connections, nil } - answers := struct { + connectionDetails := struct { Label string `survey:"label"` Path string `survey:"path"` }{} - var qs = []*survey.Question{ - { - Name: "path", - Prompt: &survey.Input{Message: "What path should the events be forwarded to (ie: /webhooks)?"}, - Validate: func(val interface{}) error { - str, ok := val.(string) - isPath, err := isPath(str) - if !ok || !isPath || err != nil { - return errors.New("invalid path") - } - return nil + + if len(cliPath) != 0 { + connectionDetails.Path = cliPath + connectionDetails.Label = "CLI" + } else { + var qs = []*survey.Question{ + { + Name: "path", + Prompt: &survey.Input{Message: "What path should the events be forwarded to (ie: /webhooks)?"}, + Validate: func(val interface{}) error { + str, ok := val.(string) + isPath, err := isPath(str) + if !ok || !isPath || err != nil { + return errors.New("invalid path") + } + return nil + }, }, - }, - { - Name: "label", - Prompt: &survey.Input{Message: "What's your connection label (ie: My API)?"}, - Validate: survey.Required, - }, - } + { + Name: "label", + Prompt: &survey.Input{Message: "What's your connection label (ie: My API)?"}, + Validate: survey.Required, + }, + } - err := survey.Ask(qs, &answers) - if err != nil { - fmt.Println(err.Error()) - return connections, err + err := survey.Ask(qs, &connectionDetails) + if err != nil { + fmt.Println(err.Error()) + return connections, err + } } - alias := slug.Make(answers.Label) + + alias := slug.Make(connectionDetails.Label) + connection, err := client.Connection.Create(context.Background(), &hookdecksdk.ConnectionCreateRequest{ Name: hookdecksdk.OptionalOrNull(&alias), SourceId: hookdecksdk.OptionalOrNull(&sources[0].Id), Destination: hookdecksdk.OptionalOrNull(&hookdecksdk.ConnectionCreateRequestDestination{ Name: alias, - CliPath: &answers.Path, + CliPath: &connectionDetails.Path, }), }) if err != nil { diff --git a/pkg/listen/listen.go b/pkg/listen/listen.go index e98b03f..f3a019f 100644 --- a/pkg/listen/listen.go +++ b/pkg/listen/listen.go @@ -31,7 +31,8 @@ import ( ) type Flags struct { - NoWSS bool + NoWSS bool + CliPath string } // listenCmd represents the listen command @@ -46,6 +47,17 @@ func Listen(URL *url.URL, sourceQuery string, connectionFilterString string, fla isMultiSource := len(sourceAliases) > 1 || (len(sourceAliases) == 1 && sourceAliases[0] == "*") + if flags.CliPath != "" { + if isMultiSource { + return errors.New("Can only set a CLI path when listening to a single source") + } + + _, err = isPath(flags.CliPath) + if err != nil { + return errors.New("The CLI path must be in a valid format") + } + } + if config.Profile.APIKey == "" { guestURL, err = login.GuestLogin(config) if guestURL == "" { @@ -62,11 +74,33 @@ func Listen(URL *url.URL, sourceQuery string, connectionFilterString string, fla return err } - connections, err := getConnections(sdkClient, sources, connectionFilterString, isMultiSource) + connections, err := getConnections(sdkClient, sources, connectionFilterString, isMultiSource, flags.CliPath) if err != nil { return err } + // If the "clii-path" flag has been passed and the destination has a current cli path value but it's different, update destination path + if len(flags.CliPath) != 0 && + len(connections) == 1 && + *connections[0].Destination.CliPath != "" && + *connections[0].Destination.CliPath != flags.CliPath { + + l := log.StandardLogger() + updateMsg := fmt.Sprintf("Updating destination CLI path from \"%s\" to \"%s\"", *connections[0].Destination.CliPath, flags.CliPath) + l.Debug(updateMsg) + + path := flags.CliPath + _, err := sdkClient.Destination.Update(context.Background(), connections[0].Destination.Id, &hookdecksdk.DestinationUpdateRequest{ + CliPath: hookdecksdk.Optional[string](path), + }) + + if err != nil { + return err + } + + connections[0].Destination.CliPath = &path + } + sources = getRelevantSources(sources, connections) if err := validateData(sources, connections); err != nil {