From 3407a0b555669263d1e33688c39dfb43a67c9048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 16 Mar 2021 23:33:11 +0100 Subject: [PATCH 01/39] Move commands to their own functions --- cmd/add.go | 14 ++-- cmd/add_resource.go | 128 ++++++++++++++++----------------- cmd/api.go | 95 ++++++++++++------------- cmd/auth.go | 56 ++++++++------- cmd/billing.go | 36 +++++----- cmd/completion.go | 44 ++++++------ cmd/connect.go | 118 +++++++++++++++--------------- cmd/create.go | 18 +++-- cmd/describe.go | 132 ++++------------------------------ cmd/describe_connector.go | 46 ++++++++++++ cmd/describe_endpoint.go | 44 ++++++++++++ cmd/describe_resource.cmd.go | 42 +++++++++++ cmd/list.go | 23 +++--- cmd/list_connectors.go | 57 ++++++++------- cmd/list_endpoints.go | 62 ++++++++-------- cmd/list_pipelines.go | 60 ++++++++-------- cmd/list_resource_types.go | 60 ++++++++-------- cmd/list_resources.go | 60 ++++++++-------- cmd/list_resources_test.go | 8 +++ cmd/list_transforms.go | 62 ++++++++-------- cmd/logs.go | 86 +++++++++++----------- cmd/open.go | 47 ++---------- cmd/open_billing.go | 40 +++++++++++ cmd/remove.go | 27 +++---- cmd/remove_connector.go | 86 +++++++++++----------- cmd/remove_endpoint.go | 46 ++++++------ cmd/remove_pipeline.go | 102 +++++++++++++------------- cmd/remove_resource.go | 86 +++++++++++----------- cmd/root.go | 54 ++++++++++---- cmd/update.go | 19 +++-- cmd/update_connector.go | 92 ++++++++++++------------ cmd/update_pipeline.go | 113 +++++++++++++++-------------- cmd/update_resource.go | 134 +++++++++++++++++------------------ cmd/version.go | 18 +++-- gen-docs/main.go | 2 +- 35 files changed, 1087 insertions(+), 1030 deletions(-) create mode 100644 cmd/describe_connector.go create mode 100644 cmd/describe_endpoint.go create mode 100644 cmd/describe_resource.cmd.go create mode 100644 cmd/list_resources_test.go create mode 100644 cmd/open_billing.go diff --git a/cmd/add.go b/cmd/add.go index 276a22049..7d174db7a 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -21,11 +21,13 @@ import ( var resName, resType string -var addCmd = &cobra.Command{ - Use: "add", - Short: "Add a resource to your Meroxa resource catalog", -} +func AddCmd() *cobra.Command { + addCmd := &cobra.Command{ + Use: "add", + Short: "Add a resource to your Meroxa resource catalog", + } + + addCmd.AddCommand(AddResourceCmd()) -func init() { - RootCmd.AddCommand(addCmd) + return addCmd } diff --git a/cmd/add_resource.go b/cmd/add_resource.go index d97c75d10..bc13b8689 100644 --- a/cmd/add_resource.go +++ b/cmd/add_resource.go @@ -27,82 +27,80 @@ import ( "github.com/spf13/cobra" ) -var addResourceCmd = &cobra.Command{ - Use: "resource --type ", - Short: "Add a resource to your Meroxa resource catalog", - Long: `Use the add command to add resources to your Meroxa resource catalog.`, - Example: "\n" + - "meroxa add resource store --type postgres -u $DATABASE_URL\n" + - "meroxa add resource datalake --type s3 -u \"s3://$AWS_ACCESS_KEY_ID:$AWS_ACCESS_KEY_SECRET@us-east-1/meroxa-demos\"\n" + - "meroxa add resource warehouse --type redshift -u $REDSHIFT_URL\n" + - "meroxa add resource slack --type url -u $WEBHOOK_URL\n", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires resource name\n\nUsage:\n meroxa add resource [flags]") - } - - resName = args[0] - - c, err := client() - - if err != nil { - return err - } - - r := meroxa.CreateResourceInput{ - Type: resType, - Name: resName, - URL: resURL, - Metadata: nil, - } - - // TODO: Figure out best way to handle creds and metadata - // Get credentials (expect a JSON string) - if resCredentials != "" { - var creds meroxa.Credentials - err = json.Unmarshal([]byte(resCredentials), &creds) - if err != nil { - return err +func AddResourceCmd() *cobra.Command { + addResourceCmd := &cobra.Command{ + Use: "resource --type ", + Short: "Add a resource to your Meroxa resource catalog", + Long: `Use the add command to add resources to your Meroxa resource catalog.`, + Example: "\n" + + "meroxa add resource store --type postgres -u $DATABASE_URL\n" + + "meroxa add resource datalake --type s3 -u \"s3://$AWS_ACCESS_KEY_ID:$AWS_ACCESS_KEY_SECRET@us-east-1/meroxa-demos\"\n" + + "meroxa add resource warehouse --type redshift -u $REDSHIFT_URL\n" + + "meroxa add resource slack --type url -u $WEBHOOK_URL\n", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires resource name\n\nUsage:\n meroxa add resource [flags]") } - r.Credentials = &creds - } + resName = args[0] + + c, err := client() - if resMetadata != "" { - var metadata map[string]string - err = json.Unmarshal([]byte(resMetadata), &metadata) if err != nil { return err } - r.Metadata = metadata - } + r := meroxa.CreateResourceInput{ + Type: resType, + Name: resName, + URL: resURL, + Metadata: nil, + } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() + // TODO: Figure out best way to handle creds and metadata + // Get credentials (expect a JSON string) + if resCredentials != "" { + var creds meroxa.Credentials + err = json.Unmarshal([]byte(resCredentials), &creds) + if err != nil { + return err + } - if !flagRootOutputJSON { - fmt.Printf("Adding %s resource (%s)...\n", resName, resType) - } + r.Credentials = &creds + } - res, err := c.CreateResource(ctx, &r) - if err != nil { - return err - } + if resMetadata != "" { + var metadata map[string]string + err = json.Unmarshal([]byte(resMetadata), &metadata) + if err != nil { + return err + } - if flagRootOutputJSON { - display.JSONPrint(res) - } else { - fmt.Printf("Resource %s successfully added!\n", res.Name) - } + r.Metadata = metadata + } - return nil - }, -} + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() -func init() { - addCmd.AddCommand(addResourceCmd) + if !flagRootOutputJSON { + fmt.Printf("Adding %s resource (%s)...\n", resName, resType) + } + + res, err := c.CreateResource(ctx, &r) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(res) + } else { + fmt.Printf("Resource %s successfully added!\n", res.Name) + } + + return nil + }, + } addResourceCmd.Flags().StringVarP(&resType, "type", "", "", "resource type") addResourceCmd.MarkFlagRequired("type") @@ -112,4 +110,6 @@ func init() { addResourceCmd.Flags().StringVarP(&resCredentials, "credentials", "", "", "resource credentials") addResourceCmd.Flags().StringVarP(&resMetadata, "metadata", "m", "", "resource metadata") -} + + return addResourceCmd +} \ No newline at end of file diff --git a/cmd/api.go b/cmd/api.go index 994ec80f8..57492031d 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -11,54 +11,53 @@ import ( "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(apiCmd) -} - -var apiCmd = &cobra.Command{ - Use: "api [body]", - Short: "Invoke Meroxa API", - Args: cobra.MinimumNArgs(2), - Example: ` +func ApiCmd() *cobra.Command { + return &cobra.Command{ + Use: "api [body]", + Short: "Invoke Meroxa API", + Args: cobra.MinimumNArgs(2), + Example: ` meroxa api GET /v1/endpoints meroxa api POST /v1/endpoints '{"protocol": "HTTP", "stream": "resource-2-499379-public.accounts", "name": "1234"}'`, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - var ( - method = args[0] - path = args[1] - body string - ) - - if len(args) > 2 { - body = args[2] - } - - resp, err := c.MakeRequestString(context.Background(), method, path, body) - if err != nil { - return err - } - - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - var prettyJSON bytes.Buffer - if err := json.Indent(&prettyJSON, b, "", "\t"); err != nil { - prettyJSON.Write(b) - } - - fmt.Printf("> %s %s\n", method, path) - fmt.Printf("< %s %s\n", resp.Status, resp.Proto) - for k, v := range resp.Header { - fmt.Printf("< %s %s\n", k, strings.Join(v, " ")) - } - fmt.Printf(prettyJSON.String()) - - return nil - }, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + var ( + method = args[0] + path = args[1] + body string + ) + + if len(args) > 2 { + body = args[2] + } + + resp, err := c.MakeRequestString(context.Background(), method, path, body) + if err != nil { + return err + } + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + var prettyJSON bytes.Buffer + if err := json.Indent(&prettyJSON, b, "", "\t"); err != nil { + prettyJSON.Write(b) + } + + fmt.Printf("> %s %s\n", method, path) + fmt.Printf("< %s %s\n", resp.Status, resp.Proto) + for k, v := range resp.Header { + fmt.Printf("< %s %s\n", k, strings.Join(v, " ")) + } + fmt.Printf(prettyJSON.String()) + + return nil + }, + } } + diff --git a/cmd/auth.go b/cmd/auth.go index 41f31bbe1..871afaf57 100644 --- a/cmd/auth.go +++ b/cmd/auth.go @@ -44,40 +44,42 @@ const callbackURL = "http://localhost:21900/oauth/callback" const domain = "auth.meroxa.io" const audience = "https://api.meroxa.io/v1" -var loginCmd = &cobra.Command{ - Use: "login", - Short: "login or sign up to the Meroxa platform", - RunE: func(cmd *cobra.Command, args []string) error { - err := login() - if err != nil { - return err - } - return nil - }, +func LoginCmd() *cobra.Command { + return &cobra.Command{ + Use: "login", + Short: "login or sign up to the Meroxa platform", + RunE: func(cmd *cobra.Command, args []string) error { + err := login() + if err != nil { + return err + } + return nil + }, + } } // logoutCmd represents the logout command -var logoutCmd = &cobra.Command{ - Use: "logout", - Short: "logout of the Meroxa platform", - RunE: func(cmd *cobra.Command, args []string) error { - // TODO: add confirmation - cfg.Set("ACCESS_TOKEN", "") - cfg.Set("REFRESH_TOKEN", "") - err := cfg.WriteConfig() - if err != nil { - return err - } - fmt.Println("credentials cleared") - return nil - }, +func LogoutCmd() *cobra.Command { + return &cobra.Command{ + Use: "logout", + Short: "logout of the Meroxa platform", + RunE: func(cmd *cobra.Command, args []string) error { + // TODO: add confirmation + cfg.Set("ACCESS_TOKEN", "") + cfg.Set("REFRESH_TOKEN", "") + err := cfg.WriteConfig() + if err != nil { + return err + } + fmt.Println("credentials cleared") + return nil + }, + } } func init() { // Login - RootCmd.AddCommand(loginCmd) - // Logout - RootCmd.AddCommand(logoutCmd) + } func login() error { diff --git a/cmd/billing.go b/cmd/billing.go index 48452c23d..23b586251 100644 --- a/cmd/billing.go +++ b/cmd/billing.go @@ -22,22 +22,20 @@ import ( ) // billingCmd represents the billing command -var billingCmd = &cobra.Command{ - Use: "billing", - Short: "Open your billing page in a web browser", - RunE: func(cmd *cobra.Command, args []string) error { - fmt.Println("meroxa open billing") - err := openBillingCmd.RunE(cmd, args) - - if err != nil { - return err - } - - return nil - }, -} - -func init() { - // TODO: Check how to disable parent flags (e.g.: --json) - RootCmd.AddCommand(billingCmd) -} +// TODO: Check how to disable parent flags (e.g.: --json) +func BillingCmd() *cobra.Command { + return &cobra.Command{ + Use: "billing", + Short: "Open your billing page in a web browser", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("meroxa open billing") + err := OpenBillingCmd().RunE(cmd, args) + + if err != nil { + return err + } + + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/completion.go b/cmd/completion.go index bf3ba384f..37b673663 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -6,10 +6,11 @@ import ( ) // completionCmd represents the completion command -var completionCmd = &cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", - Short: "Generate completion script", - Long: `To load completions: +func CompletionCmd() *cobra.Command { + return &cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate completion script", + Long: `To load completions: Bash: @@ -40,23 +41,20 @@ var completionCmd = &cobra.Command{ # To load completions for each session, execute once: $ meroxa completion fish > ~/.config/fish/completions/meroxa.fish `, - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { - switch args[0] { - case "bash": - cmd.Root().GenBashCompletion(os.Stdout) - case "zsh": - cmd.Root().GenZshCompletion(os.Stdout) - case "fish": - cmd.Root().GenFishCompletion(os.Stdout, true) - case "powershell": - cmd.Root().GenPowerShellCompletion(os.Stdout) - } - }, -} - -func init() { - RootCmd.AddCommand(completionCmd) + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + cmd.Root().GenZshCompletion(os.Stdout) + case "fish": + cmd.Root().GenFishCompletion(os.Stdout, true) + case "powershell": + cmd.Root().GenPowerShellCompletion(os.Stdout) + } + }, + } } diff --git a/cmd/connect.go b/cmd/connect.go index dbc9c0488..f1ccc1f1a 100644 --- a/cmd/connect.go +++ b/cmd/connect.go @@ -24,10 +24,11 @@ import ( ) // connectCmd represents the connect command -var connectCmd = &cobra.Command{ - Use: "connect --from --to ", - Short: "Connect two resources together", - Long: `Use the connect command to automatically configure the connectors required to pull data from one resource +func ConnectCmd() *cobra.Command { + connectCmd := &cobra.Command{ + Use: "connect --from --to ", + Short: "Connect two resources together", + Long: `Use the connect command to automatically configure the connectors required to pull data from one resource (source) to another (destination). This command is equivalent to creating two connectors separately, one from the source to Meroxa and another from Meroxa @@ -40,70 +41,69 @@ or meroxa create connector --from postgres --input accounts # Creates source connector meroxa create connector --to redshift --input orders # Creates destination connector `, - RunE: func(cmd *cobra.Command, args []string) error { - // config - cfgString, err := cmd.Flags().GetString("config") - if err != nil { - return err - } - - cfg := struct { - From *Config `json:"from"` - To *Config `json:"to"` - }{ - From: &Config{}, - To: &Config{}, - } - if cfgString != "" { - err = json.Unmarshal([]byte(cfgString), &cfg) + RunE: func(cmd *cobra.Command, args []string) error { + // config + cfgString, err := cmd.Flags().GetString("config") if err != nil { return err } - } - - // merge in input - input, err := cmd.Flags().GetString("input") - if err != nil { - return err - } - - // create connector from source to meroxa - fmt.Printf("Creating connector from source %s...", source) - - // we indicate what type of connector we're creating using its `mx:connectorType` key - metadata := map[string]string{"mx:connectorType": ""} - metadata["mx:connectorType"] = "source" - - srcCon, err := createConnector("", source, cfg.From, metadata, input) - if err != nil { - return err - } - fmt.Printf("Connector from source %s successfully created!", source) - - // we use the stream of the source as the input for the destination below - inputStreams := srcCon.Streams["output"].([]interface{}) - - // create connector from meroxa to destination - fmt.Printf("Creating connector to destination %s...", destination) - - metadata["mx:connectorType"] = "destination" - _, err = createConnector("", destination, cfg.To, metadata, inputStreams[0].(string)) - if err != nil { - return err - } - fmt.Printf("Connector to destination %s successfully created!", destination) - return nil - }, -} -func init() { - RootCmd.AddCommand(connectCmd) + cfg := struct { + From *Config `json:"from"` + To *Config `json:"to"` + }{ + From: &Config{}, + To: &Config{}, + } + if cfgString != "" { + err = json.Unmarshal([]byte(cfgString), &cfg) + if err != nil { + return err + } + } + + // merge in input + input, err := cmd.Flags().GetString("input") + if err != nil { + return err + } + + // create connector from source to meroxa + fmt.Printf("Creating connector from source %s...", source) + + // we indicate what type of connector we're creating using its `mx:connectorType` key + metadata := map[string]string{"mx:connectorType": ""} + metadata["mx:connectorType"] = "source" + + srcCon, err := createConnector("", source, cfg.From, metadata, input) + if err != nil { + return err + } + fmt.Printf("Connector from source %s successfully created!", source) + + // we use the stream of the source as the input for the destination below + inputStreams := srcCon.Streams["output"].([]interface{}) + + // create connector from meroxa to destination + fmt.Printf("Creating connector to destination %s...", destination) + + metadata["mx:connectorType"] = "destination" + _, err = createConnector("", destination, cfg.To, metadata, inputStreams[0].(string)) + if err != nil { + return err + } + fmt.Printf("Connector to destination %s successfully created!", destination) + return nil + }, + } - // Flags connectCmd.Flags().StringVarP(&source, "from", "", "", "source resource name") connectCmd.MarkFlagRequired("from") connectCmd.Flags().StringVarP(&destination, "to", "", "", "destination resource name") connectCmd.MarkFlagRequired("to") connectCmd.Flags().StringP("config", "c", "", "connector configuration") connectCmd.Flags().String("input", "", "command delimeted list of input streams") + + return connectCmd } + diff --git a/cmd/create.go b/cmd/create.go index e51760cf1..07834593f 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -29,19 +29,17 @@ var ( ) // createCmd represents the create command -var createCmd = &cobra.Command{ - Use: "create", - Short: "Create Meroxa pipeline components", - Long: `Use the create command to create various Meroxa pipeline components +func CreateCmd() *cobra.Command { + createCmd := &cobra.Command{ + Use: "create", + Short: "Create Meroxa pipeline components", + Long: `Use the create command to create various Meroxa pipeline components including connectors.`, -} - - -func init() { - RootCmd.AddCommand(createCmd) + } createCmd.AddCommand(createConnectorCmd) createCmd.AddCommand(createPipelineCmd) createCmd.AddCommand(createEndpointCmd) -} + return createCmd +} diff --git a/cmd/describe.go b/cmd/describe.go index f4bef6f34..8bc16f8df 100644 --- a/cmd/describe.go +++ b/cmd/describe.go @@ -17,126 +17,20 @@ limitations under the License. package cmd import ( - "context" - "errors" - "fmt" - - "github.com/meroxa/cli/display" - "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) // describeCmd represents the describe command -var describeCmd = &cobra.Command{ - Use: "describe", - Short: "Describe a component", - Long: `Describe a component of the Meroxa data platform, including resources and connectors`, -} - -var describeEndpointCmd = &cobra.Command{ - Use: "endpoint ", - Aliases: []string{"endpoints"}, - Short: "Describe Endpoint", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("requires endpoint name\n\nUsage:\n meroxa describe endpoint [flags]") - } - name := args[0] - - c, err := client() - if err != nil { - return err - } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - end, err := c.GetEndpoint(ctx, name) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(end) - } else { - display.PrintEndpointsTable([]meroxa.Endpoint{*end}) - } - return nil - - }, -} - -var describeResourceCmd = &cobra.Command{ - Use: "resource ", - Short: "Describe resource", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires resource name\n\nUsage:\n meroxa describe resource [flags]") - } - name := args[0] - - c, err := client() - if err != nil { - return err - } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - res, err := c.GetResourceByName(ctx, name) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(res) - } else { - display.PrintResourcesTable([]*meroxa.Resource{res}) - } - return nil - }, -} - -var describeConnectorCmd = &cobra.Command{ - Use: "connector [name]", - Short: "Describe connector", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires connector name\n\nUsage:\n meroxa describe connector [flags]") - } - var ( - err error - conn *meroxa.Connector - ) - name := args[0] - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - conn, err = c.GetConnectorByName(ctx, name) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(conn) - } else { - display.PrintConnectorsTable([]*meroxa.Connector{conn}) - } - return nil - }, -} - -func init() { - RootCmd.AddCommand(describeCmd) - - // Subcommands - describeCmd.AddCommand(describeResourceCmd) - describeCmd.AddCommand(describeConnectorCmd) - describeCmd.AddCommand(describeEndpointCmd) -} +func DescribeCmd() *cobra.Command { + describeCmd := &cobra.Command{ + Use: "describe", + Short: "Describe a component", + Long: `Describe a component of the Meroxa data platform, including resources and connectors`, + } + + describeCmd.AddCommand(DescribeResourceCmd()) + describeCmd.AddCommand(DescribeConnectorCmd()) + describeCmd.AddCommand(DescribeEndpointCmd()) + + return describeCmd +} \ No newline at end of file diff --git a/cmd/describe_connector.go b/cmd/describe_connector.go new file mode 100644 index 000000000..cd8378477 --- /dev/null +++ b/cmd/describe_connector.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "context" + "errors" + "github.com/meroxa/cli/display" + "github.com/meroxa/meroxa-go" + "github.com/spf13/cobra" +) + +func DescribeConnectorCmd() *cobra.Command { + return &cobra.Command{ + Use: "connector [name]", + Short: "Describe connector", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires connector name\n\nUsage:\n meroxa describe connector [flags]") + } + var ( + err error + conn *meroxa.Connector + ) + name := args[0] + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + conn, err = c.GetConnectorByName(ctx, name) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(conn) + } else { + display.PrintConnectorsTable([]*meroxa.Connector{conn}) + } + return nil + }, + } +} diff --git a/cmd/describe_endpoint.go b/cmd/describe_endpoint.go new file mode 100644 index 000000000..3b5ef737b --- /dev/null +++ b/cmd/describe_endpoint.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "context" + "fmt" + "github.com/meroxa/cli/display" + "github.com/meroxa/meroxa-go" + "github.com/spf13/cobra" +) + +func DescribeEndpointCmd() *cobra.Command { + return &cobra.Command{ + Use: "endpoint ", + Aliases: []string{"endpoints"}, + Short: "Describe Endpoint", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("requires endpoint name\n\nUsage:\n meroxa describe endpoint [flags]") + } + name := args[0] + + c, err := client() + if err != nil { + return err + } + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + end, err := c.GetEndpoint(ctx, name) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(end) + } else { + display.PrintEndpointsTable([]meroxa.Endpoint{*end}) + } + return nil + + }, + } +} diff --git a/cmd/describe_resource.cmd.go b/cmd/describe_resource.cmd.go new file mode 100644 index 000000000..10f32373c --- /dev/null +++ b/cmd/describe_resource.cmd.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "context" + "errors" + "github.com/meroxa/cli/display" + "github.com/meroxa/meroxa-go" + "github.com/spf13/cobra" +) + +func DescribeResourceCmd() *cobra.Command { + return &cobra.Command{ + Use: "resource ", + Short: "Describe resource", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires resource name\n\nUsage:\n meroxa describe resource [flags]") + } + name := args[0] + + c, err := client() + if err != nil { + return err + } + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + res, err := c.GetResourceByName(ctx, name) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(res) + } else { + display.PrintResourcesTable([]*meroxa.Resource{res}) + } + return nil + }, + } +} diff --git a/cmd/list.go b/cmd/list.go index b0d9646ea..a4cf65d00 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -21,13 +21,20 @@ import ( ) // listCmd represents the list command -var listCmd = &cobra.Command{ - Use: "list", - Short: "List components", - Long: `List the components of the Meroxa platform, including pipelines, +func ListCmd() *cobra.Command { + listCmd := &cobra.Command{ + Use: "list", + Short: "List components", + Long: `List the components of the Meroxa platform, including pipelines, resources, connectors, etc... You may also filter by type.`, -} + } -func init() { - RootCmd.AddCommand(listCmd) -} + listCmd.AddCommand(ListConnectorsCmd()) + listCmd.AddCommand(ListEndpointsCmd()) + listCmd.AddCommand(ListResourceTypesCmd()) + listCmd.AddCommand(ListPipelinesCmd()) + listCmd.AddCommand(ListResourcesCmd()) + listCmd.AddCommand(ListTransformsCmd()) + + return listCmd +} \ No newline at end of file diff --git a/cmd/list_connectors.go b/cmd/list_connectors.go index 4b84b2e3e..4b36c2366 100644 --- a/cmd/list_connectors.go +++ b/cmd/list_connectors.go @@ -24,34 +24,33 @@ import ( "github.com/spf13/cobra" ) -var listConnectorsCmd = &cobra.Command{ - Use: "connectors", - Short: "List connectors", - Aliases: []string{"connector"}, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - connectors, err := c.ListConnectors(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(connectors) - } else { - display.PrintConnectorsTable(connectors) - } - return nil - }, +func ListConnectorsCmd() *cobra.Command { + return &cobra.Command{ + Use: "connectors", + Short: "List connectors", + Aliases: []string{"connector"}, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + connectors, err := c.ListConnectors(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(connectors) + } else { + display.PrintConnectorsTable(connectors) + } + return nil + }, + } } -func init() { - listCmd.AddCommand(listConnectorsCmd) -} diff --git a/cmd/list_endpoints.go b/cmd/list_endpoints.go index ee767f4f9..ab6bfafb5 100644 --- a/cmd/list_endpoints.go +++ b/cmd/list_endpoints.go @@ -18,40 +18,36 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" - "github.com/spf13/cobra" ) -var listEndpointsCmd = &cobra.Command{ - Use: "endpoint", - Aliases: []string{"endpoints"}, - Short: "List endpoints", - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx, cancel := context.WithTimeout(context.Background(), clientTimeOut) - defer cancel() - - ends, err := c.ListEndpoints(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(ends) - } else { - display.PrintEndpointsTable(ends) - } - - return nil - }, -} - -func init() { - listCmd.AddCommand(listEndpointsCmd) -} +func ListEndpointsCmd() *cobra.Command { + return &cobra.Command{ + Use: "endpoint", + Aliases: []string{"endpoints"}, + Short: "List endpoints", + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), clientTimeOut) + defer cancel() + + ends, err := c.ListEndpoints(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(ends) + } else { + display.PrintEndpointsTable(ends) + } + + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/list_pipelines.go b/cmd/list_pipelines.go index bf2b60244..6bda72522 100644 --- a/cmd/list_pipelines.go +++ b/cmd/list_pipelines.go @@ -23,34 +23,32 @@ import ( "github.com/spf13/cobra" ) -var listPipelinesCmd = &cobra.Command{ - Use: "pipelines", - Short: "List pipelines", - Aliases: []string{"pipeline"}, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - rr, err := c.ListPipelines(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(rr) - } else { - display.PrintPipelinesTable(rr) - } - return nil - }, -} - -func init() { - listCmd.AddCommand(listPipelinesCmd) -} +func ListPipelinesCmd() *cobra.Command { + return &cobra.Command{ + Use: "pipelines", + Short: "List pipelines", + Aliases: []string{"pipeline"}, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + rr, err := c.ListPipelines(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(rr) + } else { + display.PrintPipelinesTable(rr) + } + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/list_resource_types.go b/cmd/list_resource_types.go index a28bc5ee3..d9ccd9142 100644 --- a/cmd/list_resource_types.go +++ b/cmd/list_resource_types.go @@ -24,34 +24,32 @@ import ( "github.com/spf13/cobra" ) -var listResourceTypesCmd = &cobra.Command{ - Use: "resource-types", - Short: "List resources-types", - Aliases: []string{"resource-type"}, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - resTypes, err := c.ListResourceTypes(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(resTypes) - } else { - display.PrintResourceTypesTable(resTypes) - } - return nil - }, -} - -func init() { - listCmd.AddCommand(listResourceTypesCmd) -} +func ListResourceTypesCmd() *cobra.Command { + return &cobra.Command{ + Use: "resource-types", + Short: "List resources-types", + Aliases: []string{"resource-type"}, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + resTypes, err := c.ListResourceTypes(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(resTypes) + } else { + display.PrintResourceTypesTable(resTypes) + } + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/list_resources.go b/cmd/list_resources.go index 606acd0ce..804ac5e5a 100644 --- a/cmd/list_resources.go +++ b/cmd/list_resources.go @@ -24,34 +24,32 @@ import ( "github.com/spf13/cobra" ) -var listResourcesCmd = &cobra.Command{ - Use: "resources", - Short: "List resources", - Aliases: []string{"resource"}, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - rr, err := c.ListResources(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(rr) - } else { - display.PrintResourcesTable(rr) - } - return nil - }, -} - -func init() { - listCmd.AddCommand(listResourcesCmd) -} +func ListResourcesCmd() *cobra.Command { + return &cobra.Command{ + Use: "resources", + Short: "List resources", + Aliases: []string{"resource"}, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + rr, err := c.ListResources(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(rr) + } else { + display.PrintResourcesTable(rr) + } + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/list_resources_test.go b/cmd/list_resources_test.go new file mode 100644 index 000000000..0786cf78f --- /dev/null +++ b/cmd/list_resources_test.go @@ -0,0 +1,8 @@ +package cmd + +import "testing" + +func TestListResourcesCmd(t *testing.T) { + cmd := ListResourcesCmd() + cmd.Execute() +} diff --git a/cmd/list_transforms.go b/cmd/list_transforms.go index 8a84c1190..5f5e9b0e4 100644 --- a/cmd/list_transforms.go +++ b/cmd/list_transforms.go @@ -18,40 +18,36 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" - "github.com/spf13/cobra" ) -var listTransformsCmd = &cobra.Command{ - Use: "transforms", - Short: "List transforms", - Aliases: []string{"transform"}, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - rr, err := c.ListTransforms(ctx) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(rr) - } else { - display.PrintTransformsTable(rr) - } - return nil - }, -} - -func init() { - listCmd.AddCommand(listTransformsCmd) -} +func ListTransformsCmd() *cobra.Command { + return &cobra.Command{ + Use: "transforms", + Short: "List transforms", + Aliases: []string{"transform"}, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + rr, err := c.ListTransforms(ctx) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(rr) + } else { + display.PrintTransformsTable(rr) + } + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/logs.go b/cmd/logs.go index a7285a919..96406129b 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -3,52 +3,54 @@ package cmd import ( "context" "errors" + "github.com/spf13/cobra" "io" "os" - - "github.com/spf13/cobra" ) -func init() { - RootCmd.AddCommand(logsCmd) - logsCmd.AddCommand(logsConnectorCmd) -} +func LogsCmd() *cobra.Command { + logsCmd := &cobra.Command{ + Use: "logs", + Short: "Print logs for a component", + } -var logsCmd = &cobra.Command{ - Use: "logs", - Short: "Print logs for a component", -} + logsCmd.AddCommand(LogsConnectorCmd()) -var logsConnectorCmd = &cobra.Command{ - Use: "connector ", - Short: "Print logs for a connector", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires connector name\n\nUsage:\n meroxa logs connector ") - } - connector := args[0] - - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - resp, err := c.GetConnectorLogs(ctx, connector) - if err != nil { - return err - } - - _, err = io.Copy(os.Stderr, resp.Body) - if err != nil { - return err - } - - os.Stderr.Write([]byte("\n")) - - return nil - }, + return logsCmd } + +func LogsConnectorCmd() *cobra.Command { + return &cobra.Command{ + Use: "connector ", + Short: "Print logs for a connector", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires connector name\n\nUsage:\n meroxa logs connector ") + } + connector := args[0] + + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + resp, err := c.GetConnectorLogs(ctx, connector) + if err != nil { + return err + } + + _, err = io.Copy(os.Stderr, resp.Body) + if err != nil { + return err + } + + os.Stderr.Write([]byte("\n")) + + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/open.go b/cmd/open.go index 675827787..87deea518 100644 --- a/cmd/open.go +++ b/cmd/open.go @@ -17,49 +17,16 @@ limitations under the License. package cmd import ( - "fmt" - "github.com/pkg/browser" "github.com/spf13/cobra" - "os" ) -const ( - DashboardProductionURL = "https://dashboard.meroxa.io" - DashboardStagingURL = "https://dashboard.staging.meroxa.io" -) - -func getBillingURL() string { - platformURL := DashboardProductionURL - - if os.Getenv("ENV") == "staging" { - platformURL = DashboardStagingURL - } - return fmt.Sprintf("%s/account/billing", platformURL) -} - -// openBillingCmd represents the billing command -var openBillingCmd = &cobra.Command{ - Use: "billing", - Short: "Open your billing page in a web browser", - RunE: func(cmd *cobra.Command, args []string) error { - - err := browser.OpenURL(getBillingURL()) - - if err != nil { - return err - } - - return nil - }, -} - // openCmd represents the billing command -var openCmd = &cobra.Command{ - Use: "open", - Short: "Open in a web browser", -} +func OpenCmd() *cobra.Command { + openCmd := &cobra.Command{ + Use: "open", + Short: "Open in a web browser", + } -func init() { - openCmd.AddCommand(openBillingCmd) - RootCmd.AddCommand(openCmd) + openCmd.AddCommand(OpenBillingCmd()) + return openCmd } diff --git a/cmd/open_billing.go b/cmd/open_billing.go new file mode 100644 index 000000000..5b5813f0f --- /dev/null +++ b/cmd/open_billing.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "fmt" + "github.com/pkg/browser" + "github.com/spf13/cobra" + "os" +) + +const ( + DashboardProductionURL = "https://dashboard.meroxa.io" + DashboardStagingURL = "https://dashboard.staging.meroxa.io" +) + +func getBillingURL() string { + platformURL := DashboardProductionURL + + if os.Getenv("ENV") == "staging" { + platformURL = DashboardStagingURL + } + return fmt.Sprintf("%s/account/billing", platformURL) +} + +// openBillingCmd represents the billing command +func OpenBillingCmd() *cobra.Command { + return &cobra.Command{ + Use: "billing", + Short: "Open your billing page in a web browser", + RunE: func(cmd *cobra.Command, args []string) error { + + err := browser.OpenURL(getBillingURL()) + + if err != nil { + return err + } + + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/remove.go b/cmd/remove.go index e6bb08981..58478ed3b 100644 --- a/cmd/remove.go +++ b/cmd/remove.go @@ -16,20 +16,23 @@ limitations under the License. package cmd -import ( - "github.com/spf13/cobra" -) +import "github.com/spf13/cobra" // removeCmd represents the remove command -var removeCmd = &cobra.Command{ - Use: "remove", - Short: "Remove a component", - Long: `Deprovision a component of the Meroxa platform, including pipelines, +func RemoveCmd() *cobra.Command { + removeCmd := &cobra.Command{ + Use: "remove", + Short: "Remove a component", + Long: `Deprovision a component of the Meroxa platform, including pipelines, resources, and connectors`, - SuggestFor: []string{"destroy", "delete"}, - Aliases: []string{"rm", "delete"}, -} + SuggestFor: []string{"destroy", "delete"}, + Aliases: []string{"rm", "delete"}, + } + + removeCmd.AddCommand(RemoveConnectorCmd()) + removeCmd.AddCommand(RemoveEndpointCmd()) + removeCmd.AddCommand(RemovePipelineCmd()) + removeCmd.AddCommand(RemoveResourceCmd()) -func init() { - RootCmd.AddCommand(removeCmd) + return removeCmd } diff --git a/cmd/remove_connector.go b/cmd/remove_connector.go index e7ffd222e..1bd9c05c7 100644 --- a/cmd/remove_connector.go +++ b/cmd/remove_connector.go @@ -24,55 +24,53 @@ import ( "github.com/spf13/cobra" ) -var removeConnectorCmd = &cobra.Command{ - Use: "connector ", - Short: "Remove connector", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires connector name\n\nUsage:\n meroxa remove connector ") - } +func RemoveConnectorCmd() *cobra.Command { + return &cobra.Command{ + Use: "connector ", + Short: "Remove connector", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires connector name\n\nUsage:\n meroxa remove connector ") + } - // Connector Name - conName := args[0] + // Connector Name + conName := args[0] - c, err := client() - if err != nil { - return err - } + c, err := client() + if err != nil { + return err + } - // get Connector ID from name - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() + // get Connector ID from name + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() - con, err := c.GetConnectorByName(ctx, conName) - if err != nil { - return err - } + con, err := c.GetConnectorByName(ctx, conName) + if err != nil { + return err + } - c, err = client() - if err != nil { - return err - } + c, err = client() + if err != nil { + return err + } - ctx = context.Background() - ctx, cancel = context.WithTimeout(ctx, clientTimeOut) - defer cancel() + ctx = context.Background() + ctx, cancel = context.WithTimeout(ctx, clientTimeOut) + defer cancel() - err = c.DeleteConnector(ctx, con.ID) - if err != nil { - return err - } + err = c.DeleteConnector(ctx, con.ID) + if err != nil { + return err + } - if flagRootOutputJSON { - display.JSONPrint(con) - } else { - fmt.Printf("Connection %s removed\n", con.Name) - } - return nil - }, -} - -func init() { - removeCmd.AddCommand(removeConnectorCmd) -} + if flagRootOutputJSON { + display.JSONPrint(con) + } else { + fmt.Printf("Connection %s removed\n", con.Name) + } + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/remove_endpoint.go b/cmd/remove_endpoint.go index 6a8ba0720..8bfe8f937 100644 --- a/cmd/remove_endpoint.go +++ b/cmd/remove_endpoint.go @@ -22,28 +22,26 @@ import ( "github.com/spf13/cobra" ) -var removeEndpointCmd = &cobra.Command{ - Use: "endpoint ", - Aliases: []string{"endpoints"}, - Short: "Remove endpoint", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("requires endpoint name\n\nUsage:\n meroxa remove endpoint [flags]") - } - name := args[0] - - c, err := client() - if err != nil { - return err - } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - return c.DeleteEndpoint(ctx, name) - }, -} - -func init() { - removeCmd.AddCommand(removeEndpointCmd) +func RemoveEndpointCmd() *cobra.Command { + return &cobra.Command{ + Use: "endpoint ", + Aliases: []string{"endpoints"}, + Short: "Remove endpoint", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("requires endpoint name\n\nUsage:\n meroxa remove endpoint [flags]") + } + name := args[0] + + c, err := client() + if err != nil { + return err + } + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + return c.DeleteEndpoint(ctx, name) + }, + } } \ No newline at end of file diff --git a/cmd/remove_pipeline.go b/cmd/remove_pipeline.go index d19f41c10..0884f332f 100644 --- a/cmd/remove_pipeline.go +++ b/cmd/remove_pipeline.go @@ -24,56 +24,54 @@ import ( "github.com/spf13/cobra" ) -var removePipelineCmd = &cobra.Command{ - Use: "pipeline ", - Short: "Remove pipeline", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires pipeline name\n\nUsage:\n meroxa remove pipeline ") - } - - // Pipeline Name - pipelineName := args[0] - - c, err := client() - if err != nil { - return err - } - - // get Pipeline ID from name - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - pipeline, err := c.GetPipelineByName(ctx, pipelineName) - if err != nil { - return err - } - - c, err = client() - if err != nil { - return err - } - - ctx = context.Background() - ctx, cancel = context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - err = c.DeletePipeline(ctx, pipeline.ID) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(pipeline) - } else { - fmt.Printf("Pipeline %s removed\n", pipeline.Name) - } - - return nil - }, +func RemovePipelineCmd() *cobra.Command { + return &cobra.Command{ + Use: "pipeline ", + Short: "Remove pipeline", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires pipeline name\n\nUsage:\n meroxa remove pipeline ") + } + + // Pipeline Name + pipelineName := args[0] + + c, err := client() + if err != nil { + return err + } + + // get Pipeline ID from name + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + pipeline, err := c.GetPipelineByName(ctx, pipelineName) + if err != nil { + return err + } + + c, err = client() + if err != nil { + return err + } + + ctx = context.Background() + ctx, cancel = context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + err = c.DeletePipeline(ctx, pipeline.ID) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(pipeline) + } else { + fmt.Printf("Pipeline %s removed\n", pipeline.Name) + } + + return nil + }, + } } - -func init() { - removeCmd.AddCommand(removePipelineCmd) -} \ No newline at end of file diff --git a/cmd/remove_resource.go b/cmd/remove_resource.go index 2bcc2764c..c1a6d54cb 100644 --- a/cmd/remove_resource.go +++ b/cmd/remove_resource.go @@ -24,55 +24,53 @@ import ( "github.com/spf13/cobra" ) -var removeResourceCmd = &cobra.Command{ - Use: "resource ", - Short: "Remove resource", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires resource name\n\nUsage:\n meroxa remove resource ") - } - // Resource Name - resName := args[0] +func RemoveResourceCmd() *cobra.Command { + return &cobra.Command{ + Use: "resource ", + Short: "Remove resource", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires resource name\n\nUsage:\n meroxa remove resource ") + } + // Resource Name + resName := args[0] - c, err := client() - if err != nil { - return err - } + c, err := client() + if err != nil { + return err + } - // get Resource ID from name - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() + // get Resource ID from name + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() - res, err := c.GetResourceByName(ctx, resName) - if err != nil { - return err - } + res, err := c.GetResourceByName(ctx, resName) + if err != nil { + return err + } - c, err = client() - if err != nil { - return err - } + c, err = client() + if err != nil { + return err + } - ctx = context.Background() - ctx, cancel = context.WithTimeout(ctx, clientTimeOut) - defer cancel() + ctx = context.Background() + ctx, cancel = context.WithTimeout(ctx, clientTimeOut) + defer cancel() - // TODO: Update meroxa-go to `RemoveResource` to match its implementation - err = c.DeleteResource(ctx, res.ID) - if err != nil { - return err - } + // TODO: Update meroxa-go to `RemoveResource` to match its implementation + err = c.DeleteResource(ctx, res.ID) + if err != nil { + return err + } - if flagRootOutputJSON { - display.JSONPrint(res) - } else { - fmt.Printf("Resource %s removed\n", res.Name) - } - return nil - }, + if flagRootOutputJSON { + display.JSONPrint(res) + } else { + fmt.Printf("Resource %s removed\n", res.Name) + } + return nil + }, + } } - -func init() { - removeCmd.AddCommand(removeResourceCmd) -} \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index c0a2542da..39374f1e0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -47,41 +47,67 @@ var ( resMetadata string resCredentials string flagRootOutputJSON bool + rootCmd *cobra.Command cfg *viper.Viper ) // RootCmd represents the base command when called without any subcommands -var RootCmd = &cobra.Command{ - Use: "meroxa", - Short: "The Meroxa CLI", - Long: `The Meroxa CLI allows quick and easy access to the Meroxa data platform. +func RootCmd() *cobra.Command { + rootCmd := &cobra.Command{ + Use: "meroxa", + Short: "The Meroxa CLI", + Long: `The Meroxa CLI allows quick and easy access to the Meroxa data platform. Using the CLI you are able to create and manage sophisticated data pipelines with only a few simple commands. You can get started by listing the supported resource types: meroxa list resource-types`, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - // You can bind cobra and viper in a few locations, but PersistencePreRunE on the root command works well - return initConfig(cmd) - }, - TraverseChildren: true, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + // You can bind cobra and viper in a few locations, but PersistencePreRunE on the root command works well + return initConfig(cmd) + }, + TraverseChildren: true, + } + + rootCmd.PersistentFlags().BoolVar(&flagRootOutputJSON, "json", false, "output json") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/meroxa.env)") + rootCmd.SilenceUsage = true + rootCmd.DisableAutoGenTag = true + + // Commands + + rootCmd.AddCommand(AddCmd()) + rootCmd.AddCommand(ApiCmd()) + rootCmd.AddCommand(BillingCmd()) + rootCmd.AddCommand(CompletionCmd()) + rootCmd.AddCommand(ConnectCmd()) + rootCmd.AddCommand(CreateCmd()) + rootCmd.AddCommand(DescribeCmd()) + rootCmd.AddCommand(ListCmd()) + rootCmd.AddCommand(LoginCmd()) + rootCmd.AddCommand(LogoutCmd()) + rootCmd.AddCommand(LogsCmd()) + rootCmd.AddCommand(OpenCmd()) + rootCmd.AddCommand(RemoveCmd()) + rootCmd.AddCommand(UpdateCmd()) + rootCmd.AddCommand(VersionCmd()) + + return rootCmd } // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the RootCmd. func Execute(version string) { meroxaVersion = version - if err := RootCmd.Execute(); err != nil { + + if err := rootCmd.Execute(); err != nil { os.Exit(1) } } func init() { - RootCmd.PersistentFlags().BoolVar(&flagRootOutputJSON, "json", false, "output json") - RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/meroxa.env)") - RootCmd.SilenceUsage = true - RootCmd.DisableAutoGenTag = true + rootCmd = RootCmd() } // initConfig reads in config file and ENV variables if set. diff --git a/cmd/update.go b/cmd/update.go index 1dabfba1d..9cf8c6243 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -5,12 +5,17 @@ import ( ) // updateCmd represents the update command -var updateCmd = &cobra.Command{ - Use: "update", - Short: "Update a component", - Long: `Update a component of the Meroxa platform, including connectors`, -} +func UpdateCmd() *cobra.Command { + updateCmd := &cobra.Command{ + Use: "update", + Short: "Update a component", + Long: `Update a component of the Meroxa platform, including connectors`, + } + + updateCmd.AddCommand(UpdateConnectorCmd()) + updateCmd.AddCommand(UpdatePipelineCmd()) + updateCmd.AddCommand(UpdateResourceCmd()) -func init() { - RootCmd.AddCommand(updateCmd) + return updateCmd } + diff --git a/cmd/update_connector.go b/cmd/update_connector.go index a5023d451..bb11eeafd 100644 --- a/cmd/update_connector.go +++ b/cmd/update_connector.go @@ -26,52 +26,54 @@ import ( "github.com/spf13/cobra" ) -var updateConnectorCmd = &cobra.Command{ - Use: "connector --state ", - Aliases: []string{"connectors"}, - Short: "Update connector state", - PreRunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires connector name\n\nUsage:\n meroxa update connector --state ") - } - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - // Connector Name - conName := args[0] - - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - // call meroxa-go to update connector status with name - if !flagRootOutputJSON { - fmt.Printf("Updating %s connector...\n", conName) - } - - con, err := c.UpdateConnectorStatus(ctx, conName, state) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(con) - } else { - fmt.Printf("Connector %s successfully updated!\n", con.Name) - } - - return nil - }, -} +func UpdateConnectorCmd() *cobra.Command { + updateConnectorCmd := &cobra.Command{ + Use: "connector --state ", + Aliases: []string{"connectors"}, + Short: "Update connector state", + PreRunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires connector name\n\nUsage:\n meroxa update connector --state ") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + // Connector Name + conName := args[0] + + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + // call meroxa-go to update connector status with name + if !flagRootOutputJSON { + fmt.Printf("Updating %s connector...\n", conName) + } + + con, err := c.UpdateConnectorStatus(ctx, conName, state) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(con) + } else { + fmt.Printf("Connector %s successfully updated!\n", con.Name) + } + + return nil + }, + } -func init() { - updateCmd.AddCommand(updateConnectorCmd) updateConnectorCmd.Flags().StringVarP(&state, "state", "", "", "connector state") updateConnectorCmd.MarkFlagRequired("state") + + return updateConnectorCmd } + diff --git a/cmd/update_pipeline.go b/cmd/update_pipeline.go index df7d2c8f8..f3e76c702 100644 --- a/cmd/update_pipeline.go +++ b/cmd/update_pipeline.go @@ -28,62 +28,61 @@ var ( state string // connector state ) -var updatePipelineCmd = &cobra.Command{ - Use: "pipeline --state ", - Aliases: []string{"pipelines"}, - Short: "Update pipeline state", - PreRunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires pipeline name\n\nUsage:\n meroxa update pipeline --state ") - } - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - // Pipeline Name - pipelineName := args[0] - - c, err := client() - if err != nil { - return err - } - - // get pipeline id from name - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - pipeline, err := c.GetPipelineByName(ctx, pipelineName) - if err != nil { - return err - } - - ctx = context.Background() - ctx, cancel = context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - // call meroxa-go to update pipeline status with name - if !flagRootOutputJSON { - fmt.Printf("Updating %s pipeline...\n", pipelineName) - } - - p, err := c.UpdatePipelineStatus(ctx, pipeline.ID, state) - if err != nil { - return err - } - - if flagRootOutputJSON { - display.JSONPrint(p) - } else { - fmt.Printf("Pipeline %s successfully updated!\n", p.Name) - } - - return nil - }, -} - -func init() { - updateCmd.AddCommand(updatePipelineCmd) +func UpdatePipelineCmd() *cobra.Command { + updatePipelineCmd := &cobra.Command{ + Use: "pipeline --state ", + Aliases: []string{"pipelines"}, + Short: "Update pipeline state", + PreRunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires pipeline name\n\nUsage:\n meroxa update pipeline --state ") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + // Pipeline Name + pipelineName := args[0] + + c, err := client() + if err != nil { + return err + } + + // get pipeline id from name + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + pipeline, err := c.GetPipelineByName(ctx, pipelineName) + if err != nil { + return err + } + + ctx = context.Background() + ctx, cancel = context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + // call meroxa-go to update pipeline status with name + if !flagRootOutputJSON { + fmt.Printf("Updating %s pipeline...\n", pipelineName) + } + + p, err := c.UpdatePipelineStatus(ctx, pipeline.ID, state) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(p) + } else { + fmt.Printf("Pipeline %s successfully updated!\n", p.Name) + } + + return nil + }, + } updatePipelineCmd.Flags().StringVarP(&state, "state", "", "", "pipeline state") updatePipelineCmd.MarkFlagRequired("state") -} + return updatePipelineCmd +} \ No newline at end of file diff --git a/cmd/update_resource.go b/cmd/update_resource.go index 411765251..d54c56d5b 100644 --- a/cmd/update_resource.go +++ b/cmd/update_resource.go @@ -28,86 +28,86 @@ import ( "github.com/spf13/cobra" ) -var updateResourceCmd = &cobra.Command{ - Use: "resource ", - Short: "Update a resource", - Long: `Use the update command to update various Meroxa resources.`, - Aliases: []string{"resources"}, - // TODO: Change the design so a new name for the resource could be set - // meroxa update resource --name - PreRunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 || (resURL == "" && resMetadata == "" && resCredentials == "") { - return errors.New("requires a resource name and either `--metadata`, `--url` or `--credentials` to update the resource \n\nUsage:\n meroxa update resource [--url | --metadata | --credentials ]") - } - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - // Resource Name - resName = args[0] - c, err := client() - - if err != nil { - return err - } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - var res meroxa.UpdateResourceInput - - // If url was provided, update it - if resURL != "" { - res.URL = resURL - } - - // TODO: Figure out best way to handle creds and metadata - // Get credentials (expect a JSON string) - if resCredentials != "" { - var creds meroxa.Credentials - err = json.Unmarshal([]byte(resCredentials), &creds) - if err != nil { - return err +func UpdateResourceCmd() *cobra.Command { + updateResourceCmd := &cobra.Command{ + Use: "resource ", + Short: "Update a resource", + Long: `Use the update command to update various Meroxa resources.`, + Aliases: []string{"resources"}, + // TODO: Change the design so a new name for the resource could be set + // meroxa update resource --name + PreRunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 || (resURL == "" && resMetadata == "" && resCredentials == "") { + return errors.New("requires a resource name and either `--metadata`, `--url` or `--credentials` to update the resource \n\nUsage:\n meroxa update resource [--url | --metadata | --credentials ]") } - res.Credentials = &creds - } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + // Resource Name + resName = args[0] + c, err := client() - // If metadata was provided, update it - if resMetadata != "" { - var metadata map[string]string - err = json.Unmarshal([]byte(resMetadata), &metadata) if err != nil { return err } + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() - res.Metadata = metadata - } + var res meroxa.UpdateResourceInput + + // If url was provided, update it + if resURL != "" { + res.URL = resURL + } - // call meroxa-go to update resource - if !flagRootOutputJSON { - fmt.Printf("Updating %s resource...\n", resName) - } + // TODO: Figure out best way to handle creds and metadata + // Get credentials (expect a JSON string) + if resCredentials != "" { + var creds meroxa.Credentials + err = json.Unmarshal([]byte(resCredentials), &creds) + if err != nil { + return err + } - resource, err := c.UpdateResource(ctx, resName, res) - if err != nil { - return err - } + res.Credentials = &creds + } - if flagRootOutputJSON { - display.JSONPrint(resource) - } else { - fmt.Printf("Resource %s successfully updated!\n", resName) - } + // If metadata was provided, update it + if resMetadata != "" { + var metadata map[string]string + err = json.Unmarshal([]byte(resMetadata), &metadata) + if err != nil { + return err + } - return nil - }, -} + res.Metadata = metadata + } -func init() { - updateCmd.AddCommand(updateResourceCmd) + // call meroxa-go to update resource + if !flagRootOutputJSON { + fmt.Printf("Updating %s resource...\n", resName) + } + + resource, err := c.UpdateResource(ctx, resName, res) + if err != nil { + return err + } + + if flagRootOutputJSON { + display.JSONPrint(resource) + } else { + fmt.Printf("Resource %s successfully updated!\n", resName) + } + + return nil + }, + } updateResourceCmd.Flags().StringVarP(&resURL, "url", "u", "", "resource url") updateResourceCmd.Flags().StringVarP(&resMetadata, "metadata", "m", "", "resource metadata") updateResourceCmd.Flags().StringVarP(&resCredentials, "credentials", "", "", "resource credentials") -} + + return updateResourceCmd +} \ No newline at end of file diff --git a/cmd/version.go b/cmd/version.go index 80073d7ce..6f4556993 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -23,16 +23,14 @@ import ( ) // versionCmd represents the version command -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Display the Meroxa CLI version", - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("meroxa/%s %s/%s\n", meroxaVersion, runtime.GOOS, runtime.GOARCH) - }, -} - -func init() { - RootCmd.AddCommand(versionCmd) +func VersionCmd() *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "Display the Meroxa CLI version", + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("meroxa/%s %s/%s\n", meroxaVersion, runtime.GOOS, runtime.GOARCH) + }, + } } // Before changing this function, we'll need to update how the we're using the User-Agent when interacting with diff --git a/gen-docs/main.go b/gen-docs/main.go index 4520da3ee..8b9fd547a 100644 --- a/gen-docs/main.go +++ b/gen-docs/main.go @@ -13,7 +13,7 @@ func main() { // set HOME env var so that default values involve user's home directory do not depend on the running user. os.Setenv("HOME", "/home/user") - err := doc.GenMarkdownTree(cmd.RootCmd, "./docs/cmd") + err := doc.GenMarkdownTree(cmd.RootCmd(), "./docs/cmd") if err != nil { log.Fatal(err) } From 7af3e82fd8da84adf1b41d600b8b22e68aeb9729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Thu, 18 Mar 2021 13:38:29 +0100 Subject: [PATCH 02/39] feat(cli): Add test for root cmd --- cmd/root_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 cmd/root_test.go diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 000000000..f150b7ba6 --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,59 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestRootCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"The Meroxa CLI allows quick and easy access to the Meroxa data platform.\n\n" + + "Using the CLI you are able to create and manage sophisticated data pipelines\n" + + "with only a few simple commands. You can get started by listing the supported\n" + + "resource types:\n\n" + + "meroxa list resource-types\n\n"}, + {"Usage:\n meroxa [command]\n\n"}, + {"Available Commands:"}, + {"add Add a resource to your Meroxa resource catalog"}, + {"api Invoke Meroxa API"}, + {"billing Open your billing page in a web browser"}, + {"completion Generate completion script"}, + {"connect Connect two resources together"}, + {"create Create Meroxa pipeline components"}, + {"describe Describe a component"}, + {"help Help about any command"}, + {"list List components"}, + {"login login or sign up to the Meroxa platform"}, + {"logout logout of the Meroxa platform"}, + {"logs Print logs for a component"}, + {"open Open in a web browser"}, + {"remove Remove a component"}, + {"update Update a component"}, + {"version Display the Meroxa CLI version"}, + {"Flags:\n" + + " --config string config file (default is $HOME/meroxa.env)\n" + + " -h, --help help for meroxa\n" + + " --json output json\n\n"}, + {"Use \"meroxa [command] --help\" for more information about a command."}, + } + + cmd := RootCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.Execute() + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} \ No newline at end of file From f2756fd3f220b1950dbae07b9fa5e48e31cb9a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 13:33:50 +0100 Subject: [PATCH 03/39] Remove test --- cmd/list_resources_test.go | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 cmd/list_resources_test.go diff --git a/cmd/list_resources_test.go b/cmd/list_resources_test.go deleted file mode 100644 index 0786cf78f..000000000 --- a/cmd/list_resources_test.go +++ /dev/null @@ -1,8 +0,0 @@ -package cmd - -import "testing" - -func TestListResourcesCmd(t *testing.T) { - cmd := ListResourcesCmd() - cmd.Execute() -} From 8fb20ea269a322632f5d7a133473a24055bad537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 15:51:32 +0100 Subject: [PATCH 04/39] Add list test --- cmd/list_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 4 ++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 cmd/list_test.go diff --git a/cmd/list_test.go b/cmd/list_test.go new file mode 100644 index 000000000..f144bb8e7 --- /dev/null +++ b/cmd/list_test.go @@ -0,0 +1,51 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestListCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"List the components of the Meroxa platform, including pipelines,\n" + + " resources, connectors, etc... You may also filter by type."}, + {"Usage:\n meroxa list [command]\n\n"}, + {"Available Commands:"}, + {"connectors List connectors"}, + {"endpoint List endpoints"}, + {"pipelines List pipelines"}, + {"resource-types List resources-types"}, + {"resources List resources"}, + {"transforms List transforms"}, + {"Flags:\n -h, --help help for list\n"}, + {"Global Flags:\n" + + " --config string config file (default is $HOME/meroxa.env)\n" + + " --json output json\n"}, + {"Use \"meroxa list [command] --help\" for more information about a command.\n"}, + } + + rootCmd := RootCmd() + listCmd := ListCmd() + rootCmd.AddCommand(listCmd) + + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"list"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} diff --git a/cmd/root.go b/cmd/root.go index 39374f1e0..64f37b414 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -96,8 +96,8 @@ meroxa list resource-types`, return rootCmd } -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the RootCmd. +// Execute fills in the version based on main.version by goreleaser. +// This is called by main.main() func Execute(version string) { meroxaVersion = version From 1cac755e7c9eddf9e973e4c77b3c201df2bc4603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 16:21:37 +0100 Subject: [PATCH 05/39] Add create test --- cmd/create_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 cmd/create_test.go diff --git a/cmd/create_test.go b/cmd/create_test.go new file mode 100644 index 000000000..3b14a8228 --- /dev/null +++ b/cmd/create_test.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestCreateCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Use the create command to create various Meroxa pipeline components\n" + + "including connectors."}, + {"Usage:\n meroxa create [command]"}, + {"Available Commands:"}, + {"connector Create a connector"}, + {"endpoint Create an endpoint"}, + {"pipeline Create a pipeline"}, + {"Flags:\n -h, --help help for create\n"}, + {"Global Flags:\n" + + " --config string config file (default is $HOME/meroxa.env)\n" + + " --json output json\n"}, + {"Use \"meroxa create [command] --help\" for more information about a command.\n"}, + } + + rootCmd := RootCmd() + listCmd := ListCmd() + rootCmd.AddCommand(listCmd) + + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"create"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} From 9237e8266756f4ea2fb4baf0fff64e8d9ef174c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 16:25:55 +0100 Subject: [PATCH 06/39] Add `add` test --- cmd/add_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ cmd/create_test.go | 4 ---- cmd/list_test.go | 4 ---- 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 cmd/add_test.go diff --git a/cmd/add_test.go b/cmd/add_test.go new file mode 100644 index 000000000..e2404586b --- /dev/null +++ b/cmd/add_test.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestAddCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Add a resource to your Meroxa resource catalog"}, + {"Usage:\n" + + " meroxa add [command]"}, + {"Available Commands:"}, + {"resource Add a resource to your Meroxa resource catalog"}, + {"Flags:\n" + + " -h, --help help for add"}, + } + + rootCmd := RootCmd() + listCmd := ListCmd() + rootCmd.AddCommand(listCmd) + + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"add"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} diff --git a/cmd/create_test.go b/cmd/create_test.go index 3b14a8228..08930c5e6 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -19,10 +19,6 @@ func TestCreateCmd(t *testing.T) { {"endpoint Create an endpoint"}, {"pipeline Create a pipeline"}, {"Flags:\n -h, --help help for create\n"}, - {"Global Flags:\n" + - " --config string config file (default is $HOME/meroxa.env)\n" + - " --json output json\n"}, - {"Use \"meroxa create [command] --help\" for more information about a command.\n"}, } rootCmd := RootCmd() diff --git a/cmd/list_test.go b/cmd/list_test.go index f144bb8e7..c24baf060 100644 --- a/cmd/list_test.go +++ b/cmd/list_test.go @@ -22,10 +22,6 @@ func TestListCmd(t *testing.T) { {"resources List resources"}, {"transforms List transforms"}, {"Flags:\n -h, --help help for list\n"}, - {"Global Flags:\n" + - " --config string config file (default is $HOME/meroxa.env)\n" + - " --json output json\n"}, - {"Use \"meroxa list [command] --help\" for more information about a command.\n"}, } rootCmd := RootCmd() From 96919c2f48fa9ec418b861d4be7300e7f36d154a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 16:28:46 +0100 Subject: [PATCH 07/39] Add describe test --- cmd/describe_endpoint.go | 2 +- cmd/describe_test.go | 45 ++++++++++++++++++++++++++++ docs/cmd/meroxa_describe.md | 2 +- docs/cmd/meroxa_describe_endpoint.md | 2 +- 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 cmd/describe_test.go diff --git a/cmd/describe_endpoint.go b/cmd/describe_endpoint.go index 3b5ef737b..0b94880bb 100644 --- a/cmd/describe_endpoint.go +++ b/cmd/describe_endpoint.go @@ -12,7 +12,7 @@ func DescribeEndpointCmd() *cobra.Command { return &cobra.Command{ Use: "endpoint ", Aliases: []string{"endpoints"}, - Short: "Describe Endpoint", + Short: "Describe endpoint", RunE: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { return fmt.Errorf("requires endpoint name\n\nUsage:\n meroxa describe endpoint [flags]") diff --git a/cmd/describe_test.go b/cmd/describe_test.go new file mode 100644 index 000000000..039f01433 --- /dev/null +++ b/cmd/describe_test.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestDescribeCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Describe a component of the Meroxa data platform, including resources and connectors"}, + {"Usage:\n" + + " meroxa describe [command]"}, + {"Available Commands:"}, + {"connector Describe connector"}, + {"endpoint Describe endpoint"}, + {"resource Describe resource"}, + {"Flags:\n" + + " -h, --help help for describe"}, + } + + rootCmd := RootCmd() + listCmd := ListCmd() + rootCmd.AddCommand(listCmd) + + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"describe"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} diff --git a/docs/cmd/meroxa_describe.md b/docs/cmd/meroxa_describe.md index 96fc429d8..94d26b332 100644 --- a/docs/cmd/meroxa_describe.md +++ b/docs/cmd/meroxa_describe.md @@ -23,6 +23,6 @@ Describe a component of the Meroxa data platform, including resources and connec * [meroxa](meroxa.md) - The Meroxa CLI * [meroxa describe connector](meroxa_describe_connector.md) - Describe connector -* [meroxa describe endpoint](meroxa_describe_endpoint.md) - Describe Endpoint +* [meroxa describe endpoint](meroxa_describe_endpoint.md) - Describe endpoint * [meroxa describe resource](meroxa_describe_resource.md) - Describe resource diff --git a/docs/cmd/meroxa_describe_endpoint.md b/docs/cmd/meroxa_describe_endpoint.md index 7d91a79c2..e9a07aa46 100644 --- a/docs/cmd/meroxa_describe_endpoint.md +++ b/docs/cmd/meroxa_describe_endpoint.md @@ -1,6 +1,6 @@ ## meroxa describe endpoint -Describe Endpoint +Describe endpoint ``` meroxa describe endpoint [flags] From d37a84b8ebc8cfc1b4966bbc7215c18d44754a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 16:32:04 +0100 Subject: [PATCH 08/39] Add open test --- cmd/add_test.go | 3 --- cmd/create_test.go | 3 --- cmd/describe_test.go | 3 --- cmd/open_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 cmd/open_test.go diff --git a/cmd/add_test.go b/cmd/add_test.go index e2404586b..2ca2ecb95 100644 --- a/cmd/add_test.go +++ b/cmd/add_test.go @@ -21,9 +21,6 @@ func TestAddCmd(t *testing.T) { } rootCmd := RootCmd() - listCmd := ListCmd() - rootCmd.AddCommand(listCmd) - b := bytes.NewBufferString("") rootCmd.SetOut(b) rootCmd.SetArgs([]string{"add"}) diff --git a/cmd/create_test.go b/cmd/create_test.go index 08930c5e6..ecf39d5f6 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -22,9 +22,6 @@ func TestCreateCmd(t *testing.T) { } rootCmd := RootCmd() - listCmd := ListCmd() - rootCmd.AddCommand(listCmd) - b := bytes.NewBufferString("") rootCmd.SetOut(b) rootCmd.SetArgs([]string{"create"}) diff --git a/cmd/describe_test.go b/cmd/describe_test.go index 039f01433..b826db5bf 100644 --- a/cmd/describe_test.go +++ b/cmd/describe_test.go @@ -23,9 +23,6 @@ func TestDescribeCmd(t *testing.T) { } rootCmd := RootCmd() - listCmd := ListCmd() - rootCmd.AddCommand(listCmd) - b := bytes.NewBufferString("") rootCmd.SetOut(b) rootCmd.SetArgs([]string{"describe"}) diff --git a/cmd/open_test.go b/cmd/open_test.go new file mode 100644 index 000000000..035c70d1a --- /dev/null +++ b/cmd/open_test.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestOpenCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Open in a web browser"}, + {"Usage:\n" + + " meroxa open [command]"}, + {"Available Commands:"}, + {"billing Open your billing page in a web browser"}, + {"Flags:\n" + + " -h, --help help for open"}, + } + + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"open"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} From 77062a8d96beddd696c040276a5899d4f7de6053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 16:38:21 +0100 Subject: [PATCH 09/39] Add remove test --- cmd/remove_test.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 cmd/remove_test.go diff --git a/cmd/remove_test.go b/cmd/remove_test.go new file mode 100644 index 000000000..8e413b330 --- /dev/null +++ b/cmd/remove_test.go @@ -0,0 +1,86 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +var tests = []struct { + expected string +}{ + {"Deprovision a component of the Meroxa platform, including pipelines,\n" + + " resources, and connectors"}, + {"Usage:\n" + + " meroxa remove [command]"}, + {"Aliases:\n" + + " remove, rm, delete"}, + {"Available Commands:"}, + {"connector Remove connector"}, + {"endpoint Remove endpoint"}, + {"pipeline Remove pipeline"}, + {"resource Remove resource"}, + {"Flags:\n" + + " -h, --help help for remove"}, +} + +func TestRemoveCmd(t *testing.T) { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"remove"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} + +func TestRemoveCmdWithRmAlias(t *testing.T) { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"rm"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} + +func TestRemoveCmdWithDeleteAlias(t *testing.T) { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"delete"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} From 22a021d5c0bf6e750a5c9f13222056464d257c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 17:05:31 +0100 Subject: [PATCH 10/39] Add update test --- cmd/update_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 cmd/update_test.go diff --git a/cmd/update_test.go b/cmd/update_test.go new file mode 100644 index 000000000..2b9369f65 --- /dev/null +++ b/cmd/update_test.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestUpdateCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Update a component of the Meroxa platform, including connectors"}, + {"Usage:\n" + + " meroxa update [command]"}, + {"Available Commands:"}, + {"connector Update connector state"}, + {"pipeline Update pipeline state"}, + {"resource Update a resource"}, + {"Flags:\n" + + " -h, --help help for update"}, + } + + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"update"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} From 9ffd1cc24dd6e202ed819f380ecb81e75dddd5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 19:27:24 +0100 Subject: [PATCH 11/39] Add test for adding a resource --- cmd/add_resource_test.go | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 cmd/add_resource_test.go diff --git a/cmd/add_resource_test.go b/cmd/add_resource_test.go new file mode 100644 index 000000000..a944506e5 --- /dev/null +++ b/cmd/add_resource_test.go @@ -0,0 +1,52 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestAddResourceCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: required flag(s) \"type\", \"url\" not set", + []string{"add", "resource"}}, + { + "Error: required flag(s) \"type\" not set", + []string{"add", "resource", "--url", "myUrl"}}, + { + "Error: requires resource name", + []string{"add", "resource", "--url", "myUrl", "--type", "postgres"}, + }, + // TODO: Add a test with resource name as argument and mocking the call + } + + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + + for _, tt := range tests { + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } + + + + + + +} From fd6bbfb212b0c81e718e31b1890baa86faea2d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 20:59:32 +0100 Subject: [PATCH 12/39] Rename display to utils pkg --- cmd/add_resource.go | 4 ++-- cmd/create_connector.go | 4 ++-- cmd/create_pipeline.go | 4 ++-- cmd/describe_connector.go | 6 +++--- cmd/describe_endpoint.go | 6 +++--- cmd/describe_resource.cmd.go | 6 +++--- cmd/list_connectors.go | 6 +++--- cmd/list_endpoints.go | 6 +++--- cmd/list_pipelines.go | 6 +++--- cmd/list_resource_types.go | 6 +++--- cmd/list_resources.go | 6 +++--- cmd/list_transforms.go | 6 +++--- cmd/remove_connector.go | 4 ++-- cmd/remove_pipeline.go | 4 ++-- cmd/remove_resource.go | 4 ++-- cmd/update_connector.go | 4 ++-- cmd/update_pipeline.go | 4 ++-- cmd/update_resource.go | 4 ++-- {display => utils}/display.go | 2 +- {display => utils}/display_test.go | 2 +- 20 files changed, 47 insertions(+), 47 deletions(-) rename {display => utils}/display.go (99%) rename {display => utils}/display_test.go (99%) diff --git a/cmd/add_resource.go b/cmd/add_resource.go index bc13b8689..de5780ac1 100644 --- a/cmd/add_resource.go +++ b/cmd/add_resource.go @@ -22,7 +22,7 @@ import ( "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -93,7 +93,7 @@ func AddResourceCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(res) + utils.JSONPrint(res) } else { fmt.Printf("Resource %s successfully added!\n", res.Name) } diff --git a/cmd/create_connector.go b/cmd/create_connector.go index 3a0cd10d0..2b0b83902 100644 --- a/cmd/create_connector.go +++ b/cmd/create_connector.go @@ -21,7 +21,7 @@ import ( "encoding/json" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -88,7 +88,7 @@ var createConnectorCmd = &cobra.Command{ } if flagRootOutputJSON { - display.JSONPrint(c) + utils.JSONPrint(c) } else { fmt.Printf("Connector %s successfully created!\n", c.Name) } diff --git a/cmd/create_pipeline.go b/cmd/create_pipeline.go index 7f2f1e02e..04df550b2 100644 --- a/cmd/create_pipeline.go +++ b/cmd/create_pipeline.go @@ -21,7 +21,7 @@ import ( "encoding/json" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -71,7 +71,7 @@ var createPipelineCmd = &cobra.Command{ } if flagRootOutputJSON { - display.JSONPrint(res) + utils.JSONPrint(res) } else { fmt.Printf("Pipeline %s successfully created!\n", p.Name) } diff --git a/cmd/describe_connector.go b/cmd/describe_connector.go index cd8378477..4e3f9fcbf 100644 --- a/cmd/describe_connector.go +++ b/cmd/describe_connector.go @@ -3,7 +3,7 @@ package cmd import ( "context" "errors" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -36,9 +36,9 @@ func DescribeConnectorCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(conn) + utils.JSONPrint(conn) } else { - display.PrintConnectorsTable([]*meroxa.Connector{conn}) + utils.PrintConnectorsTable([]*meroxa.Connector{conn}) } return nil }, diff --git a/cmd/describe_endpoint.go b/cmd/describe_endpoint.go index 0b94880bb..592600c3f 100644 --- a/cmd/describe_endpoint.go +++ b/cmd/describe_endpoint.go @@ -3,7 +3,7 @@ package cmd import ( "context" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -33,9 +33,9 @@ func DescribeEndpointCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(end) + utils.JSONPrint(end) } else { - display.PrintEndpointsTable([]meroxa.Endpoint{*end}) + utils.PrintEndpointsTable([]meroxa.Endpoint{*end}) } return nil diff --git a/cmd/describe_resource.cmd.go b/cmd/describe_resource.cmd.go index 10f32373c..db4a2ab6f 100644 --- a/cmd/describe_resource.cmd.go +++ b/cmd/describe_resource.cmd.go @@ -3,7 +3,7 @@ package cmd import ( "context" "errors" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -32,9 +32,9 @@ func DescribeResourceCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(res) + utils.JSONPrint(res) } else { - display.PrintResourcesTable([]*meroxa.Resource{res}) + utils.PrintResourcesTable([]*meroxa.Resource{res}) } return nil }, diff --git a/cmd/list_connectors.go b/cmd/list_connectors.go index 4b36c2366..c60a08f13 100644 --- a/cmd/list_connectors.go +++ b/cmd/list_connectors.go @@ -19,7 +19,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -45,9 +45,9 @@ func ListConnectorsCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(connectors) + utils.JSONPrint(connectors) } else { - display.PrintConnectorsTable(connectors) + utils.PrintConnectorsTable(connectors) } return nil }, diff --git a/cmd/list_endpoints.go b/cmd/list_endpoints.go index ab6bfafb5..0de8b0979 100644 --- a/cmd/list_endpoints.go +++ b/cmd/list_endpoints.go @@ -18,7 +18,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -42,9 +42,9 @@ func ListEndpointsCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(ends) + utils.JSONPrint(ends) } else { - display.PrintEndpointsTable(ends) + utils.PrintEndpointsTable(ends) } return nil diff --git a/cmd/list_pipelines.go b/cmd/list_pipelines.go index 6bda72522..c41f20b5f 100644 --- a/cmd/list_pipelines.go +++ b/cmd/list_pipelines.go @@ -18,7 +18,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -44,9 +44,9 @@ func ListPipelinesCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(rr) + utils.JSONPrint(rr) } else { - display.PrintPipelinesTable(rr) + utils.PrintPipelinesTable(rr) } return nil }, diff --git a/cmd/list_resource_types.go b/cmd/list_resource_types.go index d9ccd9142..df1aa727f 100644 --- a/cmd/list_resource_types.go +++ b/cmd/list_resource_types.go @@ -19,7 +19,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -45,9 +45,9 @@ func ListResourceTypesCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(resTypes) + utils.JSONPrint(resTypes) } else { - display.PrintResourceTypesTable(resTypes) + utils.PrintResourceTypesTable(resTypes) } return nil }, diff --git a/cmd/list_resources.go b/cmd/list_resources.go index 804ac5e5a..d251eadb1 100644 --- a/cmd/list_resources.go +++ b/cmd/list_resources.go @@ -19,7 +19,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -45,9 +45,9 @@ func ListResourcesCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(rr) + utils.JSONPrint(rr) } else { - display.PrintResourcesTable(rr) + utils.PrintResourcesTable(rr) } return nil }, diff --git a/cmd/list_transforms.go b/cmd/list_transforms.go index 5f5e9b0e4..ff7d9c029 100644 --- a/cmd/list_transforms.go +++ b/cmd/list_transforms.go @@ -18,7 +18,7 @@ package cmd import ( "context" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -43,9 +43,9 @@ func ListTransformsCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(rr) + utils.JSONPrint(rr) } else { - display.PrintTransformsTable(rr) + utils.PrintTransformsTable(rr) } return nil }, diff --git a/cmd/remove_connector.go b/cmd/remove_connector.go index 1bd9c05c7..fea907fc9 100644 --- a/cmd/remove_connector.go +++ b/cmd/remove_connector.go @@ -20,7 +20,7 @@ import ( "context" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -66,7 +66,7 @@ func RemoveConnectorCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(con) + utils.JSONPrint(con) } else { fmt.Printf("Connection %s removed\n", con.Name) } diff --git a/cmd/remove_pipeline.go b/cmd/remove_pipeline.go index 0884f332f..15054c2b0 100644 --- a/cmd/remove_pipeline.go +++ b/cmd/remove_pipeline.go @@ -20,7 +20,7 @@ import ( "context" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -66,7 +66,7 @@ func RemovePipelineCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(pipeline) + utils.JSONPrint(pipeline) } else { fmt.Printf("Pipeline %s removed\n", pipeline.Name) } diff --git a/cmd/remove_resource.go b/cmd/remove_resource.go index c1a6d54cb..fa51914a5 100644 --- a/cmd/remove_resource.go +++ b/cmd/remove_resource.go @@ -20,7 +20,7 @@ import ( "context" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -66,7 +66,7 @@ func RemoveResourceCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(res) + utils.JSONPrint(res) } else { fmt.Printf("Resource %s removed\n", res.Name) } diff --git a/cmd/update_connector.go b/cmd/update_connector.go index bb11eeafd..5e3b95f31 100644 --- a/cmd/update_connector.go +++ b/cmd/update_connector.go @@ -22,7 +22,7 @@ import ( "fmt" "time" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -62,7 +62,7 @@ func UpdateConnectorCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(con) + utils.JSONPrint(con) } else { fmt.Printf("Connector %s successfully updated!\n", con.Name) } diff --git a/cmd/update_pipeline.go b/cmd/update_pipeline.go index f3e76c702..086d4ef1b 100644 --- a/cmd/update_pipeline.go +++ b/cmd/update_pipeline.go @@ -20,7 +20,7 @@ import ( "context" "errors" "fmt" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/spf13/cobra" ) @@ -74,7 +74,7 @@ func UpdatePipelineCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(p) + utils.JSONPrint(p) } else { fmt.Printf("Pipeline %s successfully updated!\n", p.Name) } diff --git a/cmd/update_resource.go b/cmd/update_resource.go index d54c56d5b..9255b1494 100644 --- a/cmd/update_resource.go +++ b/cmd/update_resource.go @@ -23,7 +23,7 @@ import ( "fmt" "time" - "github.com/meroxa/cli/display" + "github.com/meroxa/cli/utils" "github.com/meroxa/meroxa-go" "github.com/spf13/cobra" ) @@ -96,7 +96,7 @@ func UpdateResourceCmd() *cobra.Command { } if flagRootOutputJSON { - display.JSONPrint(resource) + utils.JSONPrint(resource) } else { fmt.Printf("Resource %s successfully updated!\n", resName) } diff --git a/display/display.go b/utils/display.go similarity index 99% rename from display/display.go rename to utils/display.go index 8dca3783c..7b088447e 100644 --- a/display/display.go +++ b/utils/display.go @@ -1,4 +1,4 @@ -package display +package utils import ( "encoding/json" diff --git a/display/display_test.go b/utils/display_test.go similarity index 99% rename from display/display_test.go rename to utils/display_test.go index e9f129aaa..16c480a23 100644 --- a/display/display_test.go +++ b/utils/display_test.go @@ -1,4 +1,4 @@ -package display +package utils import ( "bytes" From b9c0b9706347f9a36f6a6c6d8e225d079bcb9e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 21:43:26 +0100 Subject: [PATCH 13/39] Add license --- cmd/describe_connector.go | 16 ++++++++++++++++ cmd/describe_endpoint.go | 16 ++++++++++++++++ cmd/list.go | 4 ++-- cmd/logs.go | 16 ++++++++++++++++ cmd/open_billing.go | 16 ++++++++++++++++ cmd/update.go | 16 ++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/cmd/describe_connector.go b/cmd/describe_connector.go index 4e3f9fcbf..2e7995a90 100644 --- a/cmd/describe_connector.go +++ b/cmd/describe_connector.go @@ -1,3 +1,19 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( diff --git a/cmd/describe_endpoint.go b/cmd/describe_endpoint.go index 592600c3f..3de247e19 100644 --- a/cmd/describe_endpoint.go +++ b/cmd/describe_endpoint.go @@ -1,3 +1,19 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( diff --git a/cmd/list.go b/cmd/list.go index a4cf65d00..c1e217487 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -1,5 +1,3 @@ -package cmd - /* Copyright © 2020 Meroxa Inc @@ -16,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +package cmd + import ( "github.com/spf13/cobra" ) diff --git a/cmd/logs.go b/cmd/logs.go index 96406129b..1908031ef 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -1,3 +1,19 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( diff --git a/cmd/open_billing.go b/cmd/open_billing.go index 5b5813f0f..5d61dbdef 100644 --- a/cmd/open_billing.go +++ b/cmd/open_billing.go @@ -1,3 +1,19 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( diff --git a/cmd/update.go b/cmd/update.go index 9cf8c6243..e05c18b3a 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,3 +1,19 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( From 9f3a7218af818629430752daa12b7fbef6f48457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 21:43:38 +0100 Subject: [PATCH 14/39] Separate auth cmds --- cmd/client.go | 109 +++++++++++++++++++++++++ cmd/{auth.go => login.go} | 165 ++++++-------------------------------- cmd/logout.go | 41 ++++++++++ 3 files changed, 176 insertions(+), 139 deletions(-) rename cmd/{auth.go => login.go} (69%) create mode 100644 cmd/logout.go diff --git a/cmd/client.go b/cmd/client.go index 5a076c36c..402dc6544 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -1,11 +1,120 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "github.com/dgrijalva/jwt-go" + "io/ioutil" + "net/http" "os" + "time" "github.com/meroxa/meroxa-go" ) +const clientID = "2VC9z0ZxtzTcQLDNygeEELV3lYFRZwpb" +const domain = "auth.meroxa.io" + +func refresh(domain string, clientID string, refreshToken string) (accessToken string, newRefreshToken string, err error) { + url := fmt.Sprintf("https://%s/oauth/token", domain) + var tokenBody = make(map[string]string) + tokenBody["client_id"] = clientID + + if refreshToken != "" { + tokenBody["grant_type"] = "refresh_token" + tokenBody["refresh_token"] = refreshToken + } else { + return "", "", errors.New("no refresh token") + } + requestBody, err := json.Marshal(tokenBody) + if err != nil { + fmt.Println("marshal:", err) + return "", "", err + } + + resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody)) + if err != nil { + fmt.Println("request error:", err) + return "", "", err + } + defer resp.Body.Close() + responseBody, err := ioutil.ReadAll(resp.Body) + + if len(responseBody) > 0 { + var ff interface{} + json.Unmarshal(responseBody, &ff) + result := ff.(map[string]interface{}) + accessToken = fmt.Sprintf("%v", result["access_token"]) + if refreshToken == "" { + newRefreshToken = fmt.Sprintf("%v", result["refresh_token"]) + } + + return accessToken, newRefreshToken, nil + } + + return "", "", nil +} + +func getAccessToken() (string, error) { + // check access token expiration + accessToken := cfg.GetString("ACCESS_TOKEN") + if accessToken == "" { + return "", fmt.Errorf("please login or signup by running 'meroxa login'") + } + + // check access exp and grab refresh + token, _, err := new(jwt.Parser).ParseUnverified(accessToken, jwt.MapClaims{}) + if err != nil { + fmt.Println(err) + return "", fmt.Errorf("please login or signup by running 'meroxa login'") + } + + // check token exp + claims, ok := token.Claims.(jwt.MapClaims) + if !ok { + return "", fmt.Errorf("please login or signup by running 'meroxa login'") + } + + var exp time.Time + tokenExp := claims["exp"].(float64) + exp = time.Unix(int64(tokenExp), 0) + + if exp.After(time.Now()) { + return accessToken, nil + } + + // access token is expire, use refresh + refreshToken := cfg.GetString("REFRESH_TOKEN") + if refreshToken == "" { + return "", fmt.Errorf("please login or signup by running 'meroxa login'") + } + accessToken, _, err = refresh(domain, clientID, refreshToken) + if err != nil { + return "", fmt.Errorf("please login or signup by running 'meroxa login'") + } + cfg.Set("ACCESS_TOKEN", accessToken) + + return accessToken, nil +} + func isDebugEnabled() bool { if val, ok := os.LookupEnv("MEROXA_DEBUG"); ok { if val == "1" { diff --git a/cmd/auth.go b/cmd/login.go similarity index 69% rename from cmd/auth.go rename to cmd/login.go index 871afaf57..29c966113 100644 --- a/cmd/auth.go +++ b/cmd/login.go @@ -17,18 +17,13 @@ limitations under the License. package cmd import ( - "bytes" "encoding/json" - "errors" "fmt" - "github.com/dgrijalva/jwt-go" "github.com/fatih/color" - "github.com/spf13/viper" - "strings" - cv "github.com/nirasan/go-oauth-pkce-code-verifier" "github.com/skratchdot/open-golang/open" "github.com/spf13/cobra" + "github.com/spf13/viper" "io" "io/ioutil" "log" @@ -36,58 +31,12 @@ import ( "net/http" "net/url" "os" - "time" + "strings" ) -const clientID = "2VC9z0ZxtzTcQLDNygeEELV3lYFRZwpb" const callbackURL = "http://localhost:21900/oauth/callback" -const domain = "auth.meroxa.io" const audience = "https://api.meroxa.io/v1" -func LoginCmd() *cobra.Command { - return &cobra.Command{ - Use: "login", - Short: "login or sign up to the Meroxa platform", - RunE: func(cmd *cobra.Command, args []string) error { - err := login() - if err != nil { - return err - } - return nil - }, - } -} - -// logoutCmd represents the logout command -func LogoutCmd() *cobra.Command { - return &cobra.Command{ - Use: "logout", - Short: "logout of the Meroxa platform", - RunE: func(cmd *cobra.Command, args []string) error { - // TODO: add confirmation - cfg.Set("ACCESS_TOKEN", "") - cfg.Set("REFRESH_TOKEN", "") - err := cfg.WriteConfig() - if err != nil { - return err - } - fmt.Println("credentials cleared") - return nil - }, - } -} - -func init() { - // Login - -} - -func login() error { - log.Println(color.CyanString("You will now be taken to your browser for authentication or open the url below in a browser.")) - authorizeUser(clientID, domain, callbackURL) - return nil -} - // AuthorizeUser implements the PKCE OAuth2 flow. func authorizeUser(clientID string, authDomain string, redirectURL string) { // initialize the code verifier @@ -191,6 +140,19 @@ func authorizeUser(clientID string, authDomain string, redirectURL string) { server.Serve(l) } +func login() error { + log.Println(color.CyanString("You will now be taken to your browser for authentication or open the url below in a browser.")) + authorizeUser(clientID, domain, callbackURL) + return nil +} + +// cleanup closes the HTTP server +func cleanup(server *http.Server) { + // we run this as a goroutine so that this function falls through and + // the socket to the browser gets flushed/closed before the server goes away + go server.Close() +} + // getAccessToken trades the authorization code retrieved from the first OAuth2 leg for an access token func getAccessTokenAuth(clientID string, codeVerifier string, authorizationCode string, callbackURL string) (string, string, error) { // set the url and form-encoded data for the POST to the access token endpoint @@ -230,91 +192,16 @@ func getAccessTokenAuth(clientID string, codeVerifier string, authorizationCode return accessToken, refreshToken, nil } -// cleanup closes the HTTP server -func cleanup(server *http.Server) { - // we run this as a goroutine so that this function falls through and - // the socket to the browser gets flushed/closed before the server goes away - go server.Close() -} - -func refresh(domain string, clientID string, refreshToken string) (accessToken string, newRefreshToken string, err error) { - url := fmt.Sprintf("https://%s/oauth/token", domain) - var tokenBody = make(map[string]string) - tokenBody["client_id"] = clientID - - if refreshToken != "" { - tokenBody["grant_type"] = "refresh_token" - tokenBody["refresh_token"] = refreshToken - } else { - return "", "", errors.New("no refresh token") - } - requestBody, err := json.Marshal(tokenBody) - if err != nil { - fmt.Println("marshal:", err) - return "", "", err - } - - resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody)) - if err != nil { - fmt.Println("request error:", err) - return "", "", err - } - defer resp.Body.Close() - responseBody, err := ioutil.ReadAll(resp.Body) - - if len(responseBody) > 0 { - var ff interface{} - json.Unmarshal(responseBody, &ff) - result := ff.(map[string]interface{}) - accessToken = fmt.Sprintf("%v", result["access_token"]) - if refreshToken == "" { - newRefreshToken = fmt.Sprintf("%v", result["refresh_token"]) - } - - return accessToken, newRefreshToken, nil - } - - return "", "", nil -} - -func getAccessToken() (string, error) { - // check access token expiration - accessToken := cfg.GetString("ACCESS_TOKEN") - if accessToken == "" { - return "", fmt.Errorf("please login or signup by running 'meroxa login'") - } - - // check access exp and grab refresh - token, _, err := new(jwt.Parser).ParseUnverified(accessToken, jwt.MapClaims{}) - if err != nil { - fmt.Println(err) - return "", fmt.Errorf("please login or signup by running 'meroxa login'") - } - - // check token exp - claims, ok := token.Claims.(jwt.MapClaims) - if !ok { - return "", fmt.Errorf("please login or signup by running 'meroxa login'") - } - - var exp time.Time - tokenExp := claims["exp"].(float64) - exp = time.Unix(int64(tokenExp), 0) - - if exp.After(time.Now()) { - return accessToken, nil - } - - // access token is expire, use refresh - refreshToken := cfg.GetString("REFRESH_TOKEN") - if refreshToken == "" { - return "", fmt.Errorf("please login or signup by running 'meroxa login'") - } - accessToken, _, err = refresh(domain, clientID, refreshToken) - if err != nil { - return "", fmt.Errorf("please login or signup by running 'meroxa login'") +func LoginCmd() *cobra.Command { + return &cobra.Command{ + Use: "login", + Short: "login or sign up to the Meroxa platform", + RunE: func(cmd *cobra.Command, args []string) error { + err := login() + if err != nil { + return err + } + return nil + }, } - cfg.Set("ACCESS_TOKEN", accessToken) - - return accessToken, nil } diff --git a/cmd/logout.go b/cmd/logout.go new file mode 100644 index 000000000..7e49b577f --- /dev/null +++ b/cmd/logout.go @@ -0,0 +1,41 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +// logoutCmd represents the logout command +func LogoutCmd() *cobra.Command { + return &cobra.Command{ + Use: "logout", + Short: "logout of the Meroxa platform", + RunE: func(cmd *cobra.Command, args []string) error { + // TODO: add confirmation + cfg.Set("ACCESS_TOKEN", "") + cfg.Set("REFRESH_TOKEN", "") + err := cfg.WriteConfig() + if err != nil { + return err + } + fmt.Println("credentials cleared") + return nil + }, + } +} From 3b3d1fd21d105add1c826b0ce7ecf25545016d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 21:50:27 +0100 Subject: [PATCH 15/39] Move functions used to its cmd file --- cmd/configs.go | 30 ------------------------------ cmd/create_connector.go | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 30 deletions(-) delete mode 100644 cmd/configs.go diff --git a/cmd/configs.go b/cmd/configs.go deleted file mode 100644 index b01e23ae0..000000000 --- a/cmd/configs.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd - -import "fmt" - -// Config defines a dictionary to be used across our cmd package -type Config map[string]string - -// Set a key value pair -func (c Config) Set(key, value string) error { - c[key] = value - return nil -} - -// Get a key value pair -func (c Config) Get(key string) (string, bool) { - v, ok := c[key] - return v, ok -} - -// Merge one Config definition onto another -func (c Config) Merge(cfg Config) error { - for k, v := range cfg { - _, exist := c[k] - if exist { - return fmt.Errorf("merge config, key %s already present", k) - } - c[k] = v - } - return nil -} diff --git a/cmd/create_connector.go b/cmd/create_connector.go index 2b0b83902..2f733c621 100644 --- a/cmd/create_connector.go +++ b/cmd/create_connector.go @@ -26,6 +26,33 @@ import ( "github.com/spf13/cobra" ) +// Config defines a dictionary to be used across our cmd package +type Config map[string]string + +// Set a key value pair +func (c Config) Set(key, value string) error { + c[key] = value + return nil +} + +// Get a key value pair +func (c Config) Get(key string) (string, bool) { + v, ok := c[key] + return v, ok +} + +// Merge one Config definition onto another +func (c Config) Merge(cfg Config) error { + for k, v := range cfg { + _, exist := c[k] + if exist { + return fmt.Errorf("merge config, key %s already present", k) + } + c[k] = v + } + return nil +} + var createConnectorCmd = &cobra.Command{ Use: "connector [] [flags]", Short: "Create a connector", From be07e0eb4b01bdf74168bf2c84d00e75bd7974ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 22:02:34 +0100 Subject: [PATCH 16/39] Add connect test --- cmd/add_resource_test.go | 21 +++++++----------- cmd/connect_test.go | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 cmd/connect_test.go diff --git a/cmd/add_resource_test.go b/cmd/add_resource_test.go index a944506e5..76632176c 100644 --- a/cmd/add_resource_test.go +++ b/cmd/add_resource_test.go @@ -14,10 +14,12 @@ func TestAddResourceCmd(t *testing.T) { }{ { "Error: required flag(s) \"type\", \"url\" not set", - []string{"add", "resource"}}, + []string{"add", "resource"}, + }, { "Error: required flag(s) \"type\" not set", - []string{"add", "resource", "--url", "myUrl"}}, + []string{"add", "resource", "--url", "myUrl"}, + }, { "Error: requires resource name", []string{"add", "resource", "--url", "myUrl", "--type", "postgres"}, @@ -25,12 +27,11 @@ func TestAddResourceCmd(t *testing.T) { // TODO: Add a test with resource name as argument and mocking the call } - rootCmd := RootCmd() - b := bytes.NewBufferString("") - rootCmd.SetOut(b) - rootCmd.SetErr(b) - for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) rootCmd.SetArgs(tt.args) rootCmd.Execute() output, err := ioutil.ReadAll(b) @@ -43,10 +44,4 @@ func TestAddResourceCmd(t *testing.T) { t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) } } - - - - - - } diff --git a/cmd/connect_test.go b/cmd/connect_test.go new file mode 100644 index 000000000..70b76981a --- /dev/null +++ b/cmd/connect_test.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestConnectCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: required flag(s) \"from\", \"to\" not set", + []string{"connect"}, + }, + { + "Error: required flag(s) \"to\" not set", + []string{"connect", "--from", "resource-name"}, + }, + { + "Error: required flag(s) \"from\" not set", + []string{"connect", "--to", "resource-name"}, + }, + // TODO: Add a test with connect --to and --from mocking the call + } + + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From f091b9b372dbe217b75ea3d236dffdd9932dcc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 22:08:28 +0100 Subject: [PATCH 17/39] Add create connector test --- cmd/create_connector_test.go | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 cmd/create_connector_test.go diff --git a/cmd/create_connector_test.go b/cmd/create_connector_test.go new file mode 100644 index 000000000..76c917539 --- /dev/null +++ b/cmd/create_connector_test.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestCreateConnectorCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires either a source (--from) or a destination (--to)", + []string{"create", "connector"}, + }, + { + "Error: required flag(s) \"input\" not set", + []string{"create", "connector", "--to", "pg2redshift"}, + }, + { + "Error: required flag(s) \"input\" not set", + []string{"create", "connector", "--from", "pg2kafka"}, + }, + // TODO: Add a test with "--input" and mocking the call + // TODO: Add a test with connector name as argument and mocking the call + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 4dd718a4c08963e89cd4845375dc4ccb3347e34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 22:17:08 +0100 Subject: [PATCH 18/39] Refactor cmds --- cmd/create.go | 6 +- cmd/create_connector.go | 119 ++++++++++++++++++++-------------------- cmd/create_endpoint.go | 47 ++++++++-------- cmd/create_pipeline.go | 91 +++++++++++++++--------------- 4 files changed, 134 insertions(+), 129 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 07834593f..55750b0fd 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -37,9 +37,9 @@ func CreateCmd() *cobra.Command { including connectors.`, } - createCmd.AddCommand(createConnectorCmd) - createCmd.AddCommand(createPipelineCmd) - createCmd.AddCommand(createEndpointCmd) + createCmd.AddCommand(CreateConnectorCmd()) + createCmd.AddCommand(CreatePipelineCmd()) + createCmd.AddCommand(CreateEndpointCmd()) return createCmd } diff --git a/cmd/create_connector.go b/cmd/create_connector.go index 2f733c621..b1b41e198 100644 --- a/cmd/create_connector.go +++ b/cmd/create_connector.go @@ -53,78 +53,78 @@ func (c Config) Merge(cfg Config) error { return nil } -var createConnectorCmd = &cobra.Command{ - Use: "connector [] [flags]", - Short: "Create a connector", - Long: "Use create connector to create a connector from a source (--from) or to a destination (--to)", - Example: "\n" + - "meroxa create connector [] --from pg2kafka --input accounts \n" + - "meroxa create connector [] --to pg2redshift --input orders # --input will be the desired stream", - PreRunE: func(cmd *cobra.Command, args []string) error { - if source == "" && destination == "" { - return errors.New("requires either a source (--from) or a destination (--to)\n\nUsage:\n meroxa create connector [--from | --to]") - } +func CreateConnectorCmd() *cobra.Command { + createConnectorCmd := &cobra.Command{ + Use: "connector [] [flags]", + Short: "Create a connector", + Long: "Use create connector to create a connector from a source (--from) or to a destination (--to)", + Example: "\n" + + "meroxa create connector [] --from pg2kafka --input accounts \n" + + "meroxa create connector [] --to pg2redshift --input orders # --input will be the desired stream", + PreRunE: func(cmd *cobra.Command, args []string) error { + if source == "" && destination == "" { + return errors.New("requires either a source (--from) or a destination (--to)\n\nUsage:\n meroxa create connector [--from | --to]") + } - return nil - }, + return nil + }, - RunE: func(cmd *cobra.Command, args []string) error { - cfg := &Config{} - if cfgString != "" { - err := json.Unmarshal([]byte(cfgString), cfg) - if err != nil { - return err + RunE: func(cmd *cobra.Command, args []string) error { + cfg := &Config{} + if cfgString != "" { + err := json.Unmarshal([]byte(cfgString), cfg) + if err != nil { + return err + } + } + + // Process metadata + metadata := map[string]string{} + if metadataString != "" { + err := json.Unmarshal([]byte(metadataString), &metadata) + if err != nil { + return err + } } - } - // Process metadata - metadata := map[string]string{} - if metadataString != "" { - err := json.Unmarshal([]byte(metadataString), &metadata) + // merge in input + err := cfg.Set("input", input) if err != nil { return err } - } - - // merge in input - err := cfg.Set("input", input) - if err != nil { - return err - } - if source != "" { - res = source - metadata["mx:connectorType"] = "source" - } else if destination != "" { - res = destination - metadata["mx:connectorType"] = "destination" - } + if source != "" { + res = source + metadata["mx:connectorType"] = "source" + } else if destination != "" { + res = destination + metadata["mx:connectorType"] = "destination" + } - // If user specified an optional connector name - if len(args) > 0 { - con = args[0] - } + // If user specified an optional connector name + if len(args) > 0 { + con = args[0] + } - if !flagRootOutputJSON { - fmt.Println("Creating connector...") - } + if !flagRootOutputJSON { + fmt.Println("Creating connector...") + } - c, err := createConnector(con, res, cfg, metadata, input) - if err != nil { - return err - } + c, err := createConnector(con, res, cfg, metadata, input) + if err != nil { + return err + } - if flagRootOutputJSON { - utils.JSONPrint(c) - } else { - fmt.Printf("Connector %s successfully created!\n", c.Name) - } + if flagRootOutputJSON { + utils.JSONPrint(c) + } else { + fmt.Printf("Connector %s successfully created!\n", c.Name) + } - return nil - }, -} + return nil + }, + } -func init() { createConnectorCmd.Flags().StringVarP(&cfgString, "config", "c", "", "connector configuration") createConnectorCmd.Flags().StringVarP(&metadataString, "metadata", "m", "", "connector metadata") createConnectorCmd.Flags().StringVarP(&input, "input", "", "", "command delimeted list of input streams") @@ -134,7 +134,10 @@ func init() { // Hide metadata flag for now. This could probably go away createConnectorCmd.Flags().MarkHidden("metadata") + + return createConnectorCmd } + func createConnector(connectorName string, resourceName string, config *Config, metadata map[string]string, input string) (*meroxa.Connector, error) { c, err := client() if err != nil { diff --git a/cmd/create_endpoint.go b/cmd/create_endpoint.go index 9b86ec421..6d0928d6f 100644 --- a/cmd/create_endpoint.go +++ b/cmd/create_endpoint.go @@ -26,34 +26,35 @@ var ( flagEndpointCmdStream string ) -var createEndpointCmd = &cobra.Command{ - Use: "endpoint [] [flags]", - Aliases: []string{"endpoints"}, - Short: "Create an endpoint", - Long: "Use create endpoint to expose an endpoint to a connector stream", - Example: ` +func CreateEndpointCmd() *cobra.Command { + createEndpointCmd := &cobra.Command{ + Use: "endpoint [] [flags]", + Aliases: []string{"endpoints"}, + Short: "Create an endpoint", + Long: "Use create endpoint to expose an endpoint to a connector stream", + Example: ` meroxa create endpoint my-endpoint --protocol http --stream my-stream`, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := client() - if err != nil { - return err - } + RunE: func(cmd *cobra.Command, args []string) error { + c, err := client() + if err != nil { + return err + } - ctx, cancel := context.WithTimeout(context.Background(), clientTimeOut) - defer cancel() + ctx, cancel := context.WithTimeout(context.Background(), clientTimeOut) + defer cancel() - var name string - if len(args) > 0 { - name = args[0] - } + var name string + if len(args) > 0 { + name = args[0] + } - return c.CreateEndpoint(ctx, name, flagEndpointCmdProtocol, flagEndpointCmdStream) - }, -} + return c.CreateEndpoint(ctx, name, flagEndpointCmdProtocol, flagEndpointCmdStream) + }, + } -func init() { createEndpointCmd.Flags().StringVarP(&flagEndpointCmdProtocol, "protocol", "p", "", "protocol, value can be http or grpc (required)") createEndpointCmd.Flags().StringVarP(&flagEndpointCmdStream, "stream", "s", "", "stream name (required)") - cobra.MarkFlagRequired(createEndpointCmd.Flags(), "protocol") - cobra.MarkFlagRequired(createEndpointCmd.Flags(), "stream") + createEndpointCmd.MarkFlagRequired("protocol") + createEndpointCmd.MarkFlagRequired("stream") + return createEndpointCmd } \ No newline at end of file diff --git a/cmd/create_pipeline.go b/cmd/create_pipeline.go index 04df550b2..bca45a236 100644 --- a/cmd/create_pipeline.go +++ b/cmd/create_pipeline.go @@ -26,59 +26,60 @@ import ( "github.com/spf13/cobra" ) -var createPipelineCmd = &cobra.Command{ - Use: "pipeline ", - Short: "Create a pipeline", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires a pipeline name\n\nUsage:\n meroxa create pipeline [flags]") - } - pipelineName := args[0] +func CreatePipelineCmd() *cobra.Command { + createPipelineCmd := &cobra.Command{ + Use: "pipeline ", + Short: "Create a pipeline", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires a pipeline name\n\nUsage:\n meroxa create pipeline [flags]") + } + pipelineName := args[0] - c, err := client() - if err != nil { - return err - } - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() + c, err := client() + if err != nil { + return err + } + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() - p := &meroxa.Pipeline{ - Name: pipelineName, - } + p := &meroxa.Pipeline{ + Name: pipelineName, + } - // Process metadata - metadataString, err := cmd.Flags().GetString("metadata") - if err != nil { - return err - } - if metadataString != "" { - var metadata map[string]string - err = json.Unmarshal([]byte(metadataString), &metadata) + // Process metadata + metadataString, err := cmd.Flags().GetString("metadata") if err != nil { return err } - p.Metadata = metadata - } + if metadataString != "" { + var metadata map[string]string + err = json.Unmarshal([]byte(metadataString), &metadata) + if err != nil { + return err + } + p.Metadata = metadata + } - if !flagRootOutputJSON { - fmt.Println("Creating Pipeline...") - } + if !flagRootOutputJSON { + fmt.Println("Creating Pipeline...") + } - res, err := c.CreatePipeline(ctx, p) - if err != nil { - return err - } + res, err := c.CreatePipeline(ctx, p) + if err != nil { + return err + } - if flagRootOutputJSON { - utils.JSONPrint(res) - } else { - fmt.Printf("Pipeline %s successfully created!\n", p.Name) - } - return nil - }, -} + if flagRootOutputJSON { + utils.JSONPrint(res) + } else { + fmt.Printf("Pipeline %s successfully created!\n", p.Name) + } + return nil + }, + } -func init() { createPipelineCmd.Flags().StringP("metadata", "m", "", "pipeline metadata") -} + return createPipelineCmd +} \ No newline at end of file From 17dcf9cc2c6d80af99d61f5de5e8e7b9eae55257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 22:21:00 +0100 Subject: [PATCH 19/39] Add create endpoint test --- cmd/create_endpoint_test.go | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 cmd/create_endpoint_test.go diff --git a/cmd/create_endpoint_test.go b/cmd/create_endpoint_test.go new file mode 100644 index 000000000..be3e98066 --- /dev/null +++ b/cmd/create_endpoint_test.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestCreateEndpointCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: required flag(s) \"protocol\", \"stream\" not set", + []string{"create", "endpoint"}, + }, + { + "Error: required flag(s) \"stream\" not set", + []string{"create", "endpoint", "--protocol", "http"}, + }, + { + "Error: required flag(s) \"protocol\" not set", + []string{"create", "endpoint", "--stream", "my-strea,"}, + }, + // TODO: Add a test with "--protocol" and "--stream", mocking the call + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 86eb10027c01f6ae9e42baa1e1a31f895f8a130f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Mon, 22 Mar 2021 22:23:13 +0100 Subject: [PATCH 20/39] Add create pipeline test --- cmd/create_pipeline_test.go | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/create_pipeline_test.go diff --git a/cmd/create_pipeline_test.go b/cmd/create_pipeline_test.go new file mode 100644 index 000000000..a4aa10d04 --- /dev/null +++ b/cmd/create_pipeline_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestCreatePipelineCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires a pipeline name", + []string{"create", "pipeline"}, + }, + // TODO: Add a test mocking the call when specifying pipeline name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 6bf1b309f8fe8352c00c55b6043ee0945915f3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:27:41 +0100 Subject: [PATCH 21/39] Add describe connector test --- cmd/describe_connector_test.go | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/describe_connector_test.go diff --git a/cmd/describe_connector_test.go b/cmd/describe_connector_test.go new file mode 100644 index 000000000..1f0a4c779 --- /dev/null +++ b/cmd/describe_connector_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestDescribeConnectorCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires connector name", + []string{"describe", "connector"}, + }, + // TODO: Add a test mocking the call when specifying connector name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From dc7e5d95522dcbaf806874173d46635e3db98891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:29:14 +0100 Subject: [PATCH 22/39] Add describe endpoint test --- cmd/describe_endpoint_test.go | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/describe_endpoint_test.go diff --git a/cmd/describe_endpoint_test.go b/cmd/describe_endpoint_test.go new file mode 100644 index 000000000..abe443c1e --- /dev/null +++ b/cmd/describe_endpoint_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestDescribeEndpointCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires endpoint name", + []string{"describe", "endpoint"}, + }, + // TODO: Add a test mocking the call when specifying endpoint name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 5ca7db75c69ddd2e0a33933c56943c2dabeff7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:30:13 +0100 Subject: [PATCH 23/39] Add describe resource test --- cmd/describe_resource_test.go | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/describe_resource_test.go diff --git a/cmd/describe_resource_test.go b/cmd/describe_resource_test.go new file mode 100644 index 000000000..c5dfbbc03 --- /dev/null +++ b/cmd/describe_resource_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestDescribeResourceCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires resource name", + []string{"describe", "resource"}, + }, + // TODO: Add a test mocking the call when specifying resource name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 37f203611a7a46283d96b7f4c69e84dc355dd55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:35:17 +0100 Subject: [PATCH 24/39] Add logs test --- cmd/logs_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 cmd/logs_test.go diff --git a/cmd/logs_test.go b/cmd/logs_test.go new file mode 100644 index 000000000..6acf9bc5c --- /dev/null +++ b/cmd/logs_test.go @@ -0,0 +1,41 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestLogsCmd(t *testing.T) { + tests := []struct { + expected string + }{ + {"Print logs for a component"}, + {"Usage:\n meroxa logs [command]\n\n"}, + {"Available Commands:"}, + {"connector Print logs for a connector"}, + {"Flags:\n -h, --help help for logs\n"}, + } + + rootCmd := RootCmd() + listCmd := ListCmd() + rootCmd.AddCommand(listCmd) + + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetArgs([]string{"logs"}) + rootCmd.Execute() + + out, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + for _, tt := range tests { + if !strings.Contains(string(out), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(out)) + } + } +} From 1c951fc08004e7a68f191feee4b161fe4fc291c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:37:01 +0100 Subject: [PATCH 25/39] Add remove connector test --- cmd/remove_connector_test.go | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/remove_connector_test.go diff --git a/cmd/remove_connector_test.go b/cmd/remove_connector_test.go new file mode 100644 index 000000000..f3b8a5d6e --- /dev/null +++ b/cmd/remove_connector_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestRemoveConnectorCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires connector name", + []string{"remove", "connector"}, + }, + // TODO: Add a test mocking the call when specifying connector name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From cd8ef9b9fed547e5aaf9dcbf2ed6468b6b823330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:38:31 +0100 Subject: [PATCH 26/39] Add remove endpoint test --- cmd/remove_endpoint_test.go | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/remove_endpoint_test.go diff --git a/cmd/remove_endpoint_test.go b/cmd/remove_endpoint_test.go new file mode 100644 index 000000000..085141d4c --- /dev/null +++ b/cmd/remove_endpoint_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestRemoveEndpointCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires endpoint name", + []string{"remove", "endpoint"}, + }, + // TODO: Add a test mocking the call when specifying endpoint name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 6ffdb2e555e1820ccd2d7bdd5465157073832c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:39:42 +0100 Subject: [PATCH 27/39] Add remove pipeline test --- cmd/remove_pipeline_test.go | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/remove_pipeline_test.go diff --git a/cmd/remove_pipeline_test.go b/cmd/remove_pipeline_test.go new file mode 100644 index 000000000..4641f34d3 --- /dev/null +++ b/cmd/remove_pipeline_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestRemovePipelineCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires pipeline name", + []string{"remove", "pipeline"}, + }, + // TODO: Add a test mocking the call when specifying pipeline name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 155c5f17b1488d66f1d6b2ab7dcfa801995df8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:40:41 +0100 Subject: [PATCH 28/39] Add remove resource test --- cmd/remove_resource_test.go | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cmd/remove_resource_test.go diff --git a/cmd/remove_resource_test.go b/cmd/remove_resource_test.go new file mode 100644 index 000000000..5dd146256 --- /dev/null +++ b/cmd/remove_resource_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestRemoveResourceCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires resource name", + []string{"remove", "resource"}, + }, + // TODO: Add a test mocking the call when specifying resource name as argument + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 550a24d3d462e799f54ee3248841f19374d0f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:43:30 +0100 Subject: [PATCH 29/39] Add update connector test --- cmd/update_connector.go | 1 + cmd/update_connector_test.go | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 cmd/update_connector_test.go diff --git a/cmd/update_connector.go b/cmd/update_connector.go index 5e3b95f31..e5ae5bb78 100644 --- a/cmd/update_connector.go +++ b/cmd/update_connector.go @@ -71,6 +71,7 @@ func UpdateConnectorCmd() *cobra.Command { }, } + // TODO: Validate state has to be either of pause|resume|restart updateConnectorCmd.Flags().StringVarP(&state, "state", "", "", "connector state") updateConnectorCmd.MarkFlagRequired("state") diff --git a/cmd/update_connector_test.go b/cmd/update_connector_test.go new file mode 100644 index 000000000..b1a13ba97 --- /dev/null +++ b/cmd/update_connector_test.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestUpdateConnectorCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires connector name", + []string{"update", "connector"}, + }, + { + "Error: required flag(s) \"state\" not set", + []string{"update", "connector", "name"}, + }, + // TODO: Add a test mocking the call when specifying --state + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 206ebd6f29d7e2501aec3ed0dcb52b77a2673c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:44:56 +0100 Subject: [PATCH 30/39] Add update pipeline test --- cmd/update_pipeline_test.go | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 cmd/update_pipeline_test.go diff --git a/cmd/update_pipeline_test.go b/cmd/update_pipeline_test.go new file mode 100644 index 000000000..f2917eabc --- /dev/null +++ b/cmd/update_pipeline_test.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestUpdatePipelineCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires pipeline name", + []string{"update", "pipeline"}, + }, + { + "Error: required flag(s) \"state\" not set", + []string{"update", "pipeline", "name"}, + }, + // TODO: Add a test mocking the call when specifying --state + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From 4514a251e5707d6570842cdd3c8045a70b92e02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 10:51:48 +0100 Subject: [PATCH 31/39] Add instructions for running tests --- Makefile | 4 ++++ README.md | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/Makefile b/Makefile index 93016a48e..28d686576 100644 --- a/Makefile +++ b/Makefile @@ -20,3 +20,7 @@ test: .PHONY: docs docs: go run gen-docs/main.go + +.PHONY: test +test: + go test -v ${GO_TEST_FLAGS} -count=1 -timeout 5m ./... \ No newline at end of file diff --git a/README.md b/README.md index ee9189674..5bee2e55a 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ git tag is pushed to the repo. * Tag - `git tag -a vX.X.X -m ""` * Push - `git push origin vX.X.X` +## Tests + +``` +make test +``` + ## Contributing See [CONTRIBUTING.md](/CONTRIBUTING.md). \ No newline at end of file From 714078e3600a8b131b1f15c3537a6f763e580390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 11:17:04 +0100 Subject: [PATCH 32/39] Add update resource test --- cmd/update_resource_test.go | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 cmd/update_resource_test.go diff --git a/cmd/update_resource_test.go b/cmd/update_resource_test.go new file mode 100644 index 000000000..35063b6ad --- /dev/null +++ b/cmd/update_resource_test.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestUpdateResourceCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires a resource name and either `--metadata`, `--url` or `--credentials` to update the resource", + []string{"update", "resource"}, + }, + { + "Error: requires a resource name and either `--metadata`, `--url` or `--credentials` to update the resource", + []string{"update", "resource", "--metadata", "{\"logical_replication\": \"true\"}"}, + }, + { + "Error: requires a resource name and either `--metadata`, `--url` or `--credentials` to update the resource", + []string{"update", "resource", "name"}, + }, + // TODO: Add a test mocking the call when specifying resource name and one of the required flags + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From dbedcf55b4eb799815907aaa37f446e6258f2956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 11:52:29 +0100 Subject: [PATCH 33/39] Remove unnecessary code --- cmd/list_test.go | 3 --- cmd/logs_test.go | 3 --- 2 files changed, 6 deletions(-) diff --git a/cmd/list_test.go b/cmd/list_test.go index c24baf060..35cc4941d 100644 --- a/cmd/list_test.go +++ b/cmd/list_test.go @@ -25,9 +25,6 @@ func TestListCmd(t *testing.T) { } rootCmd := RootCmd() - listCmd := ListCmd() - rootCmd.AddCommand(listCmd) - b := bytes.NewBufferString("") rootCmd.SetOut(b) rootCmd.SetArgs([]string{"list"}) diff --git a/cmd/logs_test.go b/cmd/logs_test.go index 6acf9bc5c..659945f3f 100644 --- a/cmd/logs_test.go +++ b/cmd/logs_test.go @@ -19,9 +19,6 @@ func TestLogsCmd(t *testing.T) { } rootCmd := RootCmd() - listCmd := ListCmd() - rootCmd.AddCommand(listCmd) - b := bytes.NewBufferString("") rootCmd.SetOut(b) rootCmd.SetArgs([]string{"logs"}) From 07fadb846e6b8bf7c5d00f58be43ebf19aaa7990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:17:14 +0100 Subject: [PATCH 34/39] Update comments --- cmd/add.go | 1 + cmd/add_resource.go | 1 + cmd/api.go | 1 + cmd/billing.go | 3 ++- cmd/completion.go | 2 +- cmd/connect.go | 2 +- cmd/create.go | 2 +- cmd/create_connector.go | 1 + cmd/create_endpoint.go | 1 + cmd/create_pipeline.go | 1 + cmd/describe.go | 2 +- cmd/describe_connector.go | 1 + cmd/describe_endpoint.go | 1 + cmd/list.go | 2 +- cmd/list_connectors.go | 1 + cmd/list_endpoints.go | 1 + cmd/list_pipelines.go | 1 + cmd/list_resource_types.go | 3 ++- cmd/list_resources.go | 1 + cmd/list_transforms.go | 1 + cmd/login.go | 1 + cmd/logout.go | 2 +- cmd/open.go | 2 +- cmd/open_billing.go | 2 +- cmd/remove.go | 2 +- cmd/remove_connector.go | 1 + cmd/remove_endpoint.go | 1 + cmd/remove_pipeline.go | 1 + cmd/remove_resource.go | 1 + cmd/update.go | 2 +- cmd/update_connector.go | 1 + cmd/update_pipeline.go | 1 + cmd/update_resource.go | 1 + cmd/version.go | 2 +- 34 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cmd/add.go b/cmd/add.go index 7d174db7a..fe05410ed 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -21,6 +21,7 @@ import ( var resName, resType string +// AddCmd represents the `meroxa add` command func AddCmd() *cobra.Command { addCmd := &cobra.Command{ Use: "add", diff --git a/cmd/add_resource.go b/cmd/add_resource.go index de5780ac1..a980d6672 100644 --- a/cmd/add_resource.go +++ b/cmd/add_resource.go @@ -27,6 +27,7 @@ import ( "github.com/spf13/cobra" ) +// AddResourceCmd represents the `meroxa add resource` command func AddResourceCmd() *cobra.Command { addResourceCmd := &cobra.Command{ Use: "resource --type ", diff --git a/cmd/api.go b/cmd/api.go index 57492031d..e5139af79 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" ) +// ApiCmd represents the `meroxa api` command func ApiCmd() *cobra.Command { return &cobra.Command{ Use: "api [body]", diff --git a/cmd/billing.go b/cmd/billing.go index 23b586251..f9ca66713 100644 --- a/cmd/billing.go +++ b/cmd/billing.go @@ -21,8 +21,9 @@ import ( "github.com/spf13/cobra" ) -// billingCmd represents the billing command // TODO: Check how to disable parent flags (e.g.: --json) + +// BillingCmd represents the `meroxa billing` command func BillingCmd() *cobra.Command { return &cobra.Command{ Use: "billing", diff --git a/cmd/completion.go b/cmd/completion.go index 37b673663..0ef02e073 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -5,7 +5,7 @@ import ( "os" ) -// completionCmd represents the completion command +// CompletionCmd represents the completion command func CompletionCmd() *cobra.Command { return &cobra.Command{ Use: "completion [bash|zsh|fish|powershell]", diff --git a/cmd/connect.go b/cmd/connect.go index f1ccc1f1a..34ecc9f65 100644 --- a/cmd/connect.go +++ b/cmd/connect.go @@ -23,7 +23,7 @@ import ( "github.com/spf13/cobra" ) -// connectCmd represents the connect command +// ConnectCmd represents the `meroxa connect` command func ConnectCmd() *cobra.Command { connectCmd := &cobra.Command{ Use: "connect --from --to ", diff --git a/cmd/create.go b/cmd/create.go index 55750b0fd..f8533c417 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -28,7 +28,7 @@ var ( input string ) -// createCmd represents the create command +// CreateCmd represents the `meroxa create` command func CreateCmd() *cobra.Command { createCmd := &cobra.Command{ Use: "create", diff --git a/cmd/create_connector.go b/cmd/create_connector.go index b1b41e198..c3840ae52 100644 --- a/cmd/create_connector.go +++ b/cmd/create_connector.go @@ -53,6 +53,7 @@ func (c Config) Merge(cfg Config) error { return nil } +// CreateConnectorCmd represents the `meroxa create connector` command func CreateConnectorCmd() *cobra.Command { createConnectorCmd := &cobra.Command{ Use: "connector [] [flags]", diff --git a/cmd/create_endpoint.go b/cmd/create_endpoint.go index 6d0928d6f..7ecd15a75 100644 --- a/cmd/create_endpoint.go +++ b/cmd/create_endpoint.go @@ -26,6 +26,7 @@ var ( flagEndpointCmdStream string ) +// CreateEndpointCmd represents the `meroxa create endpoint` command func CreateEndpointCmd() *cobra.Command { createEndpointCmd := &cobra.Command{ Use: "endpoint [] [flags]", diff --git a/cmd/create_pipeline.go b/cmd/create_pipeline.go index bca45a236..28c1d1a2a 100644 --- a/cmd/create_pipeline.go +++ b/cmd/create_pipeline.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" ) +// CreatePipelineCmd represents the `meroxa create pipeline` command func CreatePipelineCmd() *cobra.Command { createPipelineCmd := &cobra.Command{ Use: "pipeline ", diff --git a/cmd/describe.go b/cmd/describe.go index 8bc16f8df..5dd68bbc7 100644 --- a/cmd/describe.go +++ b/cmd/describe.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -// describeCmd represents the describe command +// DescribeCmd represents the `meroxa describe` command func DescribeCmd() *cobra.Command { describeCmd := &cobra.Command{ Use: "describe", diff --git a/cmd/describe_connector.go b/cmd/describe_connector.go index 2e7995a90..d62346828 100644 --- a/cmd/describe_connector.go +++ b/cmd/describe_connector.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// DescribeConnectorCmd represents the `meroxa describe connector` command func DescribeConnectorCmd() *cobra.Command { return &cobra.Command{ Use: "connector [name]", diff --git a/cmd/describe_endpoint.go b/cmd/describe_endpoint.go index 3de247e19..e8bb6836e 100644 --- a/cmd/describe_endpoint.go +++ b/cmd/describe_endpoint.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// DescribeEndpointCmd represents the `meroxa describe endpoint` command func DescribeEndpointCmd() *cobra.Command { return &cobra.Command{ Use: "endpoint ", diff --git a/cmd/list.go b/cmd/list.go index c1e217487..28f66cc93 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -// listCmd represents the list command +// ListCmd represents the `meroxa list` command func ListCmd() *cobra.Command { listCmd := &cobra.Command{ Use: "list", diff --git a/cmd/list_connectors.go b/cmd/list_connectors.go index c60a08f13..d22c4cb08 100644 --- a/cmd/list_connectors.go +++ b/cmd/list_connectors.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// ListConnectorsCmd represents the `meroxa list connectors` command func ListConnectorsCmd() *cobra.Command { return &cobra.Command{ Use: "connectors", diff --git a/cmd/list_endpoints.go b/cmd/list_endpoints.go index 0de8b0979..d5e307231 100644 --- a/cmd/list_endpoints.go +++ b/cmd/list_endpoints.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" ) +// ListEndpointsCmd represents the `meroxa list endpoints` command func ListEndpointsCmd() *cobra.Command { return &cobra.Command{ Use: "endpoint", diff --git a/cmd/list_pipelines.go b/cmd/list_pipelines.go index c41f20b5f..114ebb697 100644 --- a/cmd/list_pipelines.go +++ b/cmd/list_pipelines.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" ) +// ListPipelinesCmd represents the `meroxa list pipelines` command func ListPipelinesCmd() *cobra.Command { return &cobra.Command{ Use: "pipelines", diff --git a/cmd/list_resource_types.go b/cmd/list_resource_types.go index df1aa727f..d91cd808b 100644 --- a/cmd/list_resource_types.go +++ b/cmd/list_resource_types.go @@ -24,10 +24,11 @@ import ( "github.com/spf13/cobra" ) +// ListResourceTypesCmd represents the `meroxa list resource-types` command func ListResourceTypesCmd() *cobra.Command { return &cobra.Command{ Use: "resource-types", - Short: "List resources-types", + Short: "List resource-types", Aliases: []string{"resource-type"}, RunE: func(cmd *cobra.Command, args []string) error { c, err := client() diff --git a/cmd/list_resources.go b/cmd/list_resources.go index d251eadb1..104ee3293 100644 --- a/cmd/list_resources.go +++ b/cmd/list_resources.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// ListResourcesCmd represents the `meroxa list resources` command func ListResourcesCmd() *cobra.Command { return &cobra.Command{ Use: "resources", diff --git a/cmd/list_transforms.go b/cmd/list_transforms.go index ff7d9c029..650c6f69d 100644 --- a/cmd/list_transforms.go +++ b/cmd/list_transforms.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" ) +// ListTransformsCmd represents the `meroxa list transforms` command func ListTransformsCmd() *cobra.Command { return &cobra.Command{ Use: "transforms", diff --git a/cmd/login.go b/cmd/login.go index 29c966113..23c8de931 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -192,6 +192,7 @@ func getAccessTokenAuth(clientID string, codeVerifier string, authorizationCode return accessToken, refreshToken, nil } +// LoginCmd represents the `meroxa login` command func LoginCmd() *cobra.Command { return &cobra.Command{ Use: "login", diff --git a/cmd/logout.go b/cmd/logout.go index 7e49b577f..fa1572257 100644 --- a/cmd/logout.go +++ b/cmd/logout.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/cobra" ) -// logoutCmd represents the logout command +// LogoutCmd represents the `meroxa logout` command func LogoutCmd() *cobra.Command { return &cobra.Command{ Use: "logout", diff --git a/cmd/open.go b/cmd/open.go index 87deea518..8e54ed112 100644 --- a/cmd/open.go +++ b/cmd/open.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -// openCmd represents the billing command +// OpenCmd represents the `meroxa open` command func OpenCmd() *cobra.Command { openCmd := &cobra.Command{ Use: "open", diff --git a/cmd/open_billing.go b/cmd/open_billing.go index 5d61dbdef..4f3f1f5ea 100644 --- a/cmd/open_billing.go +++ b/cmd/open_billing.go @@ -37,7 +37,7 @@ func getBillingURL() string { return fmt.Sprintf("%s/account/billing", platformURL) } -// openBillingCmd represents the billing command +// OpenBillingCmd represents the `meroxa open billing` command func OpenBillingCmd() *cobra.Command { return &cobra.Command{ Use: "billing", diff --git a/cmd/remove.go b/cmd/remove.go index 58478ed3b..091d6230d 100644 --- a/cmd/remove.go +++ b/cmd/remove.go @@ -18,7 +18,7 @@ package cmd import "github.com/spf13/cobra" -// removeCmd represents the remove command +// RemoveCmd represents the `meroxa remove` command func RemoveCmd() *cobra.Command { removeCmd := &cobra.Command{ Use: "remove", diff --git a/cmd/remove_connector.go b/cmd/remove_connector.go index fea907fc9..18b43b6f3 100644 --- a/cmd/remove_connector.go +++ b/cmd/remove_connector.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// RemoveConnectorCmd represents the `meroxa remove connector` command func RemoveConnectorCmd() *cobra.Command { return &cobra.Command{ Use: "connector ", diff --git a/cmd/remove_endpoint.go b/cmd/remove_endpoint.go index 8bfe8f937..d8756f254 100644 --- a/cmd/remove_endpoint.go +++ b/cmd/remove_endpoint.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" ) +// RemoveEndpointCmd represents the `meroxa remove endpoint` command func RemoveEndpointCmd() *cobra.Command { return &cobra.Command{ Use: "endpoint ", diff --git a/cmd/remove_pipeline.go b/cmd/remove_pipeline.go index 15054c2b0..14d3ac807 100644 --- a/cmd/remove_pipeline.go +++ b/cmd/remove_pipeline.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// RemovePipelineCmd represents the `meroxa remove pipeline` command func RemovePipelineCmd() *cobra.Command { return &cobra.Command{ Use: "pipeline ", diff --git a/cmd/remove_resource.go b/cmd/remove_resource.go index fa51914a5..10de4a9bf 100644 --- a/cmd/remove_resource.go +++ b/cmd/remove_resource.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" ) +// RemoveResourceCmd represents the `meroxa remove resource` command func RemoveResourceCmd() *cobra.Command { return &cobra.Command{ Use: "resource ", diff --git a/cmd/update.go b/cmd/update.go index e05c18b3a..874ecf9d4 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -// updateCmd represents the update command +// UpdateCmd represents the `meroxa update` command func UpdateCmd() *cobra.Command { updateCmd := &cobra.Command{ Use: "update", diff --git a/cmd/update_connector.go b/cmd/update_connector.go index e5ae5bb78..151bb8dc8 100644 --- a/cmd/update_connector.go +++ b/cmd/update_connector.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" ) +// UpdateConnectorCmd represents the `meroxa update connector` command func UpdateConnectorCmd() *cobra.Command { updateConnectorCmd := &cobra.Command{ Use: "connector --state ", diff --git a/cmd/update_pipeline.go b/cmd/update_pipeline.go index 086d4ef1b..a65b10f90 100644 --- a/cmd/update_pipeline.go +++ b/cmd/update_pipeline.go @@ -28,6 +28,7 @@ var ( state string // connector state ) +// UpdatePipelineCmd represents the `meroxa update pipeline` command func UpdatePipelineCmd() *cobra.Command { updatePipelineCmd := &cobra.Command{ Use: "pipeline --state ", diff --git a/cmd/update_resource.go b/cmd/update_resource.go index 9255b1494..724c599e5 100644 --- a/cmd/update_resource.go +++ b/cmd/update_resource.go @@ -28,6 +28,7 @@ import ( "github.com/spf13/cobra" ) +// UpdateResourceCmd represents the `meroxa update resource` command func UpdateResourceCmd() *cobra.Command { updateResourceCmd := &cobra.Command{ Use: "resource ", diff --git a/cmd/version.go b/cmd/version.go index 6f4556993..fdc9b1bd1 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -22,7 +22,7 @@ import ( "runtime" ) -// versionCmd represents the version command +// VersionCmd represents the `meroxa version` command func VersionCmd() *cobra.Command { return &cobra.Command{ Use: "version", From 3d3356f556a1fba3a137c08034350cc10401bcd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:17:31 +0100 Subject: [PATCH 35/39] Fix cmd file name --- cmd/{describe_resource.cmd.go => describe_resource.go} | 1 + 1 file changed, 1 insertion(+) rename cmd/{describe_resource.cmd.go => describe_resource.go} (92%) diff --git a/cmd/describe_resource.cmd.go b/cmd/describe_resource.go similarity index 92% rename from cmd/describe_resource.cmd.go rename to cmd/describe_resource.go index db4a2ab6f..3b5872390 100644 --- a/cmd/describe_resource.cmd.go +++ b/cmd/describe_resource.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" ) +// DescribeResourceCmd represents the `meroxa describe resource` command func DescribeResourceCmd() *cobra.Command { return &cobra.Command{ Use: "resource ", From 6c874f4e6ff99f78c1c5e563ae01d09add4b1264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:17:48 +0100 Subject: [PATCH 36/39] Separate logs connector to its own file --- cmd/logs.go | 41 +------------------------ cmd/logs_connector.go | 62 ++++++++++++++++++++++++++++++++++++++ cmd/logs_connector_test.go | 39 ++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 40 deletions(-) create mode 100644 cmd/logs_connector.go create mode 100644 cmd/logs_connector_test.go diff --git a/cmd/logs.go b/cmd/logs.go index 1908031ef..47bdc78cf 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -17,13 +17,10 @@ limitations under the License. package cmd import ( - "context" - "errors" "github.com/spf13/cobra" - "io" - "os" ) +// LogsCmd represents the `meroxa logs` command func LogsCmd() *cobra.Command { logsCmd := &cobra.Command{ Use: "logs", @@ -33,40 +30,4 @@ func LogsCmd() *cobra.Command { logsCmd.AddCommand(LogsConnectorCmd()) return logsCmd -} - -func LogsConnectorCmd() *cobra.Command { - return &cobra.Command{ - Use: "connector ", - Short: "Print logs for a connector", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("requires connector name\n\nUsage:\n meroxa logs connector ") - } - connector := args[0] - - c, err := client() - if err != nil { - return err - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, clientTimeOut) - defer cancel() - - resp, err := c.GetConnectorLogs(ctx, connector) - if err != nil { - return err - } - - _, err = io.Copy(os.Stderr, resp.Body) - if err != nil { - return err - } - - os.Stderr.Write([]byte("\n")) - - return nil - }, - } } \ No newline at end of file diff --git a/cmd/logs_connector.go b/cmd/logs_connector.go new file mode 100644 index 000000000..2e75daba4 --- /dev/null +++ b/cmd/logs_connector.go @@ -0,0 +1,62 @@ +/* +Copyright © 2020 Meroxa Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "context" + "errors" + "github.com/spf13/cobra" + "io" + "os" +) + +// LogsConnectorCmd represents the `meroxa logs connector` command +func LogsConnectorCmd() *cobra.Command { + return &cobra.Command{ + Use: "connector ", + Short: "Print logs for a connector", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires connector name\n\nUsage:\n meroxa logs connector ") + } + connector := args[0] + + c, err := client() + if err != nil { + return err + } + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, clientTimeOut) + defer cancel() + + resp, err := c.GetConnectorLogs(ctx, connector) + if err != nil { + return err + } + + _, err = io.Copy(os.Stderr, resp.Body) + if err != nil { + return err + } + + os.Stderr.Write([]byte("\n")) + + return nil + }, + } +} \ No newline at end of file diff --git a/cmd/logs_connector_test.go b/cmd/logs_connector_test.go new file mode 100644 index 000000000..1b3545680 --- /dev/null +++ b/cmd/logs_connector_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestLogsConnectorCmd(t *testing.T) { + tests := []struct { + expected string + args []string + }{ + { + "Error: requires connector name", + []string{"logs", "connector"}, + }, + // TODO: Add a test mocking the call when specifying connector name + } + + for _, tt := range tests { + rootCmd := RootCmd() + b := bytes.NewBufferString("") + rootCmd.SetOut(b) + rootCmd.SetErr(b) + rootCmd.SetArgs(tt.args) + rootCmd.Execute() + output, err := ioutil.ReadAll(b) + + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(output), tt.expected) { + t.Fatalf("expected \"%s\" got \"%s\"", tt.expected, string(output)) + } + } +} From f7ba760c5773850111efc0f293e4bf61c92c3d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:23:09 +0100 Subject: [PATCH 37/39] Remove duplicate make build --- Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 28d686576..a2a93e688 100644 --- a/Makefile +++ b/Makefile @@ -15,12 +15,8 @@ gomod: .PHONY: test test: - go test -v ${GO_TEST_FLAGS} -count=1 ./... + go test -v ${GO_TEST_FLAGS} -count=1 -timeout 5m ./... .PHONY: docs docs: go run gen-docs/main.go - -.PHONY: test -test: - go test -v ${GO_TEST_FLAGS} -count=1 -timeout 5m ./... \ No newline at end of file From 925a77a2146a1c0788f690d169108c185a76672a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:23:22 +0100 Subject: [PATCH 38/39] Update test --- cmd/list_test.go | 2 +- docs/cmd/meroxa_list.md | 2 +- docs/cmd/meroxa_list_resource-types.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/list_test.go b/cmd/list_test.go index 35cc4941d..ce7c5f9b5 100644 --- a/cmd/list_test.go +++ b/cmd/list_test.go @@ -18,7 +18,7 @@ func TestListCmd(t *testing.T) { {"connectors List connectors"}, {"endpoint List endpoints"}, {"pipelines List pipelines"}, - {"resource-types List resources-types"}, + {"resource-types List resource-types"}, {"resources List resources"}, {"transforms List transforms"}, {"Flags:\n -h, --help help for list\n"}, diff --git a/docs/cmd/meroxa_list.md b/docs/cmd/meroxa_list.md index c94bfa939..f7a4d8789 100644 --- a/docs/cmd/meroxa_list.md +++ b/docs/cmd/meroxa_list.md @@ -26,7 +26,7 @@ List the components of the Meroxa platform, including pipelines, * [meroxa list connectors](meroxa_list_connectors.md) - List connectors * [meroxa list endpoint](meroxa_list_endpoint.md) - List endpoints * [meroxa list pipelines](meroxa_list_pipelines.md) - List pipelines -* [meroxa list resource-types](meroxa_list_resource-types.md) - List resources-types +* [meroxa list resource-types](meroxa_list_resource-types.md) - List resource-types * [meroxa list resources](meroxa_list_resources.md) - List resources * [meroxa list transforms](meroxa_list_transforms.md) - List transforms diff --git a/docs/cmd/meroxa_list_resource-types.md b/docs/cmd/meroxa_list_resource-types.md index 53026a812..806cbb08c 100644 --- a/docs/cmd/meroxa_list_resource-types.md +++ b/docs/cmd/meroxa_list_resource-types.md @@ -1,6 +1,6 @@ ## meroxa list resource-types -List resources-types +List resource-types ``` meroxa list resource-types [flags] From 57a973c44b720fb40962f6f52755d83bb490bea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Barroso?= Date: Tue, 23 Mar 2021 12:41:28 +0100 Subject: [PATCH 39/39] Clearer var name --- cmd/connect_test.go | 1 - cmd/root.go | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/connect_test.go b/cmd/connect_test.go index 70b76981a..ce20fd6cd 100644 --- a/cmd/connect_test.go +++ b/cmd/connect_test.go @@ -27,7 +27,6 @@ func TestConnectCmd(t *testing.T) { // TODO: Add a test with connect --to and --from mocking the call } - for _, tt := range tests { rootCmd := RootCmd() b := bytes.NewBufferString("") diff --git a/cmd/root.go b/cmd/root.go index 64f37b414..98d91b521 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -47,7 +47,7 @@ var ( resMetadata string resCredentials string flagRootOutputJSON bool - rootCmd *cobra.Command + meroxaCmd *cobra.Command cfg *viper.Viper ) @@ -75,8 +75,7 @@ meroxa list resource-types`, rootCmd.SilenceUsage = true rootCmd.DisableAutoGenTag = true - // Commands - + // Subcommands rootCmd.AddCommand(AddCmd()) rootCmd.AddCommand(ApiCmd()) rootCmd.AddCommand(BillingCmd()) @@ -101,13 +100,13 @@ meroxa list resource-types`, func Execute(version string) { meroxaVersion = version - if err := rootCmd.Execute(); err != nil { + if err := meroxaCmd.Execute(); err != nil { os.Exit(1) } } func init() { - rootCmd = RootCmd() + meroxaCmd = RootCmd() } // initConfig reads in config file and ENV variables if set.