diff --git a/.gitignore b/.gitignore index 2564227..5f86f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /ukfast cover.out dist/ +__debug_bin diff --git a/cmd/account.go b/cmd/account.go deleted file mode 100644 index aa66973..0000000 --- a/cmd/account.go +++ /dev/null @@ -1,210 +0,0 @@ -package cmd - -import ( - "fmt" - "strconv" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/helper" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/account" -) - -func accountRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "account", - Short: "Commands relating to Account service", - } - - // Child root commands - cmd.AddCommand(accountContactRootCmd()) - cmd.AddCommand(accountDetailsRootCmd()) - cmd.AddCommand(accountCreditRootCmd()) - cmd.AddCommand(accountInvoiceRootCmd()) - cmd.AddCommand(accountInvoiceQueryRootCmd()) - - return cmd -} - -// OutputAccountContacts implements OutputDataProvider for outputting an array of Contacts -type OutputAccountContacts struct { - Contacts []account.Contact -} - -func outputAccountContacts(contacts []account.Contact) { - err := Output(&OutputAccountContacts{Contacts: contacts}) - if err != nil { - output.Fatalf("Failed to output contacts: %s", err) - } -} - -func (o *OutputAccountContacts) GetData() interface{} { - return o.Contacts -} - -func (o *OutputAccountContacts) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, contact := range o.Contacts { - fields := o.getOrderedFields(contact) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputAccountContacts) getOrderedFields(contact account.Contact) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(contact.ID), true)) - fields.Set("type", output.NewFieldValue(contact.Type.String(), true)) - fields.Set("first_name", output.NewFieldValue(contact.FirstName, true)) - fields.Set("last_name", output.NewFieldValue(contact.LastName, true)) - - return fields -} - -// OutputAccountDetails implements OutputDataProvider for outputting an array of Details -type OutputAccountDetails struct { - Details []account.Details -} - -func outputAccountDetails(details []account.Details) { - err := Output(&OutputAccountDetails{Details: details}) - if err != nil { - output.Fatalf("Failed to output details: %s", err) - } -} - -func (o *OutputAccountDetails) GetData() interface{} { - return o.Details -} - -func (o *OutputAccountDetails) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, detail := range o.Details { - fields := o.getOrderedFields(detail) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputAccountDetails) getOrderedFields(details account.Details) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("company_registration_number", output.NewFieldValue(details.CompanyRegistrationNumber, true)) - fields.Set("vat_identification_number", output.NewFieldValue(details.VATIdentificationNumber, true)) - fields.Set("primary_contact_id", output.NewFieldValue(strconv.Itoa(details.PrimaryContactID), true)) - - return fields -} - -// OutputAccountCredits implements OutputDataProvider for outputting an array of Credits -type OutputAccountCredits struct { - Credits []account.Credit -} - -func outputAccountCredits(credits []account.Credit) { - err := Output(&OutputAccountCredits{Credits: credits}) - if err != nil { - output.Fatalf("Failed to output credits: %s", err) - } -} - -func (o *OutputAccountCredits) GetData() interface{} { - return o.Credits -} - -func (o *OutputAccountCredits) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, credit := range o.Credits { - fields := o.getOrderedFields(credit) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputAccountCredits) getOrderedFields(credit account.Credit) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("type", output.NewFieldValue(credit.Type, true)) - fields.Set("total", output.NewFieldValue(strconv.Itoa(credit.Total), true)) - fields.Set("remaining", output.NewFieldValue(strconv.Itoa(credit.Remaining), true)) - - return fields -} - -// OutputAccountInvoices implements OutputDataProvider for outputting an array of Invoices -type OutputAccountInvoices struct { - Invoices []account.Invoice -} - -func outputAccountInvoices(invoices []account.Invoice) { - err := Output(&OutputAccountInvoices{Invoices: invoices}) - if err != nil { - output.Fatalf("Failed to output invoices: %s", err) - } -} - -func (o *OutputAccountInvoices) GetData() interface{} { - return o.Invoices -} - -func (o *OutputAccountInvoices) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, invoice := range o.Invoices { - fields := o.getOrderedFields(invoice) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputAccountInvoices) getOrderedFields(invoice account.Invoice) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(invoice.ID), true)) - fields.Set("date", output.NewFieldValue(invoice.Date.String(), true)) - fields.Set("paid", output.NewFieldValue(strconv.FormatBool(invoice.Paid), true)) - fields.Set("net", output.NewFieldValue(fmt.Sprintf("%f", invoice.Net), true)) - fields.Set("vat", output.NewFieldValue(fmt.Sprintf("%f", invoice.VAT), true)) - fields.Set("gross", output.NewFieldValue(fmt.Sprintf("%f", invoice.Gross), true)) - - return fields -} - -// OutputAccountInvoiceQueries implements OutputDataProvider for outputting an array of InvoiceQueries -type OutputAccountInvoiceQueries struct { - InvoiceQueries []account.InvoiceQuery -} - -func outputAccountInvoiceQueries(queries []account.InvoiceQuery) { - err := Output(&OutputAccountInvoiceQueries{InvoiceQueries: queries}) - if err != nil { - output.Fatalf("Failed to output queries: %s", err) - } -} - -func (o *OutputAccountInvoiceQueries) GetData() interface{} { - return o.InvoiceQueries -} - -func (o *OutputAccountInvoiceQueries) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, query := range o.InvoiceQueries { - fields := o.getOrderedFields(query) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputAccountInvoiceQueries) getOrderedFields(query account.InvoiceQuery) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(query.ID), true)) - fields.Set("contact_id", output.NewFieldValue(strconv.Itoa(query.ContactID), false)) - fields.Set("amount", output.NewFieldValue(fmt.Sprintf("%f", query.Amount), true)) - fields.Set("what_was_expected", output.NewFieldValue(query.WhatWasExpected, false)) - fields.Set("what_was_received", output.NewFieldValue(query.WhatWasReceived, false)) - fields.Set("proposed_solution", output.NewFieldValue(query.ProposedSolution, false)) - fields.Set("invoice_ids", output.NewFieldValue(helper.JoinInt(query.InvoiceIDs, ", "), true)) - - return fields -} diff --git a/cmd/account/account.go b/cmd/account/account.go new file mode 100644 index 0000000..a405c85 --- /dev/null +++ b/cmd/account/account.go @@ -0,0 +1,22 @@ +package account + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func AccountRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "account", + Short: "Commands relating to Account service", + } + + // Child root commands + cmd.AddCommand(accountContactRootCmd(f)) + cmd.AddCommand(accountDetailsRootCmd(f)) + cmd.AddCommand(accountCreditRootCmd(f)) + cmd.AddCommand(accountInvoiceRootCmd(f)) + cmd.AddCommand(accountInvoiceQueryRootCmd(f)) + + return cmd +} diff --git a/cmd/account_contact.go b/cmd/account/account_contact.go similarity index 69% rename from cmd/account_contact.go rename to cmd/account/account_contact.go index 8862462..7b1fd0c 100644 --- a/cmd/account_contact.go +++ b/cmd/account/account_contact.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -6,32 +6,33 @@ import ( "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/account" ) -func accountContactRootCmd() *cobra.Command { +func accountContactRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "contact", Short: "sub-commands relating to contacts", } // Child commands - cmd.AddCommand(accountContactListCmd()) - cmd.AddCommand(accountContactShowCmd()) + cmd.AddCommand(accountContactListCmd(f)) + cmd.AddCommand(accountContactShowCmd(f)) return cmd } -func accountContactListCmd() *cobra.Command { +func accountContactListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists contacts", Long: "This command lists contacts", Example: "ukfast account contact list", RunE: func(cmd *cobra.Command, args []string) error { - return accountContactList(getClient().AccountService(), cmd, args) + return accountContactList(f.NewClient().AccountService(), cmd, args) }, } } @@ -47,11 +48,10 @@ func accountContactList(service account.AccountService, cmd *cobra.Command, args return fmt.Errorf("Error retrieving contacts: %s", err) } - outputAccountContacts(contacts) - return nil + return output.CommandOutput(cmd, OutputAccountContactsProvider(contacts)) } -func accountContactShowCmd() *cobra.Command { +func accountContactShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a contact", @@ -64,13 +64,13 @@ func accountContactShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - accountContactShow(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountContactShow(f.NewClient().AccountService(), cmd, args) }, } } -func accountContactShow(service account.AccountService, cmd *cobra.Command, args []string) { +func accountContactShow(service account.AccountService, cmd *cobra.Command, args []string) error { var contacts []account.Contact for _, arg := range args { contactID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func accountContactShow(service account.AccountService, cmd *cobra.Command, args contacts = append(contacts, contact) } - outputAccountContacts(contacts) + return output.CommandOutput(cmd, OutputAccountContactsProvider(contacts)) } diff --git a/cmd/account_contact_test.go b/cmd/account/account_contact_test.go similarity index 88% rename from cmd/account_contact_test.go rename to cmd/account/account_contact_test.go index 64b38ab..97e5729 100644 --- a/cmd/account_contact_test.go +++ b/cmd/account/account_contact_test.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" @@ -24,21 +25,21 @@ func Test_accountContactList(t *testing.T) { accountContactList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockAccountService(mockCtrl) - cmd := accountContactListCmd() + cmd := accountContactListCmd(nil) cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") err := accountContactList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetContactsError_OutputsFatal", func(t *testing.T) { + t.Run("GetContactsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -55,13 +56,13 @@ func Test_accountContactList(t *testing.T) { func Test_accountContactShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := accountContactShowCmd().Args(nil, []string{"123"}) + err := accountContactShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := accountContactShowCmd().Args(nil, []string{}) + err := accountContactShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing contact", err.Error()) diff --git a/cmd/account_credit.go b/cmd/account/account_credit.go similarity index 55% rename from cmd/account_credit.go rename to cmd/account/account_credit.go index c4a82ec..2abf654 100644 --- a/cmd/account_credit.go +++ b/cmd/account/account_credit.go @@ -1,48 +1,49 @@ -package cmd +package account import ( + "fmt" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/account" ) -func accountCreditRootCmd() *cobra.Command { +func accountCreditRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "credit", Short: "sub-commands relating to credits", } // Child commands - cmd.AddCommand(accountCreditListCmd()) + cmd.AddCommand(accountCreditListCmd(f)) return cmd } -func accountCreditListCmd() *cobra.Command { +func accountCreditListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists credits", Long: "This command lists credits", Example: "ukfast account credit list", - Run: func(cmd *cobra.Command, args []string) { - accountCreditList(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountCreditList(f.NewClient().AccountService(), cmd, args) }, } } -func accountCreditList(service account.AccountService, cmd *cobra.Command, args []string) { +func accountCreditList(service account.AccountService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } credits, err := service.GetCredits(params) if err != nil { - output.Fatalf("Error retrieving credits: %s", err) - return + return fmt.Errorf("Error retrieving credits: %s", err) } - outputAccountCredits(credits) + return output.CommandOutput(cmd, OutputAccountCreditsProvider(credits)) } diff --git a/cmd/account_credit_test.go b/cmd/account/account_credit_test.go similarity index 65% rename from cmd/account_credit_test.go rename to cmd/account/account_credit_test.go index c8aa1df..466c4d9 100644 --- a/cmd/account_credit_test.go +++ b/cmd/account/account_credit_test.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -6,8 +6,9 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" ) @@ -23,20 +24,19 @@ func Test_accountCreditList(t *testing.T) { accountCreditList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockAccountService(mockCtrl) - cmd := accountCreditListCmd() + cmd := accountCreditListCmd(nil) cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - accountCreditList(service, cmd, []string{}) - }) + err := accountCreditList(service, cmd, []string{}) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetCreditsError_OutputsFatal", func(t *testing.T) { + t.Run("GetCreditsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -44,8 +44,7 @@ func Test_accountCreditList(t *testing.T) { service.EXPECT().GetCredits(gomock.Any()).Return([]account.Credit{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving credits: test error\n", func() { - accountCreditList(service, &cobra.Command{}, []string{}) - }) + err := accountCreditList(service, &cobra.Command{}, []string{}) + assert.Equal(t, "Error retrieving credits: test error", err.Error()) }) } diff --git a/cmd/account_details.go b/cmd/account/account_details.go similarity index 50% rename from cmd/account_details.go rename to cmd/account/account_details.go index 8f1614d..2ffb2ea 100644 --- a/cmd/account_details.go +++ b/cmd/account/account_details.go @@ -1,41 +1,43 @@ -package cmd +package account import ( + "fmt" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/account" ) -func accountDetailsRootCmd() *cobra.Command { +func accountDetailsRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "details", Short: "sub-commands relating to account details", } // Child commands - cmd.AddCommand(accountDetailsShowCmd()) + cmd.AddCommand(accountDetailsShowCmd(f)) return cmd } -func accountDetailsShowCmd() *cobra.Command { +func accountDetailsShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show", Short: "Shows account details", Long: "This command shows account details", Example: "ukfast account detail show", - Run: func(cmd *cobra.Command, args []string) { - accountDetailsShow(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountDetailsShow(f.NewClient().AccountService(), cmd, args) }, } } -func accountDetailsShow(service account.AccountService, cmd *cobra.Command, args []string) { +func accountDetailsShow(service account.AccountService, cmd *cobra.Command, args []string) error { details, err := service.GetDetails() if err != nil { - output.Fatalf("Error retrieving details: %s", err) - return + return fmt.Errorf("Error retrieving details: %s", err) } - outputAccountDetails([]account.Details{details}) + return output.CommandOutput(cmd, OutputAccountDetailsProvider([]account.Details{details})) } diff --git a/cmd/account_details_test.go b/cmd/account/account_details_test.go similarity index 73% rename from cmd/account_details_test.go rename to cmd/account/account_details_test.go index 822daac..8937ef6 100644 --- a/cmd/account_details_test.go +++ b/cmd/account/account_details_test.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -7,8 +7,8 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" + "gopkg.in/go-playground/assert.v1" ) func Test_accountDetailShow(t *testing.T) { @@ -23,7 +23,7 @@ func Test_accountDetailShow(t *testing.T) { accountDetailsShow(service, &cobra.Command{}, []string{""}) }) - t.Run("GetDetailsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDetailsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -31,8 +31,8 @@ func Test_accountDetailShow(t *testing.T) { service.EXPECT().GetDetails().Return(account.Details{}, errors.New("test error")) - test_output.AssertFatalOutput(t, "Error retrieving details: test error\n", func() { - accountDetailsShow(service, &cobra.Command{}, []string{""}) - }) + err := accountDetailsShow(service, &cobra.Command{}, []string{""}) + + assert.Equal(t, "Error retrieving details: test error", err.Error()) }) } diff --git a/cmd/account_invoice.go b/cmd/account/account_invoice.go similarity index 62% rename from cmd/account_invoice.go rename to cmd/account/account_invoice.go index 19efd8e..3f51ad6 100644 --- a/cmd/account_invoice.go +++ b/cmd/account/account_invoice.go @@ -1,57 +1,57 @@ -package cmd +package account import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/account" ) -func accountInvoiceRootCmd() *cobra.Command { +func accountInvoiceRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "invoice", Short: "sub-commands relating to invoices", } // Child commands - cmd.AddCommand(accountInvoiceListCmd()) - cmd.AddCommand(accountInvoiceShowCmd()) + cmd.AddCommand(accountInvoiceListCmd(f)) + cmd.AddCommand(accountInvoiceShowCmd(f)) return cmd } -func accountInvoiceListCmd() *cobra.Command { +func accountInvoiceListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists invoices", Long: "This command lists invoices", Example: "ukfast account invoice list", - Run: func(cmd *cobra.Command, args []string) { - accountInvoiceList(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountInvoiceList(f.NewClient().AccountService(), cmd, args) }, } } -func accountInvoiceList(service account.AccountService, cmd *cobra.Command, args []string) { +func accountInvoiceList(service account.AccountService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } invoices, err := service.GetInvoices(params) if err != nil { - output.Fatalf("Error retrieving invoices: %s", err) - return + return fmt.Errorf("Error retrieving invoices: %s", err) } - outputAccountInvoices(invoices) + return output.CommandOutput(cmd, OutputAccountInvoicesProvider(invoices)) } -func accountInvoiceShowCmd() *cobra.Command { +func accountInvoiceShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a invoice", @@ -64,13 +64,13 @@ func accountInvoiceShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - accountInvoiceShow(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountInvoiceShow(f.NewClient().AccountService(), cmd, args) }, } } -func accountInvoiceShow(service account.AccountService, cmd *cobra.Command, args []string) { +func accountInvoiceShow(service account.AccountService, cmd *cobra.Command, args []string) error { var invoices []account.Invoice for _, arg := range args { invoiceID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func accountInvoiceShow(service account.AccountService, cmd *cobra.Command, args invoices = append(invoices, invoice) } - outputAccountInvoices(invoices) + return output.CommandOutput(cmd, OutputAccountInvoicesProvider(invoices)) } diff --git a/cmd/account_invoice_test.go b/cmd/account/account_invoice_test.go similarity index 83% rename from cmd/account_invoice_test.go rename to cmd/account/account_invoice_test.go index 5d37969..4c77163 100644 --- a/cmd/account_invoice_test.go +++ b/cmd/account/account_invoice_test.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" @@ -24,7 +25,7 @@ func Test_accountInvoiceList(t *testing.T) { accountInvoiceList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_accountInvoiceList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - accountInvoiceList(service, cmd, []string{}) - }) + err := accountInvoiceList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetInvoicesError_OutputsFatal", func(t *testing.T) { + t.Run("GetInvoicesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -45,21 +46,21 @@ func Test_accountInvoiceList(t *testing.T) { service.EXPECT().GetInvoices(gomock.Any()).Return([]account.Invoice{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving invoices: test error\n", func() { - accountInvoiceList(service, &cobra.Command{}, []string{}) - }) + err := accountInvoiceList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving invoices: test error", err.Error()) }) } func Test_accountInvoiceShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := accountInvoiceShowCmd().Args(nil, []string{"123"}) + err := accountInvoiceShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := accountInvoiceShowCmd().Args(nil, []string{}) + err := accountInvoiceShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing invoice", err.Error()) diff --git a/cmd/account_invoicequery.go b/cmd/account/account_invoicequery.go similarity index 70% rename from cmd/account_invoicequery.go rename to cmd/account/account_invoicequery.go index a859244..3f07c98 100644 --- a/cmd/account_invoicequery.go +++ b/cmd/account/account_invoicequery.go @@ -1,58 +1,58 @@ -package cmd +package account import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/account" ) -func accountInvoiceQueryRootCmd() *cobra.Command { +func accountInvoiceQueryRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "invoicequery", Short: "sub-commands relating to invoice queries", } // Child commands - cmd.AddCommand(accountInvoiceQueryListCmd()) - cmd.AddCommand(accountInvoiceQueryShowCmd()) - cmd.AddCommand(accountInvoiceQueryCreateCmd()) + cmd.AddCommand(accountInvoiceQueryListCmd(f)) + cmd.AddCommand(accountInvoiceQueryShowCmd(f)) + cmd.AddCommand(accountInvoiceQueryCreateCmd(f)) return cmd } -func accountInvoiceQueryListCmd() *cobra.Command { +func accountInvoiceQueryListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists invoice queries", Long: "This command lists invoice queries", Example: "ukfast account invoicequery list", - Run: func(cmd *cobra.Command, args []string) { - accountInvoiceQueryList(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountInvoiceQueryList(f.NewClient().AccountService(), cmd, args) }, } } -func accountInvoiceQueryList(service account.AccountService, cmd *cobra.Command, args []string) { +func accountInvoiceQueryList(service account.AccountService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } queries, err := service.GetInvoiceQueries(params) if err != nil { - output.Fatalf("Error retrieving invoice queries: %s", err) - return + return fmt.Errorf("Error retrieving invoice queries: %s", err) } - outputAccountInvoiceQueries(queries) + return output.CommandOutput(cmd, OutputAccountInvoiceQueriesProvider(queries)) } -func accountInvoiceQueryShowCmd() *cobra.Command { +func accountInvoiceQueryShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows an invoice query", @@ -65,13 +65,13 @@ func accountInvoiceQueryShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - accountInvoiceQueryShow(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountInvoiceQueryShow(f.NewClient().AccountService(), cmd, args) }, } } -func accountInvoiceQueryShow(service account.AccountService, cmd *cobra.Command, args []string) { +func accountInvoiceQueryShow(service account.AccountService, cmd *cobra.Command, args []string) error { var queries []account.InvoiceQuery for _, arg := range args { queryID, err := strconv.Atoi(arg) @@ -89,10 +89,10 @@ func accountInvoiceQueryShow(service account.AccountService, cmd *cobra.Command, queries = append(queries, query) } - outputAccountInvoiceQueries(queries) + return output.CommandOutput(cmd, OutputAccountInvoiceQueriesProvider(queries)) } -func accountInvoiceQueryCreateCmd() *cobra.Command { +func accountInvoiceQueryCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a invoice query", @@ -105,8 +105,8 @@ func accountInvoiceQueryCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - accountInvoiceQueryCreate(getClient().AccountService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return accountInvoiceQueryCreate(f.NewClient().AccountService(), cmd, args) }, } @@ -128,7 +128,7 @@ func accountInvoiceQueryCreateCmd() *cobra.Command { return cmd } -func accountInvoiceQueryCreate(service account.AccountService, cmd *cobra.Command, args []string) { +func accountInvoiceQueryCreate(service account.AccountService, cmd *cobra.Command, args []string) error { createRequest := account.CreateInvoiceQueryRequest{} createRequest.ContactID, _ = cmd.Flags().GetInt("contact-id") createRequest.ContactMethod, _ = cmd.Flags().GetString("contact-method") @@ -140,15 +140,13 @@ func accountInvoiceQueryCreate(service account.AccountService, cmd *cobra.Comman id, err := service.CreateInvoiceQuery(createRequest) if err != nil { - output.Fatalf("Error creating invoice query: %s", err) - return + return fmt.Errorf("Error creating invoice query: %s", err) } query, err := service.GetInvoiceQuery(id) if err != nil { - output.Fatalf("Error retrieving new invoice query [%d]: %s", id, err) - return + return fmt.Errorf("Error retrieving new invoice query [%d]: %s", id, err) } - outputAccountInvoiceQueries([]account.InvoiceQuery{query}) + return output.CommandOutput(cmd, OutputAccountInvoiceQueriesProvider([]account.InvoiceQuery{query})) } diff --git a/cmd/account_invoicequery_test.go b/cmd/account/account_invoicequery_test.go similarity index 79% rename from cmd/account_invoicequery_test.go rename to cmd/account/account_invoicequery_test.go index 475eb1e..5b9c682 100644 --- a/cmd/account_invoicequery_test.go +++ b/cmd/account/account_invoicequery_test.go @@ -1,4 +1,4 @@ -package cmd +package account import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" @@ -24,7 +25,7 @@ func Test_accountInvoiceQueryList(t *testing.T) { accountInvoiceQueryList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_accountInvoiceQueryList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - accountInvoiceQueryList(service, cmd, []string{}) - }) + err := accountInvoiceQueryList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetInvoiceQueriesError_OutputsFatal", func(t *testing.T) { + t.Run("GetInvoiceQueriesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -45,21 +46,21 @@ func Test_accountInvoiceQueryList(t *testing.T) { service.EXPECT().GetInvoiceQueries(gomock.Any()).Return([]account.InvoiceQuery{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving invoice queries: test error\n", func() { - accountInvoiceQueryList(service, &cobra.Command{}, []string{}) - }) + err := accountInvoiceQueryList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving invoice queries: test error", err.Error()) }) } func Test_accountInvoiceQueryShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := accountInvoiceQueryShowCmd().Args(nil, []string{"123"}) + err := accountInvoiceQueryShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := accountInvoiceQueryShowCmd().Args(nil, []string{}) + err := accountInvoiceQueryShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing invoice query", err.Error()) @@ -123,7 +124,7 @@ func Test_accountInvoiceQueryCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockAccountService(mockCtrl) - cmd := accountInvoiceQueryCreateCmd() + cmd := accountInvoiceQueryCreateCmd(nil) cmd.Flags().Set("contact-id", "4") gomock.InOrder( @@ -138,7 +139,7 @@ func Test_accountInvoiceQueryCreate(t *testing.T) { accountInvoiceQueryCreate(service, cmd, []string{}) }) - t.Run("CreateInvoiceQueryError_OutputsFatal", func(t *testing.T) { + t.Run("CreateInvoiceQueryError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -147,13 +148,12 @@ func Test_accountInvoiceQueryCreate(t *testing.T) { service.EXPECT().CreateInvoiceQuery(gomock.Any()).Return(123, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating invoice query: test error\n", func() { - accountInvoiceQueryCreate(service, &cobra.Command{}, []string{}) - }) - }) + err := accountInvoiceQueryCreate(service, &cobra.Command{}, []string{}) - t.Run("GetInvoiceQueryError_OutputsFatal", func(t *testing.T) { + assert.Equal(t, "Error creating invoice query: test error", err.Error()) + }) + t.Run("GetInvoiceQueryError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -164,8 +164,8 @@ func Test_accountInvoiceQueryCreate(t *testing.T) { service.EXPECT().GetInvoiceQuery(123).Return(account.InvoiceQuery{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new invoice query [123]: test error\n", func() { - accountInvoiceQueryCreate(service, &cobra.Command{}, []string{}) - }) + err := accountInvoiceQueryCreate(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving new invoice query [123]: test error", err.Error()) }) } diff --git a/cmd/account/output.go b/cmd/account/output.go new file mode 100644 index 0000000..0193ff8 --- /dev/null +++ b/cmd/account/output.go @@ -0,0 +1,113 @@ +package account + +import ( + "fmt" + "strconv" + + "github.com/ukfast/cli/internal/pkg/helper" + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/account" +) + +func OutputAccountContactsProvider(contacts []account.Contact) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(contacts), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, contact := range contacts { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(contact.ID), true)) + fields.Set("type", output.NewFieldValue(contact.Type.String(), true)) + fields.Set("first_name", output.NewFieldValue(contact.FirstName, true)) + fields.Set("last_name", output.NewFieldValue(contact.LastName, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputAccountDetailsProvider(details []account.Details) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(details), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, detail := range details { + fields := output.NewOrderedFields() + fields.Set("company_registration_number", output.NewFieldValue(detail.CompanyRegistrationNumber, true)) + fields.Set("vat_identification_number", output.NewFieldValue(detail.VATIdentificationNumber, true)) + fields.Set("primary_contact_id", output.NewFieldValue(strconv.Itoa(detail.PrimaryContactID), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputAccountCreditsProvider(credits []account.Credit) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(credits), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, credit := range credits { + fields := output.NewOrderedFields() + fields.Set("type", output.NewFieldValue(credit.Type, true)) + fields.Set("total", output.NewFieldValue(strconv.Itoa(credit.Total), true)) + fields.Set("remaining", output.NewFieldValue(strconv.Itoa(credit.Remaining), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputAccountInvoicesProvider(invoices []account.Invoice) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(invoices), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, invoice := range invoices { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(invoice.ID), true)) + fields.Set("date", output.NewFieldValue(invoice.Date.String(), true)) + fields.Set("paid", output.NewFieldValue(strconv.FormatBool(invoice.Paid), true)) + fields.Set("net", output.NewFieldValue(fmt.Sprintf("%f", invoice.Net), true)) + fields.Set("vat", output.NewFieldValue(fmt.Sprintf("%f", invoice.VAT), true)) + fields.Set("gross", output.NewFieldValue(fmt.Sprintf("%f", invoice.Gross), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputAccountInvoiceQueriesProvider(queries []account.InvoiceQuery) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(queries), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, query := range queries { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(query.ID), true)) + fields.Set("contact_id", output.NewFieldValue(strconv.Itoa(query.ContactID), false)) + fields.Set("amount", output.NewFieldValue(fmt.Sprintf("%f", query.Amount), true)) + fields.Set("what_was_expected", output.NewFieldValue(query.WhatWasExpected, false)) + fields.Set("what_was_received", output.NewFieldValue(query.WhatWasReceived, false)) + fields.Set("proposed_solution", output.NewFieldValue(query.ProposedSolution, false)) + fields.Set("invoice_ids", output.NewFieldValue(helper.JoinInt(query.InvoiceIDs, ", "), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/account_test.go b/cmd/account_test.go deleted file mode 100644 index ec0abd9..0000000 --- a/cmd/account_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/service/account" -) - -func TestOutputAccountContacts_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputAccountContacts{ - Contacts: []account.Contact{ - account.Contact{ - FirstName: "testname", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []account.Contact{}, data) - assert.Equal(t, "testname", data.([]account.Contact)[0].FirstName) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputAccountContacts{ - Contacts: []account.Contact{ - account.Contact{ - FirstName: "testname1", - }, - account.Contact{ - FirstName: "testname2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []account.Contact{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testname1", data.([]account.Contact)[0].FirstName) - assert.Equal(t, "testname2", data.([]account.Contact)[1].FirstName) - }) -} - -func TestOutputAccountContacts_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputAccountContacts{ - Contacts: []account.Contact{ - account.Contact{ - FirstName: "testname", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("first_name")) - assert.Equal(t, "testname", data[0].Get("first_name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputAccountContacts{ - Contacts: []account.Contact{ - account.Contact{ - FirstName: "testname1", - }, - account.Contact{ - FirstName: "testname2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("first_name")) - assert.Equal(t, "testname1", data[0].Get("first_name").Value) - assert.True(t, data[1].Exists("first_name")) - assert.Equal(t, "testname2", data[1].Get("first_name").Value) - }) -} - -func TestOutputAccountDetails_GetData_ExpectedData(t *testing.T) { - o := OutputAccountDetails{ - Details: []account.Details{ - account.Details{ - VATIdentificationNumber: "GB123", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []account.Details{}, data) - assert.Equal(t, "GB123", data.([]account.Details)[0].VATIdentificationNumber) -} - -func TestOutputAccountDetails_GetFieldData_ExpectedFieldData(t *testing.T) { - o := OutputAccountDetails{ - Details: []account.Details{ - account.Details{ - VATIdentificationNumber: "GB123", - }, - account.Details{ - VATIdentificationNumber: "GB456", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("vat_identification_number")) - assert.Equal(t, "GB123", data[0].Get("vat_identification_number").Value) - assert.True(t, data[1].Exists("vat_identification_number")) - assert.Equal(t, "GB456", data[1].Get("vat_identification_number").Value) -} diff --git a/cmd/completion.go b/cmd/completion.go index e139c93..b9c6009 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -func completionRootCmd() *cobra.Command { +func CompletionRootCmd() *cobra.Command { cmd := &cobra.Command{ Use: "completion", Short: "Commands for generating shell completions", diff --git a/cmd/ddosx.go b/cmd/ddosx.go deleted file mode 100644 index 9df5fd4..0000000 --- a/cmd/ddosx.go +++ /dev/null @@ -1,672 +0,0 @@ -package cmd - -import ( - "fmt" - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/ddosx" -) - -func ddosxRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "ddosx", - Short: "Commands relating to DDoSX service", - } - - // Child root commands - cmd.AddCommand(ddosxDomainRootCmd()) - cmd.AddCommand(ddosxRecordRootCmd()) - cmd.AddCommand(ddosxSSLRootCmd()) - - return cmd -} - -// OutputDDoSXDomains implements OutputDataProvider for outputting an array of Domains -type OutputDDoSXDomains struct { - Domains []ddosx.Domain -} - -func outputDDoSXDomains(domains []ddosx.Domain) { - err := Output(&OutputDDoSXDomains{Domains: domains}) - if err != nil { - output.Fatalf("Failed to output domains: %s", err) - } -} - -func (o *OutputDDoSXDomains) GetData() interface{} { - return o.Domains -} - -func (o *OutputDDoSXDomains) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, domain := range o.Domains { - fields := o.getOrderedFields(domain) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXDomains) getOrderedFields(domain ddosx.Domain) *output.OrderedFields { - fields := output.NewOrderedFields() - - var safednsZoneID string - if domain.SafeDNSZoneID != nil { - safednsZoneID = strconv.Itoa(*domain.SafeDNSZoneID) - } - - fields.Set("name", output.NewFieldValue(domain.Name, true)) - fields.Set("status", output.NewFieldValue(domain.Status.String(), true)) - fields.Set("safedns_zone_id", output.NewFieldValue(safednsZoneID, true)) - fields.Set("dns_active", output.NewFieldValue(strconv.FormatBool(domain.DNSActive), true)) - fields.Set("cdn_active", output.NewFieldValue(strconv.FormatBool(domain.CDNActive), true)) - fields.Set("waf_active", output.NewFieldValue(strconv.FormatBool(domain.WAFActive), true)) - - return fields -} - -// OutputDDoSXRecords implements OutputDataProvider for outputting an array of Records -type OutputDDoSXRecords struct { - Records []ddosx.Record -} - -func outputDDoSXRecords(records []ddosx.Record) { - err := Output(&OutputDDoSXRecords{Records: records}) - if err != nil { - output.Fatalf("Failed to output records: %s", err) - } -} - -func (o *OutputDDoSXRecords) GetData() interface{} { - return o.Records -} - -func (o *OutputDDoSXRecords) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, record := range o.Records { - fields := o.getOrderedFields(record) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXRecords) getOrderedFields(record ddosx.Record) *output.OrderedFields { - fields := output.NewOrderedFields() - - var safeDNSRecordID string - if record.SafeDNSRecordID != nil { - safeDNSRecordID = strconv.Itoa(*record.SafeDNSRecordID) - } - var sslID string - if record.SSLID != nil { - sslID = *record.SSLID - } - - fields.Set("id", output.NewFieldValue(record.ID, true)) - fields.Set("safedns_record_id", output.NewFieldValue(safeDNSRecordID, true)) - fields.Set("ssl_id", output.NewFieldValue(sslID, true)) - fields.Set("domain_name", output.NewFieldValue(record.DomainName, true)) - fields.Set("name", output.NewFieldValue(record.Name, true)) - fields.Set("type", output.NewFieldValue(record.Type.String(), true)) - fields.Set("content", output.NewFieldValue(record.Content, true)) - - return fields -} - -// OutputDDoSXWAFs implements OutputDataProvider for outputting an array of WAFs -type OutputDDoSXWAFs struct { - WAFs []ddosx.WAF -} - -func outputDDoSXWAFs(wafs []ddosx.WAF) { - err := Output(&OutputDDoSXWAFs{WAFs: wafs}) - if err != nil { - output.Fatalf("Failed to output wafs: %s", err) - } -} - -func (o *OutputDDoSXWAFs) GetData() interface{} { - return o.WAFs -} - -func (o *OutputDDoSXWAFs) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, waf := range o.WAFs { - fields := o.getOrderedFields(waf) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXWAFs) getOrderedFields(waf ddosx.WAF) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("mode", output.NewFieldValue(waf.Mode.String(), true)) - fields.Set("paranoia_level", output.NewFieldValue(waf.ParanoiaLevel.String(), true)) - - return fields -} - -// OutputDDoSXWAFRuleSets implements OutputDataProvider for outputting an array of WAFRuleSets -type OutputDDoSXWAFRuleSets struct { - WAFRuleSets []ddosx.WAFRuleSet -} - -func outputDDoSXWAFRuleSets(wafRuleSets []ddosx.WAFRuleSet) { - err := Output(&OutputDDoSXWAFRuleSets{WAFRuleSets: wafRuleSets}) - if err != nil { - output.Fatalf("Failed to output waf rule sets: %s", err) - } -} - -func (o *OutputDDoSXWAFRuleSets) GetData() interface{} { - return o.WAFRuleSets -} - -func (o *OutputDDoSXWAFRuleSets) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, wafRuleSet := range o.WAFRuleSets { - fields := o.getOrderedFields(wafRuleSet) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXWAFRuleSets) getOrderedFields(wafRuleSet ddosx.WAFRuleSet) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(wafRuleSet.ID, true)) - fields.Set("name", output.NewFieldValue(wafRuleSet.Name.String(), true)) - fields.Set("active", output.NewFieldValue(strconv.FormatBool(wafRuleSet.Active), true)) - - return fields -} - -// OutputDDoSXWAFRules implements OutputDataProvider for outputting an array of WAFRules -type OutputDDoSXWAFRules struct { - WAFRules []ddosx.WAFRule -} - -func outputDDoSXWAFRules(wafRules []ddosx.WAFRule) { - err := Output(&OutputDDoSXWAFRules{WAFRules: wafRules}) - if err != nil { - output.Fatalf("Failed to output waf rules: %s", err) - } -} - -func (o *OutputDDoSXWAFRules) GetData() interface{} { - return o.WAFRules -} - -func (o *OutputDDoSXWAFRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, wafRule := range o.WAFRules { - fields := o.getOrderedFields(wafRule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXWAFRules) getOrderedFields(wafRule ddosx.WAFRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(wafRule.ID, true)) - fields.Set("uri", output.NewFieldValue(wafRule.URI, true)) - fields.Set("ip", output.NewFieldValue(wafRule.IP.String(), true)) - - return fields -} - -// OutputDDoSXWAFAdvancedRules implements OutputDataProvider for outputting an array of WAFAdvancedRules -type OutputDDoSXWAFAdvancedRules struct { - WAFAdvancedRules []ddosx.WAFAdvancedRule -} - -func outputDDoSXWAFAdvancedRules(wafAdvancedRules []ddosx.WAFAdvancedRule) { - err := Output(&OutputDDoSXWAFAdvancedRules{WAFAdvancedRules: wafAdvancedRules}) - if err != nil { - output.Fatalf("Failed to output waf rules: %s", err) - } -} - -func (o *OutputDDoSXWAFAdvancedRules) GetData() interface{} { - return o.WAFAdvancedRules -} - -func (o *OutputDDoSXWAFAdvancedRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, wafAdvancedRule := range o.WAFAdvancedRules { - fields := o.getOrderedFields(wafAdvancedRule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXWAFAdvancedRules) getOrderedFields(wafAdvancedRule ddosx.WAFAdvancedRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(wafAdvancedRule.ID, true)) - fields.Set("section", output.NewFieldValue(wafAdvancedRule.Section.String(), true)) - fields.Set("modifier", output.NewFieldValue(wafAdvancedRule.Modifier.String(), true)) - fields.Set("phrase", output.NewFieldValue(wafAdvancedRule.Phrase, true)) - fields.Set("ip", output.NewFieldValue(wafAdvancedRule.IP.String(), true)) - - return fields -} - -// OutputDDoSXSSLs implements OutputDataProvider for outputting an array of SSLs -type OutputDDoSXSSLs struct { - SSLs []ddosx.SSL -} - -func outputDDoSXSSLs(ssls []ddosx.SSL) { - err := Output(&OutputDDoSXSSLs{SSLs: ssls}) - if err != nil { - output.Fatalf("Failed to output ssls: %s", err) - } -} - -func (o *OutputDDoSXSSLs) GetData() interface{} { - return o.SSLs -} - -func (o *OutputDDoSXSSLs) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, ssl := range o.SSLs { - fields := o.getOrderedFields(ssl) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXSSLs) getOrderedFields(ssl ddosx.SSL) *output.OrderedFields { - fields := output.NewOrderedFields() - - var ukfastSSLID string - if ssl.UKFastSSLID != nil { - ukfastSSLID = strconv.Itoa(*ssl.UKFastSSLID) - } - - fields.Set("id", output.NewFieldValue(ssl.ID, true)) - fields.Set("ukfast_ssl_id", output.NewFieldValue(ukfastSSLID, true)) - fields.Set("domains", output.NewFieldValue(strings.Join(ssl.Domains, ", "), true)) - fields.Set("friendly_name", output.NewFieldValue(ssl.FriendlyName, true)) - - return fields -} - -// OutputDDoSXSSLContents implements OutputDataProvider for outputting an array of SSLContentss -type OutputDDoSXSSLContents struct { - SSLContents []ddosx.SSLContent -} - -func outputDDoSXSSLContents(sslContents []ddosx.SSLContent) { - err := Output(&OutputDDoSXSSLContents{SSLContents: sslContents}) - if err != nil { - output.Fatalf("Failed to output ssl contents: %s", err) - } -} - -func (o *OutputDDoSXSSLContents) GetData() interface{} { - return o.SSLContents -} - -func (o *OutputDDoSXSSLContents) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, sslContent := range o.SSLContents { - fields := o.getOrderedFields(sslContent) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXSSLContents) getOrderedFields(sslContent ddosx.SSLContent) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("certificate", output.NewFieldValue(sslContent.Certificate, true)) - fields.Set("ca_bundle", output.NewFieldValue(sslContent.CABundle, true)) - return fields -} - -// OutputDDoSXSSLPrivateKeys implements OutputDataProvider for outputting an array of SSLPrivateKeyss -type OutputDDoSXSSLPrivateKeys struct { - SSLPrivateKeys []ddosx.SSLPrivateKey -} - -func outputDDoSXSSLPrivateKeys(sslPrivateKeys []ddosx.SSLPrivateKey) { - err := Output(&OutputDDoSXSSLPrivateKeys{SSLPrivateKeys: sslPrivateKeys}) - if err != nil { - output.Fatalf("Failed to output ssl private key: %s", err) - } -} - -func (o *OutputDDoSXSSLPrivateKeys) GetData() interface{} { - return o.SSLPrivateKeys -} - -func (o *OutputDDoSXSSLPrivateKeys) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, sslPrivateKey := range o.SSLPrivateKeys { - fields := o.getOrderedFields(sslPrivateKey) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXSSLPrivateKeys) getOrderedFields(sslPrivateKey ddosx.SSLPrivateKey) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("key", output.NewFieldValue(sslPrivateKey.Key, true)) - return fields -} - -// OutputDDoSXACLIPRules implements OutputDataProvider for outputting an array of ACLIPRules -type OutputDDoSXACLIPRules struct { - ACLIPRules []ddosx.ACLIPRule -} - -func outputDDoSXACLIPRules(rules []ddosx.ACLIPRule) { - err := Output(&OutputDDoSXACLIPRules{ACLIPRules: rules}) - if err != nil { - output.Fatalf("Failed to output domain ACL IP rules: %s", err) - } -} - -func (o *OutputDDoSXACLIPRules) GetData() interface{} { - return o.ACLIPRules -} - -func (o *OutputDDoSXACLIPRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, rule := range o.ACLIPRules { - fields := o.getOrderedFields(rule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXACLIPRules) getOrderedFields(rule ddosx.ACLIPRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(rule.ID, true)) - fields.Set("mode", output.NewFieldValue(rule.Mode.String(), true)) - fields.Set("ip", output.NewFieldValue(rule.IP.String(), true)) - fields.Set("uri", output.NewFieldValue(rule.URI, true)) - - return fields -} - -// OutputDDoSXACLGeoIPRules implements OutputDataProvider for outputting an array of ACLGeoIPRules -type OutputDDoSXACLGeoIPRules struct { - ACLGeoIPRules []ddosx.ACLGeoIPRule -} - -func outputDDoSXACLGeoIPRules(rules []ddosx.ACLGeoIPRule) { - err := Output(&OutputDDoSXACLGeoIPRules{ACLGeoIPRules: rules}) - if err != nil { - output.Fatalf("Failed to output domain ACL GeoIP rules: %s", err) - } -} - -func (o *OutputDDoSXACLGeoIPRules) GetData() interface{} { - return o.ACLGeoIPRules -} - -func (o *OutputDDoSXACLGeoIPRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, rule := range o.ACLGeoIPRules { - fields := o.getOrderedFields(rule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXACLGeoIPRules) getOrderedFields(rule ddosx.ACLGeoIPRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(rule.ID, true)) - fields.Set("name", output.NewFieldValue(rule.Name, true)) - fields.Set("code", output.NewFieldValue(rule.Code, true)) - - return fields -} - -// OutputDDoSXACLGeoIPRulesModes implements OutputDataProvider for outputting an array of ACLGeoIPRulesModes -type OutputDDoSXACLGeoIPRulesModes struct { - ACLGeoIPRulesModes []ddosx.ACLGeoIPRulesMode -} - -func outputDDoSXACLGeoIPRulesModes(modes []ddosx.ACLGeoIPRulesMode) { - err := Output(&OutputDDoSXACLGeoIPRulesModes{ACLGeoIPRulesModes: modes}) - if err != nil { - output.Fatalf("Failed to output domain ACL GeoIP rules modes: %s", err) - } -} - -func (o *OutputDDoSXACLGeoIPRulesModes) GetData() interface{} { - return o.ACLGeoIPRulesModes -} - -func (o *OutputDDoSXACLGeoIPRulesModes) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, mode := range o.ACLGeoIPRulesModes { - fields := o.getOrderedFields(mode) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXACLGeoIPRulesModes) getOrderedFields(mode ddosx.ACLGeoIPRulesMode) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("mode", output.NewFieldValue(mode.String(), true)) - - return fields -} - -// OutputDDoSXDomainProperties implements OutputDataProvider for outputting an array of ACLGeoIPRulesModes -type OutputDDoSXDomainProperties struct { - DomainProperties []ddosx.DomainProperty -} - -func outputDDoSXDomainProperties(properties []ddosx.DomainProperty) { - err := Output(&OutputDDoSXDomainProperties{DomainProperties: properties}) - if err != nil { - output.Fatalf("Failed to output domain properties: %s", err) - } -} - -func (o *OutputDDoSXDomainProperties) GetData() interface{} { - return o.DomainProperties -} - -func (o *OutputDDoSXDomainProperties) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, property := range o.DomainProperties { - fields := o.getOrderedFields(property) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXDomainProperties) getOrderedFields(property ddosx.DomainProperty) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(property.ID, true)) - fields.Set("name", output.NewFieldValue(property.Name.String(), true)) - fields.Set("value", output.NewFieldValue(fmt.Sprintf("%v", property.Value), true)) - - return fields -} - -type OutputDDoSXDomainVerificationFilesFile struct { - Name string - Content string -} - -// OutputDDoSXDomainVerificationFiles implements OutputDataProvider for outputting an array of OutputDDoSXDomainVerificationFilesFile -type OutputDDoSXDomainVerificationFiles struct { - DomainVerificationFiles []OutputDDoSXDomainVerificationFilesFile -} - -func outputDDoSXDomainVerificationFiles(files []OutputDDoSXDomainVerificationFilesFile) { - err := Output(&OutputDDoSXDomainVerificationFiles{DomainVerificationFiles: files}) - if err != nil { - output.Fatalf("Failed to output domain verification files: %s", err) - } -} - -func (o *OutputDDoSXDomainVerificationFiles) GetData() interface{} { - return o.DomainVerificationFiles -} - -func (o *OutputDDoSXDomainVerificationFiles) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, file := range o.DomainVerificationFiles { - fields := o.getOrderedFields(file) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXDomainVerificationFiles) getOrderedFields(file OutputDDoSXDomainVerificationFilesFile) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("name", output.NewFieldValue(file.Name, true)) - fields.Set("content", output.NewFieldValue(file.Content, true)) - - return fields -} - -// OutputDDoSXCDNRules implements OutputDataProvider for outputting an array of CDNRules -type OutputDDoSXCDNRules struct { - CDNRules []ddosx.CDNRule -} - -func outputDDoSXCDNRules(rules []ddosx.CDNRule) { - err := Output(&OutputDDoSXCDNRules{CDNRules: rules}) - if err != nil { - output.Fatalf("Failed to output domain ACL GeoIP rules: %s", err) - } -} - -func (o *OutputDDoSXCDNRules) GetData() interface{} { - return o.CDNRules -} - -func (o *OutputDDoSXCDNRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, rule := range o.CDNRules { - fields := o.getOrderedFields(rule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXCDNRules) getOrderedFields(rule ddosx.CDNRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("id", output.NewFieldValue(rule.ID, true)) - fields.Set("uri", output.NewFieldValue(rule.URI, true)) - fields.Set("cache_control", output.NewFieldValue(rule.CacheControl.String(), true)) - fields.Set("cache_control_duration", output.NewFieldValue(rule.CacheControlDuration.String(), true)) - fields.Set("mime_types", output.NewFieldValue(strings.Join(rule.MimeTypes, ", "), true)) - fields.Set("type", output.NewFieldValue(rule.Type.String(), true)) - - return fields -} - -// OutputDDoSXHSTSConfiguration implements OutputDataProvider for outputting an array of HSTSConfiguration -type OutputDDoSXHSTSConfiguration struct { - HSTSConfiguration []ddosx.HSTSConfiguration -} - -func outputDDoSXHSTSConfiguration(configurations []ddosx.HSTSConfiguration) { - err := Output(&OutputDDoSXHSTSConfiguration{HSTSConfiguration: configurations}) - if err != nil { - output.Fatalf("Failed to output domain HSTS configurations: %s", err) - } -} - -func (o *OutputDDoSXHSTSConfiguration) GetData() interface{} { - return o.HSTSConfiguration -} - -func (o *OutputDDoSXHSTSConfiguration) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, configuration := range o.HSTSConfiguration { - fields := o.getOrderedFields(configuration) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXHSTSConfiguration) getOrderedFields(configuration ddosx.HSTSConfiguration) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("enabled", output.NewFieldValue(strconv.FormatBool(configuration.Enabled), true)) - - return fields -} - -// OutputDDoSXHSTSRules implements OutputDataProvider for outputting an array of HSTSRules -type OutputDDoSXHSTSRules struct { - HSTSRules []ddosx.HSTSRule -} - -func outputDDoSXHSTSRules(rules []ddosx.HSTSRule) { - err := Output(&OutputDDoSXHSTSRules{HSTSRules: rules}) - if err != nil { - output.Fatalf("Failed to output domain HSTS rules: %s", err) - } -} - -func (o *OutputDDoSXHSTSRules) GetData() interface{} { - return o.HSTSRules -} - -func (o *OutputDDoSXHSTSRules) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, rule := range o.HSTSRules { - fields := o.getOrderedFields(rule) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputDDoSXHSTSRules) getOrderedFields(rule ddosx.HSTSRule) *output.OrderedFields { - fields := output.NewOrderedFields() - - recordName := "" - if rule.RecordName != nil { - recordName = *rule.RecordName - } - - fields.Set("id", output.NewFieldValue(rule.ID, true)) - fields.Set("max_age", output.NewFieldValue(strconv.Itoa(rule.MaxAge), true)) - fields.Set("preload", output.NewFieldValue(strconv.FormatBool(rule.Preload), true)) - fields.Set("include_subdomains", output.NewFieldValue(strconv.FormatBool(rule.IncludeSubdomains), true)) - fields.Set("type", output.NewFieldValue(rule.Type.String(), true)) - fields.Set("record_name", output.NewFieldValue(recordName, true)) - - return fields -} diff --git a/cmd/ddosx/ddosx.go b/cmd/ddosx/ddosx.go new file mode 100644 index 0000000..abd10bc --- /dev/null +++ b/cmd/ddosx/ddosx.go @@ -0,0 +1,21 @@ +package ddosx + +import ( + "github.com/spf13/afero" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func DDoSXRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { + cmd := &cobra.Command{ + Use: "ddosx", + Short: "Commands relating to DDoSX service", + } + + // Child root commands + cmd.AddCommand(ddosxDomainRootCmd(f, appFilesystem)) + cmd.AddCommand(ddosxRecordRootCmd(f)) + cmd.AddCommand(ddosxSSLRootCmd(f)) + + return cmd +} diff --git a/cmd/ddosx_domain.go b/cmd/ddosx/ddosx_domain.go similarity index 64% rename from cmd/ddosx_domain.go rename to cmd/ddosx/ddosx_domain.go index 21c7e42..884440d 100644 --- a/cmd/ddosx_domain.go +++ b/cmd/ddosx/ddosx_domain.go @@ -1,69 +1,69 @@ -package cmd +package ddosx import ( "errors" "fmt" + "github.com/spf13/afero" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainRootCmd() *cobra.Command { +func ddosxDomainRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "domain", Short: "sub-commands relating to domains", } // Child commands - cmd.AddCommand(ddosxDomainListCmd()) - cmd.AddCommand(ddosxDomainShowCmd()) - cmd.AddCommand(ddosxDomainCreateCmd()) - cmd.AddCommand(ddosxDomainDeleteCmd()) - cmd.AddCommand(ddosxDomainDeployCmd()) + cmd.AddCommand(ddosxDomainListCmd(f)) + cmd.AddCommand(ddosxDomainShowCmd(f)) + cmd.AddCommand(ddosxDomainCreateCmd(f)) + cmd.AddCommand(ddosxDomainDeleteCmd(f)) + cmd.AddCommand(ddosxDomainDeployCmd(f)) // Child root commands - cmd.AddCommand(ddosxDomainRecordRootCmd()) - cmd.AddCommand(ddosxDomainWAFRootCmd()) - cmd.AddCommand(ddosxDomainACLRootCmd()) - cmd.AddCommand(ddosxDomainPropertyRootCmd()) - cmd.AddCommand(ddosxDomainVerificationRootCmd()) - cmd.AddCommand(ddosxDomainCDNRootCmd()) - cmd.AddCommand(ddosxDomainHSTSRootCmd()) + cmd.AddCommand(ddosxDomainRecordRootCmd(f)) + cmd.AddCommand(ddosxDomainWAFRootCmd(f)) + cmd.AddCommand(ddosxDomainACLRootCmd(f)) + cmd.AddCommand(ddosxDomainPropertyRootCmd(f)) + cmd.AddCommand(ddosxDomainVerificationRootCmd(f, appFilesystem)) + cmd.AddCommand(ddosxDomainCDNRootCmd(f)) + cmd.AddCommand(ddosxDomainHSTSRootCmd(f)) return cmd } -func ddosxDomainListCmd() *cobra.Command { +func ddosxDomainListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists domains", Long: "This command lists domains", Example: "ukfast ddosx domain list", - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomains(params) if err != nil { - output.Fatalf("Error retrieving domains: %s", err) - return + return fmt.Errorf("Error retrieving domains: %s", err) } - outputDDoSXDomains(domains) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider(domains)) } -func ddosxDomainShowCmd() *cobra.Command { +func ddosxDomainShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a domain", @@ -76,13 +76,13 @@ func ddosxDomainShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var domains []ddosx.Domain for _, arg := range args { domain, err := service.GetDomain(arg) @@ -94,17 +94,17 @@ func ddosxDomainShow(service ddosx.DDoSXService, cmd *cobra.Command, args []stri domains = append(domains, domain) } - outputDDoSXDomains(domains) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider(domains)) } -func ddosxDomainCreateCmd() *cobra.Command { +func ddosxDomainCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a domain", Long: "This command creates a new domain", Example: "ukfast ddosx domain create --name example.com", - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -115,7 +115,7 @@ func ddosxDomainCreateCmd() *cobra.Command { return cmd } -func ddosxDomainCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { domainName, _ := cmd.Flags().GetString("name") createRequest := ddosx.CreateDomainRequest{ @@ -124,20 +124,18 @@ func ddosxDomainCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []st err := service.CreateDomain(createRequest) if err != nil { - output.Fatalf("Error creating domain: %s", err) - return + return fmt.Errorf("Error creating domain: %s", err) } domain, err := service.GetDomain(domainName) if err != nil { - output.Fatalf("Error retrieving new domain: %s", err) - return + return fmt.Errorf("Error retrieving new domain: %s", err) } - outputDDoSXDomains([]ddosx.Domain{domain}) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider([]ddosx.Domain{domain})) } -func ddosxDomainDeleteCmd() *cobra.Command { +func ddosxDomainDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a domain", @@ -151,7 +149,7 @@ func ddosxDomainDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainDelete(f.NewClient().DDoSXService(), cmd, args) }, } } @@ -166,7 +164,7 @@ func ddosxDomainDelete(service ddosx.DDoSXService, cmd *cobra.Command, args []st } } -func ddosxDomainDeployCmd() *cobra.Command { +func ddosxDomainDeployCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "deploy ...", Short: "Deploys a domain", @@ -179,8 +177,8 @@ func ddosxDomainDeployCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainDeploy(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainDeploy(f.NewClient().DDoSXService(), cmd, args) }, } @@ -189,7 +187,7 @@ func ddosxDomainDeployCmd() *cobra.Command { return cmd } -func ddosxDomainDeploy(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainDeploy(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var domains []ddosx.Domain for _, arg := range args { err := service.DeployDomain(arg) @@ -200,7 +198,7 @@ func ddosxDomainDeploy(service ddosx.DDoSXService, cmd *cobra.Command, args []st waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(DomainStatusWaitFunc(service, arg, ddosx.DomainStatusConfigured)) + err := helper.WaitForCommand(DomainStatusWaitFunc(service, arg, ddosx.DomainStatusConfigured)) if err != nil { output.OutputWithErrorLevelf("Error deploying domain [%s]: %s", arg, err) continue @@ -216,10 +214,10 @@ func ddosxDomainDeploy(service ddosx.DDoSXService, cmd *cobra.Command, args []st domains = append(domains, domain) } - outputDDoSXDomains(domains) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider(domains)) } -func DomainStatusWaitFunc(service ddosx.DDoSXService, domainName string, status ddosx.DomainStatus) WaitFunc { +func DomainStatusWaitFunc(service ddosx.DDoSXService, domainName string, status ddosx.DomainStatus) helper.WaitFunc { return func() (finished bool, err error) { domain, err := service.GetDomain(domainName) if err != nil { diff --git a/cmd/ddosx/ddosx_domain_acl.go b/cmd/ddosx/ddosx_domain_acl.go new file mode 100644 index 0000000..b70bafd --- /dev/null +++ b/cmd/ddosx/ddosx_domain_acl.go @@ -0,0 +1,19 @@ +package ddosx + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func ddosxDomainACLRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "acl", + Short: "sub-commands relating to domain ACLs", + } + + // Child root commands + cmd.AddCommand(ddosxDomainACLIPRuleRootCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRuleRootCmd(f)) + + return cmd +} diff --git a/cmd/ddosx_domain_acl_geoip.go b/cmd/ddosx/ddosx_domain_acl_geoip.go similarity index 68% rename from cmd/ddosx_domain_acl_geoip.go rename to cmd/ddosx/ddosx_domain_acl_geoip.go index 7c70f32..0e70631 100644 --- a/cmd/ddosx_domain_acl_geoip.go +++ b/cmd/ddosx/ddosx_domain_acl_geoip.go @@ -1,34 +1,36 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainACLGeoIPRuleRootCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "geoip", Short: "sub-commands relating to domain ACL GeoIP rules", } // Child commands - cmd.AddCommand(ddosxDomainACLGeoIPRuleListCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRuleShowCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRuleCreateCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainACLGeoIPRuleListCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRuleDeleteCmd(f)) // Child root commands - cmd.AddCommand(ddosxDomainACLGeoIPRulesModeRootCmd()) + cmd.AddCommand(ddosxDomainACLGeoIPRulesModeRootCmd(f)) return cmd } -func ddosxDomainACLGeoIPRuleListCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists ACL GeoIP rules", @@ -41,29 +43,27 @@ func ddosxDomainACLGeoIPRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainACLGeoIPRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainACLGeoIPRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain ACL GeoIP rules: %s", err) - return + return fmt.Errorf("Error retrieving domain ACL GeoIP rules: %s", err) } - outputDDoSXACLGeoIPRules(domains) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesProvider(domains)) } -func ddosxDomainACLGeoIPRuleShowCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows domain ACL GeoIP rules", @@ -79,13 +79,13 @@ func ddosxDomainACLGeoIPRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainACLGeoIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.ACLGeoIPRule @@ -99,10 +99,10 @@ func ddosxDomainACLGeoIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, rules = append(rules, rule) } - outputDDoSXACLGeoIPRules(rules) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesProvider(rules)) } -func ddosxDomainACLGeoIPRuleCreateCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates ACL GeoIP rules", @@ -115,8 +115,8 @@ func ddosxDomainACLGeoIPRuleCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRuleCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -126,27 +126,25 @@ func ddosxDomainACLGeoIPRuleCreateCmd() *cobra.Command { return cmd } -func ddosxDomainACLGeoIPRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { createRequest := ddosx.CreateACLGeoIPRuleRequest{} createRequest.Code, _ = cmd.Flags().GetString("code") id, err := service.CreateDomainACLGeoIPRule(args[0], createRequest) if err != nil { - output.Fatalf("Error creating domain ACL GeoIP rule: %s", err) - return + return fmt.Errorf("Error creating domain ACL GeoIP rule: %s", err) } rule, err := service.GetDomainACLGeoIPRule(args[0], id) if err != nil { - output.Fatalf("Error retrieving new domain ACL GeoIP rule [%s]: %s", id, err) - return + return fmt.Errorf("Error retrieving new domain ACL GeoIP rule [%s]: %s", id, err) } - outputDDoSXACLGeoIPRules([]ddosx.ACLGeoIPRule{rule}) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesProvider([]ddosx.ACLGeoIPRule{rule})) } -func ddosxDomainACLGeoIPRuleUpdateCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates ACL GeoIP rules", @@ -162,8 +160,8 @@ func ddosxDomainACLGeoIPRuleUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRuleUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -172,7 +170,7 @@ func ddosxDomainACLGeoIPRuleUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainACLGeoIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchACLGeoIPRuleRequest{} if cmd.Flags().Changed("code") { @@ -196,10 +194,10 @@ func ddosxDomainACLGeoIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Comman rules = append(rules, rule) } - outputDDoSXACLGeoIPRules(rules) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesProvider(rules)) } -func ddosxDomainACLGeoIPRuleDeleteCmd() *cobra.Command { +func ddosxDomainACLGeoIPRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes ACL GeoIP rules", @@ -216,7 +214,7 @@ func ddosxDomainACLGeoIPRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainACLGeoIPRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_acl_geoip_mode.go b/cmd/ddosx/ddosx_domain_acl_geoip_mode.go similarity index 62% rename from cmd/ddosx_domain_acl_geoip_mode.go rename to cmd/ddosx/ddosx_domain_acl_geoip_mode.go index 39dee48..ad34c5a 100644 --- a/cmd/ddosx_domain_acl_geoip_mode.go +++ b/cmd/ddosx/ddosx_domain_acl_geoip_mode.go @@ -1,27 +1,29 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainACLGeoIPRulesModeRootCmd() *cobra.Command { +func ddosxDomainACLGeoIPRulesModeRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "mode", Short: "sub-commands relating to domain ACL GeoIP rules mode", } // Child commands - cmd.AddCommand(ddosxDomainACLGeoIPRulesModeShowCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRulesModeUpdateCmd()) + cmd.AddCommand(ddosxDomainACLGeoIPRulesModeShowCmd(f)) + cmd.AddCommand(ddosxDomainACLGeoIPRulesModeUpdateCmd(f)) return cmd } -func ddosxDomainACLGeoIPRulesModeShowCmd() *cobra.Command { +func ddosxDomainACLGeoIPRulesModeShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a domain", @@ -34,13 +36,13 @@ func ddosxDomainACLGeoIPRulesModeShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRulesModeShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRulesModeShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainACLGeoIPRulesModeShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRulesModeShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var modes []ddosx.ACLGeoIPRulesMode for _, arg := range args { mode, err := service.GetDomainACLGeoIPRulesMode(arg) @@ -52,10 +54,10 @@ func ddosxDomainACLGeoIPRulesModeShow(service ddosx.DDoSXService, cmd *cobra.Com modes = append(modes, mode) } - outputDDoSXACLGeoIPRulesModes(modes) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesModesProvider(modes)) } -func ddosxDomainACLGeoIPRulesModeUpdateCmd() *cobra.Command { +func ddosxDomainACLGeoIPRulesModeUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ", Short: "Updates a domain ACL GeoIP rule filtering mode", @@ -68,8 +70,8 @@ func ddosxDomainACLGeoIPRulesModeUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLGeoIPRulesModeUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLGeoIPRulesModeUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -78,30 +80,27 @@ func ddosxDomainACLGeoIPRulesModeUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainACLGeoIPRulesModeUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLGeoIPRulesModeUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchACLGeoIPRulesModeRequest{} if cmd.Flags().Changed("mode") { mode, _ := cmd.Flags().GetString("mode") parsedMode, err := ddosx.ParseACLGeoIPRulesMode(mode) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest.Mode = parsedMode } err := service.PatchDomainACLGeoIPRulesMode(args[0], patchRequest) if err != nil { - output.Fatalf("Error updating domain ACL GeoIP rule filtering mode: %s", err.Error()) - return + return fmt.Errorf("Error updating domain ACL GeoIP rule filtering mode: %s", err.Error()) } mode, err := service.GetDomainACLGeoIPRulesMode(args[0]) if err != nil { - output.Fatalf("Error retrieving updated domain ACL GeoIP rule filtering mode: %s", err) - return + return fmt.Errorf("Error retrieving updated domain ACL GeoIP rule filtering mode: %s", err) } - outputDDoSXACLGeoIPRulesModes([]ddosx.ACLGeoIPRulesMode{mode}) + return output.CommandOutput(cmd, OutputDDoSXACLGeoIPRulesModesProvider([]ddosx.ACLGeoIPRulesMode{mode})) } diff --git a/cmd/ddosx_domain_acl_geoip_mode_test.go b/cmd/ddosx/ddosx_domain_acl_geoip_mode_test.go similarity index 75% rename from cmd/ddosx_domain_acl_geoip_mode_test.go rename to cmd/ddosx/ddosx_domain_acl_geoip_mode_test.go index d6569ca..7460d53 100644 --- a/cmd/ddosx_domain_acl_geoip_mode_test.go +++ b/cmd/ddosx/ddosx_domain_acl_geoip_mode_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -9,18 +9,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" + "github.com/ukfast/sdk-go/pkg/connection" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) func Test_ddosxDomainACLGeoIPRulesModeShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainACLGeoIPRulesModeShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainACLGeoIPRulesModeShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainACLGeoIPRulesModeShowCmd().Args(nil, []string{}) + err := ddosxDomainACLGeoIPRulesModeShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -69,14 +70,14 @@ func Test_ddosxDomainACLGeoIPRulesModeShow(t *testing.T) { func Test_ddosxDomainACLGeoIPRulesModeUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd() + cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd() + cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -90,7 +91,7 @@ func Test_ddosxDomainACLGeoIPRulesModeUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd() + cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd(nil) cmd.Flags().Set("mode", "whitelist") expectedRequest := ddosx.PatchACLGeoIPRulesModeRequest{ @@ -105,36 +106,32 @@ func Test_ddosxDomainACLGeoIPRulesModeUpdate(t *testing.T) { ddosxDomainACLGeoIPRulesModeUpdate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("InvalidMode_OutputsFatal", func(t *testing.T) { + t.Run("InvalidMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd() + cmd := ddosxDomainACLGeoIPRulesModeUpdateCmd(nil) cmd.Flags().Set("mode", "invalidmode") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.ACLGeoIPRulesMode") - }, func() { - ddosxDomainACLGeoIPRulesModeUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) - }) + err := ddosxDomainACLGeoIPRulesModeUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) - t.Run("PatchDomainACLGeoIPRulesMode_OutputsFatal", func(t *testing.T) { + t.Run("PatchDomainACLGeoIPRulesMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - service.EXPECT().PatchDomainACLGeoIPRulesMode("testdomain1.co.uk", gomock.Any()).Return(errors.New("test error")) - test_output.AssertFatalOutput(t, "Error updating domain ACL GeoIP rule filtering mode: test error\n", func() { - ddosxDomainACLGeoIPRulesModeUpdate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) - }) + err := ddosxDomainACLGeoIPRulesModeUpdate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - t.Run("GetDomainACLGeoIPRulesMode_OutputsFatal", func(t *testing.T) { + assert.Equal(t, "Error updating domain ACL GeoIP rule filtering mode: test error", err.Error()) + }) + t.Run("GetDomainACLGeoIPRulesMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -145,8 +142,8 @@ func Test_ddosxDomainACLGeoIPRulesModeUpdate(t *testing.T) { service.EXPECT().GetDomainACLGeoIPRulesMode("testdomain1.co.uk").Return(ddosx.ACLGeoIPRulesMode(""), errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving updated domain ACL GeoIP rule filtering mode: test error\n", func() { - ddosxDomainACLGeoIPRulesModeUpdate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLGeoIPRulesModeUpdate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving updated domain ACL GeoIP rule filtering mode: test error", err.Error()) }) } diff --git a/cmd/ddosx_domain_acl_geoip_test.go b/cmd/ddosx/ddosx_domain_acl_geoip_test.go similarity index 84% rename from cmd/ddosx_domain_acl_geoip_test.go rename to cmd/ddosx/ddosx_domain_acl_geoip_test.go index 491e9bc..cb0002e 100644 --- a/cmd/ddosx_domain_acl_geoip_test.go +++ b/cmd/ddosx/ddosx_domain_acl_geoip_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -14,14 +15,14 @@ import ( func Test_ddosxDomainACLGeoIPRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleListCmd() + cmd := ddosxDomainACLGeoIPRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleListCmd() + cmd := ddosxDomainACLGeoIPRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -41,7 +42,7 @@ func Test_ddosxDomainACLGeoIPRuleList(t *testing.T) { ddosxDomainACLGeoIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -49,12 +50,12 @@ func Test_ddosxDomainACLGeoIPRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainACLGeoIPRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLGeoIPRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainACLGeoIPRules_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainACLGeoIPRules_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -63,22 +64,22 @@ func Test_ddosxDomainACLGeoIPRuleList(t *testing.T) { service.EXPECT().GetDomainACLGeoIPRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.ACLGeoIPRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain ACL GeoIP rules: test error\n", func() { - ddosxDomainACLGeoIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLGeoIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain ACL GeoIP rules: test error", err.Error()) }) } func Test_ddosxDomainACLGeoIPRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleShowCmd() + cmd := ddosxDomainACLGeoIPRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleShowCmd() + cmd := ddosxDomainACLGeoIPRuleShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -86,7 +87,7 @@ func Test_ddosxDomainACLGeoIPRuleShowCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleShowCmd() + cmd := ddosxDomainACLGeoIPRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -122,14 +123,14 @@ func Test_ddosxDomainACLGeoIPRuleShow(t *testing.T) { func Test_ddosxDomainACLGeoIPRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleCreateCmd() + cmd := ddosxDomainACLGeoIPRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleCreateCmd() + cmd := ddosxDomainACLGeoIPRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -143,7 +144,7 @@ func Test_ddosxDomainACLGeoIPRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLGeoIPRuleCreateCmd() + cmd := ddosxDomainACLGeoIPRuleCreateCmd(nil) cmd.Flags().Set("code", "GB") expectedRequest := ddosx.CreateACLGeoIPRuleRequest{ @@ -158,7 +159,7 @@ func Test_ddosxDomainACLGeoIPRuleCreate(t *testing.T) { ddosxDomainACLGeoIPRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("CreateDomainACLGeoIPRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainACLGeoIPRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -167,17 +168,17 @@ func Test_ddosxDomainACLGeoIPRuleCreate(t *testing.T) { service.EXPECT().CreateDomainACLGeoIPRule("testdomain1.co.uk", gomock.Any()).Return("00000000-0000-0000-0000-000000000000", errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating domain ACL GeoIP rule: test error\n", func() { - ddosxDomainACLGeoIPRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLGeoIPRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain ACL GeoIP rule: test error", err.Error()) }) - t.Run("GetDomainACLGeoIPRuleError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainACLGeoIPRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLGeoIPRuleCreateCmd() + cmd := ddosxDomainACLGeoIPRuleCreateCmd(nil) cmd.Flags().Set("code", "GB") gomock.InOrder( @@ -185,22 +186,22 @@ func Test_ddosxDomainACLGeoIPRuleCreate(t *testing.T) { service.EXPECT().GetDomainACLGeoIPRule("testdomain1.co.uk", "00000000-0000-0000-0000-000000000000").Return(ddosx.ACLGeoIPRule{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new domain ACL GeoIP rule [00000000-0000-0000-0000-000000000000]: test error\n", func() { - ddosxDomainACLGeoIPRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLGeoIPRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving new domain ACL GeoIP rule [00000000-0000-0000-0000-000000000000]: test error", err.Error()) }) } func Test_ddosxDomainACLGeoIPRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleUpdateCmd() + cmd := ddosxDomainACLGeoIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleUpdateCmd() + cmd := ddosxDomainACLGeoIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -208,7 +209,7 @@ func Test_ddosxDomainACLGeoIPRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleUpdateCmd() + cmd := ddosxDomainACLGeoIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -222,7 +223,7 @@ func Test_ddosxDomainACLGeoIPRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLGeoIPRuleUpdateCmd() + cmd := ddosxDomainACLGeoIPRuleUpdateCmd(nil) cmd.Flags().Set("code", "GB") expectedRequest := ddosx.PatchACLGeoIPRuleRequest{ @@ -269,14 +270,14 @@ func Test_ddosxDomainACLGeoIPRuleUpdate(t *testing.T) { func Test_ddosxDomainACLGeoIPRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleDeleteCmd() + cmd := ddosxDomainACLGeoIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleDeleteCmd() + cmd := ddosxDomainACLGeoIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -284,7 +285,7 @@ func Test_ddosxDomainACLGeoIPRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLGeoIPRuleDeleteCmd() + cmd := ddosxDomainACLGeoIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_acl_ip.go b/cmd/ddosx/ddosx_domain_acl_ip.go similarity index 76% rename from cmd/ddosx_domain_acl_ip.go rename to cmd/ddosx/ddosx_domain_acl_ip.go index 25253b0..6dc9518 100644 --- a/cmd/ddosx_domain_acl_ip.go +++ b/cmd/ddosx/ddosx_domain_acl_ip.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -9,28 +9,29 @@ import ( "github.com/spf13/cobra" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainACLIPRuleRootCmd() *cobra.Command { +func ddosxDomainACLIPRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "ip", Short: "sub-commands relating to domain ACL IP rules", } // Child commands - cmd.AddCommand(ddosxDomainACLIPRuleListCmd()) - cmd.AddCommand(ddosxDomainACLIPRuleShowCmd()) - cmd.AddCommand(ddosxDomainACLIPRuleCreateCmd()) - cmd.AddCommand(ddosxDomainACLIPRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainACLIPRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainACLIPRuleListCmd(f)) + cmd.AddCommand(ddosxDomainACLIPRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainACLIPRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainACLIPRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainACLIPRuleDeleteCmd(f)) return cmd } -func ddosxDomainACLIPRuleListCmd() *cobra.Command { +func ddosxDomainACLIPRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists ACL IP rules", @@ -43,29 +44,27 @@ func ddosxDomainACLIPRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLIPRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLIPRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainACLIPRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLIPRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainACLIPRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain ACL IP rules: %s", err) - return + return fmt.Errorf("Error retrieving domain ACL IP rules: %s", err) } - outputDDoSXACLIPRules(domains) + return output.CommandOutput(cmd, OutputDDoSXACLIPRulesProvider(domains)) } -func ddosxDomainACLIPRuleShowCmd() *cobra.Command { +func ddosxDomainACLIPRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows domain ACL IP rules", @@ -81,13 +80,13 @@ func ddosxDomainACLIPRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLIPRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLIPRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainACLIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.ACLIPRule @@ -101,10 +100,10 @@ func ddosxDomainACLIPRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, ar rules = append(rules, rule) } - outputDDoSXACLIPRules(rules) + return output.CommandOutput(cmd, OutputDDoSXACLIPRulesProvider(rules)) } -func ddosxDomainACLIPRuleCreateCmd() *cobra.Command { +func ddosxDomainACLIPRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates ACL IP rules", @@ -118,7 +117,7 @@ func ddosxDomainACLIPRuleCreateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainACLIPRuleCreate(getClient().DDoSXService(), cmd, args) + return ddosxDomainACLIPRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -154,11 +153,10 @@ func ddosxDomainACLIPRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, return fmt.Errorf("Error retrieving new domain ACL IP rule [%s]: %s", id, err) } - outputDDoSXACLIPRules([]ddosx.ACLIPRule{rule}) - return nil + return output.CommandOutput(cmd, OutputDDoSXACLIPRulesProvider([]ddosx.ACLIPRule{rule})) } -func ddosxDomainACLIPRuleUpdateCmd() *cobra.Command { +func ddosxDomainACLIPRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates ACL IP rules", @@ -174,8 +172,8 @@ func ddosxDomainACLIPRuleUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLIPRuleUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainACLIPRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -186,7 +184,7 @@ func ddosxDomainACLIPRuleUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainACLIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainACLIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchACLIPRuleRequest{} if cmd.Flags().Changed("ip") { @@ -203,8 +201,7 @@ func ddosxDomainACLIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, mode, _ := cmd.Flags().GetString("mode") parsedMode, err := ddosx.ParseACLIPMode(mode) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest.Mode = parsedMode } @@ -226,10 +223,10 @@ func ddosxDomainACLIPRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, rules = append(rules, rule) } - outputDDoSXACLIPRules(rules) + return output.CommandOutput(cmd, OutputDDoSXACLIPRulesProvider(rules)) } -func ddosxDomainACLIPRuleDeleteCmd() *cobra.Command { +func ddosxDomainACLIPRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes ACL IP rules", @@ -246,7 +243,7 @@ func ddosxDomainACLIPRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainACLIPRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainACLIPRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_acl_ip_test.go b/cmd/ddosx/ddosx_domain_acl_ip_test.go similarity index 86% rename from cmd/ddosx_domain_acl_ip_test.go rename to cmd/ddosx/ddosx_domain_acl_ip_test.go index 40bbe3e..2d3e257 100644 --- a/cmd/ddosx_domain_acl_ip_test.go +++ b/cmd/ddosx/ddosx_domain_acl_ip_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -10,20 +10,21 @@ import ( "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" + "github.com/ukfast/sdk-go/pkg/connection" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) func Test_ddosxDomainACLIPRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleListCmd() + cmd := ddosxDomainACLIPRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleListCmd() + cmd := ddosxDomainACLIPRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -43,7 +44,7 @@ func Test_ddosxDomainACLIPRuleList(t *testing.T) { ddosxDomainACLIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -51,12 +52,12 @@ func Test_ddosxDomainACLIPRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainACLIPRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLIPRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -65,22 +66,22 @@ func Test_ddosxDomainACLIPRuleList(t *testing.T) { service.EXPECT().GetDomainACLIPRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.ACLIPRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain ACL IP rules: test error\n", func() { - ddosxDomainACLIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainACLIPRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain ACL IP rules: test error", err.Error()) }) } func Test_ddosxDomainACLIPRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleShowCmd() + cmd := ddosxDomainACLIPRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleShowCmd() + cmd := ddosxDomainACLIPRuleShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -88,7 +89,7 @@ func Test_ddosxDomainACLIPRuleShowCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleShowCmd() + cmd := ddosxDomainACLIPRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -124,14 +125,14 @@ func Test_ddosxDomainACLIPRuleShow(t *testing.T) { func Test_ddosxDomainACLIPRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -145,7 +146,7 @@ func Test_ddosxDomainACLIPRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) cmd.Flags().Set("ip", "1.2.3.4") cmd.Flags().Set("uri", "testuri") cmd.Flags().Set("mode", "allow") @@ -164,13 +165,13 @@ func Test_ddosxDomainACLIPRuleCreate(t *testing.T) { ddosxDomainACLIPRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("InvalidMode_OutputsFatal", func(t *testing.T) { + t.Run("InvalidMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) cmd.Flags().Set("ip", "1.2.3.4") cmd.Flags().Set("uri", "testuri") cmd.Flags().Set("mode", "invalidmode") @@ -179,13 +180,13 @@ func Test_ddosxDomainACLIPRuleCreate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("CreateDomainACLIPRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainACLIPRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) cmd.Flags().Set("ip", "1.2.3.4") cmd.Flags().Set("uri", "testuri") cmd.Flags().Set("mode", "allow") @@ -196,13 +197,13 @@ func Test_ddosxDomainACLIPRuleCreate(t *testing.T) { assert.Equal(t, "Error creating domain ACL IP rule: test error", err.Error()) }) - t.Run("CreateDomainACLIPRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainACLIPRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleCreateCmd() + cmd := ddosxDomainACLIPRuleCreateCmd(nil) cmd.Flags().Set("ip", "1.2.3.4") cmd.Flags().Set("uri", "testuri") cmd.Flags().Set("mode", "allow") @@ -219,14 +220,14 @@ func Test_ddosxDomainACLIPRuleCreate(t *testing.T) { func Test_ddosxDomainACLIPRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleUpdateCmd() + cmd := ddosxDomainACLIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleUpdateCmd() + cmd := ddosxDomainACLIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -234,7 +235,7 @@ func Test_ddosxDomainACLIPRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleUpdateCmd() + cmd := ddosxDomainACLIPRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -248,7 +249,7 @@ func Test_ddosxDomainACLIPRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleUpdateCmd() + cmd := ddosxDomainACLIPRuleUpdateCmd(nil) cmd.Flags().Set("mode", "deny") cmd.Flags().Set("uri", "testuri") cmd.Flags().Set("ip", "1.2.3.4") @@ -267,20 +268,18 @@ func Test_ddosxDomainACLIPRuleUpdate(t *testing.T) { ddosxDomainACLIPRuleUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) }) - t.Run("InvalidMode_OutputsFatal", func(t *testing.T) { + t.Run("InvalidMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainACLIPRuleUpdateCmd() + cmd := ddosxDomainACLIPRuleUpdateCmd(nil) cmd.Flags().Set("mode", "invalidmode") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.ACLIPMode") - }, func() { - ddosxDomainACLIPRuleUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) - }) + err := ddosxDomainACLIPRuleUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) t.Run("UpdateDomainACLIPRuleError_OutputsError", func(t *testing.T) { @@ -315,14 +314,14 @@ func Test_ddosxDomainACLIPRuleUpdate(t *testing.T) { func Test_ddosxDomainACLIPRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleDeleteCmd() + cmd := ddosxDomainACLIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleDeleteCmd() + cmd := ddosxDomainACLIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -330,7 +329,7 @@ func Test_ddosxDomainACLIPRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainACLIPRuleDeleteCmd() + cmd := ddosxDomainACLIPRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_cdn.go b/cmd/ddosx/ddosx_domain_cdn.go similarity index 70% rename from cmd/ddosx_domain_cdn.go rename to cmd/ddosx/ddosx_domain_cdn.go index 40c6773..c2e62a2 100644 --- a/cmd/ddosx_domain_cdn.go +++ b/cmd/ddosx/ddosx_domain_cdn.go @@ -1,31 +1,33 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainCDNRootCmd() *cobra.Command { +func ddosxDomainCDNRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "cdn", Short: "sub-commands relating to domain CDN", } // Child commands - cmd.AddCommand(ddosxDomainCDNEnableCmd()) - cmd.AddCommand(ddosxDomainCDNDisableCmd()) - cmd.AddCommand(ddosxDomainCDNPurgeCmd()) + cmd.AddCommand(ddosxDomainCDNEnableCmd(f)) + cmd.AddCommand(ddosxDomainCDNDisableCmd(f)) + cmd.AddCommand(ddosxDomainCDNPurgeCmd(f)) // Child root commands - cmd.AddCommand(ddosxDomainCDNRuleRootCmd()) + cmd.AddCommand(ddosxDomainCDNRuleRootCmd(f)) return cmd } -func ddosxDomainCDNEnableCmd() *cobra.Command { +func ddosxDomainCDNEnableCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "enable ...", Short: "Enables CDN for a domain", @@ -38,13 +40,13 @@ func ddosxDomainCDNEnableCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNEnable(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCDNEnable(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainCDNEnable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCDNEnable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var domains []ddosx.Domain for _, arg := range args { @@ -63,10 +65,10 @@ func ddosxDomainCDNEnable(service ddosx.DDoSXService, cmd *cobra.Command, args [ domains = append(domains, domain) } - outputDDoSXDomains(domains) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider(domains)) } -func ddosxDomainCDNDisableCmd() *cobra.Command { +func ddosxDomainCDNDisableCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "disable ...", Short: "Disables CDN for a domain", @@ -79,13 +81,13 @@ func ddosxDomainCDNDisableCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNDisable(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCDNDisable(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainCDNDisable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCDNDisable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var domains []ddosx.Domain for _, arg := range args { @@ -104,10 +106,10 @@ func ddosxDomainCDNDisable(service ddosx.DDoSXService, cmd *cobra.Command, args domains = append(domains, domain) } - outputDDoSXDomains(domains) + return output.CommandOutput(cmd, OutputDDoSXDomainsProvider(domains)) } -func ddosxDomainCDNPurgeCmd() *cobra.Command { +func ddosxDomainCDNPurgeCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "purge ", Short: "Purges CDN content for a domain", @@ -120,8 +122,8 @@ func ddosxDomainCDNPurgeCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNPurge(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCDNPurge(f.NewClient().DDoSXService(), cmd, args) }, } @@ -133,13 +135,15 @@ func ddosxDomainCDNPurgeCmd() *cobra.Command { return cmd } -func ddosxDomainCDNPurge(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCDNPurge(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { purgeRequest := ddosx.PurgeCDNRequest{} purgeRequest.RecordName, _ = cmd.Flags().GetString("record-name") purgeRequest.URI, _ = cmd.Flags().GetString("uri") err := service.PurgeDomainCDN(args[0], purgeRequest) if err != nil { - output.Fatalf("Error purging CDN content for domain: %s", err.Error()) + return fmt.Errorf("Error purging CDN content for domain: %s", err.Error()) } + + return nil } diff --git a/cmd/ddosx_domain_cdn_rule.go b/cmd/ddosx/ddosx_domain_cdn_rule.go similarity index 82% rename from cmd/ddosx_domain_cdn_rule.go rename to cmd/ddosx/ddosx_domain_cdn_rule.go index bda7922..41f7cdc 100644 --- a/cmd/ddosx_domain_cdn_rule.go +++ b/cmd/ddosx/ddosx_domain_cdn_rule.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -6,28 +6,29 @@ import ( "github.com/spf13/cobra" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainCDNRuleRootCmd() *cobra.Command { +func ddosxDomainCDNRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "rule", Short: "sub-commands relating to CDN rules", } // Child commands - cmd.AddCommand(ddosxDomainCDNRuleListCmd()) - cmd.AddCommand(ddosxDomainCDNRuleShowCmd()) - cmd.AddCommand(ddosxDomainCDNRuleCreateCmd()) - cmd.AddCommand(ddosxDomainCDNRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainCDNRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainCDNRuleListCmd(f)) + cmd.AddCommand(ddosxDomainCDNRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainCDNRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainCDNRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainCDNRuleDeleteCmd(f)) return cmd } -func ddosxDomainCDNRuleListCmd() *cobra.Command { +func ddosxDomainCDNRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists domain CDN rules", @@ -40,29 +41,27 @@ func ddosxDomainCDNRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCDNRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainCDNRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCDNRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainCDNRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving CDN rules: %s", err) - return + return fmt.Errorf("Error retrieving CDN rules: %s", err) } - outputDDoSXCDNRules(domains) + return output.CommandOutput(cmd, OutputDDoSXCDNRulesProvider(domains)) } -func ddosxDomainCDNRuleShowCmd() *cobra.Command { +func ddosxDomainCDNRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows CDN rules", @@ -78,13 +77,13 @@ func ddosxDomainCDNRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainCDNRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainCDNRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainCDNRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.CDNRule for _, arg := range args[1:] { rule, err := service.GetDomainCDNRule(args[0], arg) @@ -96,10 +95,10 @@ func ddosxDomainCDNRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args rules = append(rules, rule) } - outputDDoSXCDNRules(rules) + return output.CommandOutput(cmd, OutputDDoSXCDNRulesProvider(rules)) } -func ddosxDomainCDNRuleCreateCmd() *cobra.Command { +func ddosxDomainCDNRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates domain CDN rules", @@ -113,7 +112,7 @@ func ddosxDomainCDNRuleCreateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainCDNRuleCreate(getClient().DDoSXService(), cmd, args) + return ddosxDomainCDNRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -169,11 +168,10 @@ func ddosxDomainCDNRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, ar return fmt.Errorf("Error retrieving new CDN rule [%s]: %s", id, err.Error()) } - outputDDoSXCDNRules([]ddosx.CDNRule{rule}) - return nil + return output.CommandOutput(cmd, OutputDDoSXCDNRulesProvider([]ddosx.CDNRule{rule})) } -func ddosxDomainCDNRuleUpdateCmd() *cobra.Command { +func ddosxDomainCDNRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates CDN rules", @@ -190,7 +188,7 @@ func ddosxDomainCDNRuleUpdateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainCDNRuleUpdate(getClient().DDoSXService(), cmd, args) + return ddosxDomainCDNRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -262,11 +260,11 @@ func ddosxDomainCDNRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, ar rules = append(rules, rule) } - outputDDoSXCDNRules(rules) + return output.CommandOutput(cmd, OutputDDoSXCDNRulesProvider(rules)) return nil } -func ddosxDomainCDNRuleDeleteCmd() *cobra.Command { +func ddosxDomainCDNRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes CDN rules", @@ -283,7 +281,7 @@ func ddosxDomainCDNRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainCDNRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainCDNRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_cdn_rule_test.go b/cmd/ddosx/ddosx_domain_cdn_rule_test.go similarity index 86% rename from cmd/ddosx_domain_cdn_rule_test.go rename to cmd/ddosx/ddosx_domain_cdn_rule_test.go index 06997ee..95eafc6 100644 --- a/cmd/ddosx_domain_cdn_rule_test.go +++ b/cmd/ddosx/ddosx_domain_cdn_rule_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -15,14 +15,14 @@ import ( func Test_ddosxDomainCDNRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainCDNRuleListCmd() + cmd := ddosxDomainCDNRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleListCmd() + cmd := ddosxDomainCDNRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -42,7 +42,7 @@ func Test_ddosxDomainCDNRuleList(t *testing.T) { ddosxDomainCDNRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -50,12 +50,12 @@ func Test_ddosxDomainCDNRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainCDNRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainCDNRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -64,28 +64,28 @@ func Test_ddosxDomainCDNRuleList(t *testing.T) { service.EXPECT().GetDomainCDNRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.CDNRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving CDN rules: test error\n", func() { - ddosxDomainCDNRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainCDNRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving CDN rules: test error", err.Error()) }) } func Test_ddosxDomainCDNRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainCDNRuleShowCmd().Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + err := ddosxDomainCDNRuleShowCmd(nil).Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainCDNRuleShowCmd().Args(nil, []string{}) + err := ddosxDomainCDNRuleShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) }) t.Run("MissingCDNRule_Error", func(t *testing.T) { - err := ddosxDomainCDNRuleShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainCDNRuleShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) assert.Equal(t, "Missing rule", err.Error()) @@ -134,14 +134,14 @@ func Test_ddosxDomainCDNRuleShow(t *testing.T) { func Test_ddosxDomainCDNRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -155,7 +155,7 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("uri", "test.html") cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("mime-type", "test/*") @@ -176,12 +176,12 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { ddosxDomainCDNRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("ParseCDNRuleCacheControlError_OutputsFatal", func(t *testing.T) { + t.Run("ParseCDNRuleCacheControlError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("cache-control", "invalid") err := ddosxDomainCDNRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) @@ -189,12 +189,12 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("ParseCDNRuleTypeError_OutputsFatal", func(t *testing.T) { + t.Run("ParseCDNRuleTypeError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("type", "invalid") @@ -203,12 +203,12 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("ParseDurationError_OutputsFatal", func(t *testing.T) { + t.Run("ParseDurationError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("type", "per-uri") cmd.Flags().Set("cache-control-duration", "invalid") @@ -218,13 +218,13 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("CreateDomainCDNRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainCDNRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("uri", "test.html") cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("mime-type", "test/*") @@ -237,13 +237,13 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { assert.Equal(t, "Error creating CDN rule: test error", err.Error()) }) - t.Run("GetDomainCDNRuleError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainCDNRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleCreateCmd() + cmd := ddosxDomainCDNRuleCreateCmd(nil) cmd.Flags().Set("uri", "test.html") cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("mime-type", "test/*") @@ -262,14 +262,14 @@ func Test_ddosxDomainCDNRuleCreate(t *testing.T) { func Test_ddosxDomainCDNRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -277,7 +277,7 @@ func Test_ddosxDomainCDNRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -291,7 +291,7 @@ func Test_ddosxDomainCDNRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) cmd.Flags().Set("uri", "test.html") cmd.Flags().Set("cache-control", "custom") cmd.Flags().Set("mime-type", "test/*") @@ -312,12 +312,12 @@ func Test_ddosxDomainCDNRuleUpdate(t *testing.T) { ddosxDomainCDNRuleUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) }) - t.Run("ParseCDNRuleCacheControlError_OutputsFatal", func(t *testing.T) { + t.Run("ParseCDNRuleCacheControlError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) cmd.Flags().Set("cache-control", "invalid") err := ddosxDomainCDNRuleUpdate(service, cmd, []string{"testdomain1.co.uk"}) @@ -325,12 +325,12 @@ func Test_ddosxDomainCDNRuleUpdate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("ParseCDNRuleTypeError_OutputsFatal", func(t *testing.T) { + t.Run("ParseCDNRuleTypeError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) cmd.Flags().Set("type", "invalid") err := ddosxDomainCDNRuleUpdate(service, cmd, []string{"testdomain1.co.uk"}) @@ -338,12 +338,12 @@ func Test_ddosxDomainCDNRuleUpdate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("ParseDurationError_OutputsFatal", func(t *testing.T) { + t.Run("ParseDurationError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCDNRuleUpdateCmd() + cmd := ddosxDomainCDNRuleUpdateCmd(nil) cmd.Flags().Set("cache-control-duration", "invalid") err := ddosxDomainCDNRuleUpdate(service, cmd, []string{"testdomain1.co.uk"}) @@ -383,14 +383,14 @@ func Test_ddosxDomainCDNRuleUpdate(t *testing.T) { func Test_ddosxDomainCDNRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainCDNRuleDeleteCmd() + cmd := ddosxDomainCDNRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleDeleteCmd() + cmd := ddosxDomainCDNRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -398,7 +398,7 @@ func Test_ddosxDomainCDNRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainCDNRuleDeleteCmd() + cmd := ddosxDomainCDNRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_cdn_test.go b/cmd/ddosx/ddosx_domain_cdn_test.go similarity index 87% rename from cmd/ddosx_domain_cdn_test.go rename to cmd/ddosx/ddosx_domain_cdn_test.go index 0af1572..06d422a 100644 --- a/cmd/ddosx_domain_cdn_test.go +++ b/cmd/ddosx/ddosx_domain_cdn_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_ddosxDomainCDNEnableCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainCDNEnableCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainCDNEnableCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainCDNEnableCmd().Args(nil, []string{}) + err := ddosxDomainCDNEnableCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -70,13 +70,13 @@ func Test_ddosxDomainCDNEnable(t *testing.T) { func Test_ddosxDomainCDNDisableCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainCDNDisableCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainCDNDisableCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainCDNDisableCmd().Args(nil, []string{}) + err := ddosxDomainCDNDisableCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -126,13 +126,13 @@ func Test_ddosxDomainCDNDisable(t *testing.T) { func Test_ddosxDomainCDNPurgeCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainCDNPurgeCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainCDNPurgeCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainCDNPurgeCmd().Args(nil, []string{}) + err := ddosxDomainCDNPurgeCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -144,7 +144,7 @@ func Test_ddosxDomainCDNPurge(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - cmd := ddosxDomainCDNPurgeCmd() + cmd := ddosxDomainCDNPurgeCmd(nil) cmd.Flags().Set("record-name", "example.com") cmd.Flags().Set("uri", "test.html") @@ -160,11 +160,11 @@ func Test_ddosxDomainCDNPurge(t *testing.T) { ddosxDomainCDNPurge(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("DeleteDomainCDNConfiguration_OutputsFatal", func(t *testing.T) { + t.Run("DeleteDomainCDNConfiguration_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - cmd := ddosxDomainCDNPurgeCmd() + cmd := ddosxDomainCDNPurgeCmd(nil) cmd.Flags().Set("record-name", "example.com") cmd.Flags().Set("uri", "test.html") @@ -172,8 +172,8 @@ func Test_ddosxDomainCDNPurge(t *testing.T) { service.EXPECT().PurgeDomainCDN("testdomain1.co.uk", gomock.Any()).Return(errors.New("test error")) - test_output.AssertFatalOutput(t, "Error purging CDN content for domain: test error\n", func() { - ddosxDomainCDNPurge(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainCDNPurge(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error purging CDN content for domain: test error", err.Error()) }) } diff --git a/cmd/ddosx_domain_hsts.go b/cmd/ddosx/ddosx_domain_hsts.go similarity index 70% rename from cmd/ddosx_domain_hsts.go rename to cmd/ddosx/ddosx_domain_hsts.go index 373d92a..71cdadf 100644 --- a/cmd/ddosx_domain_hsts.go +++ b/cmd/ddosx/ddosx_domain_hsts.go @@ -1,31 +1,32 @@ -package cmd +package ddosx import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainHSTSRootCmd() *cobra.Command { +func ddosxDomainHSTSRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "hsts", Short: "sub-commands relating to domain HSTS", } // Child commands - cmd.AddCommand(ddosxDomainHSTSShowCmd()) - cmd.AddCommand(ddosxDomainHSTSEnableCmd()) - cmd.AddCommand(ddosxDomainHSTSDisableCmd()) + cmd.AddCommand(ddosxDomainHSTSShowCmd(f)) + cmd.AddCommand(ddosxDomainHSTSEnableCmd(f)) + cmd.AddCommand(ddosxDomainHSTSDisableCmd(f)) // Child root commands - cmd.AddCommand(ddosxDomainHSTSRuleRootCmd()) + cmd.AddCommand(ddosxDomainHSTSRuleRootCmd(f)) return cmd } -func ddosxDomainHSTSShowCmd() *cobra.Command { +func ddosxDomainHSTSShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows HSTS for a domain", @@ -38,13 +39,13 @@ func ddosxDomainHSTSShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainHSTSShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var configurations []ddosx.HSTSConfiguration for _, arg := range args { @@ -57,10 +58,10 @@ func ddosxDomainHSTSShow(service ddosx.DDoSXService, cmd *cobra.Command, args [] configurations = append(configurations, configuration) } - outputDDoSXHSTSConfiguration(configurations) + return output.CommandOutput(cmd, OutputDDoSXHSTSConfigurationsProvider(configurations)) } -func ddosxDomainHSTSEnableCmd() *cobra.Command { +func ddosxDomainHSTSEnableCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "enable ...", Short: "Enables HSTS for a domain", @@ -73,13 +74,13 @@ func ddosxDomainHSTSEnableCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSEnable(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSEnable(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainHSTSEnable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSEnable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var configurations []ddosx.HSTSConfiguration for _, arg := range args { @@ -98,10 +99,10 @@ func ddosxDomainHSTSEnable(service ddosx.DDoSXService, cmd *cobra.Command, args configurations = append(configurations, configuration) } - outputDDoSXHSTSConfiguration(configurations) + return output.CommandOutput(cmd, OutputDDoSXHSTSConfigurationsProvider(configurations)) } -func ddosxDomainHSTSDisableCmd() *cobra.Command { +func ddosxDomainHSTSDisableCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "disable ...", Short: "Disables HSTS for a domain", @@ -114,13 +115,13 @@ func ddosxDomainHSTSDisableCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSDisable(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSDisable(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainHSTSDisable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSDisable(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var configurations []ddosx.HSTSConfiguration for _, arg := range args { @@ -139,5 +140,5 @@ func ddosxDomainHSTSDisable(service ddosx.DDoSXService, cmd *cobra.Command, args configurations = append(configurations, configuration) } - outputDDoSXHSTSConfiguration(configurations) + return output.CommandOutput(cmd, OutputDDoSXHSTSConfigurationsProvider(configurations)) } diff --git a/cmd/ddosx_domain_hsts_rule.go b/cmd/ddosx/ddosx_domain_hsts_rule.go similarity index 77% rename from cmd/ddosx_domain_hsts_rule.go rename to cmd/ddosx/ddosx_domain_hsts_rule.go index ebbf927..3e1d1b5 100644 --- a/cmd/ddosx_domain_hsts_rule.go +++ b/cmd/ddosx/ddosx_domain_hsts_rule.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -6,28 +6,29 @@ import ( "github.com/spf13/cobra" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainHSTSRuleRootCmd() *cobra.Command { +func ddosxDomainHSTSRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "rule", Short: "sub-commands relating to HSTS rules", } // Child commands - cmd.AddCommand(ddosxDomainHSTSRuleListCmd()) - cmd.AddCommand(ddosxDomainHSTSRuleShowCmd()) - cmd.AddCommand(ddosxDomainHSTSRuleCreateCmd()) - cmd.AddCommand(ddosxDomainHSTSRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainHSTSRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainHSTSRuleListCmd(f)) + cmd.AddCommand(ddosxDomainHSTSRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainHSTSRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainHSTSRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainHSTSRuleDeleteCmd(f)) return cmd } -func ddosxDomainHSTSRuleListCmd() *cobra.Command { +func ddosxDomainHSTSRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists domain HSTS rules", @@ -40,29 +41,27 @@ func ddosxDomainHSTSRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainHSTSRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainHSTSRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving HSTS rules: %s", err) - return + return fmt.Errorf("Error retrieving HSTS rules: %s", err) } - outputDDoSXHSTSRules(domains) + return output.CommandOutput(cmd, OutputDDoSXHSTSRulesProvider(domains)) } -func ddosxDomainHSTSRuleShowCmd() *cobra.Command { +func ddosxDomainHSTSRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows HSTS rules", @@ -78,13 +77,13 @@ func ddosxDomainHSTSRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainHSTSRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.HSTSRule for _, arg := range args[1:] { rule, err := service.GetDomainHSTSRule(args[0], arg) @@ -96,10 +95,10 @@ func ddosxDomainHSTSRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, arg rules = append(rules, rule) } - outputDDoSXHSTSRules(rules) + return output.CommandOutput(cmd, OutputDDoSXHSTSRulesProvider(rules)) } -func ddosxDomainHSTSRuleCreateCmd() *cobra.Command { +func ddosxDomainHSTSRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates domain HSTS rules", @@ -113,7 +112,7 @@ func ddosxDomainHSTSRuleCreateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainHSTSRuleCreate(getClient().DDoSXService(), cmd, args) + return ddosxDomainHSTSRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -155,11 +154,10 @@ func ddosxDomainHSTSRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, a return fmt.Errorf("Error retrieving new HSTS rule [%s]: %s", id, err.Error()) } - outputDDoSXHSTSRules([]ddosx.HSTSRule{rule}) - return nil + return output.CommandOutput(cmd, OutputDDoSXHSTSRulesProvider([]ddosx.HSTSRule{rule})) } -func ddosxDomainHSTSRuleUpdateCmd() *cobra.Command { +func ddosxDomainHSTSRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates HSTS rules", @@ -175,8 +173,8 @@ func ddosxDomainHSTSRuleUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSRuleUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainHSTSRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -187,7 +185,7 @@ func ddosxDomainHSTSRuleUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainHSTSRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainHSTSRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchHSTSRuleRequest{} if cmd.Flags().Changed("max-age") { @@ -216,16 +214,16 @@ func ddosxDomainHSTSRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, a rule, err := service.GetDomainHSTSRule(args[0], arg) if err != nil { output.OutputWithErrorLevelf("Error retrieving updated HSTS rule [%s]: %s", arg, err.Error()) - return + continue } rules = append(rules, rule) } - outputDDoSXHSTSRules(rules) + return output.CommandOutput(cmd, OutputDDoSXHSTSRulesProvider(rules)) } -func ddosxDomainHSTSRuleDeleteCmd() *cobra.Command { +func ddosxDomainHSTSRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes HSTS rules", @@ -242,7 +240,7 @@ func ddosxDomainHSTSRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainHSTSRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainHSTSRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_hsts_rule_test.go b/cmd/ddosx/ddosx_domain_hsts_rule_test.go similarity index 87% rename from cmd/ddosx_domain_hsts_rule_test.go rename to cmd/ddosx/ddosx_domain_hsts_rule_test.go index 1156c77..0c075b0 100644 --- a/cmd/ddosx_domain_hsts_rule_test.go +++ b/cmd/ddosx/ddosx_domain_hsts_rule_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -16,14 +16,14 @@ import ( func Test_ddosxDomainHSTSRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleListCmd() + cmd := ddosxDomainHSTSRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleListCmd() + cmd := ddosxDomainHSTSRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -43,7 +43,7 @@ func Test_ddosxDomainHSTSRuleList(t *testing.T) { ddosxDomainHSTSRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -51,12 +51,12 @@ func Test_ddosxDomainHSTSRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainHSTSRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainHSTSRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -65,28 +65,28 @@ func Test_ddosxDomainHSTSRuleList(t *testing.T) { service.EXPECT().GetDomainHSTSRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.HSTSRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving HSTS rules: test error\n", func() { - ddosxDomainHSTSRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainHSTSRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving HSTS rules: test error", err.Error()) }) } func Test_ddosxDomainHSTSRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainHSTSRuleShowCmd().Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + err := ddosxDomainHSTSRuleShowCmd(nil).Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainHSTSRuleShowCmd().Args(nil, []string{}) + err := ddosxDomainHSTSRuleShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) }) t.Run("MissingHSTSRule_Error", func(t *testing.T) { - err := ddosxDomainHSTSRuleShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainHSTSRuleShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) assert.Equal(t, "Missing rule", err.Error()) @@ -135,14 +135,14 @@ func Test_ddosxDomainHSTSRuleShow(t *testing.T) { func Test_ddosxDomainHSTSRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -156,7 +156,7 @@ func Test_ddosxDomainHSTSRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) cmd.Flags().Set("type", "record") cmd.Flags().Set("record-name", "example.com") @@ -175,12 +175,12 @@ func Test_ddosxDomainHSTSRuleCreate(t *testing.T) { ddosxDomainHSTSRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("ParseHSTSRuleTypeError_OutputsFatal", func(t *testing.T) { + t.Run("ParseHSTSRuleTypeError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) cmd.Flags().Set("type", "invalid") err := ddosxDomainHSTSRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) @@ -188,13 +188,13 @@ func Test_ddosxDomainHSTSRuleCreate(t *testing.T) { assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("CreateDomainHSTSRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainHSTSRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) cmd.Flags().Set("type", "record") service.EXPECT().CreateDomainHSTSRule("testdomain1.co.uk", gomock.Any()).Return("", errors.New("test error")) @@ -204,13 +204,13 @@ func Test_ddosxDomainHSTSRuleCreate(t *testing.T) { assert.Equal(t, "Error creating HSTS rule: test error", err.Error()) }) - t.Run("GetDomainHSTSRuleError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainHSTSRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainHSTSRuleCreateCmd() + cmd := ddosxDomainHSTSRuleCreateCmd(nil) cmd.Flags().Set("type", "record") gomock.InOrder( @@ -226,14 +226,14 @@ func Test_ddosxDomainHSTSRuleCreate(t *testing.T) { func Test_ddosxDomainHSTSRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleUpdateCmd() + cmd := ddosxDomainHSTSRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleUpdateCmd() + cmd := ddosxDomainHSTSRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -241,7 +241,7 @@ func Test_ddosxDomainHSTSRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleUpdateCmd() + cmd := ddosxDomainHSTSRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -255,7 +255,7 @@ func Test_ddosxDomainHSTSRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainHSTSRuleUpdateCmd() + cmd := ddosxDomainHSTSRuleUpdateCmd(nil) cmd.Flags().Set("max-age", "300") cmd.Flags().Set("preload", "true") cmd.Flags().Set("include-subdomains", "true") @@ -306,14 +306,14 @@ func Test_ddosxDomainHSTSRuleUpdate(t *testing.T) { func Test_ddosxDomainHSTSRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleDeleteCmd() + cmd := ddosxDomainHSTSRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleDeleteCmd() + cmd := ddosxDomainHSTSRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -321,7 +321,7 @@ func Test_ddosxDomainHSTSRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainHSTSRuleDeleteCmd() + cmd := ddosxDomainHSTSRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_hsts_test.go b/cmd/ddosx/ddosx_domain_hsts_test.go similarity index 93% rename from cmd/ddosx_domain_hsts_test.go rename to cmd/ddosx/ddosx_domain_hsts_test.go index 9cbc165..c036e28 100644 --- a/cmd/ddosx_domain_hsts_test.go +++ b/cmd/ddosx/ddosx_domain_hsts_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_ddosxDomainHSTSEnableCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainHSTSEnableCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainHSTSEnableCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainHSTSEnableCmd().Args(nil, []string{}) + err := ddosxDomainHSTSEnableCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -70,13 +70,13 @@ func Test_ddosxDomainHSTSEnable(t *testing.T) { func Test_ddosxDomainHSTSDisableCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainHSTSDisableCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainHSTSDisableCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainHSTSDisableCmd().Args(nil, []string{}) + err := ddosxDomainHSTSDisableCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/ddosx_domain_property.go b/cmd/ddosx/ddosx_domain_property.go similarity index 71% rename from cmd/ddosx_domain_property.go rename to cmd/ddosx/ddosx_domain_property.go index 6701230..8a96b1d 100644 --- a/cmd/ddosx_domain_property.go +++ b/cmd/ddosx/ddosx_domain_property.go @@ -1,29 +1,31 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainPropertyRootCmd() *cobra.Command { +func ddosxDomainPropertyRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "property", Short: "sub-commands relating to domain properties", } // Child commands - cmd.AddCommand(ddosxDomainPropertyListCmd()) - cmd.AddCommand(ddosxDomainPropertyShowCmd()) - cmd.AddCommand(ddosxDomainPropertyUpdateCmd()) + cmd.AddCommand(ddosxDomainPropertyListCmd(f)) + cmd.AddCommand(ddosxDomainPropertyShowCmd(f)) + cmd.AddCommand(ddosxDomainPropertyUpdateCmd(f)) return cmd } -func ddosxDomainPropertyListCmd() *cobra.Command { +func ddosxDomainPropertyListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list ", Short: "Lists domain properties", @@ -36,8 +38,8 @@ func ddosxDomainPropertyListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainPropertyList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainPropertyList(f.NewClient().DDoSXService(), cmd, args) }, } @@ -46,11 +48,10 @@ func ddosxDomainPropertyListCmd() *cobra.Command { return cmd } -func ddosxDomainPropertyList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainPropertyList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -60,14 +61,13 @@ func ddosxDomainPropertyList(service ddosx.DDoSXService, cmd *cobra.Command, arg properties, err := service.GetDomainProperties(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain properties: %s", err) - return + return fmt.Errorf("Error retrieving domain properties: %s", err) } - outputDDoSXDomainProperties(properties) + return output.CommandOutput(cmd, OutputDDoSXDomainPropertiesProvider(properties)) } -func ddosxDomainPropertyShowCmd() *cobra.Command { +func ddosxDomainPropertyShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ", Short: "Shows domain properties", @@ -83,13 +83,13 @@ func ddosxDomainPropertyShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainPropertyShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainPropertyShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainPropertyShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainPropertyShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var properties []ddosx.DomainProperty @@ -103,10 +103,10 @@ func ddosxDomainPropertyShow(service ddosx.DDoSXService, cmd *cobra.Command, arg properties = append(properties, property) } - outputDDoSXDomainProperties(properties) + return output.CommandOutput(cmd, OutputDDoSXDomainPropertiesProvider(properties)) } -func ddosxDomainPropertyUpdateCmd() *cobra.Command { +func ddosxDomainPropertyUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates domain properties", @@ -122,8 +122,8 @@ func ddosxDomainPropertyUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainPropertyUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainPropertyUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -132,7 +132,7 @@ func ddosxDomainPropertyUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainPropertyUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainPropertyUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var properties []ddosx.DomainProperty updateRequest := ddosx.PatchDomainPropertyRequest{} @@ -158,5 +158,5 @@ func ddosxDomainPropertyUpdate(service ddosx.DDoSXService, cmd *cobra.Command, a properties = append(properties, property) } - outputDDoSXDomainProperties(properties) + return output.CommandOutput(cmd, OutputDDoSXDomainPropertiesProvider(properties)) } diff --git a/cmd/ddosx_domain_property_test.go b/cmd/ddosx/ddosx_domain_property_test.go similarity index 85% rename from cmd/ddosx_domain_property_test.go rename to cmd/ddosx/ddosx_domain_property_test.go index 615101c..5d77d41 100644 --- a/cmd/ddosx_domain_property_test.go +++ b/cmd/ddosx/ddosx_domain_property_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -9,6 +9,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -16,14 +17,14 @@ import ( func Test_ddosxDomainPropertyListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainPropertyListCmd() + cmd := ddosxDomainPropertyListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainPropertyListCmd() + cmd := ddosxDomainPropertyListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -48,7 +49,7 @@ func Test_ddosxDomainPropertyList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainPropertyListCmd() + cmd := ddosxDomainPropertyListCmd(nil) cmd.Flags().Set("name", "testproperty1") expectedParams := connection.APIRequestParameters{ @@ -66,7 +67,7 @@ func Test_ddosxDomainPropertyList(t *testing.T) { ddosxDomainPropertyList(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -74,12 +75,12 @@ func Test_ddosxDomainPropertyList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainPropertyList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainPropertyList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainPropertiesError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainPropertiesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -88,28 +89,28 @@ func Test_ddosxDomainPropertyList(t *testing.T) { service.EXPECT().GetDomainProperties("testdomain1.co.uk", gomock.Any()).Return([]ddosx.DomainProperty{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain properties: test error\n", func() { - ddosxDomainPropertyList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainPropertyList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain properties: test error", err.Error()) }) } func Test_ddosxDomainPropertyShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainPropertyShowCmd().Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + err := ddosxDomainPropertyShowCmd(nil).Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainPropertyShowCmd().Args(nil, []string{}) + err := ddosxDomainPropertyShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) }) t.Run("MissingDomainProperty_Error", func(t *testing.T) { - err := ddosxDomainPropertyShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainPropertyShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) assert.Equal(t, "Missing domain property", err.Error()) @@ -158,20 +159,20 @@ func Test_ddosxDomainPropertyShow(t *testing.T) { func Test_ddosxDomainPropertyUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainPropertyUpdateCmd().Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) + err := ddosxDomainPropertyUpdateCmd(nil).Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - err := ddosxDomainPropertyUpdateCmd().Args(nil, []string{}) + err := ddosxDomainPropertyUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) }) t.Run("MissingDomainProperty_Error", func(t *testing.T) { - err := ddosxDomainPropertyUpdateCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainPropertyUpdateCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) assert.Equal(t, "Missing domain property", err.Error()) @@ -184,7 +185,7 @@ func Test_ddosxDomainPropertyUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainPropertyUpdateCmd() + cmd := ddosxDomainPropertyUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") gomock.InOrder( diff --git a/cmd/ddosx_domain_record.go b/cmd/ddosx/ddosx_domain_record.go similarity index 75% rename from cmd/ddosx_domain_record.go rename to cmd/ddosx/ddosx_domain_record.go index 28490cf..1994e8c 100644 --- a/cmd/ddosx_domain_record.go +++ b/cmd/ddosx/ddosx_domain_record.go @@ -1,31 +1,33 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainRecordRootCmd() *cobra.Command { +func ddosxDomainRecordRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "record", Short: "sub-commands relating to domain records", } // Child commands - cmd.AddCommand(ddosxDomainRecordListCmd()) - cmd.AddCommand(ddosxDomainRecordShowCmd()) - cmd.AddCommand(ddosxDomainRecordCreateCmd()) - cmd.AddCommand(ddosxDomainRecordUpdateCmd()) - cmd.AddCommand(ddosxDomainRecordDeleteCmd()) + cmd.AddCommand(ddosxDomainRecordListCmd(f)) + cmd.AddCommand(ddosxDomainRecordShowCmd(f)) + cmd.AddCommand(ddosxDomainRecordCreateCmd(f)) + cmd.AddCommand(ddosxDomainRecordUpdateCmd(f)) + cmd.AddCommand(ddosxDomainRecordDeleteCmd(f)) return cmd } -func ddosxDomainRecordListCmd() *cobra.Command { +func ddosxDomainRecordListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists domain records", @@ -38,29 +40,27 @@ func ddosxDomainRecordListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainRecordList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainRecordList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainRecordList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainRecordList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } records, err := service.GetDomainRecords(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain records: %s", err) - return + return fmt.Errorf("Error retrieving domain records: %s", err) } - outputDDoSXRecords(records) + return output.CommandOutput(cmd, OutputDDoSXRecordsProvider(records)) } -func ddosxDomainRecordShowCmd() *cobra.Command { +func ddosxDomainRecordShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows domain records", @@ -76,13 +76,13 @@ func ddosxDomainRecordShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainRecordShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainRecordShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainRecordShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainRecordShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var records []ddosx.Record @@ -96,10 +96,10 @@ func ddosxDomainRecordShow(service ddosx.DDoSXService, cmd *cobra.Command, args records = append(records, record) } - outputDDoSXRecords(records) + return output.CommandOutput(cmd, OutputDDoSXRecordsProvider(records)) } -func ddosxDomainRecordCreateCmd() *cobra.Command { +func ddosxDomainRecordCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a domain record", @@ -112,8 +112,8 @@ func ddosxDomainRecordCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainRecordCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainRecordCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -130,7 +130,7 @@ func ddosxDomainRecordCreateCmd() *cobra.Command { return cmd } -func ddosxDomainRecordCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainRecordCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { name, _ := cmd.Flags().GetString("name") recordType, _ := cmd.Flags().GetString("type") content, _ := cmd.Flags().GetString("content") @@ -147,20 +147,18 @@ func ddosxDomainRecordCreate(service ddosx.DDoSXService, cmd *cobra.Command, arg id, err := service.CreateDomainRecord(args[0], createRequest) if err != nil { - output.Fatalf("Error creating domain record: %s", err) - return + return fmt.Errorf("Error creating domain record: %s", err) } record, err := service.GetDomainRecord(args[0], id) if err != nil { - output.Fatalf("Error retrieving new domain record [%s]: %s", id, err) - return + return fmt.Errorf("Error retrieving new domain record [%s]: %s", id, err) } - outputDDoSXRecords([]ddosx.Record{record}) + return output.CommandOutput(cmd, OutputDDoSXRecordsProvider([]ddosx.Record{record})) } -func ddosxDomainRecordUpdateCmd() *cobra.Command { +func ddosxDomainRecordUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a domain record", @@ -176,8 +174,8 @@ func ddosxDomainRecordUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainRecordUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainRecordUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -191,7 +189,7 @@ func ddosxDomainRecordUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainRecordUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainRecordUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchRecordRequest{} if cmd.Flags().Changed("name") { @@ -228,10 +226,10 @@ func ddosxDomainRecordUpdate(service ddosx.DDoSXService, cmd *cobra.Command, arg records = append(records, record) } - outputDDoSXRecords(records) + return output.CommandOutput(cmd, OutputDDoSXRecordsProvider(records)) } -func ddosxDomainRecordDeleteCmd() *cobra.Command { +func ddosxDomainRecordDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a domain record", @@ -248,7 +246,7 @@ func ddosxDomainRecordDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainRecordDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainRecordDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_record_test.go b/cmd/ddosx/ddosx_domain_record_test.go similarity index 85% rename from cmd/ddosx_domain_record_test.go rename to cmd/ddosx/ddosx_domain_record_test.go index c039536..2f4f67e 100644 --- a/cmd/ddosx_domain_record_test.go +++ b/cmd/ddosx/ddosx_domain_record_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -14,14 +15,14 @@ import ( func Test_ddosxDomainRecordListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainRecordListCmd() + cmd := ddosxDomainRecordListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainRecordListCmd() + cmd := ddosxDomainRecordListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -41,7 +42,7 @@ func Test_ddosxDomainRecordList(t *testing.T) { ddosxDomainRecordList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -49,12 +50,12 @@ func Test_ddosxDomainRecordList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainRecordList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainRecordList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainRecordsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainRecordsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -63,22 +64,22 @@ func Test_ddosxDomainRecordList(t *testing.T) { service.EXPECT().GetDomainRecords("testdomain1.co.uk", gomock.Any()).Return([]ddosx.Record{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain records: test error\n", func() { - ddosxDomainRecordList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainRecordList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain records: test error", err.Error()) }) } func Test_ddosxDomainRecordShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainRecordShowCmd() + cmd := ddosxDomainRecordShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainRecordShowCmd() + cmd := ddosxDomainRecordShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -86,7 +87,7 @@ func Test_ddosxDomainRecordShowCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := ddosxDomainRecordShowCmd() + cmd := ddosxDomainRecordShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -122,14 +123,14 @@ func Test_ddosxDomainRecordShow(t *testing.T) { func Test_ddosxDomainRecordCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainRecordCreateCmd() + cmd := ddosxDomainRecordCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainRecordCreateCmd() + cmd := ddosxDomainRecordCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -143,7 +144,7 @@ func Test_ddosxDomainRecordCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainRecordCreateCmd() + cmd := ddosxDomainRecordCreateCmd(nil) cmd.Flags().Set("name", "sub.testdomain1.co.uk") expectedRequest := ddosx.CreateRecordRequest{ @@ -158,7 +159,7 @@ func Test_ddosxDomainRecordCreate(t *testing.T) { ddosxDomainRecordCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("CreateDomainRecordError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -167,12 +168,12 @@ func Test_ddosxDomainRecordCreate(t *testing.T) { service.EXPECT().CreateDomainRecord("testdomain1.co.uk", gomock.Any()).Return("00000000-0000-0000-0000-000000000000", errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating domain record: test error\n", func() { - ddosxDomainRecordCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainRecordCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain record: test error", err.Error()) }) - t.Run("GetDomainRecordError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -184,22 +185,22 @@ func Test_ddosxDomainRecordCreate(t *testing.T) { service.EXPECT().GetDomainRecord("testdomain1.co.uk", "00000000-0000-0000-0000-000000000000").Return(ddosx.Record{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new domain record [00000000-0000-0000-0000-000000000000]: test error\n", func() { - ddosxDomainRecordCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainRecordCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving new domain record [00000000-0000-0000-0000-000000000000]: test error", err.Error()) }) } func Test_ddosxDomainRecordUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainRecordUpdateCmd() + cmd := ddosxDomainRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainRecordUpdateCmd() + cmd := ddosxDomainRecordUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -207,7 +208,7 @@ func Test_ddosxDomainRecordUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := ddosxDomainRecordUpdateCmd() + cmd := ddosxDomainRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -221,7 +222,7 @@ func Test_ddosxDomainRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainRecordUpdateCmd() + cmd := ddosxDomainRecordUpdateCmd(nil) cmd.Flags().Set("content", "1.2.3.4") expectedRequest := ddosx.PatchRecordRequest{ @@ -241,7 +242,7 @@ func Test_ddosxDomainRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainRecordUpdateCmd() + cmd := ddosxDomainRecordUpdateCmd(nil) cmd.Flags().Set("name", "sub1.testdomain1.co.uk") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -264,7 +265,7 @@ func Test_ddosxDomainRecordUpdate(t *testing.T) { ddosxDomainRecordUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) }) - t.Run("UpdateDomainRecordError_OutputsFatal", func(t *testing.T) { + t.Run("UpdateDomainRecordError_OutputsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -277,7 +278,7 @@ func Test_ddosxDomainRecordUpdate(t *testing.T) { }) }) - t.Run("GetDomainRecordError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainRecordError_OutputsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -296,14 +297,14 @@ func Test_ddosxDomainRecordUpdate(t *testing.T) { func Test_ddosxDomainRecordDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainRecordDeleteCmd() + cmd := ddosxDomainRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainRecordDeleteCmd() + cmd := ddosxDomainRecordDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -311,7 +312,7 @@ func Test_ddosxDomainRecordDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := ddosxDomainRecordDeleteCmd() + cmd := ddosxDomainRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_test.go b/cmd/ddosx/ddosx_domain_test.go similarity index 88% rename from cmd/ddosx_domain_test.go rename to cmd/ddosx/ddosx_domain_test.go index b8e5fc5..51348ae 100644 --- a/cmd/ddosx_domain_test.go +++ b/cmd/ddosx/ddosx_domain_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -8,6 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -25,7 +27,7 @@ func Test_ddosxDomainList(t *testing.T) { ddosxDomainList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -33,12 +35,12 @@ func Test_ddosxDomainList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainList(service, cmd, []string{}) - }) + err := ddosxDomainList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -47,21 +49,21 @@ func Test_ddosxDomainList(t *testing.T) { service.EXPECT().GetDomains(gomock.Any()).Return([]ddosx.Domain{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domains: test error\n", func() { - ddosxDomainList(service, &cobra.Command{}, []string{}) - }) + err := ddosxDomainList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving domains: test error", err.Error()) }) } func Test_ddosxDomainShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainShowCmd().Args(nil, []string{}) + err := ddosxDomainShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -114,7 +116,7 @@ func Test_ddosxDomainCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCreateCmd() + cmd := ddosxDomainCreateCmd(nil) cmd.Flags().Set("name", "testdomain1.co.uk") expectedRequest := ddosx.CreateDomainRequest{ @@ -129,7 +131,7 @@ func Test_ddosxDomainCreate(t *testing.T) { ddosxDomainCreate(service, cmd, []string{}) }) - t.Run("CreateDomain_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomain_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -138,18 +140,18 @@ func Test_ddosxDomainCreate(t *testing.T) { service.EXPECT().CreateDomain(gomock.Any()).Return(errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating domain: test error\n", func() { - ddosxDomainCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain: test error", err.Error()) }) - t.Run("CreateDomain_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomain_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainCreateCmd() + cmd := ddosxDomainCreateCmd(nil) cmd.Flags().Set("name", "testdomain1.co.uk") gomock.InOrder( @@ -157,21 +159,21 @@ func Test_ddosxDomainCreate(t *testing.T) { service.EXPECT().GetDomain("testdomain1.co.uk").Return(ddosx.Domain{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new domain: test error\n", func() { - ddosxDomainCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving new domain: test error", err.Error()) }) } func Test_ddosxDomainDeployCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainDeployCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainDeployCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainDeployCmd().Args(nil, []string{}) + err := ddosxDomainDeployCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -255,10 +257,10 @@ func Test_ddosxDomainDeploy(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainDeployCmd() + cmd := ddosxDomainDeployCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -276,10 +278,10 @@ func Test_ddosxDomainDeploy(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainDeployCmd() + cmd := ddosxDomainDeployCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -329,7 +331,7 @@ func TestDomainStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) @@ -348,7 +350,7 @@ func TestDomainStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) @@ -367,7 +369,7 @@ func TestDomainStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) @@ -385,7 +387,7 @@ func TestDomainStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockDDoSXService(mockCtrl) diff --git a/cmd/ddosx/ddosx_domain_verification.go b/cmd/ddosx/ddosx_domain_verification.go new file mode 100644 index 0000000..0b701d9 --- /dev/null +++ b/cmd/ddosx/ddosx_domain_verification.go @@ -0,0 +1,20 @@ +package ddosx + +import ( + "github.com/spf13/afero" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func ddosxDomainVerificationRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { + cmd := &cobra.Command{ + Use: "verification", + Short: "sub-commands relating to domain verification", + } + + // Child root commands + cmd.AddCommand(ddosxDomainVerificationFileUploadRootCmd(f, appFilesystem)) + cmd.AddCommand(ddosxDomainVerificationDNSRootCmd(f)) + + return cmd +} diff --git a/cmd/ddosx_domain_verification_dns.go b/cmd/ddosx/ddosx_domain_verification_dns.go similarity index 75% rename from cmd/ddosx_domain_verification_dns.go rename to cmd/ddosx/ddosx_domain_verification_dns.go index 2351594..620bcba 100644 --- a/cmd/ddosx_domain_verification_dns.go +++ b/cmd/ddosx/ddosx_domain_verification_dns.go @@ -1,26 +1,27 @@ -package cmd +package ddosx import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainVerificationDNSRootCmd() *cobra.Command { +func ddosxDomainVerificationDNSRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "dns", Short: "sub-commands relating to DNS domain verification", } // Child commands - cmd.AddCommand(ddosxDomainVerificationDNSVerifyCmd()) + cmd.AddCommand(ddosxDomainVerificationDNSVerifyCmd(f)) return cmd } -func ddosxDomainVerificationDNSVerifyCmd() *cobra.Command { +func ddosxDomainVerificationDNSVerifyCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "verify ...", Short: "Verifies a domain via DNS verification method", @@ -34,7 +35,7 @@ func ddosxDomainVerificationDNSVerifyCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainVerificationDNSVerify(getClient().DDoSXService(), cmd, args) + return ddosxDomainVerificationDNSVerify(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_verification_dns_test.go b/cmd/ddosx/ddosx_domain_verification_dns_test.go similarity index 88% rename from cmd/ddosx_domain_verification_dns_test.go rename to cmd/ddosx/ddosx_domain_verification_dns_test.go index c79a6d3..5e29dc2 100644 --- a/cmd/ddosx_domain_verification_dns_test.go +++ b/cmd/ddosx/ddosx_domain_verification_dns_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -13,13 +13,13 @@ import ( func Test_ddosxDomainVerificationDNSVerifyCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainVerificationDNSVerifyCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainVerificationDNSVerifyCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainVerificationDNSVerifyCmd().Args(nil, []string{}) + err := ddosxDomainVerificationDNSVerifyCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/ddosx_domain_verification_fileupload.go b/cmd/ddosx/ddosx_domain_verification_fileupload.go similarity index 68% rename from cmd/ddosx_domain_verification_fileupload.go rename to cmd/ddosx/ddosx_domain_verification_fileupload.go index f242d89..473bac4 100644 --- a/cmd/ddosx_domain_verification_fileupload.go +++ b/cmd/ddosx/ddosx_domain_verification_fileupload.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -8,27 +8,28 @@ import ( "github.com/spf13/afero" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/spf13/cobra" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainVerificationFileUploadRootCmd() *cobra.Command { +func ddosxDomainVerificationFileUploadRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "fileupload", Short: "sub-commands relating to file upload domain verification", } // Child commands - cmd.AddCommand(ddosxDomainVerificationFileUploadShowCmd()) - cmd.AddCommand(ddosxDomainVerificationFileUploadDownloadCmd()) - cmd.AddCommand(ddosxDomainVerificationFileUploadVerifyCmd()) + cmd.AddCommand(ddosxDomainVerificationFileUploadShowCmd(f)) + cmd.AddCommand(ddosxDomainVerificationFileUploadDownloadCmd(f, appFilesystem)) + cmd.AddCommand(ddosxDomainVerificationFileUploadVerifyCmd(f)) return cmd } -func ddosxDomainVerificationFileUploadShowCmd() *cobra.Command { +func ddosxDomainVerificationFileUploadShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows the verification file for a domain", @@ -41,13 +42,13 @@ func ddosxDomainVerificationFileUploadShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainVerificationFileUploadShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainVerificationFileUploadShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainVerificationFileUploadShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainVerificationFileUploadShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var files []OutputDDoSXDomainVerificationFilesFile for _, arg := range args { @@ -63,10 +64,10 @@ func ddosxDomainVerificationFileUploadShow(service ddosx.DDoSXService, cmd *cobr }) } - outputDDoSXDomainVerificationFiles(files) + return output.CommandOutput(cmd, OutputDDoSXDomainVerificationFilesProvider(files)) } -func ddosxDomainVerificationFileUploadDownloadCmd() *cobra.Command { +func ddosxDomainVerificationFileUploadDownloadCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "download ", Short: "Downloads the verification file for a domain", @@ -79,8 +80,8 @@ func ddosxDomainVerificationFileUploadDownloadCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainVerificationFileUploadDownload(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainVerificationFileUploadDownload(f.NewClient().DDoSXService(), appFilesystem, cmd, args) }, } @@ -90,11 +91,10 @@ func ddosxDomainVerificationFileUploadDownloadCmd() *cobra.Command { return cmd } -func ddosxDomainVerificationFileUploadDownload(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainVerificationFileUploadDownload(service ddosx.DDoSXService, appFilesystem afero.Fs, cmd *cobra.Command, args []string) error { content, filename, err := service.DownloadDomainVerificationFile(args[0]) if err != nil { - output.Fatalf("Error retrieving domain verification file: %s", err) - return + return fmt.Errorf("Error retrieving domain verification file: %s", err) } directory, _ := cmd.Flags().GetString("path") @@ -103,20 +103,19 @@ func ddosxDomainVerificationFileUploadDownload(service ddosx.DDoSXService, cmd * _, err = appFilesystem.Stat(targetFilePath) if err == nil || !os.IsNotExist(err) { - output.Fatalf("Destination file [%s] exists", targetFilePath) - return + return fmt.Errorf("Destination file [%s] exists", targetFilePath) } err = afero.WriteFile(appFilesystem, targetFilePath, []byte(content), 0644) if err != nil { - output.Fatalf("Error writing domain verification file to [%s]: %s", targetFilePath, err.Error()) - return + return fmt.Errorf("Error writing domain verification file to [%s]: %s", targetFilePath, err.Error()) } fmt.Println(targetFilePath) + return nil } -func ddosxDomainVerificationFileUploadVerifyCmd() *cobra.Command { +func ddosxDomainVerificationFileUploadVerifyCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "verify ...", Short: "Verifies a domain via verification file method", @@ -130,7 +129,7 @@ func ddosxDomainVerificationFileUploadVerifyCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxDomainVerificationFileUploadVerify(getClient().DDoSXService(), cmd, args) + return ddosxDomainVerificationFileUploadVerify(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_verification_fileupload_test.go b/cmd/ddosx/ddosx_domain_verification_fileupload_test.go similarity index 74% rename from cmd/ddosx_domain_verification_fileupload_test.go rename to cmd/ddosx/ddosx_domain_verification_fileupload_test.go index fc8b96a..bd74d2b 100644 --- a/cmd/ddosx_domain_verification_fileupload_test.go +++ b/cmd/ddosx/ddosx_domain_verification_fileupload_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -20,13 +20,13 @@ import ( func Test_ddosxDomainVerificationFileUploadShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainVerificationFileUploadShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadShowCmd().Args(nil, []string{}) + err := ddosxDomainVerificationFileUploadShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -75,13 +75,13 @@ func Test_ddosxDomainVerificationFileUploadShow(t *testing.T) { func Test_ddosxDomainVerificationFileUploadDownloadCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadDownloadCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainVerificationFileUploadDownloadCmd(nil, nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadDownloadCmd().Args(nil, []string{}) + err := ddosxDomainVerificationFileUploadDownloadCmd(nil, nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -90,18 +90,18 @@ func Test_ddosxDomainVerificationFileUploadDownloadCmd_Args(t *testing.T) { func Test_ddosxDomainVerificationFileUploadDownload(t *testing.T) { t.Run("Valid_FileCreated", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainVerificationFileUploadDownloadCmd() + cmd := ddosxDomainVerificationFileUploadDownloadCmd(nil, appFilesystem) cmd.Flags().Set("path", "/tmp") service.EXPECT().DownloadDomainVerificationFile("testdomain1.co.uk").Return("testfilecontent", "testfilename.txt", nil) output := test.CatchStdOut(t, func() { - ddosxDomainVerificationFileUploadDownload(service, cmd, []string{"testdomain1.co.uk"}) + ddosxDomainVerificationFileUploadDownload(service, appFilesystem, cmd, []string{"testdomain1.co.uk"}) }) filename := filepath.Join("/tmp", "testfilename.txt") @@ -114,46 +114,47 @@ func Test_ddosxDomainVerificationFileUploadDownload(t *testing.T) { assert.Equal(t, filename+"\n", output) }) - t.Run("FileExists_OutputsFatal", func(t *testing.T) { + t.Run("FileExists_ReturnsError", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() afero.WriteFile(appFilesystem, "/tmp/testfilename.txt", []byte{}, 0644) mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainVerificationFileUploadDownloadCmd() + cmd := ddosxDomainVerificationFileUploadDownloadCmd(nil, appFilesystem) cmd.Flags().Set("path", "/tmp") service.EXPECT().DownloadDomainVerificationFile("testdomain1.co.uk").Return("testfilecontent", "testfilename.txt", nil) filename := filepath.Join("/tmp", "testfilename.txt") - test_output.AssertFatalOutput(t, fmt.Sprintf("Destination file [%s] exists\n", filename), func() { - ddosxDomainVerificationFileUploadDownload(service, cmd, []string{"testdomain1.co.uk"}) - }) + + err := ddosxDomainVerificationFileUploadDownload(service, appFilesystem, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, fmt.Sprintf("Destination file [%s] exists", filename), err.Error()) }) - t.Run("WriteFileError_OutputsFatal", func(t *testing.T) { + t.Run("WriteFileError_ReturnsError", func(t *testing.T) { - appFilesystem = afero.NewRegexpFs(afero.NewMemMapFs(), regexp.MustCompile(`\.invalid$`)) + appFilesystem := afero.NewRegexpFs(afero.NewMemMapFs(), regexp.MustCompile(`\.invalid$`)) mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainVerificationFileUploadDownloadCmd() + cmd := ddosxDomainVerificationFileUploadDownloadCmd(nil, appFilesystem) cmd.Flags().Set("path", "/tmp") service.EXPECT().DownloadDomainVerificationFile("testdomain1.co.uk").Return("testfilecontent", "testfilename.txt", nil) filename := filepath.Join("/tmp", "testfilename.txt") - test_output.AssertFatalOutput(t, fmt.Sprintf("Error writing domain verification file to [%s]: open %s: file does not exist\n", filename, filename), func() { - ddosxDomainVerificationFileUploadDownload(service, cmd, []string{"testdomain1.co.uk"}) - }) + + err := ddosxDomainVerificationFileUploadDownload(service, appFilesystem, cmd, []string{"testdomain1.co.uk"}) + assert.Equal(t, fmt.Sprintf("Error writing domain verification file to [%s]: open %s: file does not exist", filename, filename), err.Error()) }) - t.Run("DownloadDomainVerificationFileError_OutputsFatal", func(t *testing.T) { + t.Run("DownloadDomainVerificationFileError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -162,21 +163,21 @@ func Test_ddosxDomainVerificationFileUploadDownload(t *testing.T) { service.EXPECT().DownloadDomainVerificationFile("testdomain1.co.uk").Return("testfilecontent", "testfilename", errors.New("test error")) - test_output.AssertFatalOutput(t, "Error retrieving domain verification file: test error\n", func() { - ddosxDomainVerificationFileUploadDownload(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainVerificationFileUploadDownload(service, nil, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain verification file: test error", err.Error()) }) } func Test_ddosxDomainVerificationFileUploadVerifyCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadVerifyCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainVerificationFileUploadVerifyCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainVerificationFileUploadVerifyCmd().Args(nil, []string{}) + err := ddosxDomainVerificationFileUploadVerifyCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/ddosx_domain_waf.go b/cmd/ddosx/ddosx_domain_waf.go similarity index 72% rename from cmd/ddosx_domain_waf.go rename to cmd/ddosx/ddosx_domain_waf.go index 279b0e7..3270990 100644 --- a/cmd/ddosx_domain_waf.go +++ b/cmd/ddosx/ddosx_domain_waf.go @@ -1,34 +1,36 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainWAFRootCmd() *cobra.Command { +func ddosxDomainWAFRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "waf", Short: "sub-commands relating to domain web application firewalls", } // Child commands - cmd.AddCommand(ddosxDomainWAFShowCmd()) - cmd.AddCommand(ddosxDomainWAFCreateCmd()) - cmd.AddCommand(ddosxDomainWAFUpdateCmd()) - cmd.AddCommand(ddosxDomainWAFDeleteCmd()) + cmd.AddCommand(ddosxDomainWAFShowCmd(f)) + cmd.AddCommand(ddosxDomainWAFCreateCmd(f)) + cmd.AddCommand(ddosxDomainWAFUpdateCmd(f)) + cmd.AddCommand(ddosxDomainWAFDeleteCmd(f)) // Child root commands - cmd.AddCommand(ddosxDomainWAFRuleSetRootCmd()) - cmd.AddCommand(ddosxDomainWAFRuleRootCmd()) - cmd.AddCommand(ddosxDomainWAFAdvancedRuleRootCmd()) + cmd.AddCommand(ddosxDomainWAFRuleSetRootCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleRootCmd(f)) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleRootCmd(f)) return cmd } -func ddosxDomainWAFShowCmd() *cobra.Command { +func ddosxDomainWAFShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a domain WAF", @@ -41,13 +43,13 @@ func ddosxDomainWAFShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var wafs []ddosx.WAF for _, arg := range args { waf, err := service.GetDomainWAF(arg) @@ -59,10 +61,10 @@ func ddosxDomainWAFShow(service ddosx.DDoSXService, cmd *cobra.Command, args []s wafs = append(wafs, waf) } - outputDDoSXWAFs(wafs) + return output.CommandOutput(cmd, OutputDDoSXWAFsProvider(wafs)) } -func ddosxDomainWAFCreateCmd() *cobra.Command { +func ddosxDomainWAFCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a domain WAF", @@ -75,8 +77,8 @@ func ddosxDomainWAFCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -88,18 +90,16 @@ func ddosxDomainWAFCreateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { mode, _ := cmd.Flags().GetString("mode") parsedMode, err := ddosx.ParseWAFMode(mode) if err != nil { - output.Fatal(err.Error()) - return + return err } paranoiaLevel, _ := cmd.Flags().GetString("paranoia-level") parsedParanoiaLevel, err := ddosx.ParseWAFParanoiaLevel(paranoiaLevel) if err != nil { - output.Fatal(err.Error()) - return + return err } createRequest := ddosx.CreateWAFRequest{ @@ -109,20 +109,18 @@ func ddosxDomainWAFCreate(service ddosx.DDoSXService, cmd *cobra.Command, args [ err = service.CreateDomainWAF(args[0], createRequest) if err != nil { - output.Fatalf("Error creating domain waf: %s", err) - return + return fmt.Errorf("Error creating domain waf: %s", err) } waf, err := service.GetDomainWAF(args[0]) if err != nil { - output.Fatalf("Error retrieving domain waf: %s", err) - return + return fmt.Errorf("Error retrieving domain waf: %s", err) } - outputDDoSXWAFs([]ddosx.WAF{waf}) + return output.CommandOutput(cmd, OutputDDoSXWAFsProvider([]ddosx.WAF{waf})) } -func ddosxDomainWAFUpdateCmd() *cobra.Command { +func ddosxDomainWAFUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ..", Short: "Updates a domain WAF", @@ -135,8 +133,8 @@ func ddosxDomainWAFUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -146,15 +144,14 @@ func ddosxDomainWAFUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchWAFRequest{} if cmd.Flags().Changed("mode") { mode, _ := cmd.Flags().GetString("mode") parsedMode, err := ddosx.ParseWAFMode(mode) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest.Mode = parsedMode @@ -164,8 +161,7 @@ func ddosxDomainWAFUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args [ paranoiaLevel, _ := cmd.Flags().GetString("paranoia-level") parsedParanoiaLevel, err := ddosx.ParseWAFParanoiaLevel(paranoiaLevel) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest.ParanoiaLevel = parsedParanoiaLevel @@ -188,10 +184,10 @@ func ddosxDomainWAFUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args [ wafs = append(wafs, waf) } - outputDDoSXWAFs(wafs) + return output.CommandOutput(cmd, OutputDDoSXWAFsProvider(wafs)) } -func ddosxDomainWAFDeleteCmd() *cobra.Command { +func ddosxDomainWAFDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a domain WAF", @@ -205,7 +201,7 @@ func ddosxDomainWAFDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainWAFDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_waf_advancedrule.go b/cmd/ddosx/ddosx_domain_waf_advancedrule.go similarity index 73% rename from cmd/ddosx_domain_waf_advancedrule.go rename to cmd/ddosx/ddosx_domain_waf_advancedrule.go index 27fb61d..2da89df 100644 --- a/cmd/ddosx_domain_waf_advancedrule.go +++ b/cmd/ddosx/ddosx_domain_waf_advancedrule.go @@ -1,33 +1,35 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/ukfast/sdk-go/pkg/connection" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainWAFAdvancedRuleRootCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "advancedrule", Short: "sub-commands relating to domain web application firewall advanced rules", } // Child commands - cmd.AddCommand(ddosxDomainWAFAdvancedRuleListCmd()) - cmd.AddCommand(ddosxDomainWAFAdvancedRuleShowCmd()) - cmd.AddCommand(ddosxDomainWAFAdvancedRuleCreateCmd()) - cmd.AddCommand(ddosxDomainWAFAdvancedRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainWAFAdvancedRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleListCmd(f)) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainWAFAdvancedRuleDeleteCmd(f)) return cmd } -func ddosxDomainWAFAdvancedRuleListCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists domain WAF advanced rules", @@ -40,29 +42,27 @@ func ddosxDomainWAFAdvancedRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFAdvancedRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFAdvancedRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFAdvancedRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFAdvancedRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainWAFAdvancedRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain WAF advanced rules: %s", err) - return + return fmt.Errorf("Error retrieving domain WAF advanced rules: %s", err) } - outputDDoSXWAFAdvancedRules(domains) + return output.CommandOutput(cmd, OutputDDoSXWAFAdvancedRulesProvider(domains)) } -func ddosxDomainWAFAdvancedRuleShowCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows domain WAF advanced rules", @@ -78,13 +78,13 @@ func ddosxDomainWAFAdvancedRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFAdvancedRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFAdvancedRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFAdvancedRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFAdvancedRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.WAFAdvancedRule @@ -98,10 +98,10 @@ func ddosxDomainWAFAdvancedRuleShow(service ddosx.DDoSXService, cmd *cobra.Comma rules = append(rules, rule) } - outputDDoSXWAFAdvancedRules(rules) + return output.CommandOutput(cmd, OutputDDoSXWAFAdvancedRulesProvider(rules)) } -func ddosxDomainWAFAdvancedRuleCreateCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates domain WAF advanced rules", @@ -114,8 +114,8 @@ func ddosxDomainWAFAdvancedRuleCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFAdvancedRuleCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFAdvancedRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -131,14 +131,13 @@ func ddosxDomainWAFAdvancedRuleCreateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFAdvancedRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFAdvancedRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { createRequest := ddosx.CreateWAFAdvancedRuleRequest{} modifier, _ := cmd.Flags().GetString("modifier") parsedModifier, err := ddosx.ParseWAFAdvancedRuleModifier(modifier) if err != nil { - output.Fatal(err.Error()) - return + return err } createRequest.Modifier = parsedModifier section, _ := cmd.Flags().GetString("section") @@ -149,20 +148,18 @@ func ddosxDomainWAFAdvancedRuleCreate(service ddosx.DDoSXService, cmd *cobra.Com id, err := service.CreateDomainWAFAdvancedRule(args[0], createRequest) if err != nil { - output.Fatalf("Error creating domain WAF advanced rule: %s", err) - return + return fmt.Errorf("Error creating domain WAF advanced rule: %s", err) } rule, err := service.GetDomainWAFAdvancedRule(args[0], id) if err != nil { - output.Fatalf("Error retrieving new domain WAF advanced rule [%s]: %s", id, err) - return + return fmt.Errorf("Error retrieving new domain WAF advanced rule [%s]: %s", id, err) } - outputDDoSXWAFAdvancedRules([]ddosx.WAFAdvancedRule{rule}) + return output.CommandOutput(cmd, OutputDDoSXWAFAdvancedRulesProvider([]ddosx.WAFAdvancedRule{rule})) } -func ddosxDomainWAFAdvancedRuleUpdateCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates domain WAF advanced rules", @@ -178,8 +175,8 @@ func ddosxDomainWAFAdvancedRuleUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFAdvancedRuleUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFAdvancedRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -191,15 +188,14 @@ func ddosxDomainWAFAdvancedRuleUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFAdvancedRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFAdvancedRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchWAFAdvancedRuleRequest{} if cmd.Flags().Changed("modifier") { modifier, _ := cmd.Flags().GetString("modifier") parsedModifier, err := ddosx.ParseWAFAdvancedRuleModifier(modifier) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest.Modifier = parsedModifier } @@ -232,10 +228,10 @@ func ddosxDomainWAFAdvancedRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Com rules = append(rules, rule) } - outputDDoSXWAFAdvancedRules(rules) + return output.CommandOutput(cmd, OutputDDoSXWAFAdvancedRulesProvider(rules)) } -func ddosxDomainWAFAdvancedRuleDeleteCmd() *cobra.Command { +func ddosxDomainWAFAdvancedRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes domain WAF advanced rules", @@ -252,7 +248,7 @@ func ddosxDomainWAFAdvancedRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFAdvancedRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainWAFAdvancedRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_waf_advancedrule_test.go b/cmd/ddosx/ddosx_domain_waf_advancedrule_test.go similarity index 81% rename from cmd/ddosx_domain_waf_advancedrule_test.go rename to cmd/ddosx/ddosx_domain_waf_advancedrule_test.go index 7928d92..fc8053d 100644 --- a/cmd/ddosx_domain_waf_advancedrule_test.go +++ b/cmd/ddosx/ddosx_domain_waf_advancedrule_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,21 +7,23 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" + "github.com/ukfast/sdk-go/pkg/connection" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) func Test_ddosxDomainWAFAdvancedRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleListCmd() + cmd := ddosxDomainWAFAdvancedRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleListCmd() + cmd := ddosxDomainWAFAdvancedRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -41,7 +43,7 @@ func Test_ddosxDomainWAFAdvancedRuleList(t *testing.T) { ddosxDomainWAFAdvancedRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -49,12 +51,12 @@ func Test_ddosxDomainWAFAdvancedRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainWAFAdvancedRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -63,22 +65,22 @@ func Test_ddosxDomainWAFAdvancedRuleList(t *testing.T) { service.EXPECT().GetDomainWAFAdvancedRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.WAFAdvancedRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain WAF advanced rules: test error\n", func() { - ddosxDomainWAFAdvancedRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain WAF advanced rules: test error", err.Error()) }) } func Test_ddosxDomainWAFAdvancedRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleShowCmd() + cmd := ddosxDomainWAFAdvancedRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleShowCmd() + cmd := ddosxDomainWAFAdvancedRuleShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -86,7 +88,7 @@ func Test_ddosxDomainWAFAdvancedRuleShowCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleShowCmd() + cmd := ddosxDomainWAFAdvancedRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -122,14 +124,14 @@ func Test_ddosxDomainWAFAdvancedRuleShow(t *testing.T) { func Test_ddosxDomainWAFAdvancedRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -143,7 +145,7 @@ func Test_ddosxDomainWAFAdvancedRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "contains") cmd.Flags().Set("phrase", "testphrase") @@ -164,32 +166,30 @@ func Test_ddosxDomainWAFAdvancedRuleCreate(t *testing.T) { ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("InvalidModifier_OutputsFatal", func(t *testing.T) { + t.Run("InvalidModifier_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "invalidmodifier") cmd.Flags().Set("phrase", "testphrase") cmd.Flags().Set("ip", "1.2.3.4") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFAdvancedRuleModifier") - }, func() { - ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) - t.Run("CreateDomainWAFAdvancedRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainWAFAdvancedRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "contains") cmd.Flags().Set("phrase", "testphrase") @@ -197,18 +197,18 @@ func Test_ddosxDomainWAFAdvancedRuleCreate(t *testing.T) { service.EXPECT().CreateDomainWAFAdvancedRule("testdomain1.co.uk", gomock.Any()).Return("00000000-0000-0000-0000-000000000000", errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating domain WAF advanced rule: test error\n", func() { - ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain WAF advanced rule: test error", err.Error()) }) - t.Run("GetDomainWAFAdvancedRuleError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainWAFAdvancedRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleCreateCmd() + cmd := ddosxDomainWAFAdvancedRuleCreateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "contains") cmd.Flags().Set("phrase", "testphrase") @@ -219,22 +219,22 @@ func Test_ddosxDomainWAFAdvancedRuleCreate(t *testing.T) { service.EXPECT().GetDomainWAFAdvancedRule("testdomain1.co.uk", "00000000-0000-0000-0000-000000000000").Return(ddosx.WAFAdvancedRule{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new domain WAF advanced rule [00000000-0000-0000-0000-000000000000]: test error\n", func() { - ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving new domain WAF advanced rule [00000000-0000-0000-0000-000000000000]: test error", err.Error()) }) } func Test_ddosxDomainWAFAdvancedRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleUpdateCmd() + cmd := ddosxDomainWAFAdvancedRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleUpdateCmd() + cmd := ddosxDomainWAFAdvancedRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -242,7 +242,7 @@ func Test_ddosxDomainWAFAdvancedRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingAdvancedRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleUpdateCmd() + cmd := ddosxDomainWAFAdvancedRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -256,7 +256,7 @@ func Test_ddosxDomainWAFAdvancedRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleUpdateCmd() + cmd := ddosxDomainWAFAdvancedRuleUpdateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "contains") cmd.Flags().Set("phrase", "testphrase") @@ -277,23 +277,21 @@ func Test_ddosxDomainWAFAdvancedRuleUpdate(t *testing.T) { ddosxDomainWAFAdvancedRuleUpdate(service, cmd, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) }) - t.Run("InvalidModifier_OutputsFatal", func(t *testing.T) { + t.Run("InvalidModifier_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFAdvancedRuleUpdateCmd() + cmd := ddosxDomainWAFAdvancedRuleUpdateCmd(nil) cmd.Flags().Set("section", "REQUEST_URI") cmd.Flags().Set("modifier", "invalidmodifier") cmd.Flags().Set("phrase", "testphrase") cmd.Flags().Set("ip", "1.2.3.4") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFAdvancedRuleModifier") - }, func() { - ddosxDomainWAFAdvancedRuleUpdate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFAdvancedRuleUpdate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) t.Run("PatchDomainWAFAdvancedRuleError_OutputsError", func(t *testing.T) { @@ -328,14 +326,14 @@ func Test_ddosxDomainWAFAdvancedRuleUpdate(t *testing.T) { func Test_ddosxDomainWAFAdvancedRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleDeleteCmd() + cmd := ddosxDomainWAFAdvancedRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleDeleteCmd() + cmd := ddosxDomainWAFAdvancedRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -343,7 +341,7 @@ func Test_ddosxDomainWAFAdvancedRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingAdvancedRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFAdvancedRuleDeleteCmd() + cmd := ddosxDomainWAFAdvancedRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_waf_rule.go b/cmd/ddosx/ddosx_domain_waf_rule.go similarity index 71% rename from cmd/ddosx_domain_waf_rule.go rename to cmd/ddosx/ddosx_domain_waf_rule.go index 1fc8806..fae6df2 100644 --- a/cmd/ddosx_domain_waf_rule.go +++ b/cmd/ddosx/ddosx_domain_waf_rule.go @@ -1,33 +1,35 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/ukfast/sdk-go/pkg/connection" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainWAFRuleRootCmd() *cobra.Command { +func ddosxDomainWAFRuleRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "rule", Short: "sub-commands relating to domain web application firewall rules", } // Child commands - cmd.AddCommand(ddosxDomainWAFRuleListCmd()) - cmd.AddCommand(ddosxDomainWAFRuleShowCmd()) - cmd.AddCommand(ddosxDomainWAFRuleCreateCmd()) - cmd.AddCommand(ddosxDomainWAFRuleUpdateCmd()) - cmd.AddCommand(ddosxDomainWAFRuleDeleteCmd()) + cmd.AddCommand(ddosxDomainWAFRuleListCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleShowCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleCreateCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleUpdateCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleDeleteCmd(f)) return cmd } -func ddosxDomainWAFRuleListCmd() *cobra.Command { +func ddosxDomainWAFRuleListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists domain WAF rules", @@ -40,29 +42,27 @@ func ddosxDomainWAFRuleListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainWAFRules(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain WAF rules: %s", err) - return + return fmt.Errorf("Error retrieving domain WAF rules: %s", err) } - outputDDoSXWAFRules(domains) + return output.CommandOutput(cmd, OutputDDoSXWAFRulesProvider(domains)) } -func ddosxDomainWAFRuleShowCmd() *cobra.Command { +func ddosxDomainWAFRuleShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows domain WAF rules", @@ -78,13 +78,13 @@ func ddosxDomainWAFRuleShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rules []ddosx.WAFRule @@ -98,10 +98,10 @@ func ddosxDomainWAFRuleShow(service ddosx.DDoSXService, cmd *cobra.Command, args rules = append(rules, rule) } - outputDDoSXWAFRules(rules) + return output.CommandOutput(cmd, OutputDDoSXWAFRulesProvider(rules)) } -func ddosxDomainWAFRuleCreateCmd() *cobra.Command { +func ddosxDomainWAFRuleCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates domain WAF rules", @@ -114,8 +114,8 @@ func ddosxDomainWAFRuleCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleCreate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -127,7 +127,7 @@ func ddosxDomainWAFRuleCreateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { createRequest := ddosx.CreateWAFRuleRequest{} createRequest.URI, _ = cmd.Flags().GetString("uri") @@ -136,20 +136,18 @@ func ddosxDomainWAFRuleCreate(service ddosx.DDoSXService, cmd *cobra.Command, ar id, err := service.CreateDomainWAFRule(args[0], createRequest) if err != nil { - output.Fatalf("Error creating domain WAF rule: %s", err) - return + return fmt.Errorf("Error creating domain WAF rule: %s", err) } rule, err := service.GetDomainWAFRule(args[0], id) if err != nil { - output.Fatalf("Error retrieving new domain WAF rule [%s]: %s", id, err) - return + return fmt.Errorf("Error retrieving new domain WAF rule [%s]: %s", id, err) } - outputDDoSXWAFRules([]ddosx.WAFRule{rule}) + return output.CommandOutput(cmd, OutputDDoSXWAFRulesProvider([]ddosx.WAFRule{rule})) } -func ddosxDomainWAFRuleUpdateCmd() *cobra.Command { +func ddosxDomainWAFRuleUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates WAF rules", @@ -165,8 +163,8 @@ func ddosxDomainWAFRuleUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -176,7 +174,7 @@ func ddosxDomainWAFRuleUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchWAFRuleRequest{} if cmd.Flags().Changed("uri") { @@ -205,10 +203,10 @@ func ddosxDomainWAFRuleUpdate(service ddosx.DDoSXService, cmd *cobra.Command, ar rules = append(rules, rule) } - outputDDoSXWAFRules(rules) + return output.CommandOutput(cmd, OutputDDoSXWAFRulesProvider(rules)) } -func ddosxDomainWAFRuleDeleteCmd() *cobra.Command { +func ddosxDomainWAFRuleDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes WAF rules", @@ -225,7 +223,7 @@ func ddosxDomainWAFRuleDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleDelete(getClient().DDoSXService(), cmd, args) + ddosxDomainWAFRuleDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_domain_waf_rule_test.go b/cmd/ddosx/ddosx_domain_waf_rule_test.go similarity index 85% rename from cmd/ddosx_domain_waf_rule_test.go rename to cmd/ddosx/ddosx_domain_waf_rule_test.go index 9d56518..a1004d2 100644 --- a/cmd/ddosx_domain_waf_rule_test.go +++ b/cmd/ddosx/ddosx_domain_waf_rule_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -14,14 +15,14 @@ import ( func Test_ddosxDomainWAFRuleListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleListCmd() + cmd := ddosxDomainWAFRuleListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleListCmd() + cmd := ddosxDomainWAFRuleListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -41,7 +42,7 @@ func Test_ddosxDomainWAFRuleList(t *testing.T) { ddosxDomainWAFRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -49,12 +50,12 @@ func Test_ddosxDomainWAFRuleList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainWAFRuleList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -63,22 +64,22 @@ func Test_ddosxDomainWAFRuleList(t *testing.T) { service.EXPECT().GetDomainWAFRules("testdomain1.co.uk", gomock.Any()).Return([]ddosx.WAFRule{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain WAF rules: test error\n", func() { - ddosxDomainWAFRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain WAF rules: test error", err.Error()) }) } func Test_ddosxDomainWAFRuleShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleShowCmd() + cmd := ddosxDomainWAFRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleShowCmd() + cmd := ddosxDomainWAFRuleShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -86,7 +87,7 @@ func Test_ddosxDomainWAFRuleShowCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleShowCmd() + cmd := ddosxDomainWAFRuleShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -122,14 +123,14 @@ func Test_ddosxDomainWAFRuleShow(t *testing.T) { func Test_ddosxDomainWAFRuleCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleCreateCmd() + cmd := ddosxDomainWAFRuleCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleCreateCmd() + cmd := ddosxDomainWAFRuleCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -143,7 +144,7 @@ func Test_ddosxDomainWAFRuleCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFRuleCreateCmd() + cmd := ddosxDomainWAFRuleCreateCmd(nil) cmd.Flags().Set("uri", "test.html") expectedRequest := ddosx.CreateWAFRuleRequest{ @@ -158,7 +159,7 @@ func Test_ddosxDomainWAFRuleCreate(t *testing.T) { ddosxDomainWAFRuleCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("CreateDomainWAFRuleError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainWAFRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -167,12 +168,12 @@ func Test_ddosxDomainWAFRuleCreate(t *testing.T) { service.EXPECT().CreateDomainWAFRule("testdomain1.co.uk", gomock.Any()).Return("00000000-0000-0000-0000-000000000000", errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating domain WAF rule: test error\n", func() { - ddosxDomainWAFRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain WAF rule: test error", err.Error()) }) - t.Run("GetDomainWAFRuleError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainWAFRuleError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -184,22 +185,22 @@ func Test_ddosxDomainWAFRuleCreate(t *testing.T) { service.EXPECT().GetDomainWAFRule("testdomain1.co.uk", "00000000-0000-0000-0000-000000000000").Return(ddosx.WAFRule{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new domain WAF rule [00000000-0000-0000-0000-000000000000]: test error\n", func() { - ddosxDomainWAFRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleCreate(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving new domain WAF rule [00000000-0000-0000-0000-000000000000]: test error", err.Error()) }) } func Test_ddosxDomainWAFRuleUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleUpdateCmd() + cmd := ddosxDomainWAFRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleUpdateCmd() + cmd := ddosxDomainWAFRuleUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -207,7 +208,7 @@ func Test_ddosxDomainWAFRuleUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleUpdateCmd() + cmd := ddosxDomainWAFRuleUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -221,7 +222,7 @@ func Test_ddosxDomainWAFRuleUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFRuleUpdateCmd() + cmd := ddosxDomainWAFRuleUpdateCmd(nil) cmd.Flags().Set("uri", "test.html") cmd.Flags().Set("ip", "1.2.3.4") @@ -270,14 +271,14 @@ func Test_ddosxDomainWAFRuleUpdate(t *testing.T) { func Test_ddosxDomainWAFRuleDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleDeleteCmd() + cmd := ddosxDomainWAFRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleDeleteCmd() + cmd := ddosxDomainWAFRuleDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -285,7 +286,7 @@ func Test_ddosxDomainWAFRuleDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRule_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleDeleteCmd() + cmd := ddosxDomainWAFRuleDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) diff --git a/cmd/ddosx_domain_waf_ruleset.go b/cmd/ddosx/ddosx_domain_waf_ruleset.go similarity index 70% rename from cmd/ddosx_domain_waf_ruleset.go rename to cmd/ddosx/ddosx_domain_waf_ruleset.go index 96bfb12..1cf0309 100644 --- a/cmd/ddosx_domain_waf_ruleset.go +++ b/cmd/ddosx/ddosx_domain_waf_ruleset.go @@ -1,30 +1,32 @@ -package cmd +package ddosx import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxDomainWAFRuleSetRootCmd() *cobra.Command { +func ddosxDomainWAFRuleSetRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "ruleset", Short: "sub-commands relating to domain web application firewall rule sets", } // Child commands - cmd.AddCommand(ddosxDomainWAFRuleSetListCmd()) - cmd.AddCommand(ddosxDomainWAFRuleSetShowCmd()) - cmd.AddCommand(ddosxDomainWAFRuleSetUpdateCmd()) + cmd.AddCommand(ddosxDomainWAFRuleSetListCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleSetShowCmd(f)) + cmd.AddCommand(ddosxDomainWAFRuleSetUpdateCmd(f)) return cmd } -func ddosxDomainWAFRuleSetListCmd() *cobra.Command { +func ddosxDomainWAFRuleSetListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists WAF rule sets", @@ -37,29 +39,27 @@ func ddosxDomainWAFRuleSetListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleSetList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleSetList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFRuleSetList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleSetList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomainWAFRuleSets(args[0], params) if err != nil { - output.Fatalf("Error retrieving domain waf rule sets: %s", err) - return + return fmt.Errorf("Error retrieving domain waf rule sets: %s", err) } - outputDDoSXWAFRuleSets(domains) + return output.CommandOutput(cmd, OutputDDoSXWAFRuleSetsProvider(domains)) } -func ddosxDomainWAFRuleSetShowCmd() *cobra.Command { +func ddosxDomainWAFRuleSetShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows WAF rule sets", @@ -75,12 +75,13 @@ func ddosxDomainWAFRuleSetShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleSetShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleSetShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxDomainWAFRuleSetShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { + +func ddosxDomainWAFRuleSetShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var rulesets []ddosx.WAFRuleSet for _, arg := range args[1:] { ruleset, err := service.GetDomainWAFRuleSet(args[0], arg) @@ -92,10 +93,10 @@ func ddosxDomainWAFRuleSetShow(service ddosx.DDoSXService, cmd *cobra.Command, a rulesets = append(rulesets, ruleset) } - outputDDoSXWAFRuleSets(rulesets) + return output.CommandOutput(cmd, OutputDDoSXWAFRuleSetsProvider(rulesets)) } -func ddosxDomainWAFRuleSetUpdateCmd() *cobra.Command { +func ddosxDomainWAFRuleSetUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates WAF rule sets", @@ -111,8 +112,8 @@ func ddosxDomainWAFRuleSetUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxDomainWAFRuleSetUpdate(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxDomainWAFRuleSetUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -121,7 +122,7 @@ func ddosxDomainWAFRuleSetUpdateCmd() *cobra.Command { return cmd } -func ddosxDomainWAFRuleSetUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxDomainWAFRuleSetUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { patchRequest := ddosx.PatchWAFRuleSetRequest{} if cmd.Flags().Changed("active") { @@ -146,5 +147,5 @@ func ddosxDomainWAFRuleSetUpdate(service ddosx.DDoSXService, cmd *cobra.Command, rulesets = append(rulesets, ruleset) } - outputDDoSXWAFRuleSets(rulesets) + return output.CommandOutput(cmd, OutputDDoSXWAFRuleSetsProvider(rulesets)) } diff --git a/cmd/ddosx_domain_waf_ruleset_test.go b/cmd/ddosx/ddosx_domain_waf_ruleset_test.go similarity index 86% rename from cmd/ddosx_domain_waf_ruleset_test.go rename to cmd/ddosx/ddosx_domain_waf_ruleset_test.go index cc8f028..fbb05e6 100644 --- a/cmd/ddosx_domain_waf_ruleset_test.go +++ b/cmd/ddosx/ddosx_domain_waf_ruleset_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/ptr" @@ -15,14 +16,14 @@ import ( func Test_ddosxDomainWAFRuleSetListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetListCmd() + cmd := ddosxDomainWAFRuleSetListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetListCmd() + cmd := ddosxDomainWAFRuleSetListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -42,7 +43,7 @@ func Test_ddosxDomainWAFRuleSetList(t *testing.T) { ddosxDomainWAFRuleSetList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -50,12 +51,12 @@ func Test_ddosxDomainWAFRuleSetList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxDomainWAFRuleSetList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleSetList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -64,22 +65,22 @@ func Test_ddosxDomainWAFRuleSetList(t *testing.T) { service.EXPECT().GetDomainWAFRuleSets("testdomain1.co.uk", gomock.Any()).Return([]ddosx.WAFRuleSet{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain waf rule sets: test error\n", func() { - ddosxDomainWAFRuleSetList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFRuleSetList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain waf rule sets: test error", err.Error()) }) } func Test_ddosxDomainWAFRuleSetShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetShowCmd() + cmd := ddosxDomainWAFRuleSetShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetShowCmd() + cmd := ddosxDomainWAFRuleSetShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -87,7 +88,7 @@ func Test_ddosxDomainWAFRuleSetShowCmd_Args(t *testing.T) { }) t.Run("MissingRuleSet_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetShowCmd() + cmd := ddosxDomainWAFRuleSetShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -123,14 +124,14 @@ func Test_ddosxDomainWAFRuleSetShow(t *testing.T) { func Test_ddosxDomainWAFRuleSetUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetUpdateCmd() + cmd := ddosxDomainWAFRuleSetUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingDomain_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetUpdateCmd() + cmd := ddosxDomainWAFRuleSetUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -138,7 +139,7 @@ func Test_ddosxDomainWAFRuleSetUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRuleSet_Error", func(t *testing.T) { - cmd := ddosxDomainWAFRuleSetUpdateCmd() + cmd := ddosxDomainWAFRuleSetUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.co.uk"}) assert.NotNil(t, err) @@ -152,7 +153,7 @@ func Test_ddosxDomainWAFRuleSetUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFRuleSetUpdateCmd() + cmd := ddosxDomainWAFRuleSetUpdateCmd(nil) cmd.Flags().Set("active", "true") expectedRequest := ddosx.PatchWAFRuleSetRequest{ diff --git a/cmd/ddosx_domain_waf_test.go b/cmd/ddosx/ddosx_domain_waf_test.go similarity index 76% rename from cmd/ddosx_domain_waf_test.go rename to cmd/ddosx/ddosx_domain_waf_test.go index b88142f..c663d4d 100644 --- a/cmd/ddosx_domain_waf_test.go +++ b/cmd/ddosx/ddosx_domain_waf_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -9,18 +9,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" + "github.com/ukfast/sdk-go/pkg/connection" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) func Test_ddosxDomainWAFShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainWAFShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainWAFShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainWAFShowCmd().Args(nil, []string{}) + err := ddosxDomainWAFShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -69,13 +70,13 @@ func Test_ddosxDomainWAFShow(t *testing.T) { func Test_ddosxDomainWAFCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainWAFCreateCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainWAFCreateCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainWAFCreateCmd().Args(nil, []string{}) + err := ddosxDomainWAFCreateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -88,7 +89,7 @@ func Test_ddosxDomainWAFCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFCreateCmd() + cmd := ddosxDomainWAFCreateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") @@ -105,64 +106,60 @@ func Test_ddosxDomainWAFCreate(t *testing.T) { ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("InvalidMode_OutputsFatal", func(t *testing.T) { + t.Run("InvalidMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFCreateCmd() + cmd := ddosxDomainWAFCreateCmd(nil) cmd.Flags().Set("mode", "invalidmode") cmd.Flags().Set("paranoia-level", "high") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFMode") - }, func() { - ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) - t.Run("InvalidParanoiaLevel_OutputsFatal", func(t *testing.T) { + t.Run("InvalidParanoiaLevel_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFCreateCmd() + cmd := ddosxDomainWAFCreateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "invalidparanoialevel") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFParanoiaLevel") - }, func() { - ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) - t.Run("CreateDomainWAFError_OutputsFatal", func(t *testing.T) { + t.Run("CreateDomainWAFError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFCreateCmd() + cmd := ddosxDomainWAFCreateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") service.EXPECT().CreateDomainWAF("testdomain1.co.uk", gomock.Any()).Return(errors.New("test error")) - test_output.AssertFatalOutput(t, "Error creating domain waf: test error\n", func() { - ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error creating domain waf: test error", err.Error()) }) - t.Run("GetDomainWAFError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainWAFError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFCreateCmd() + cmd := ddosxDomainWAFCreateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") @@ -171,21 +168,21 @@ func Test_ddosxDomainWAFCreate(t *testing.T) { service.EXPECT().GetDomainWAF("testdomain1.co.uk").Return(ddosx.WAF{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving domain waf: test error\n", func() { - ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFCreate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain waf: test error", err.Error()) }) } func Test_ddosxDomainWAFUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainWAFUpdateCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainWAFUpdateCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainWAFUpdateCmd().Args(nil, []string{}) + err := ddosxDomainWAFUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -198,7 +195,7 @@ func Test_ddosxDomainWAFUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFUpdateCmd() + cmd := ddosxDomainWAFUpdateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") @@ -215,38 +212,34 @@ func Test_ddosxDomainWAFUpdate(t *testing.T) { ddosxDomainWAFUpdate(service, cmd, []string{"testdomain1.co.uk"}) }) - t.Run("InvalidMode_OutputsFatal", func(t *testing.T) { + t.Run("InvalidMode_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFUpdateCmd() + cmd := ddosxDomainWAFUpdateCmd(nil) cmd.Flags().Set("mode", "invalidmode") cmd.Flags().Set("paranoia-level", "high") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFMode") - }, func() { - ddosxDomainWAFUpdate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFUpdate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) - t.Run("InvalidParanoiaLevel_OutputsFatal", func(t *testing.T) { + t.Run("InvalidParanoiaLevel_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFUpdateCmd() + cmd := ddosxDomainWAFUpdateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "invalidparanoialevel") - test_output.AssertFatalOutputFunc(t, func(stdErr string) { - assert.Contains(t, stdErr, "Invalid ddosx.WAFParanoiaLevel") - }, func() { - ddosxDomainWAFUpdate(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := ddosxDomainWAFUpdate(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &connection.ErrInvalidEnumValue{}, err) }) t.Run("UpdateDomainWAFError_OutputsError", func(t *testing.T) { @@ -254,7 +247,7 @@ func Test_ddosxDomainWAFUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFUpdateCmd() + cmd := ddosxDomainWAFUpdateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") @@ -270,7 +263,7 @@ func Test_ddosxDomainWAFUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxDomainWAFUpdateCmd() + cmd := ddosxDomainWAFUpdateCmd(nil) cmd.Flags().Set("mode", "on") cmd.Flags().Set("paranoia-level", "high") @@ -287,13 +280,13 @@ func Test_ddosxDomainWAFUpdate(t *testing.T) { func Test_ddosxDomainWAFDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxDomainWAFDeleteCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := ddosxDomainWAFDeleteCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxDomainWAFDeleteCmd().Args(nil, []string{}) + err := ddosxDomainWAFDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/ddosx_record.go b/cmd/ddosx/ddosx_record.go similarity index 56% rename from cmd/ddosx_record.go rename to cmd/ddosx/ddosx_record.go index 7371fb9..16e45d4 100644 --- a/cmd/ddosx_record.go +++ b/cmd/ddosx/ddosx_record.go @@ -1,48 +1,49 @@ -package cmd +package ddosx import ( + "fmt" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxRecordRootCmd() *cobra.Command { +func ddosxRecordRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "record", Short: "sub-commands relating to records", } // Child commands - cmd.AddCommand(ddosxRecordListCmd()) + cmd.AddCommand(ddosxRecordListCmd(f)) return cmd } -func ddosxRecordListCmd() *cobra.Command { +func ddosxRecordListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists records", Long: "This command lists records", Example: "ukfast ddosx record list", - Run: func(cmd *cobra.Command, args []string) { - ddosxRecordList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxRecordList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxRecordList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxRecordList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } records, err := service.GetRecords(params) if err != nil { - output.Fatalf("Error retrieving records: %s", err) - return + return fmt.Errorf("Error retrieving records: %s", err) } - outputDDoSXRecords(records) + return output.CommandOutput(cmd, OutputDDoSXRecordsProvider(records)) } diff --git a/cmd/ddosx_record_test.go b/cmd/ddosx/ddosx_record_test.go similarity index 67% rename from cmd/ddosx_record_test.go rename to cmd/ddosx/ddosx_record_test.go index a426322..0506126 100644 --- a/cmd/ddosx_record_test.go +++ b/cmd/ddosx/ddosx_record_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -6,8 +6,9 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) @@ -23,7 +24,7 @@ func Test_ddosxRecordList(t *testing.T) { ddosxRecordList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -31,12 +32,12 @@ func Test_ddosxRecordList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxRecordList(service, cmd, []string{}) - }) + err := ddosxRecordList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetRecordsError_OutputsFatal", func(t *testing.T) { + t.Run("GetRecordsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -45,8 +46,8 @@ func Test_ddosxRecordList(t *testing.T) { service.EXPECT().GetRecords(gomock.Any()).Return([]ddosx.Record{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving records: test error\n", func() { - ddosxRecordList(service, &cobra.Command{}, []string{}) - }) + err := ddosxRecordList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving records: test error", err.Error()) }) } diff --git a/cmd/ddosx_ssl.go b/cmd/ddosx/ddosx_ssl.go similarity index 82% rename from cmd/ddosx_ssl.go rename to cmd/ddosx/ddosx_ssl.go index bc2407e..3ff63b0 100644 --- a/cmd/ddosx_ssl.go +++ b/cmd/ddosx/ddosx_ssl.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -6,60 +6,59 @@ import ( "io/ioutil" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxSSLRootCmd() *cobra.Command { +func ddosxSSLRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "ssl", Short: "sub-commands relating to ssls", } // Child commands - cmd.AddCommand(ddosxSSLListCmd()) - cmd.AddCommand(ddosxSSLShowCmd()) - cmd.AddCommand(ddosxSSLCreateCmd()) - cmd.AddCommand(ddosxSSLUpdateCmd()) - cmd.AddCommand(ddosxSSLDeleteCmd()) + cmd.AddCommand(ddosxSSLListCmd(f)) + cmd.AddCommand(ddosxSSLShowCmd(f)) + cmd.AddCommand(ddosxSSLCreateCmd(f)) + cmd.AddCommand(ddosxSSLUpdateCmd(f)) + cmd.AddCommand(ddosxSSLDeleteCmd(f)) // Child root rommands - cmd.AddCommand(ddosxSSLContentRootCmd()) - cmd.AddCommand(ddosxSSLPrivateKeyRootCmd()) + cmd.AddCommand(ddosxSSLContentRootCmd(f)) + cmd.AddCommand(ddosxSSLPrivateKeyRootCmd(f)) return cmd } -func ddosxSSLListCmd() *cobra.Command { +func ddosxSSLListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists ssls", Long: "This command lists ssls", Example: "ukfast ddosx ssl list", - Run: func(cmd *cobra.Command, args []string) { - ddosxSSLList(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxSSLList(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxSSLList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxSSLList(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } ssls, err := service.GetSSLs(params) if err != nil { - output.Fatalf("Error retrieving ssls: %s", err) - return + return fmt.Errorf("Error retrieving ssls: %s", err) } - outputDDoSXSSLs(ssls) + return output.CommandOutput(cmd, OutputDDoSXSSLsProvider(ssls)) } -func ddosxSSLShowCmd() *cobra.Command { +func ddosxSSLShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a ssl", @@ -72,13 +71,13 @@ func ddosxSSLShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxSSLShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxSSLShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxSSLShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxSSLShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var ssls []ddosx.SSL for _, arg := range args { ssl, err := service.GetSSL(arg) @@ -90,17 +89,17 @@ func ddosxSSLShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) ssls = append(ssls, ssl) } - outputDDoSXSSLs(ssls) + return output.CommandOutput(cmd, OutputDDoSXSSLsProvider(ssls)) } -func ddosxSSLCreateCmd() *cobra.Command { +func ddosxSSLCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates an ssl", Long: "This command creates an SSL", Example: "ukfast ddosx ssl create", RunE: func(cmd *cobra.Command, args []string) error { - return ddosxSSLCreate(getClient().DDoSXService(), cmd, args) + return ddosxSSLCreate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -151,11 +150,10 @@ func ddosxSSLCreate(service ddosx.DDoSXService, cmd *cobra.Command, args []strin return fmt.Errorf("Error retrieving new ssl [%s]: %s", id, err.Error()) } - outputDDoSXSSLs([]ddosx.SSL{ssl}) - return nil + return output.CommandOutput(cmd, OutputDDoSXSSLsProvider([]ddosx.SSL{ssl})) } -func ddosxSSLUpdateCmd() *cobra.Command { +func ddosxSSLUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ", Short: "Updates an ssl", @@ -169,7 +167,7 @@ func ddosxSSLUpdateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ddosxSSLUpdate(getClient().DDoSXService(), cmd, args) + return ddosxSSLUpdate(f.NewClient().DDoSXService(), cmd, args) }, } @@ -238,11 +236,10 @@ func ddosxSSLUpdate(service ddosx.DDoSXService, cmd *cobra.Command, args []strin return fmt.Errorf("Error retrieving updated ssl: %s", err.Error()) } - outputDDoSXSSLs([]ddosx.SSL{ssl}) - return nil + return output.CommandOutput(cmd, OutputDDoSXSSLsProvider([]ddosx.SSL{ssl})) } -func ddosxSSLDeleteCmd() *cobra.Command { +func ddosxSSLDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a ssl", @@ -256,7 +253,7 @@ func ddosxSSLDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ddosxSSLDelete(getClient().DDoSXService(), cmd, args) + ddosxSSLDelete(f.NewClient().DDoSXService(), cmd, args) }, } } diff --git a/cmd/ddosx_ssl_content.go b/cmd/ddosx/ddosx_ssl_content.go similarity index 67% rename from cmd/ddosx_ssl_content.go rename to cmd/ddosx/ddosx_ssl_content.go index b9dff43..e99303b 100644 --- a/cmd/ddosx_ssl_content.go +++ b/cmd/ddosx/ddosx_ssl_content.go @@ -1,26 +1,27 @@ -package cmd +package ddosx import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxSSLContentRootCmd() *cobra.Command { +func ddosxSSLContentRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "content", Short: "sub-commands relating to content", } // Child commands - cmd.AddCommand(ddosxSSLContentShowCmd()) + cmd.AddCommand(ddosxSSLContentShowCmd(f)) return cmd } -func ddosxSSLContentShowCmd() *cobra.Command { +func ddosxSSLContentShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a ssl's content", @@ -33,13 +34,13 @@ func ddosxSSLContentShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxSSLContentShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxSSLContentShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxSSLContentShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxSSLContentShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var sslContents []ddosx.SSLContent for _, arg := range args { sslContent, err := service.GetSSLContent(arg) @@ -51,5 +52,5 @@ func ddosxSSLContentShow(service ddosx.DDoSXService, cmd *cobra.Command, args [] sslContents = append(sslContents, sslContent) } - outputDDoSXSSLContents(sslContents) + return output.CommandOutput(cmd, OutputDDoSXSSLContentsProvider(sslContents)) } diff --git a/cmd/ddosx_ssl_content_test.go b/cmd/ddosx/ddosx_ssl_content_test.go similarity index 92% rename from cmd/ddosx_ssl_content_test.go rename to cmd/ddosx/ddosx_ssl_content_test.go index 294ceae..981d19b 100644 --- a/cmd/ddosx_ssl_content_test.go +++ b/cmd/ddosx/ddosx_ssl_content_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_ddosxSSLContentCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxSSLContentShowCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ddosxSSLContentShowCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxSSLContentShowCmd().Args(nil, []string{}) + err := ddosxSSLContentShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing ssl", err.Error()) diff --git a/cmd/ddosx_ssl_privatekey.go b/cmd/ddosx/ddosx_ssl_privatekey.go similarity index 67% rename from cmd/ddosx_ssl_privatekey.go rename to cmd/ddosx/ddosx_ssl_privatekey.go index e121ac5..db526d4 100644 --- a/cmd/ddosx_ssl_privatekey.go +++ b/cmd/ddosx/ddosx_ssl_privatekey.go @@ -1,26 +1,27 @@ -package cmd +package ddosx import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ddosx" ) -func ddosxSSLPrivateKeyRootCmd() *cobra.Command { +func ddosxSSLPrivateKeyRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "privatekey", Short: "sub-commands relating to private keys", } // Child commands - cmd.AddCommand(ddosxSSLPrivateKeyShowCmd()) + cmd.AddCommand(ddosxSSLPrivateKeyShowCmd(f)) return cmd } -func ddosxSSLPrivateKeyShowCmd() *cobra.Command { +func ddosxSSLPrivateKeyShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a ssl's private key", @@ -33,13 +34,13 @@ func ddosxSSLPrivateKeyShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ddosxSSLPrivateKeyShow(getClient().DDoSXService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ddosxSSLPrivateKeyShow(f.NewClient().DDoSXService(), cmd, args) }, } } -func ddosxSSLPrivateKeyShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) { +func ddosxSSLPrivateKeyShow(service ddosx.DDoSXService, cmd *cobra.Command, args []string) error { var sslPrivateKeys []ddosx.SSLPrivateKey for _, arg := range args { sslPrivateKey, err := service.GetSSLPrivateKey(arg) @@ -51,5 +52,5 @@ func ddosxSSLPrivateKeyShow(service ddosx.DDoSXService, cmd *cobra.Command, args sslPrivateKeys = append(sslPrivateKeys, sslPrivateKey) } - outputDDoSXSSLPrivateKeys(sslPrivateKeys) + return output.CommandOutput(cmd, OutputDDoSXSSLPrivateKeysProvider(sslPrivateKeys)) } diff --git a/cmd/ddosx_ssl_privatekey_test.go b/cmd/ddosx/ddosx_ssl_privatekey_test.go similarity index 92% rename from cmd/ddosx_ssl_privatekey_test.go rename to cmd/ddosx/ddosx_ssl_privatekey_test.go index b596c7e..37c6e3f 100644 --- a/cmd/ddosx_ssl_privatekey_test.go +++ b/cmd/ddosx/ddosx_ssl_privatekey_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_ddosxSSLPrivateKeyCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxSSLPrivateKeyShowCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ddosxSSLPrivateKeyShowCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxSSLPrivateKeyShowCmd().Args(nil, []string{}) + err := ddosxSSLPrivateKeyShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing ssl", err.Error()) diff --git a/cmd/ddosx_ssl_test.go b/cmd/ddosx/ddosx_ssl_test.go similarity index 87% rename from cmd/ddosx_ssl_test.go rename to cmd/ddosx/ddosx_ssl_test.go index 6fcd744..4fff0e5 100644 --- a/cmd/ddosx_ssl_test.go +++ b/cmd/ddosx/ddosx_ssl_test.go @@ -1,4 +1,4 @@ -package cmd +package ddosx import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ddosx" @@ -24,7 +25,7 @@ func Test_ddosxSSLList(t *testing.T) { ddosxSSLList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ddosxSSLList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ddosxSSLList(service, cmd, []string{}) - }) + err := ddosxSSLList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSSLsError_OutputsFatal", func(t *testing.T) { + t.Run("GetSSLsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ddosxSSLList(t *testing.T) { service.EXPECT().GetSSLs(gomock.Any()).Return([]ddosx.SSL{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving ssls: test error\n", func() { - ddosxSSLList(service, &cobra.Command{}, []string{}) - }) + err := ddosxSSLList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving ssls: test error", err.Error()) }) } func Test_ddosxSSLShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxSSLShowCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ddosxSSLShowCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxSSLShowCmd().Args(nil, []string{}) + err := ddosxSSLShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing ssl", err.Error()) @@ -113,7 +114,7 @@ func Test_ddosxSSLCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLCreateCmd() + cmd := ddosxSSLCreateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") cmd.Flags().Set("ukfast-ssl-id", "123") @@ -135,7 +136,7 @@ func Test_ddosxSSLCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLCreateCmd() + cmd := ddosxSSLCreateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("certificate", "testcertificate1") @@ -156,13 +157,13 @@ func Test_ddosxSSLCreate(t *testing.T) { ddosxSSLCreate(service, cmd, []string{}) }) - t.Run("CreateSSLError_OutputsFatal", func(t *testing.T) { + t.Run("CreateSSLError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLCreateCmd() + cmd := ddosxSSLCreateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") gomock.InOrder( @@ -173,13 +174,13 @@ func Test_ddosxSSLCreate(t *testing.T) { assert.Equal(t, "Error creating ssl: test error", err.Error()) }) - t.Run("GetSSLError_OutputsFatal", func(t *testing.T) { + t.Run("GetSSLError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLCreateCmd() + cmd := ddosxSSLCreateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") gomock.InOrder( @@ -194,13 +195,13 @@ func Test_ddosxSSLCreate(t *testing.T) { func Test_ddosxSSLUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxSSLUpdateCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ddosxSSLUpdateCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxSSLUpdateCmd().Args(nil, []string{}) + err := ddosxSSLUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing ssl", err.Error()) @@ -213,7 +214,7 @@ func Test_ddosxSSLUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLUpdateCmd() + cmd := ddosxSSLUpdateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") cmd.Flags().Set("ukfast-ssl-id", "123") @@ -235,7 +236,7 @@ func Test_ddosxSSLUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLUpdateCmd() + cmd := ddosxSSLUpdateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("certificate", "testcertificate1") @@ -256,12 +257,12 @@ func Test_ddosxSSLUpdate(t *testing.T) { ddosxSSLUpdate(service, cmd, []string{"00000000-0000-0000-0000-000000000000"}) }) - t.Run("UpdateSSLError_OutputsFatal", func(t *testing.T) { + t.Run("UpdateSSLError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLUpdateCmd() + cmd := ddosxSSLUpdateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") gomock.InOrder( @@ -272,12 +273,12 @@ func Test_ddosxSSLUpdate(t *testing.T) { assert.Equal(t, "Error updating ssl: test error", err.Error()) }) - t.Run("GetSSLError_OutputsFatal", func(t *testing.T) { + t.Run("GetSSLError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockDDoSXService(mockCtrl) - cmd := ddosxSSLUpdateCmd() + cmd := ddosxSSLUpdateCmd(nil) cmd.Flags().Set("friendly-name", "testssl1") gomock.InOrder( @@ -292,13 +293,13 @@ func Test_ddosxSSLUpdate(t *testing.T) { func Test_ddosxSSLDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ddosxSSLDeleteCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ddosxSSLDeleteCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ddosxSSLDeleteCmd().Args(nil, []string{}) + err := ddosxSSLDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing ssl", err.Error()) diff --git a/cmd/ddosx/output.go b/cmd/ddosx/output.go new file mode 100644 index 0000000..5d0cd52 --- /dev/null +++ b/cmd/ddosx/output.go @@ -0,0 +1,370 @@ +package ddosx + +import ( + "fmt" + "strconv" + "strings" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/ddosx" +) + +func OutputDDoSXDomainsProvider(domains []ddosx.Domain) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(domains), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, domain := range domains { + var safednsZoneID string + if domain.SafeDNSZoneID != nil { + safednsZoneID = strconv.Itoa(*domain.SafeDNSZoneID) + } + + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(domain.Name, true)) + fields.Set("status", output.NewFieldValue(domain.Status.String(), true)) + fields.Set("safedns_zone_id", output.NewFieldValue(safednsZoneID, true)) + fields.Set("dns_active", output.NewFieldValue(strconv.FormatBool(domain.DNSActive), true)) + fields.Set("cdn_active", output.NewFieldValue(strconv.FormatBool(domain.CDNActive), true)) + fields.Set("waf_active", output.NewFieldValue(strconv.FormatBool(domain.WAFActive), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXRecordsProvider(records []ddosx.Record) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(records), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, record := range records { + var safeDNSRecordID string + if record.SafeDNSRecordID != nil { + safeDNSRecordID = strconv.Itoa(*record.SafeDNSRecordID) + } + var sslID string + if record.SSLID != nil { + sslID = *record.SSLID + } + + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(record.ID, true)) + fields.Set("safedns_record_id", output.NewFieldValue(safeDNSRecordID, true)) + fields.Set("ssl_id", output.NewFieldValue(sslID, true)) + fields.Set("domain_name", output.NewFieldValue(record.DomainName, true)) + fields.Set("name", output.NewFieldValue(record.Name, true)) + fields.Set("type", output.NewFieldValue(record.Type.String(), true)) + fields.Set("content", output.NewFieldValue(record.Content, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXWAFsProvider(wafs []ddosx.WAF) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(wafs), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, waf := range wafs { + fields := output.NewOrderedFields() + fields.Set("mode", output.NewFieldValue(waf.Mode.String(), true)) + fields.Set("paranoia_level", output.NewFieldValue(waf.ParanoiaLevel.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXWAFRuleSetsProvider(rulesets []ddosx.WAFRuleSet) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rulesets), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, ruleset := range rulesets { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(ruleset.ID, true)) + fields.Set("name", output.NewFieldValue(ruleset.Name.String(), true)) + fields.Set("active", output.NewFieldValue(strconv.FormatBool(ruleset.Active), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXWAFRulesProvider(rules []ddosx.WAFRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("uri", output.NewFieldValue(rule.URI, true)) + fields.Set("ip", output.NewFieldValue(rule.IP.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXWAFAdvancedRulesProvider(rules []ddosx.WAFAdvancedRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("section", output.NewFieldValue(rule.Section.String(), true)) + fields.Set("modifier", output.NewFieldValue(rule.Modifier.String(), true)) + fields.Set("phrase", output.NewFieldValue(rule.Phrase, true)) + fields.Set("ip", output.NewFieldValue(rule.IP.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXSSLsProvider(ssls []ddosx.SSL) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(ssls), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, ssl := range ssls { + var ukfastSSLID string + if ssl.UKFastSSLID != nil { + ukfastSSLID = strconv.Itoa(*ssl.UKFastSSLID) + } + + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(ssl.ID, true)) + fields.Set("ukfast_ssl_id", output.NewFieldValue(ukfastSSLID, true)) + fields.Set("domains", output.NewFieldValue(strings.Join(ssl.Domains, ", "), true)) + fields.Set("friendly_name", output.NewFieldValue(ssl.FriendlyName, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXSSLContentsProvider(sslContents []ddosx.SSLContent) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(sslContents), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, sslContent := range sslContents { + fields := output.NewOrderedFields() + fields.Set("certificate", output.NewFieldValue(sslContent.Certificate, true)) + fields.Set("ca_bundle", output.NewFieldValue(sslContent.CABundle, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXSSLPrivateKeysProvider(sslPrivateKeys []ddosx.SSLPrivateKey) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(sslPrivateKeys), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, sslPrivateKey := range sslPrivateKeys { + fields := output.NewOrderedFields() + fields.Set("key", output.NewFieldValue(sslPrivateKey.Key, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXACLIPRulesProvider(rules []ddosx.ACLIPRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("mode", output.NewFieldValue(rule.Mode.String(), true)) + fields.Set("ip", output.NewFieldValue(rule.IP.String(), true)) + fields.Set("uri", output.NewFieldValue(rule.URI, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXACLGeoIPRulesProvider(rules []ddosx.ACLGeoIPRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("name", output.NewFieldValue(rule.Name, true)) + fields.Set("code", output.NewFieldValue(rule.Code, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXACLGeoIPRulesModesProvider(modes []ddosx.ACLGeoIPRulesMode) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(modes), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, mode := range modes { + fields := output.NewOrderedFields() + fields.Set("mode", output.NewFieldValue(mode.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXDomainPropertiesProvider(properties []ddosx.DomainProperty) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(properties), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, property := range properties { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(property.ID, true)) + fields.Set("name", output.NewFieldValue(property.Name.String(), true)) + fields.Set("value", output.NewFieldValue(fmt.Sprintf("%v", property.Value), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +type OutputDDoSXDomainVerificationFilesFile struct { + Name string + Content string +} + +func OutputDDoSXDomainVerificationFilesProvider(files []OutputDDoSXDomainVerificationFilesFile) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(files), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, file := range files { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(file.Name, true)) + fields.Set("content", output.NewFieldValue(file.Content, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXCDNRulesProvider(rules []ddosx.CDNRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("uri", output.NewFieldValue(rule.URI, true)) + fields.Set("cache_control", output.NewFieldValue(rule.CacheControl.String(), true)) + fields.Set("cache_control_duration", output.NewFieldValue(rule.CacheControlDuration.String(), true)) + fields.Set("mime_types", output.NewFieldValue(strings.Join(rule.MimeTypes, ", "), true)) + fields.Set("type", output.NewFieldValue(rule.Type.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXHSTSConfigurationsProvider(configurations []ddosx.HSTSConfiguration) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(configurations), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, configuration := range configurations { + fields := output.NewOrderedFields() + fields.Set("enabled", output.NewFieldValue(strconv.FormatBool(configuration.Enabled), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputDDoSXHSTSRulesProvider(rules []ddosx.HSTSRule) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(rules), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, rule := range rules { + recordName := "" + if rule.RecordName != nil { + recordName = *rule.RecordName + } + + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(rule.ID, true)) + fields.Set("max_age", output.NewFieldValue(strconv.Itoa(rule.MaxAge), true)) + fields.Set("preload", output.NewFieldValue(strconv.FormatBool(rule.Preload), true)) + fields.Set("include_subdomains", output.NewFieldValue(strconv.FormatBool(rule.IncludeSubdomains), true)) + fields.Set("type", output.NewFieldValue(rule.Type.String(), true)) + fields.Set("record_name", output.NewFieldValue(recordName, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/ddosx_domain_acl.go b/cmd/ddosx_domain_acl.go deleted file mode 100644 index 578583e..0000000 --- a/cmd/ddosx_domain_acl.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import "github.com/spf13/cobra" - -func ddosxDomainACLRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "acl", - Short: "sub-commands relating to domain ACLs", - } - - // Child root commands - cmd.AddCommand(ddosxDomainACLIPRuleRootCmd()) - cmd.AddCommand(ddosxDomainACLGeoIPRuleRootCmd()) - - return cmd -} diff --git a/cmd/ddosx_domain_verification.go b/cmd/ddosx_domain_verification.go deleted file mode 100644 index 03f9cd3..0000000 --- a/cmd/ddosx_domain_verification.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import "github.com/spf13/cobra" - -func ddosxDomainVerificationRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "verification", - Short: "sub-commands relating to domain verification", - } - - // Child root commands - cmd.AddCommand(ddosxDomainVerificationFileUploadRootCmd()) - cmd.AddCommand(ddosxDomainVerificationDNSRootCmd()) - - return cmd -} diff --git a/cmd/ddosx_test.go b/cmd/ddosx_test.go deleted file mode 100644 index ebbae3e..0000000 --- a/cmd/ddosx_test.go +++ /dev/null @@ -1,727 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/ptr" - "github.com/ukfast/sdk-go/pkg/service/ddosx" -) - -func TestOutputDDoSXDomains_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXDomains{ - Domains: []ddosx.Domain{ - ddosx.Domain{ - Name: "testdomain.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.Domain{}, data) - assert.Equal(t, "testdomain.com", data.([]ddosx.Domain)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXDomains{ - Domains: []ddosx.Domain{ - ddosx.Domain{ - Name: "testdomain1.com", - }, - ddosx.Domain{ - Name: "testdomain2.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.Domain{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testdomain1.com", data.([]ddosx.Domain)[0].Name) - assert.Equal(t, "testdomain2.com", data.([]ddosx.Domain)[1].Name) - }) -} - -func TestOutputDDoSXDomains_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXDomains{ - Domains: []ddosx.Domain{ - ddosx.Domain{ - Name: "testdomain.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain.com", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXDomains{ - Domains: []ddosx.Domain{ - ddosx.Domain{ - Name: "testdomain1.com", - }, - ddosx.Domain{ - Name: "testdomain2.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain1.com", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testdomain2.com", data[1].Get("name").Value) - }) -} - -func TestOutputDDoSXRecords_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXRecords{ - Records: []ddosx.Record{ - ddosx.Record{ - Name: "testdomain.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.Record{}, data) - assert.Equal(t, "testdomain.com", data.([]ddosx.Record)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXRecords{ - Records: []ddosx.Record{ - ddosx.Record{ - Name: "testdomain1.com", - }, - ddosx.Record{ - Name: "testdomain2.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.Record{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testdomain1.com", data.([]ddosx.Record)[0].Name) - assert.Equal(t, "testdomain2.com", data.([]ddosx.Record)[1].Name) - }) -} - -func TestOutputDDoSXRecords_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXRecords{ - Records: []ddosx.Record{ - ddosx.Record{ - Name: "testdomain.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain.com", data[0].Get("name").Value) - }) - - t.Run("SingleWithSafeDNSRecordID_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXRecords{ - Records: []ddosx.Record{ - ddosx.Record{ - Name: "testdomain.com", - SafeDNSRecordID: ptr.Int(123), - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain.com", data[0].Get("name").Value) - assert.Equal(t, "123", data[0].Get("safedns_record_id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXRecords{ - Records: []ddosx.Record{ - ddosx.Record{ - Name: "testdomain1.com", - }, - ddosx.Record{ - Name: "testdomain2.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain1.com", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testdomain2.com", data[1].Get("name").Value) - }) -} - -func TestOutputDDoSXWAFs_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXWAFs{ - WAFs: []ddosx.WAF{ - ddosx.WAF{ - Mode: ddosx.WAFModeOn, - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.WAF{}, data) - assert.Equal(t, ddosx.WAFModeOn, data.([]ddosx.WAF)[0].Mode) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXWAFs{ - WAFs: []ddosx.WAF{ - ddosx.WAF{ - Mode: ddosx.WAFModeOn, - }, - ddosx.WAF{ - Mode: ddosx.WAFModeOff, - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.WAF{}, data) - assert.Len(t, data, 2) - assert.Equal(t, ddosx.WAFModeOn, data.([]ddosx.WAF)[0].Mode) - assert.Equal(t, ddosx.WAFModeOff, data.([]ddosx.WAF)[1].Mode) - }) -} - -func TestOutputDDoSXWAFs_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXWAFs{ - WAFs: []ddosx.WAF{ - ddosx.WAF{ - Mode: ddosx.WAFModeOn, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("mode")) - assert.Equal(t, "On", data[0].Get("mode").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXWAFs{ - WAFs: []ddosx.WAF{ - ddosx.WAF{ - Mode: ddosx.WAFModeOn, - }, - ddosx.WAF{ - Mode: ddosx.WAFModeOff, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("mode")) - assert.Equal(t, "On", data[0].Get("mode").Value) - assert.True(t, data[1].Exists("mode")) - assert.Equal(t, "Off", data[1].Get("mode").Value) - }) -} - -func TestOutputDDoSXWAFRuleSets_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXWAFRuleSets{ - WAFRuleSets: []ddosx.WAFRuleSet{ - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.WAFRuleSet{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.WAFRuleSet)[0].ID) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXWAFRuleSets{ - WAFRuleSets: []ddosx.WAFRuleSet{ - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.WAFRuleSet{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.WAFRuleSet)[0].ID) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data.([]ddosx.WAFRuleSet)[1].ID) - }) -} - -func TestOutputDDoSXWAFRuleSets_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXWAFRuleSets{ - WAFRuleSets: []ddosx.WAFRuleSet{ - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXWAFRuleSets{ - WAFRuleSets: []ddosx.WAFRuleSet{ - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.WAFRuleSet{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - assert.True(t, data[1].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data[1].Get("id").Value) - }) -} - -func TestOutputDDoSXSSLs_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXSSLs{ - SSLs: []ddosx.SSL{ - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.SSL{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.SSL)[0].ID) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXSSLs{ - SSLs: []ddosx.SSL{ - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.SSL{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.SSL)[0].ID) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data.([]ddosx.SSL)[1].ID) - }) -} - -func TestOutputDDoSXSSLs_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXSSLs{ - SSLs: []ddosx.SSL{ - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXSSLs{ - SSLs: []ddosx.SSL{ - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.SSL{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - assert.True(t, data[1].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data[1].Get("id").Value) - }) -} - -func TestOutputDDoSXACLIPRules_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLIPRules{ - ACLIPRules: []ddosx.ACLIPRule{ - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLIPRule{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.ACLIPRule)[0].ID) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLIPRules{ - ACLIPRules: []ddosx.ACLIPRule{ - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLIPRule{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.ACLIPRule)[0].ID) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data.([]ddosx.ACLIPRule)[1].ID) - }) -} - -func TestOutputDDoSXACLIPRules_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLIPRules{ - ACLIPRules: []ddosx.ACLIPRule{ - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLIPRules{ - ACLIPRules: []ddosx.ACLIPRule{ - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.ACLIPRule{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - assert.True(t, data[1].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data[1].Get("id").Value) - }) -} - -func TestOutputDDoSXACLGeoIPRules_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRules{ - ACLGeoIPRules: []ddosx.ACLGeoIPRule{ - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLGeoIPRule{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.ACLGeoIPRule)[0].ID) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRules{ - ACLGeoIPRules: []ddosx.ACLGeoIPRule{ - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLGeoIPRule{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.ACLGeoIPRule)[0].ID) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data.([]ddosx.ACLGeoIPRule)[1].ID) - }) -} - -func TestOutputDDoSXACLGeoIPRules_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRules{ - ACLGeoIPRules: []ddosx.ACLGeoIPRule{ - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRules{ - ACLGeoIPRules: []ddosx.ACLGeoIPRule{ - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - ddosx.ACLGeoIPRule{ - ID: "00000000-0000-0000-0000-000000000001", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - assert.True(t, data[1].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000001", data[1].Get("id").Value) - }) -} - -func TestOutputDDoSXACLGeoIPRulesModes_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRulesModes{ - ACLGeoIPRulesModes: []ddosx.ACLGeoIPRulesMode{ - ddosx.ACLGeoIPRulesModeWhitelist, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLGeoIPRulesMode{}, data) - assert.Equal(t, ddosx.ACLGeoIPRulesModeWhitelist, data.([]ddosx.ACLGeoIPRulesMode)[0]) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRulesModes{ - ACLGeoIPRulesModes: []ddosx.ACLGeoIPRulesMode{ - ddosx.ACLGeoIPRulesModeWhitelist, - ddosx.ACLGeoIPRulesModeBlacklist, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.ACLGeoIPRulesMode{}, data) - assert.Len(t, data, 2) - assert.Equal(t, ddosx.ACLGeoIPRulesModeWhitelist, data.([]ddosx.ACLGeoIPRulesMode)[0]) - assert.Equal(t, ddosx.ACLGeoIPRulesModeBlacklist, data.([]ddosx.ACLGeoIPRulesMode)[1]) - }) -} - -func TestOutputDDoSXACLGeoIPRulesModes_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRulesModes{ - ACLGeoIPRulesModes: []ddosx.ACLGeoIPRulesMode{ - ddosx.ACLGeoIPRulesModeWhitelist, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("mode")) - assert.Equal(t, "Whitelist", data[0].Get("mode").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputDDoSXACLGeoIPRulesModes{ - ACLGeoIPRulesModes: []ddosx.ACLGeoIPRulesMode{ - ddosx.ACLGeoIPRulesModeWhitelist, - ddosx.ACLGeoIPRulesModeBlacklist, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("mode")) - assert.Equal(t, "Whitelist", data[0].Get("mode").Value) - assert.True(t, data[1].Exists("mode")) - assert.Equal(t, "Blacklist", data[1].Get("mode").Value) - }) -} - -func TestOutputDDoSXCDNRules_GetData_ExpectedData(t *testing.T) { - o := OutputDDoSXCDNRules{ - CDNRules: []ddosx.CDNRule{ - ddosx.CDNRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.CDNRule{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.CDNRule)[0].ID) -} - -func TestOutputDDoSXCDNRules_GetFieldData_ExpectedFieldData(t *testing.T) { - o := OutputDDoSXCDNRules{ - CDNRules: []ddosx.CDNRule{ - ddosx.CDNRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) -} - -func TestOutputDDoSXHSTSConfiguration_GetData_ExpectedData(t *testing.T) { - o := OutputDDoSXHSTSConfiguration{ - HSTSConfiguration: []ddosx.HSTSConfiguration{ - ddosx.HSTSConfiguration{ - Enabled: true, - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.HSTSConfiguration{}, data) - assert.Equal(t, true, data.([]ddosx.HSTSConfiguration)[0].Enabled) -} - -func TestOutputDDoSXHSTSConfiguration_GetFieldData_ExpectedFieldData(t *testing.T) { - o := OutputDDoSXHSTSConfiguration{ - HSTSConfiguration: []ddosx.HSTSConfiguration{ - ddosx.HSTSConfiguration{ - Enabled: true, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("enabled")) - assert.Equal(t, "true", data[0].Get("enabled").Value) -} - -func TestOutputDDoSXHSTSRules_GetData_ExpectedData(t *testing.T) { - o := OutputDDoSXHSTSRules{ - HSTSRules: []ddosx.HSTSRule{ - ddosx.HSTSRule{ - ID: "00000000-0000-0000-0000-000000000000", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ddosx.HSTSRule{}, data) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data.([]ddosx.HSTSRule)[0].ID) -} - -func TestOutputDDoSXHSTSRules_GetFieldData_ExpectedFieldData(t *testing.T) { - o := OutputDDoSXHSTSRules{ - HSTSRules: []ddosx.HSTSRule{ - ddosx.HSTSRule{ - ID: "00000000-0000-0000-0000-000000000000", - RecordName: ptr.String("example.com"), - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "00000000-0000-0000-0000-000000000000", data[0].Get("id").Value) - assert.True(t, data[0].Exists("record_name")) - assert.Equal(t, "example.com", data[0].Get("record_name").Value) -} diff --git a/cmd/ecloud.go b/cmd/ecloud.go deleted file mode 100644 index 677d877..0000000 --- a/cmd/ecloud.go +++ /dev/null @@ -1,614 +0,0 @@ -package cmd - -import ( - "errors" - "fmt" - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/ecloud" -) - -func ecloudRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "ecloud", - Short: "Commands relating to eCloud service", - } - - // Child root commands - cmd.AddCommand(ecloudVirtualMachineRootCmd()) - cmd.AddCommand(ecloudSolutionRootCmd()) - cmd.AddCommand(ecloudSiteRootCmd()) - cmd.AddCommand(ecloudHostRootCmd()) - cmd.AddCommand(ecloudFirewallRootCmd()) - cmd.AddCommand(ecloudPodRootCmd()) - cmd.AddCommand(ecloudDatastoreRootCmd()) - cmd.AddCommand(ecloudApplianceRootCmd()) - cmd.AddCommand(ecloudCreditRootCmd()) - - return cmd -} - -// OutputECloudVirtualMachines implements OutputDataProvider for outputting an array of virtual machines -type OutputECloudVirtualMachines struct { - VirtualMachines []ecloud.VirtualMachine -} - -func outputECloudVirtualMachines(vms []ecloud.VirtualMachine) { - err := Output(&OutputECloudVirtualMachines{VirtualMachines: vms}) - if err != nil { - output.Fatalf("Failed to output virtual machines: %s", err) - } -} - -func (o *OutputECloudVirtualMachines) GetData() interface{} { - return o.VirtualMachines -} - -func (o *OutputECloudVirtualMachines) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, vm := range o.VirtualMachines { - fields := o.getOrderedFields(vm) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudVirtualMachines) getOrderedFields(vm ecloud.VirtualMachine) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(vm.ID), true)) - fields.Set("name", output.NewFieldValue(vm.Name, true)) - fields.Set("hostname", output.NewFieldValue(vm.Hostname, false)) - fields.Set("computername", output.NewFieldValue(vm.ComputerName, false)) - fields.Set("cpu", output.NewFieldValue(strconv.Itoa(vm.CPU), true)) - fields.Set("ram_gb", output.NewFieldValue(strconv.Itoa(vm.RAM), true)) - fields.Set("hdd_gb", output.NewFieldValue(strconv.Itoa(vm.HDD), true)) - fields.Set("ip_internal", output.NewFieldValue(vm.IPInternal.String(), true)) - fields.Set("ip_external", output.NewFieldValue(vm.IPExternal.String(), true)) - fields.Set("platform", output.NewFieldValue(vm.Platform, false)) - fields.Set("template", output.NewFieldValue(vm.Template, false)) - fields.Set("backup", output.NewFieldValue(strconv.FormatBool(vm.Backup), false)) - fields.Set("support", output.NewFieldValue(strconv.FormatBool(vm.Support), false)) - fields.Set("environment", output.NewFieldValue(vm.Environment, false)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(vm.SolutionID), false)) - fields.Set("status", output.NewFieldValue(vm.Status.String(), true)) - fields.Set("power_status", output.NewFieldValue(vm.PowerStatus, true)) - fields.Set("tools_status", output.NewFieldValue(vm.ToolsStatus, false)) - fields.Set("encrypted", output.NewFieldValue(strconv.FormatBool(vm.Encrypted), false)) - fields.Set("role", output.NewFieldValue(vm.Role, false)) - - return fields -} - -// OutputECloudVirtualMachineDisks implements OutputDataProvider for outputting an array of virtual machine disks -type OutputECloudVirtualMachineDisks struct { - VirtualMachineDisks []ecloud.VirtualMachineDisk -} - -func outputECloudVirtualMachineDisks(disks []ecloud.VirtualMachineDisk) { - err := Output(&OutputECloudVirtualMachineDisks{VirtualMachineDisks: disks}) - if err != nil { - output.Fatalf("Failed to output virtual machine disks: %s", err) - } -} - -func (o *OutputECloudVirtualMachineDisks) GetData() interface{} { - return o.VirtualMachineDisks -} - -func (o *OutputECloudVirtualMachineDisks) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, disk := range o.VirtualMachineDisks { - fields := o.getOrderedFields(disk) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudVirtualMachineDisks) getOrderedFields(disk ecloud.VirtualMachineDisk) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("name", output.NewFieldValue(disk.Name, true)) - fields.Set("capacity", output.NewFieldValue(strconv.Itoa(disk.Capacity), true)) - fields.Set("uuid", output.NewFieldValue(disk.UUID, true)) - fields.Set("type", output.NewFieldValue(disk.Type.String(), true)) - fields.Set("key", output.NewFieldValue(strconv.Itoa(disk.Key), false)) - - return fields -} - -// OutputECloudTags implements OutputDataProvider for outputting an array of tags -type OutputECloudTags struct { - Tags []ecloud.Tag -} - -func outputECloudTags(tags []ecloud.Tag) { - err := Output(&OutputECloudTags{Tags: tags}) - if err != nil { - output.Fatalf("Failed to output tags: %s", err) - } -} - -func (o *OutputECloudTags) GetData() interface{} { - return o.Tags -} - -func (o *OutputECloudTags) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, tag := range o.Tags { - fields := o.getOrderedFields(tag) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudTags) getOrderedFields(tag ecloud.Tag) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("key", output.NewFieldValue(tag.Key, true)) - fields.Set("value", output.NewFieldValue(tag.Value, true)) - fields.Set("created_at", output.NewFieldValue(tag.CreatedAt.String(), true)) - - return fields -} - -// OutputECloudSolutions implements OutputDataProvider for outputting an array of tags -type OutputECloudSolutions struct { - Solutions []ecloud.Solution -} - -func outputECloudSolutions(solutions []ecloud.Solution) { - err := Output(&OutputECloudSolutions{Solutions: solutions}) - if err != nil { - output.Fatalf("Failed to output solutions: %s", err) - } -} - -func (o *OutputECloudSolutions) GetData() interface{} { - return o.Solutions -} - -func (o *OutputECloudSolutions) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, solution := range o.Solutions { - fields := o.getOrderedFields(solution) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudSolutions) getOrderedFields(solution ecloud.Solution) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(solution.ID), true)) - fields.Set("name", output.NewFieldValue(solution.Name, true)) - fields.Set("environment", output.NewFieldValue(solution.Environment.String(), true)) - - return fields -} - -// OutputECloudSites implements OutputDataProvider for outputting an array of sites -type OutputECloudSites struct { - Sites []ecloud.Site -} - -func outputECloudSites(sites []ecloud.Site) { - err := Output(&OutputECloudSites{Sites: sites}) - if err != nil { - output.Fatalf("Failed to output sites: %s", err) - } -} - -func (o *OutputECloudSites) GetData() interface{} { - return o.Sites -} - -func (o *OutputECloudSites) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, site := range o.Sites { - fields := o.getOrderedFields(site) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudSites) getOrderedFields(site ecloud.Site) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(site.ID), true)) - fields.Set("state", output.NewFieldValue(site.State, true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(site.SolutionID), true)) - fields.Set("pod_id", output.NewFieldValue(strconv.Itoa(site.PodID), true)) - - return fields -} - -// OutputECloudHosts implements OutputDataProvider for outputting an array of hosts -type OutputECloudHosts struct { - Hosts []ecloud.Host -} - -func outputECloudHosts(hosts []ecloud.Host) { - err := Output(&OutputECloudHosts{Hosts: hosts}) - if err != nil { - output.Fatalf("Failed to output hosts: %s", err) - } -} - -func (o *OutputECloudHosts) GetData() interface{} { - return o.Hosts -} - -func (o *OutputECloudHosts) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, host := range o.Hosts { - fields := o.getOrderedFields(host) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudHosts) getOrderedFields(host ecloud.Host) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(host.ID), true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(host.SolutionID), true)) - fields.Set("pod_id", output.NewFieldValue(strconv.Itoa(host.PodID), true)) - fields.Set("name", output.NewFieldValue(host.Name, true)) - fields.Set("cpu_quantity", output.NewFieldValue(strconv.Itoa(host.CPU.Quantity), true)) - fields.Set("cpu_cores", output.NewFieldValue(strconv.Itoa(host.CPU.Cores), true)) - fields.Set("cpu_speed", output.NewFieldValue(host.CPU.Speed, false)) - fields.Set("ram_capacity", output.NewFieldValue(strconv.Itoa(host.RAM.Capacity), true)) - fields.Set("ram_reserved", output.NewFieldValue(strconv.Itoa(host.RAM.Reserved), false)) - fields.Set("ram_allocated", output.NewFieldValue(strconv.Itoa(host.RAM.Allocated), false)) - fields.Set("ram_available", output.NewFieldValue(strconv.Itoa(host.RAM.Available), false)) - - return fields -} - -// OutputECloudDatastores implements OutputDataProvider for outputting an array of hosts -type OutputECloudDatastores struct { - Datastores []ecloud.Datastore -} - -func outputECloudDatastores(datastores []ecloud.Datastore) { - err := Output(&OutputECloudDatastores{Datastores: datastores}) - if err != nil { - output.Fatalf("Failed to output datastores: %s", err) - } -} - -func (o *OutputECloudDatastores) GetData() interface{} { - return o.Datastores -} - -func (o *OutputECloudDatastores) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, datastore := range o.Datastores { - fields := o.getOrderedFields(datastore) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudDatastores) getOrderedFields(datastore ecloud.Datastore) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(datastore.ID), true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(datastore.SolutionID), true)) - fields.Set("site_id", output.NewFieldValue(strconv.Itoa(datastore.SiteID), true)) - fields.Set("name", output.NewFieldValue(datastore.Name, true)) - fields.Set("status", output.NewFieldValue(datastore.Status.String(), true)) - fields.Set("capacity", output.NewFieldValue(strconv.Itoa(datastore.Capacity), true)) - fields.Set("allocated", output.NewFieldValue(strconv.Itoa(datastore.Allocated), false)) - fields.Set("available", output.NewFieldValue(strconv.Itoa(datastore.Available), false)) - - return fields -} - -// OutputECloudTemplates implements OutputDataProvider for outputting an array of hosts -type OutputECloudTemplates struct { - Templates []ecloud.Template -} - -func outputECloudTemplates(templates []ecloud.Template) { - err := Output(&OutputECloudTemplates{Templates: templates}) - if err != nil { - output.Fatalf("Failed to output templates: %s", err) - } -} - -func (o *OutputECloudTemplates) GetData() interface{} { - return o.Templates -} - -func (o *OutputECloudTemplates) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, template := range o.Templates { - fields := o.getOrderedFields(template) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudTemplates) getOrderedFields(template ecloud.Template) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("name", output.NewFieldValue(template.Name, true)) - fields.Set("cpu", output.NewFieldValue(strconv.Itoa(template.CPU), true)) - fields.Set("ram_gb", output.NewFieldValue(strconv.Itoa(template.RAM), true)) - fields.Set("hdd_gb", output.NewFieldValue(strconv.Itoa(template.HDD), true)) - fields.Set("platform", output.NewFieldValue(template.Platform, true)) - fields.Set("operating_system", output.NewFieldValue(template.OperatingSystem, true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(template.SolutionID), true)) - - return fields -} - -// OutputECloudNetworks implements OutputDataProvider for outputting an array of hosts -type OutputECloudNetworks struct { - Networks []ecloud.Network -} - -func outputECloudNetworks(networks []ecloud.Network) { - err := Output(&OutputECloudNetworks{Networks: networks}) - if err != nil { - output.Fatalf("Failed to output networks: %s", err) - } -} - -func (o *OutputECloudNetworks) GetData() interface{} { - return o.Networks -} - -func (o *OutputECloudNetworks) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, network := range o.Networks { - fields := o.getOrderedFields(network) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudNetworks) getOrderedFields(network ecloud.Network) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(network.ID), true)) - fields.Set("name", output.NewFieldValue(network.Name, true)) - - return fields -} - -// OutputECloudFirewalls implements OutputDataProvider for outputting an array of hosts -type OutputECloudFirewalls struct { - Firewalls []ecloud.Firewall -} - -func outputECloudFirewalls(firewalls []ecloud.Firewall) { - err := Output(&OutputECloudFirewalls{Firewalls: firewalls}) - if err != nil { - output.Fatalf("Failed to output firewalls: %s", err) - } -} - -func (o *OutputECloudFirewalls) GetData() interface{} { - return o.Firewalls -} - -func (o *OutputECloudFirewalls) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, firewall := range o.Firewalls { - fields := o.getOrderedFields(firewall) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudFirewalls) getOrderedFields(firewall ecloud.Firewall) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(firewall.ID), true)) - fields.Set("name", output.NewFieldValue(firewall.Name, true)) - fields.Set("hostname", output.NewFieldValue(firewall.Hostname, true)) - fields.Set("ip", output.NewFieldValue(firewall.IP.String(), true)) - fields.Set("role", output.NewFieldValue(firewall.Role.String(), true)) - - return fields -} - -// OutputECloudPods implements OutputDataProvider for outputting an array of pods -type OutputECloudPods struct { - Pods []ecloud.Pod -} - -func outputECloudPods(pods []ecloud.Pod) { - err := Output(&OutputECloudPods{Pods: pods}) - if err != nil { - output.Fatalf("Failed to output pods: %s", err) - } -} - -func (o *OutputECloudPods) GetData() interface{} { - return o.Pods -} - -func (o *OutputECloudPods) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, pod := range o.Pods { - fields := o.getOrderedFields(pod) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudPods) getOrderedFields(pod ecloud.Pod) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(pod.ID), true)) - fields.Set("name", output.NewFieldValue(pod.Name, true)) - - return fields -} - -// OutputECloudAppliances implements OutputDataProvider for outputting an array of appliances -type OutputECloudAppliances struct { - Appliances []ecloud.Appliance -} - -func outputECloudAppliances(appliances []ecloud.Appliance) { - err := Output(&OutputECloudAppliances{Appliances: appliances}) - if err != nil { - output.Fatalf("Failed to output appliances: %s", err) - } -} - -func (o *OutputECloudAppliances) GetData() interface{} { - return o.Appliances -} - -func (o *OutputECloudAppliances) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, appliance := range o.Appliances { - fields := o.getOrderedFields(appliance) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudAppliances) getOrderedFields(appliance ecloud.Appliance) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(appliance.ID, true)) - fields.Set("name", output.NewFieldValue(appliance.Name, true)) - fields.Set("logo_uri", output.NewFieldValue(appliance.LogoURI, false)) - fields.Set("description", output.NewFieldValue(appliance.Description, false)) - fields.Set("documentation_uri", output.NewFieldValue(appliance.DocumentationURI, false)) - fields.Set("publisher", output.NewFieldValue(appliance.Publisher, true)) - fields.Set("created_at", output.NewFieldValue(appliance.CreatedAt.String(), true)) - - return fields -} - -// OutputECloudApplianceParameters implements OutputDataProvider for outputting an array of appliance parameters -type OutputECloudApplianceParameters struct { - ApplianceParameters []ecloud.ApplianceParameter -} - -func outputECloudApplianceParameters(parameters []ecloud.ApplianceParameter) { - err := Output(&OutputECloudApplianceParameters{ApplianceParameters: parameters}) - if err != nil { - output.Fatalf("Failed to output appliance parameters: %s", err) - } -} - -func (o *OutputECloudApplianceParameters) GetData() interface{} { - return o.ApplianceParameters -} - -func (o *OutputECloudApplianceParameters) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, parameter := range o.ApplianceParameters { - fields := o.getOrderedFields(parameter) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputECloudApplianceParameters) getOrderedFields(parameter ecloud.ApplianceParameter) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(parameter.ID, true)) - fields.Set("name", output.NewFieldValue(parameter.Name, true)) - fields.Set("key", output.NewFieldValue(parameter.Key, true)) - fields.Set("type", output.NewFieldValue(parameter.Type, true)) - fields.Set("description", output.NewFieldValue(parameter.Description, true)) - fields.Set("required", output.NewFieldValue(strconv.FormatBool(parameter.Required), true)) - fields.Set("validation_rule", output.NewFieldValue(parameter.ValidationRule, false)) - - return fields -} - -// GetCreateTagRequestFromStringArrayFlag returns an array of CreateTagRequest structs from given tag string array flag -func GetCreateTagRequestFromStringArrayFlag(tagsFlag []string) ([]ecloud.CreateTagRequest, error) { - var tags []ecloud.CreateTagRequest - for _, tagFlag := range tagsFlag { - key, value, err := GetKeyValueFromStringFlag(tagFlag) - if err != nil { - return tags, err - } - - tags = append(tags, ecloud.CreateTagRequest{Key: key, Value: value}) - } - - return tags, nil -} - -// GetCreateVirtualMachineRequestParameterFromStringArrayFlag returns an array of CreateVirtualMachineRequestParameter structs from given string array flag -func GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parametersFlag []string) ([]ecloud.CreateVirtualMachineRequestParameter, error) { - var parameters []ecloud.CreateVirtualMachineRequestParameter - for _, parameterFlag := range parametersFlag { - key, value, err := GetKeyValueFromStringFlag(parameterFlag) - if err != nil { - return parameters, err - } - - parameters = append(parameters, ecloud.CreateVirtualMachineRequestParameter{Key: key, Value: value}) - } - - return parameters, nil -} - -// GetKeyValueFromStringFlag returns a string map from given string flag. Expects format 'key=value' -func GetKeyValueFromStringFlag(flag string) (key, value string, err error) { - if flag == "" { - return key, value, errors.New("Missing key/value") - } - - parts := strings.Split(flag, "=") - if len(parts) < 2 || len(parts) > 2 { - return key, value, errors.New("Invalid format, expecting: key=value") - } - if parts[0] == "" { - return key, value, errors.New("Missing key") - } - if parts[1] == "" { - return key, value, errors.New("Missing value") - } - - return parts[0], parts[1], nil -} - -// SolutionTemplateExistsWaitFunc returns WaitFunc for waiting for a template to exist -func SolutionTemplateExistsWaitFunc(service ecloud.ECloudService, solutionID int, templateName string, exists bool) WaitFunc { - return func() (finished bool, err error) { - _, err = service.GetSolutionTemplate(solutionID, templateName) - if err != nil { - if _, ok := err.(*ecloud.TemplateNotFoundError); ok { - return (exists == false), nil - } - - return false, fmt.Errorf("Failed to retrieve solution template [%s]: %s", templateName, err.Error()) - } - - return (exists == true), nil - } -} - -// PodTemplateExistsWaitFunc returns WaitFunc for waiting for a template to exist -func PodTemplateExistsWaitFunc(service ecloud.ECloudService, podID int, templateName string, exists bool) WaitFunc { - return func() (finished bool, err error) { - _, err = service.GetPodTemplate(podID, templateName) - if err != nil { - if _, ok := err.(*ecloud.TemplateNotFoundError); ok { - return (exists == false), nil - } - - return false, fmt.Errorf("Failed to retrieve pod template [%s]: %s", templateName, err.Error()) - } - - return (exists == true), nil - } -} diff --git a/cmd/ecloud/ecloud.go b/cmd/ecloud/ecloud.go new file mode 100644 index 0000000..64e3611 --- /dev/null +++ b/cmd/ecloud/ecloud.go @@ -0,0 +1,114 @@ +package ecloud + +import ( + "errors" + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/helper" + "github.com/ukfast/sdk-go/pkg/service/ecloud" +) + +func ECloudRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "ecloud", + Short: "Commands relating to eCloud service", + } + + // Child root commands + cmd.AddCommand(ecloudVirtualMachineRootCmd(f)) + cmd.AddCommand(ecloudSolutionRootCmd(f)) + cmd.AddCommand(ecloudSiteRootCmd(f)) + cmd.AddCommand(ecloudHostRootCmd(f)) + cmd.AddCommand(ecloudFirewallRootCmd(f)) + cmd.AddCommand(ecloudPodRootCmd(f)) + cmd.AddCommand(ecloudDatastoreRootCmd(f)) + cmd.AddCommand(ecloudApplianceRootCmd(f)) + cmd.AddCommand(ecloudCreditRootCmd(f)) + + return cmd +} + +// GetCreateTagRequestFromStringArrayFlag returns an array of CreateTagRequest structs from given tag string array flag +func GetCreateTagRequestFromStringArrayFlag(tagsFlag []string) ([]ecloud.CreateTagRequest, error) { + var tags []ecloud.CreateTagRequest + for _, tagFlag := range tagsFlag { + key, value, err := GetKeyValueFromStringFlag(tagFlag) + if err != nil { + return tags, err + } + + tags = append(tags, ecloud.CreateTagRequest{Key: key, Value: value}) + } + + return tags, nil +} + +// GetCreateVirtualMachineRequestParameterFromStringArrayFlag returns an array of CreateVirtualMachineRequestParameter structs from given string array flag +func GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parametersFlag []string) ([]ecloud.CreateVirtualMachineRequestParameter, error) { + var parameters []ecloud.CreateVirtualMachineRequestParameter + for _, parameterFlag := range parametersFlag { + key, value, err := GetKeyValueFromStringFlag(parameterFlag) + if err != nil { + return parameters, err + } + + parameters = append(parameters, ecloud.CreateVirtualMachineRequestParameter{Key: key, Value: value}) + } + + return parameters, nil +} + +// GetKeyValueFromStringFlag returns a string map from given string flag. Expects format 'key=value' +func GetKeyValueFromStringFlag(flag string) (key, value string, err error) { + if flag == "" { + return key, value, errors.New("Missing key/value") + } + + parts := strings.Split(flag, "=") + if len(parts) < 2 || len(parts) > 2 { + return key, value, errors.New("Invalid format, expecting: key=value") + } + if parts[0] == "" { + return key, value, errors.New("Missing key") + } + if parts[1] == "" { + return key, value, errors.New("Missing value") + } + + return parts[0], parts[1], nil +} + +// SolutionTemplateExistsWaitFunc returns WaitFunc for waiting for a template to exist +func SolutionTemplateExistsWaitFunc(service ecloud.ECloudService, solutionID int, templateName string, exists bool) helper.WaitFunc { + return func() (finished bool, err error) { + _, err = service.GetSolutionTemplate(solutionID, templateName) + if err != nil { + if _, ok := err.(*ecloud.TemplateNotFoundError); ok { + return (exists == false), nil + } + + return false, fmt.Errorf("Failed to retrieve solution template [%s]: %s", templateName, err.Error()) + } + + return (exists == true), nil + } +} + +// PodTemplateExistsWaitFunc returns WaitFunc for waiting for a template to exist +func PodTemplateExistsWaitFunc(service ecloud.ECloudService, podID int, templateName string, exists bool) helper.WaitFunc { + return func() (finished bool, err error) { + _, err = service.GetPodTemplate(podID, templateName) + if err != nil { + if _, ok := err.(*ecloud.TemplateNotFoundError); ok { + return (exists == false), nil + } + + return false, fmt.Errorf("Failed to retrieve pod template [%s]: %s", templateName, err.Error()) + } + + return (exists == true), nil + } +} diff --git a/cmd/ecloud_appliance.go b/cmd/ecloud/ecloud_appliance.go similarity index 60% rename from cmd/ecloud_appliance.go rename to cmd/ecloud/ecloud_appliance.go index 892973b..f3ccfaf 100644 --- a/cmd/ecloud_appliance.go +++ b/cmd/ecloud/ecloud_appliance.go @@ -1,59 +1,59 @@ -package cmd +package ecloud import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudApplianceRootCmd() *cobra.Command { +func ecloudApplianceRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "appliance", Short: "sub-commands relating to appliances", } // Child commands - cmd.AddCommand(ecloudApplianceListCmd()) - cmd.AddCommand(ecloudApplianceShowCmd()) + cmd.AddCommand(ecloudApplianceListCmd(f)) + cmd.AddCommand(ecloudApplianceShowCmd(f)) // Child root commands - cmd.AddCommand(ecloudApplianceParameterRootCmd()) + cmd.AddCommand(ecloudApplianceParameterRootCmd(f)) return cmd } -func ecloudApplianceListCmd() *cobra.Command { +func ecloudApplianceListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists appliances", Long: "This command lists appliances", Example: "ukfast ecloud appliance list", - Run: func(cmd *cobra.Command, args []string) { - ecloudApplianceList(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudApplianceList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudApplianceList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudApplianceList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } appliances, err := service.GetAppliances(params) if err != nil { - output.Fatalf("Error retrieving appliances: %s", err) - return + return fmt.Errorf("Error retrieving appliances: %s", err) } - outputECloudAppliances(appliances) + return output.CommandOutput(cmd, OutputECloudAppliancesProvider(appliances)) } -func ecloudApplianceShowCmd() *cobra.Command { +func ecloudApplianceShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a appliance", @@ -66,13 +66,13 @@ func ecloudApplianceShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudApplianceShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudApplianceShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudApplianceShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudApplianceShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var appliances []ecloud.Appliance for _, arg := range args { appliance, err := service.GetAppliance(arg) @@ -84,5 +84,5 @@ func ecloudApplianceShow(service ecloud.ECloudService, cmd *cobra.Command, args appliances = append(appliances, appliance) } - outputECloudAppliances(appliances) + return output.CommandOutput(cmd, OutputECloudAppliancesProvider(appliances)) } diff --git a/cmd/ecloud_appliance_parameter.go b/cmd/ecloud/ecloud_appliance_parameter.go similarity index 60% rename from cmd/ecloud_appliance_parameter.go rename to cmd/ecloud/ecloud_appliance_parameter.go index 0d1b753..f822bb5 100644 --- a/cmd/ecloud_appliance_parameter.go +++ b/cmd/ecloud/ecloud_appliance_parameter.go @@ -1,27 +1,29 @@ -package cmd +package ecloud import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudApplianceParameterRootCmd() *cobra.Command { +func ecloudApplianceParameterRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "parameter", Short: "sub-commands relating to appliance parameters", } // Child commands - cmd.AddCommand(ecloudApplianceParameterListCmd()) + cmd.AddCommand(ecloudApplianceParameterListCmd(f)) return cmd } -func ecloudApplianceParameterListCmd() *cobra.Command { +func ecloudApplianceParameterListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists appliance parameters", @@ -34,24 +36,22 @@ func ecloudApplianceParameterListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudApplianceParameterList(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudApplianceParameterList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudApplianceParameterList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudApplianceParameterList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } parameters, err := service.GetApplianceParameters(args[0], params) if err != nil { - output.Fatalf("Error retrieving appliance parameters: %s", err) - return + return fmt.Errorf("Error retrieving appliance parameters: %s", err) } - outputECloudApplianceParameters(parameters) + return output.CommandOutput(cmd, OutputECloudApplianceParametersProvider(parameters)) } diff --git a/cmd/ecloud_appliance_parameter_test.go b/cmd/ecloud/ecloud_appliance_parameter_test.go similarity index 67% rename from cmd/ecloud_appliance_parameter_test.go rename to cmd/ecloud/ecloud_appliance_parameter_test.go index 91e94b7..6ec7ad0 100644 --- a/cmd/ecloud_appliance_parameter_test.go +++ b/cmd/ecloud/ecloud_appliance_parameter_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudApplianceParameterListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudApplianceParameterListCmd().Args(nil, []string{"123"}) + err := ecloudApplianceParameterListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudApplianceParameterListCmd().Args(nil, []string{}) + err := ecloudApplianceParameterListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing appliance", err.Error()) @@ -39,7 +39,7 @@ func Test_ecloudApplianceParameterList(t *testing.T) { ecloudApplianceParameterList(service, &cobra.Command{}, []string{"00000000-0000-0000-0000-000000000000"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -47,12 +47,12 @@ func Test_ecloudApplianceParameterList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudApplianceParameterList(service, cmd, []string{"00000000-0000-0000-0000-000000000000"}) - }) + err := ecloudApplianceParameterList(service, cmd, []string{"00000000-0000-0000-0000-000000000000"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetParametersError_OutputsFatal", func(t *testing.T) { + t.Run("GetParametersError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -61,8 +61,8 @@ func Test_ecloudApplianceParameterList(t *testing.T) { service.EXPECT().GetApplianceParameters("00000000-0000-0000-0000-000000000000", gomock.Any()).Return([]ecloud.ApplianceParameter{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving appliance parameters: test error 1\n", func() { - ecloudApplianceParameterList(service, &cobra.Command{}, []string{"00000000-0000-0000-0000-000000000000"}) - }) + err := ecloudApplianceParameterList(service, &cobra.Command{}, []string{"00000000-0000-0000-0000-000000000000"}) + + assert.Equal(t, "Error retrieving appliance parameters: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_appliance_test.go b/cmd/ecloud/ecloud_appliance_test.go similarity index 82% rename from cmd/ecloud_appliance_test.go rename to cmd/ecloud/ecloud_appliance_test.go index 35dc00f..c519760 100644 --- a/cmd/ecloud_appliance_test.go +++ b/cmd/ecloud/ecloud_appliance_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudApplianceList(t *testing.T) { ecloudApplianceList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudApplianceList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudApplianceList(service, cmd, []string{}) - }) + err := ecloudApplianceList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetAppliancesError_OutputsFatal", func(t *testing.T) { + t.Run("GetAppliancesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudApplianceList(t *testing.T) { service.EXPECT().GetAppliances(gomock.Any()).Return([]ecloud.Appliance{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving appliances: test error\n", func() { - ecloudApplianceList(service, &cobra.Command{}, []string{}) - }) + err := ecloudApplianceList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving appliances: test error", err.Error()) }) } func Test_ecloudApplianceShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudApplianceShowCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := ecloudApplianceShowCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudApplianceShowCmd().Args(nil, []string{}) + err := ecloudApplianceShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing appliance", err.Error()) diff --git a/cmd/ecloud_credit.go b/cmd/ecloud/ecloud_credit.go similarity index 53% rename from cmd/ecloud_credit.go rename to cmd/ecloud/ecloud_credit.go index a4d762f..52ebea8 100644 --- a/cmd/ecloud_credit.go +++ b/cmd/ecloud/ecloud_credit.go @@ -1,48 +1,50 @@ -package cmd +package ecloud import ( + "fmt" + "github.com/spf13/cobra" + accountcmd "github.com/ukfast/cli/cmd/account" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudCreditRootCmd() *cobra.Command { +func ecloudCreditRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "credit", Short: "sub-commands relating to credits", } // Child commands - cmd.AddCommand(ecloudCreditListCmd()) + cmd.AddCommand(ecloudCreditListCmd(f)) return cmd } -func ecloudCreditListCmd() *cobra.Command { +func ecloudCreditListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists credits", Long: "This command lists credits", Example: "ukfast account credit list", - Run: func(cmd *cobra.Command, args []string) { - ecloudCreditList(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudCreditList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudCreditList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudCreditList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } credits, err := service.GetCredits(params) if err != nil { - output.Fatalf("Error retrieving credits: %s", err) - return + return fmt.Errorf("Error retrieving credits: %s", err) } - outputAccountCredits(credits) + return output.CommandOutput(cmd, accountcmd.OutputAccountCreditsProvider(credits)) } diff --git a/cmd/ecloud_credit_test.go b/cmd/ecloud/ecloud_credit_test.go similarity index 62% rename from cmd/ecloud_credit_test.go rename to cmd/ecloud/ecloud_credit_test.go index d4cc1e5..c92707a 100644 --- a/cmd/ecloud_credit_test.go +++ b/cmd/ecloud/ecloud_credit_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -6,8 +6,9 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/account" ) @@ -17,13 +18,14 @@ func Test_ecloudCreditList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - service.EXPECT().GetCredits(gomock.Any()).Return([]account.Credit{}, nil).Times(1) - ecloudCreditList(service, &cobra.Command{}, []string{}) + err := ecloudCreditList(service, &cobra.Command{}, []string{}) + + assert.Nil(t, err) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -31,21 +33,20 @@ func Test_ecloudCreditList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudCreditList(service, cmd, []string{}) - }) + err := ecloudCreditList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetCreditsError_OutputsFatal", func(t *testing.T) { + t.Run("GetCreditsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - service.EXPECT().GetCredits(gomock.Any()).Return([]account.Credit{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving credits: test error\n", func() { - ecloudCreditList(service, &cobra.Command{}, []string{}) - }) + err := ecloudCreditList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving credits: test error", err.Error()) }) } diff --git a/cmd/ecloud_datastore.go b/cmd/ecloud/ecloud_datastore.go similarity index 65% rename from cmd/ecloud_datastore.go rename to cmd/ecloud/ecloud_datastore.go index 297ac9b..81f5844 100644 --- a/cmd/ecloud_datastore.go +++ b/cmd/ecloud/ecloud_datastore.go @@ -1,57 +1,57 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudDatastoreRootCmd() *cobra.Command { +func ecloudDatastoreRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "datastore", Short: "sub-commands relating to datastores", } // Child commands - cmd.AddCommand(ecloudDatastoreListCmd()) - cmd.AddCommand(ecloudDatastoreShowCmd()) + cmd.AddCommand(ecloudDatastoreListCmd(f)) + cmd.AddCommand(ecloudDatastoreShowCmd(f)) return cmd } -func ecloudDatastoreListCmd() *cobra.Command { +func ecloudDatastoreListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists datastores", Long: "This command lists datastores", Example: "ukfast ecloud datastore list", Run: func(cmd *cobra.Command, args []string) { - ecloudDatastoreList(getClient().ECloudService(), cmd, args) + ecloudDatastoreList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudDatastoreList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudDatastoreList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } datastores, err := service.GetDatastores(params) if err != nil { - output.Fatalf("Error retrieving datastores: %s", err) - return + return fmt.Errorf("Error retrieving datastores: %s", err) } - outputECloudDatastores(datastores) + return output.CommandOutput(cmd, OutputECloudDatastoresProvider(datastores)) } -func ecloudDatastoreShowCmd() *cobra.Command { +func ecloudDatastoreShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a datastore", @@ -64,13 +64,13 @@ func ecloudDatastoreShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudDatastoreShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudDatastoreShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudDatastoreShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudDatastoreShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var datastores []ecloud.Datastore for _, arg := range args { datastoreID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func ecloudDatastoreShow(service ecloud.ECloudService, cmd *cobra.Command, args datastores = append(datastores, datastore) } - outputECloudDatastores(datastores) + return output.CommandOutput(cmd, OutputECloudDatastoresProvider(datastores)) } diff --git a/cmd/ecloud_datastore_test.go b/cmd/ecloud/ecloud_datastore_test.go similarity index 83% rename from cmd/ecloud_datastore_test.go rename to cmd/ecloud/ecloud_datastore_test.go index 61dd03f..057f898 100644 --- a/cmd/ecloud_datastore_test.go +++ b/cmd/ecloud/ecloud_datastore_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudDatastoreList(t *testing.T) { ecloudDatastoreList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudDatastoreList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudDatastoreList(service, cmd, []string{}) - }) + err := ecloudDatastoreList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDatastoresError_OutputsFatal", func(t *testing.T) { + t.Run("GetDatastoresError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudDatastoreList(t *testing.T) { service.EXPECT().GetDatastores(gomock.Any()).Return([]ecloud.Datastore{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving datastores: test error\n", func() { - ecloudDatastoreList(service, &cobra.Command{}, []string{}) - }) + err := ecloudDatastoreList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving datastores: test error", err.Error()) }) } func Test_ecloudDatastoreShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudDatastoreShowCmd().Args(nil, []string{"123"}) + err := ecloudDatastoreShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudDatastoreShowCmd().Args(nil, []string{}) + err := ecloudDatastoreShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing datastore", err.Error()) diff --git a/cmd/ecloud_firewall.go b/cmd/ecloud/ecloud_firewall.go similarity index 65% rename from cmd/ecloud_firewall.go rename to cmd/ecloud/ecloud_firewall.go index 166b838..c220819 100644 --- a/cmd/ecloud_firewall.go +++ b/cmd/ecloud/ecloud_firewall.go @@ -1,57 +1,57 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudFirewallRootCmd() *cobra.Command { +func ecloudFirewallRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "firewall", Short: "sub-commands relating to firewalls", } // Child commands - cmd.AddCommand(ecloudFirewallListCmd()) - cmd.AddCommand(ecloudFirewallShowCmd()) + cmd.AddCommand(ecloudFirewallListCmd(f)) + cmd.AddCommand(ecloudFirewallShowCmd(f)) return cmd } -func ecloudFirewallListCmd() *cobra.Command { +func ecloudFirewallListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists firewalls", Long: "This command lists firewalls", Example: "ukfast ecloud firewall list", Run: func(cmd *cobra.Command, args []string) { - ecloudFirewallList(getClient().ECloudService(), cmd, args) + ecloudFirewallList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudFirewallList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudFirewallList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } firewalls, err := service.GetFirewalls(params) if err != nil { - output.Fatalf("Error retrieving firewalls: %s", err) - return + return fmt.Errorf("Error retrieving firewalls: %s", err) } - outputECloudFirewalls(firewalls) + return output.CommandOutput(cmd, OutputECloudFirewallsProvider(firewalls)) } -func ecloudFirewallShowCmd() *cobra.Command { +func ecloudFirewallShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a firewall", @@ -64,13 +64,13 @@ func ecloudFirewallShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudFirewallShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudFirewallShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudFirewallShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudFirewallShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var firewalls []ecloud.Firewall for _, arg := range args { firewallID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func ecloudFirewallShow(service ecloud.ECloudService, cmd *cobra.Command, args [ firewalls = append(firewalls, firewall) } - outputECloudFirewalls(firewalls) + return output.CommandOutput(cmd, OutputECloudFirewallsProvider(firewalls)) } diff --git a/cmd/ecloud_firewall_test.go b/cmd/ecloud/ecloud_firewall_test.go similarity index 83% rename from cmd/ecloud_firewall_test.go rename to cmd/ecloud/ecloud_firewall_test.go index 68eef41..c81bc80 100644 --- a/cmd/ecloud_firewall_test.go +++ b/cmd/ecloud/ecloud_firewall_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudFirewallList(t *testing.T) { ecloudFirewallList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudFirewallList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudFirewallList(service, cmd, []string{}) - }) + err := ecloudFirewallList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetFirewallsError_OutputsFatal", func(t *testing.T) { + t.Run("GetFirewallsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudFirewallList(t *testing.T) { service.EXPECT().GetFirewalls(gomock.Any()).Return([]ecloud.Firewall{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving firewalls: test error\n", func() { - ecloudFirewallList(service, &cobra.Command{}, []string{}) - }) + err := ecloudFirewallList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving firewalls: test error", err.Error()) }) } func Test_ecloudFirewallShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudFirewallShowCmd().Args(nil, []string{"123"}) + err := ecloudFirewallShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudFirewallShowCmd().Args(nil, []string{}) + err := ecloudFirewallShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing firewall", err.Error()) diff --git a/cmd/ecloud_host.go b/cmd/ecloud/ecloud_host.go similarity index 65% rename from cmd/ecloud_host.go rename to cmd/ecloud/ecloud_host.go index 568da35..89e57fa 100644 --- a/cmd/ecloud_host.go +++ b/cmd/ecloud/ecloud_host.go @@ -1,57 +1,57 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudHostRootCmd() *cobra.Command { +func ecloudHostRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "host", Short: "sub-commands relating to hosts", } // Child commands - cmd.AddCommand(ecloudHostListCmd()) - cmd.AddCommand(ecloudHostShowCmd()) + cmd.AddCommand(ecloudHostListCmd(f)) + cmd.AddCommand(ecloudHostShowCmd(f)) return cmd } -func ecloudHostListCmd() *cobra.Command { +func ecloudHostListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists hosts", Long: "This command lists hosts", Example: "ukfast ecloud host list", Run: func(cmd *cobra.Command, args []string) { - ecloudHostList(getClient().ECloudService(), cmd, args) + ecloudHostList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudHostList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudHostList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } hosts, err := service.GetHosts(params) if err != nil { - output.Fatalf("Error retrieving hosts: %s", err) - return + return fmt.Errorf("Error retrieving hosts: %s", err) } - outputECloudHosts(hosts) + return output.CommandOutput(cmd, OutputECloudHostsProvider(hosts)) } -func ecloudHostShowCmd() *cobra.Command { +func ecloudHostShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a host", @@ -64,13 +64,13 @@ func ecloudHostShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudHostShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudHostShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudHostShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudHostShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var hosts []ecloud.Host for _, arg := range args { hostID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func ecloudHostShow(service ecloud.ECloudService, cmd *cobra.Command, args []str hosts = append(hosts, host) } - outputECloudHosts(hosts) + return output.CommandOutput(cmd, OutputECloudHostsProvider(hosts)) } diff --git a/cmd/ecloud_host_test.go b/cmd/ecloud/ecloud_host_test.go similarity index 83% rename from cmd/ecloud_host_test.go rename to cmd/ecloud/ecloud_host_test.go index 5d91972..ab371ca 100644 --- a/cmd/ecloud_host_test.go +++ b/cmd/ecloud/ecloud_host_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudHostList(t *testing.T) { ecloudHostList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudHostList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudHostList(service, cmd, []string{}) - }) + err := ecloudHostList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetHostsError_OutputsFatal", func(t *testing.T) { + t.Run("GetHostsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudHostList(t *testing.T) { service.EXPECT().GetHosts(gomock.Any()).Return([]ecloud.Host{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving hosts: test error\n", func() { - ecloudHostList(service, &cobra.Command{}, []string{}) - }) + err := ecloudHostList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving hosts: test error", err.Error()) }) } func Test_ecloudHostShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudHostShowCmd().Args(nil, []string{"123"}) + err := ecloudHostShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudHostShowCmd().Args(nil, []string{}) + err := ecloudHostShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing host", err.Error()) diff --git a/cmd/ecloud_pod.go b/cmd/ecloud/ecloud_pod.go similarity index 63% rename from cmd/ecloud_pod.go rename to cmd/ecloud/ecloud_pod.go index 09df5d9..efef5d2 100644 --- a/cmd/ecloud_pod.go +++ b/cmd/ecloud/ecloud_pod.go @@ -1,61 +1,61 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudPodRootCmd() *cobra.Command { +func ecloudPodRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "pod", Short: "sub-commands relating to pods", } // Child commands - cmd.AddCommand(ecloudPodListCmd()) - cmd.AddCommand(ecloudPodShowCmd()) + cmd.AddCommand(ecloudPodListCmd(f)) + cmd.AddCommand(ecloudPodShowCmd(f)) // Child root commands - cmd.AddCommand(ecloudPodTemplateRootCmd()) - cmd.AddCommand(ecloudPodApplianceRootCmd()) + cmd.AddCommand(ecloudPodTemplateRootCmd(f)) + cmd.AddCommand(ecloudPodApplianceRootCmd(f)) return cmd } -func ecloudPodListCmd() *cobra.Command { +func ecloudPodListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists pods", Long: "This command lists pods", Example: "ukfast ecloud pod list", Run: func(cmd *cobra.Command, args []string) { - ecloudPodList(getClient().ECloudService(), cmd, args) + ecloudPodList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudPodList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } pods, err := service.GetPods(params) if err != nil { - output.Fatalf("Error retrieving pods: %s", err) - return + return fmt.Errorf("Error retrieving pods: %s", err) } - outputECloudPods(pods) + return output.CommandOutput(cmd, OutputECloudPodsProvider(pods)) } -func ecloudPodShowCmd() *cobra.Command { +func ecloudPodShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a pod", @@ -68,13 +68,13 @@ func ecloudPodShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudPodShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudPodShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudPodShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var pods []ecloud.Pod for _, arg := range args { podID, err := strconv.Atoi(arg) @@ -92,5 +92,5 @@ func ecloudPodShow(service ecloud.ECloudService, cmd *cobra.Command, args []stri pods = append(pods, pod) } - outputECloudPods(pods) + return output.CommandOutput(cmd, OutputECloudPodsProvider(pods)) } diff --git a/cmd/ecloud_pod_appliance.go b/cmd/ecloud/ecloud_pod_appliance.go similarity index 63% rename from cmd/ecloud_pod_appliance.go rename to cmd/ecloud/ecloud_pod_appliance.go index a8115c3..1246f8d 100644 --- a/cmd/ecloud_pod_appliance.go +++ b/cmd/ecloud/ecloud_pod_appliance.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudPodApplianceRootCmd() *cobra.Command { +func ecloudPodApplianceRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "appliance", Short: "sub-commands relating to pod appliances", } // Child commands - cmd.AddCommand(ecloudPodApplianceListCmd()) + cmd.AddCommand(ecloudPodApplianceListCmd(f)) return cmd } -func ecloudPodApplianceListCmd() *cobra.Command { +func ecloudPodApplianceListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists pod appliances", @@ -36,29 +38,26 @@ func ecloudPodApplianceListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudPodApplianceList(getClient().ECloudService(), cmd, args) + ecloudPodApplianceList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudPodApplianceList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodApplianceList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { podID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid pod ID [%s]", args[0]) - return + return fmt.Errorf("Invalid pod ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } appliances, err := service.GetPodAppliances(podID, params) if err != nil { - output.Fatalf("Error retrieving pod appliances: %s", err) - return + return fmt.Errorf("Error retrieving pod appliances: %s", err) } - outputECloudAppliances(appliances) + return output.CommandOutput(cmd, OutputECloudAppliancesProvider(appliances)) } diff --git a/cmd/ecloud_pod_appliance_test.go b/cmd/ecloud/ecloud_pod_appliance_test.go similarity index 64% rename from cmd/ecloud_pod_appliance_test.go rename to cmd/ecloud/ecloud_pod_appliance_test.go index ea6ca69..667727d 100644 --- a/cmd/ecloud_pod_appliance_test.go +++ b/cmd/ecloud/ecloud_pod_appliance_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudPodApplianceListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodApplianceListCmd().Args(nil, []string{"123"}) + err := ecloudPodApplianceListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudPodApplianceListCmd().Args(nil, []string{}) + err := ecloudPodApplianceListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) @@ -39,18 +39,18 @@ func Test_ecloudPodApplianceList(t *testing.T) { ecloudPodApplianceList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidPodID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPodID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid pod ID [abc]\n", func() { - ecloudPodApplianceList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudPodApplianceList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid pod ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -58,12 +58,12 @@ func Test_ecloudPodApplianceList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudPodApplianceList(service, cmd, []string{"123"}) - }) + err := ecloudPodApplianceList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetAppliancesError_OutputsFatal", func(t *testing.T) { + t.Run("GetAppliancesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -71,8 +71,8 @@ func Test_ecloudPodApplianceList(t *testing.T) { service.EXPECT().GetPodAppliances(123, gomock.Any()).Return([]ecloud.Appliance{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving pod appliances: test error 1\n", func() { - ecloudPodApplianceList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudPodApplianceList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving pod appliances: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_pod_template.go b/cmd/ecloud/ecloud_pod_template.go similarity index 65% rename from cmd/ecloud_pod_template.go rename to cmd/ecloud/ecloud_pod_template.go index 743b0c2..1b3fcb8 100644 --- a/cmd/ecloud_pod_template.go +++ b/cmd/ecloud/ecloud_pod_template.go @@ -1,31 +1,33 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudPodTemplateRootCmd() *cobra.Command { +func ecloudPodTemplateRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "template", Short: "sub-commands relating to pod templates", } // Child commands - cmd.AddCommand(ecloudPodTemplateListCmd()) - cmd.AddCommand(ecloudPodTemplateShowCmd()) - cmd.AddCommand(ecloudPodTemplateUpdateCmd()) - cmd.AddCommand(ecloudPodTemplateDeleteCmd()) + cmd.AddCommand(ecloudPodTemplateListCmd(f)) + cmd.AddCommand(ecloudPodTemplateShowCmd(f)) + cmd.AddCommand(ecloudPodTemplateUpdateCmd(f)) + cmd.AddCommand(ecloudPodTemplateDeleteCmd(f)) return cmd } -func ecloudPodTemplateListCmd() *cobra.Command { +func ecloudPodTemplateListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists pod templates", @@ -39,34 +41,31 @@ func ecloudPodTemplateListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudPodTemplateList(getClient().ECloudService(), cmd, args) + ecloudPodTemplateList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudPodTemplateList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodTemplateList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { podID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid pod ID [%s]", args[0]) - return + return fmt.Errorf("Invalid pod ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } templates, err := service.GetPodTemplates(podID, params) if err != nil { - output.Fatalf("Error retrieving pod templates: %s", err) - return + return fmt.Errorf("Error retrieving pod templates: %s", err) } - outputECloudTemplates(templates) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider(templates)) } -func ecloudPodTemplateShowCmd() *cobra.Command { +func ecloudPodTemplateShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a pod template", @@ -82,17 +81,16 @@ func ecloudPodTemplateShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudPodTemplateShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudPodTemplateShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudPodTemplateShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodTemplateShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { podID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid pod ID [%s]", args[0]) - return + return fmt.Errorf("Invalid pod ID [%s]", args[0]) } var templates []ecloud.Template @@ -107,10 +105,10 @@ func ecloudPodTemplateShow(service ecloud.ECloudService, cmd *cobra.Command, arg templates = append(templates, template) } - outputECloudTemplates(templates) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider(templates)) } -func ecloudPodTemplateUpdateCmd() *cobra.Command { +func ecloudPodTemplateUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a pod template", @@ -126,8 +124,8 @@ func ecloudPodTemplateUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudPodTemplateUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudPodTemplateUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -136,11 +134,10 @@ func ecloudPodTemplateUpdateCmd() *cobra.Command { return cmd } -func ecloudPodTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { podID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid pod ID [%s]", args[0]) - return + return fmt.Errorf("Invalid pod ID [%s]", args[0]) } templateName := args[1] @@ -153,14 +150,12 @@ func ecloudPodTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, a err = service.RenamePodTemplate(podID, templateName, patchRequest) if err != nil { - output.Fatalf("Error updating pod template: %s", err) - return + return fmt.Errorf("Error updating pod template: %s", err) } - err := WaitForCommand(PodTemplateExistsWaitFunc(service, podID, name, true)) + err := helper.WaitForCommand(PodTemplateExistsWaitFunc(service, podID, name, true)) if err != nil { - output.Fatalf("Error waiting for pod template update: %s", err) - return + return fmt.Errorf("Error waiting for pod template update: %s", err) } templateName = name @@ -168,14 +163,13 @@ func ecloudPodTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, a template, err := service.GetPodTemplate(podID, templateName) if err != nil { - output.Fatalf("Error retrieving updated pod template: %s", err) - return + return fmt.Errorf("Error retrieving updated pod template: %s", err) } - outputECloudTemplates([]ecloud.Template{template}) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider([]ecloud.Template{template})) } -func ecloudPodTemplateDeleteCmd() *cobra.Command { +func ecloudPodTemplateDeleteCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "delete ...", Short: "Removes a pod template ", @@ -191,8 +185,8 @@ func ecloudPodTemplateDeleteCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudPodTemplateDelete(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudPodTemplateDelete(f.NewClient().ECloudService(), cmd, args) }, } @@ -201,11 +195,10 @@ func ecloudPodTemplateDeleteCmd() *cobra.Command { return cmd } -func ecloudPodTemplateDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudPodTemplateDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { podID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid pod ID [%s]", args[0]) - return + return fmt.Errorf("Invalid pod ID [%s]", args[0]) } for _, arg := range args[1:] { @@ -217,10 +210,12 @@ func ecloudPodTemplateDelete(service ecloud.ECloudService, cmd *cobra.Command, a waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(PodTemplateExistsWaitFunc(service, podID, arg, false)) + err := helper.WaitForCommand(PodTemplateExistsWaitFunc(service, podID, arg, false)) if err != nil { output.OutputWithErrorLevelf("Error removing pod template [%s]: %s", arg, err) } } } + + return nil } diff --git a/cmd/ecloud_pod_template_test.go b/cmd/ecloud/ecloud_pod_template_test.go similarity index 74% rename from cmd/ecloud_pod_template_test.go rename to cmd/ecloud/ecloud_pod_template_test.go index 0930b79..38029b7 100644 --- a/cmd/ecloud_pod_template_test.go +++ b/cmd/ecloud/ecloud_pod_template_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -8,6 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -15,13 +17,13 @@ import ( func Test_ecloudPodTemplateListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodTemplateListCmd().Args(nil, []string{"123"}) + err := ecloudPodTemplateListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudPodTemplateListCmd().Args(nil, []string{}) + err := ecloudPodTemplateListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) @@ -40,18 +42,18 @@ func Test_ecloudPodTemplateList(t *testing.T) { ecloudPodTemplateList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidPodID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPodID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid pod ID [abc]\n", func() { - ecloudPodTemplateList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudPodTemplateList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid pod ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +61,12 @@ func Test_ecloudPodTemplateList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudPodTemplateList(service, cmd, []string{"123"}) - }) + err := ecloudPodTemplateList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -72,28 +74,28 @@ func Test_ecloudPodTemplateList(t *testing.T) { service.EXPECT().GetPodTemplates(123, gomock.Any()).Return([]ecloud.Template{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving pod templates: test error 1\n", func() { - ecloudPodTemplateList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudPodTemplateList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving pod templates: test error 1", err.Error()) }) } func Test_ecloudPodTemplateShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodTemplateShowCmd().Args(nil, []string{"123", "testtemplate1"}) + err := ecloudPodTemplateShowCmd(nil).Args(nil, []string{"123", "testtemplate1"}) assert.Nil(t, err) }) t.Run("MissingPod_Error", func(t *testing.T) { - err := ecloudPodTemplateShowCmd().Args(nil, []string{}) + err := ecloudPodTemplateShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudPodTemplateShowCmd().Args(nil, []string{"123"}) + err := ecloudPodTemplateShowCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -126,15 +128,15 @@ func Test_ecloudPodTemplateShow(t *testing.T) { ecloudPodTemplateShow(service, &cobra.Command{}, []string{"123", "testtemplate1", "testtemplate2"}) }) - t.Run("InvalidPodID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPodID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid pod ID [abc]\n", func() { - ecloudPodTemplateShow(service, &cobra.Command{}, []string{"abc", "testtemplate1"}) - }) + err := ecloudPodTemplateShow(service, &cobra.Command{}, []string{"abc", "testtemplate1"}) + + assert.Equal(t, "Invalid pod ID [abc]", err.Error()) }) t.Run("GetPodTemplateError_OutputsError", func(t *testing.T) { @@ -153,20 +155,20 @@ func Test_ecloudPodTemplateShow(t *testing.T) { func Test_ecloudPodTemplateUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodTemplateUpdateCmd().Args(nil, []string{"123", "testname1"}) + err := ecloudPodTemplateUpdateCmd(nil).Args(nil, []string{"123", "testname1"}) assert.Nil(t, err) }) t.Run("MissingPod_Error", func(t *testing.T) { - err := ecloudPodTemplateUpdateCmd().Args(nil, []string{}) + err := ecloudPodTemplateUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudPodTemplateUpdateCmd().Args(nil, []string{"123"}) + err := ecloudPodTemplateUpdateCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -180,10 +182,10 @@ func Test_ecloudPodTemplateUpdate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudPodTemplateUpdateCmd() + cmd := ecloudPodTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") expectedPatch := ecloud.RenameTemplateRequest{ @@ -199,44 +201,44 @@ func Test_ecloudPodTemplateUpdate(t *testing.T) { ecloudPodTemplateUpdate(service, cmd, []string{"123", "testname1"}) }) - t.Run("InvalidPodID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPodID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid pod ID [abc]\n", func() { - ecloudPodTemplateUpdate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudPodTemplateUpdate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid pod ID [abc]", err.Error()) }) - t.Run("RenamePodTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("RenamePodTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudPodTemplateUpdateCmd() + cmd := ecloudPodTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") gomock.InOrder( service.EXPECT().RenamePodTemplate(123, "testname1", gomock.Any()).Return(errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error updating pod template: test error 1\n", func() { - ecloudPodTemplateUpdate(service, cmd, []string{"123", "testname1"}) - }) + err := ecloudPodTemplateUpdate(service, cmd, []string{"123", "testname1"}) + + assert.Equal(t, "Error updating pod template: test error 1", err.Error()) }) - t.Run("WaitForCommandError_OutputsFatal", func(t *testing.T) { + t.Run("WaitForCommandError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudPodTemplateUpdateCmd() + cmd := ecloudPodTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") gomock.InOrder( @@ -244,12 +246,12 @@ func Test_ecloudPodTemplateUpdate(t *testing.T) { service.EXPECT().GetPodTemplate(123, "newname").Return(ecloud.Template{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error waiting for pod template update: Error waiting for command: Failed to retrieve pod template [newname]: test error 1\n", func() { - ecloudPodTemplateUpdate(service, cmd, []string{"123", "testname1"}) - }) + err := ecloudPodTemplateUpdate(service, cmd, []string{"123", "testname1"}) + + assert.Equal(t, "Error waiting for pod template update: Error waiting for command: Failed to retrieve pod template [newname]: test error 1", err.Error()) }) - t.Run("GetPodTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("GetPodTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -259,28 +261,28 @@ func Test_ecloudPodTemplateUpdate(t *testing.T) { service.EXPECT().GetPodTemplate(123, "testname1").Return(ecloud.Template{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error retrieving updated pod template: test error 1\n", func() { - ecloudPodTemplateUpdate(service, &cobra.Command{}, []string{"123", "testname1"}) - }) + err := ecloudPodTemplateUpdate(service, &cobra.Command{}, []string{"123", "testname1"}) + + assert.Equal(t, "Error retrieving updated pod template: test error 1", err.Error()) }) } func Test_ecloudPodTemplateDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodTemplateDeleteCmd().Args(nil, []string{"123", "testname1"}) + err := ecloudPodTemplateDeleteCmd(nil).Args(nil, []string{"123", "testname1"}) assert.Nil(t, err) }) t.Run("MissingPod_Error", func(t *testing.T) { - err := ecloudPodTemplateDeleteCmd().Args(nil, []string{}) + err := ecloudPodTemplateDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudPodTemplateDeleteCmd().Args(nil, []string{"123"}) + err := ecloudPodTemplateDeleteCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -319,10 +321,10 @@ func Test_ecloudPodTemplateDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudPodTemplateDeleteCmd() + cmd := ecloudPodTemplateDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -333,15 +335,15 @@ func Test_ecloudPodTemplateDelete(t *testing.T) { ecloudPodTemplateDelete(service, cmd, []string{"123", "testname1"}) }) - t.Run("InvalidPodID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPodID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid pod ID [abc]\n", func() { - ecloudPodTemplateDelete(service, &cobra.Command{}, []string{"abc", "testname1"}) - }) + err := ecloudPodTemplateDelete(service, &cobra.Command{}, []string{"abc", "testname1"}) + + assert.Equal(t, "Invalid pod ID [abc]", err.Error()) }) t.Run("DeletePodTemplateError_OutputsError", func(t *testing.T) { @@ -363,10 +365,10 @@ func Test_ecloudPodTemplateDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudPodTemplateDeleteCmd() + cmd := ecloudPodTemplateDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( diff --git a/cmd/ecloud_pod_test.go b/cmd/ecloud/ecloud_pod_test.go similarity index 83% rename from cmd/ecloud_pod_test.go rename to cmd/ecloud/ecloud_pod_test.go index 9f27471..e3a57f3 100644 --- a/cmd/ecloud_pod_test.go +++ b/cmd/ecloud/ecloud_pod_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudPodList(t *testing.T) { ecloudPodList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudPodList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudPodList(service, cmd, []string{}) - }) + err := ecloudPodList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetPodsError_OutputsFatal", func(t *testing.T) { + t.Run("GetPodsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudPodList(t *testing.T) { service.EXPECT().GetPods(gomock.Any()).Return([]ecloud.Pod{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving pods: test error\n", func() { - ecloudPodList(service, &cobra.Command{}, []string{}) - }) + err := ecloudPodList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving pods: test error", err.Error()) }) } func Test_ecloudPodShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudPodShowCmd().Args(nil, []string{"123"}) + err := ecloudPodShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudPodShowCmd().Args(nil, []string{}) + err := ecloudPodShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing pod", err.Error()) diff --git a/cmd/ecloud_site.go b/cmd/ecloud/ecloud_site.go similarity index 68% rename from cmd/ecloud_site.go rename to cmd/ecloud/ecloud_site.go index c0bbdd9..e2841d6 100644 --- a/cmd/ecloud_site.go +++ b/cmd/ecloud/ecloud_site.go @@ -1,36 +1,38 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSiteRootCmd() *cobra.Command { +func ecloudSiteRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "site", Short: "sub-commands relating to sites", } // Child commands - cmd.AddCommand(ecloudSiteListCmd()) - cmd.AddCommand(ecloudSiteShowCmd()) + cmd.AddCommand(ecloudSiteListCmd(f)) + cmd.AddCommand(ecloudSiteShowCmd(f)) return cmd } -func ecloudSiteListCmd() *cobra.Command { +func ecloudSiteListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "Lists sites", Long: "This command lists sites", Example: "ukfast ecloud site list", Run: func(cmd *cobra.Command, args []string) { - ecloudSiteList(getClient().ECloudService(), cmd, args) + ecloudSiteList(f.NewClient().ECloudService(), cmd, args) }, } @@ -39,11 +41,10 @@ func ecloudSiteListCmd() *cobra.Command { return cmd } -func ecloudSiteList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSiteList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("state") { @@ -53,14 +54,13 @@ func ecloudSiteList(service ecloud.ECloudService, cmd *cobra.Command, args []str sites, err := service.GetSites(params) if err != nil { - output.Fatalf("Error retrieving sites: %s", err) - return + return fmt.Errorf("Error retrieving sites: %s", err) } - outputECloudSites(sites) + return output.CommandOutput(cmd, OutputECloudSitesProvider(sites)) } -func ecloudSiteShowCmd() *cobra.Command { +func ecloudSiteShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a site", @@ -73,13 +73,13 @@ func ecloudSiteShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSiteShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSiteShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSiteShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSiteShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var sites []ecloud.Site for _, arg := range args { siteID, err := strconv.Atoi(arg) @@ -97,5 +97,5 @@ func ecloudSiteShow(service ecloud.ECloudService, cmd *cobra.Command, args []str sites = append(sites, site) } - outputECloudSites(sites) + return output.CommandOutput(cmd, OutputECloudSitesProvider(sites)) } diff --git a/cmd/ecloud_site_test.go b/cmd/ecloud/ecloud_site_test.go similarity index 83% rename from cmd/ecloud_site_test.go rename to cmd/ecloud/ecloud_site_test.go index 1a0103e..4acc85e 100644 --- a/cmd/ecloud_site_test.go +++ b/cmd/ecloud/ecloud_site_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudSiteList(t *testing.T) { ecloudSiteList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudSiteList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSiteList(service, cmd, []string{}) - }) + err := ecloudSiteList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSitesError_OutputsFatal", func(t *testing.T) { + t.Run("GetSitesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudSiteList(t *testing.T) { service.EXPECT().GetSites(gomock.Any()).Return([]ecloud.Site{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving sites: test error\n", func() { - ecloudSiteList(service, &cobra.Command{}, []string{}) - }) + err := ecloudSiteList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving sites: test error", err.Error()) }) } func Test_ecloudSiteShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSiteShowCmd().Args(nil, []string{"123"}) + err := ecloudSiteShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSiteShowCmd().Args(nil, []string{}) + err := ecloudSiteShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing site", err.Error()) diff --git a/cmd/ecloud_solution.go b/cmd/ecloud/ecloud_solution.go similarity index 60% rename from cmd/ecloud_solution.go rename to cmd/ecloud/ecloud_solution.go index 52373ef..4d6e080 100644 --- a/cmd/ecloud_solution.go +++ b/cmd/ecloud/ecloud_solution.go @@ -1,48 +1,50 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionRootCmd() *cobra.Command { +func ecloudSolutionRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "solution", Short: "sub-commands relating to solutions", } // Child commands - cmd.AddCommand(ecloudSolutionListCmd()) - cmd.AddCommand(ecloudSolutionShowCmd()) - cmd.AddCommand(ecloudSolutionUpdateCmd()) + cmd.AddCommand(ecloudSolutionListCmd(f)) + cmd.AddCommand(ecloudSolutionShowCmd(f)) + cmd.AddCommand(ecloudSolutionUpdateCmd(f)) // Child root commands - cmd.AddCommand(ecloudSolutionVirtualMachineRootCmd()) - cmd.AddCommand(ecloudSolutionTagRootCmd()) - cmd.AddCommand(ecloudSolutionSiteRootCmd()) - cmd.AddCommand(ecloudSolutionNetworkRootCmd()) - cmd.AddCommand(ecloudSolutionHostRootCmd()) - cmd.AddCommand(ecloudSolutionFirewallRootCmd()) - cmd.AddCommand(ecloudSolutionTemplateRootCmd()) - cmd.AddCommand(ecloudSolutionDatastoreRootCmd()) + cmd.AddCommand(ecloudSolutionVirtualMachineRootCmd(f)) + cmd.AddCommand(ecloudSolutionTagRootCmd(f)) + cmd.AddCommand(ecloudSolutionSiteRootCmd(f)) + cmd.AddCommand(ecloudSolutionNetworkRootCmd(f)) + cmd.AddCommand(ecloudSolutionHostRootCmd(f)) + cmd.AddCommand(ecloudSolutionFirewallRootCmd(f)) + cmd.AddCommand(ecloudSolutionTemplateRootCmd(f)) + cmd.AddCommand(ecloudSolutionDatastoreRootCmd(f)) return cmd } -func ecloudSolutionListCmd() *cobra.Command { +func ecloudSolutionListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "Lists solutions", Long: "This command lists solutions", Example: "ukfast ecloud solution list", Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionList(getClient().ECloudService(), cmd, args) + ecloudSolutionList(f.NewClient().ECloudService(), cmd, args) }, } @@ -51,11 +53,10 @@ func ecloudSolutionListCmd() *cobra.Command { return cmd } -func ecloudSolutionList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -65,14 +66,13 @@ func ecloudSolutionList(service ecloud.ECloudService, cmd *cobra.Command, args [ solutions, err := service.GetSolutions(params) if err != nil { - output.Fatalf("Error retrieving solutions: %s", err) - return + return fmt.Errorf("Error retrieving solutions: %s", err) } - outputECloudSolutions(solutions) + return output.CommandOutput(cmd, OutputECloudSolutionsProvider(solutions)) } -func ecloudSolutionShowCmd() *cobra.Command { +func ecloudSolutionShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a solution", @@ -85,13 +85,13 @@ func ecloudSolutionShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var solutions []ecloud.Solution for _, arg := range args { solutionID, err := strconv.Atoi(arg) @@ -109,10 +109,10 @@ func ecloudSolutionShow(service ecloud.ECloudService, cmd *cobra.Command, args [ solutions = append(solutions, solution) } - outputECloudSolutions(solutions) + return output.CommandOutput(cmd, OutputECloudSolutionsProvider(solutions)) } -func ecloudSolutionUpdateCmd() *cobra.Command { +func ecloudSolutionUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ", Short: "Updates a solution", @@ -125,8 +125,8 @@ func ecloudSolutionUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -135,11 +135,10 @@ func ecloudSolutionUpdateCmd() *cobra.Command { return cmd } -func ecloudSolutionUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } patchRequest := ecloud.PatchSolutionRequest{} @@ -151,15 +150,13 @@ func ecloudSolutionUpdate(service ecloud.ECloudService, cmd *cobra.Command, args id, err := service.PatchSolution(solutionID, patchRequest) if err != nil { - output.Fatalf("Error updating solution: %s", err) - return + return fmt.Errorf("Error updating solution: %s", err) } solution, err := service.GetSolution(id) if err != nil { - output.Fatalf("Error retrieving updated solution: %s", err) - return + return fmt.Errorf("Error retrieving updated solution: %s", err) } - outputECloudSolutions([]ecloud.Solution{solution}) + return output.CommandOutput(cmd, OutputECloudSolutionsProvider([]ecloud.Solution{solution})) } diff --git a/cmd/ecloud_solution_datastore.go b/cmd/ecloud/ecloud_solution_datastore.go similarity index 63% rename from cmd/ecloud_solution_datastore.go rename to cmd/ecloud/ecloud_solution_datastore.go index f2355ce..64d48a6 100644 --- a/cmd/ecloud_solution_datastore.go +++ b/cmd/ecloud/ecloud_solution_datastore.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionDatastoreRootCmd() *cobra.Command { +func ecloudSolutionDatastoreRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "datastore", Short: "sub-commands relating to solution datastores", } // Child commands - cmd.AddCommand(ecloudSolutionDatastoreListCmd()) + cmd.AddCommand(ecloudSolutionDatastoreListCmd(f)) return cmd } -func ecloudSolutionDatastoreListCmd() *cobra.Command { +func ecloudSolutionDatastoreListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution datastores", @@ -36,29 +38,26 @@ func ecloudSolutionDatastoreListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionDatastoreList(getClient().ECloudService(), cmd, args) + ecloudSolutionDatastoreList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionDatastoreList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionDatastoreList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } datastores, err := service.GetSolutionDatastores(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution datastores: %s", err) - return + return fmt.Errorf("Error retrieving solution datastores: %s", err) } - outputECloudDatastores(datastores) + return output.CommandOutput(cmd, OutputECloudDatastoresProvider(datastores)) } diff --git a/cmd/ecloud_solution_datastore_test.go b/cmd/ecloud/ecloud_solution_datastore_test.go similarity index 63% rename from cmd/ecloud_solution_datastore_test.go rename to cmd/ecloud/ecloud_solution_datastore_test.go index 6ddb449..a614b75 100644 --- a/cmd/ecloud_solution_datastore_test.go +++ b/cmd/ecloud/ecloud_solution_datastore_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionDatastoreListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionDatastoreListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionDatastoreListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionDatastoreListCmd().Args(nil, []string{}) + err := ecloudSolutionDatastoreListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,7 +39,7 @@ func Test_ecloudSolutionDatastoreList(t *testing.T) { ecloudSolutionDatastoreList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -47,24 +47,24 @@ func Test_ecloudSolutionDatastoreList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionDatastoreList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionDatastoreList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionDatastoreList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionDatastoreList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("GetDatastoresError_OutputsFatal", func(t *testing.T) { + t.Run("GetDatastoresError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,8 +73,8 @@ func Test_ecloudSolutionDatastoreList(t *testing.T) { service.EXPECT().GetSolutionDatastores(123, gomock.Any()).Return([]ecloud.Datastore{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution datastores: test error 1\n", func() { - ecloudSolutionDatastoreList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionDatastoreList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution datastores: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_solution_firewall.go b/cmd/ecloud/ecloud_solution_firewall.go similarity index 63% rename from cmd/ecloud_solution_firewall.go rename to cmd/ecloud/ecloud_solution_firewall.go index e45c00a..2a14456 100644 --- a/cmd/ecloud_solution_firewall.go +++ b/cmd/ecloud/ecloud_solution_firewall.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionFirewallRootCmd() *cobra.Command { +func ecloudSolutionFirewallRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "firewall", Short: "sub-commands relating to solution firewalls", } // Child commands - cmd.AddCommand(ecloudSolutionFirewallListCmd()) + cmd.AddCommand(ecloudSolutionFirewallListCmd(f)) return cmd } -func ecloudSolutionFirewallListCmd() *cobra.Command { +func ecloudSolutionFirewallListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution firewalls", @@ -36,29 +38,26 @@ func ecloudSolutionFirewallListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionFirewallList(getClient().ECloudService(), cmd, args) + ecloudSolutionFirewallList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionFirewallList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionFirewallList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } firewalls, err := service.GetSolutionFirewalls(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution firewalls: %s", err) - return + return fmt.Errorf("Error retrieving solution firewalls: %s", err) } - outputECloudFirewalls(firewalls) + return output.CommandOutput(cmd, OutputECloudFirewallsProvider(firewalls)) } diff --git a/cmd/ecloud_solution_firewall_test.go b/cmd/ecloud/ecloud_solution_firewall_test.go similarity index 63% rename from cmd/ecloud_solution_firewall_test.go rename to cmd/ecloud/ecloud_solution_firewall_test.go index 7debc1c..a509ce8 100644 --- a/cmd/ecloud_solution_firewall_test.go +++ b/cmd/ecloud/ecloud_solution_firewall_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionFirewallListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionFirewallListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionFirewallListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionFirewallListCmd().Args(nil, []string{}) + err := ecloudSolutionFirewallListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,19 +39,19 @@ func Test_ecloudSolutionFirewallList(t *testing.T) { ecloudSolutionFirewallList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionFirewallList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionFirewallList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +59,12 @@ func Test_ecloudSolutionFirewallList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionFirewallList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionFirewallList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetFirewallsError_OutputsFatal", func(t *testing.T) { + t.Run("GetFirewallsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,8 +73,8 @@ func Test_ecloudSolutionFirewallList(t *testing.T) { service.EXPECT().GetSolutionFirewalls(123, gomock.Any()).Return([]ecloud.Firewall{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution firewalls: test error 1\n", func() { - ecloudSolutionFirewallList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionFirewallList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution firewalls: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_solution_host.go b/cmd/ecloud/ecloud_solution_host.go similarity index 63% rename from cmd/ecloud_solution_host.go rename to cmd/ecloud/ecloud_solution_host.go index 638d6a1..81c2a95 100644 --- a/cmd/ecloud_solution_host.go +++ b/cmd/ecloud/ecloud_solution_host.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionHostRootCmd() *cobra.Command { +func ecloudSolutionHostRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "host", Short: "sub-commands relating to solution hosts", } // Child commands - cmd.AddCommand(ecloudSolutionHostListCmd()) + cmd.AddCommand(ecloudSolutionHostListCmd(f)) return cmd } -func ecloudSolutionHostListCmd() *cobra.Command { +func ecloudSolutionHostListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution hosts", @@ -36,29 +38,26 @@ func ecloudSolutionHostListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionHostList(getClient().ECloudService(), cmd, args) + ecloudSolutionHostList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionHostList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionHostList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } hosts, err := service.GetSolutionHosts(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution hosts: %s", err) - return + return fmt.Errorf("Error retrieving solution hosts: %s", err) } - outputECloudHosts(hosts) + return output.CommandOutput(cmd, OutputECloudHostsProvider(hosts)) } diff --git a/cmd/ecloud_solution_host_test.go b/cmd/ecloud/ecloud_solution_host_test.go similarity index 63% rename from cmd/ecloud_solution_host_test.go rename to cmd/ecloud/ecloud_solution_host_test.go index 2d038b9..335e8b6 100644 --- a/cmd/ecloud_solution_host_test.go +++ b/cmd/ecloud/ecloud_solution_host_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionHostListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionHostListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionHostListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionHostListCmd().Args(nil, []string{}) + err := ecloudSolutionHostListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,19 +39,19 @@ func Test_ecloudSolutionHostList(t *testing.T) { ecloudSolutionHostList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionHostList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionHostList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +59,12 @@ func Test_ecloudSolutionHostList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionHostList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionHostList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetHostsError_OutputsFatal", func(t *testing.T) { + t.Run("GetHostsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,8 +73,8 @@ func Test_ecloudSolutionHostList(t *testing.T) { service.EXPECT().GetSolutionHosts(123, gomock.Any()).Return([]ecloud.Host{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution hosts: test error 1\n", func() { - ecloudSolutionHostList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionHostList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution hosts: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_solution_network.go b/cmd/ecloud/ecloud_solution_network.go similarity index 63% rename from cmd/ecloud_solution_network.go rename to cmd/ecloud/ecloud_solution_network.go index 1524510..7dfb688 100644 --- a/cmd/ecloud_solution_network.go +++ b/cmd/ecloud/ecloud_solution_network.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionNetworkRootCmd() *cobra.Command { +func ecloudSolutionNetworkRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "network", Short: "sub-commands relating to solution networks", } // Child commands - cmd.AddCommand(ecloudSolutionNetworkListCmd()) + cmd.AddCommand(ecloudSolutionNetworkListCmd(f)) return cmd } -func ecloudSolutionNetworkListCmd() *cobra.Command { +func ecloudSolutionNetworkListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution networks", @@ -36,29 +38,26 @@ func ecloudSolutionNetworkListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionNetworkList(getClient().ECloudService(), cmd, args) + ecloudSolutionNetworkList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionNetworkList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionNetworkList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } networks, err := service.GetSolutionNetworks(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution networks: %s", err) - return + return fmt.Errorf("Error retrieving solution networks: %s", err) } - outputECloudNetworks(networks) + return output.CommandOutput(cmd, OutputECloudNetworksProvider(networks)) } diff --git a/cmd/ecloud_solution_network_test.go b/cmd/ecloud/ecloud_solution_network_test.go similarity index 63% rename from cmd/ecloud_solution_network_test.go rename to cmd/ecloud/ecloud_solution_network_test.go index fc73a94..74a80de 100644 --- a/cmd/ecloud_solution_network_test.go +++ b/cmd/ecloud/ecloud_solution_network_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionNetworkListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionNetworkListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionNetworkListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionNetworkListCmd().Args(nil, []string{}) + err := ecloudSolutionNetworkListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,18 +39,18 @@ func Test_ecloudSolutionNetworkList(t *testing.T) { ecloudSolutionNetworkList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionNetworkList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionNetworkList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -58,12 +58,12 @@ func Test_ecloudSolutionNetworkList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionNetworkList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionNetworkList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetNetworksError_OutputsFatal", func(t *testing.T) { + t.Run("GetNetworksError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -71,8 +71,8 @@ func Test_ecloudSolutionNetworkList(t *testing.T) { service.EXPECT().GetSolutionNetworks(123, gomock.Any()).Return([]ecloud.Network{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution networks: test error 1\n", func() { - ecloudSolutionNetworkList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionNetworkList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution networks: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_solution_site.go b/cmd/ecloud/ecloud_solution_site.go similarity index 63% rename from cmd/ecloud_solution_site.go rename to cmd/ecloud/ecloud_solution_site.go index 2a470f4..4b97d2c 100644 --- a/cmd/ecloud_solution_site.go +++ b/cmd/ecloud/ecloud_solution_site.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionSiteRootCmd() *cobra.Command { +func ecloudSolutionSiteRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "site", Short: "sub-commands relating to solution sites", } // Child commands - cmd.AddCommand(ecloudSolutionSiteListCmd()) + cmd.AddCommand(ecloudSolutionSiteListCmd(f)) return cmd } -func ecloudSolutionSiteListCmd() *cobra.Command { +func ecloudSolutionSiteListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution sites", @@ -36,29 +38,26 @@ func ecloudSolutionSiteListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionSiteList(getClient().ECloudService(), cmd, args) + ecloudSolutionSiteList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionSiteList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionSiteList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } sites, err := service.GetSolutionSites(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution sites: %s", err) - return + return fmt.Errorf("Error retrieving solution sites: %s", err) } - outputECloudSites(sites) + return output.CommandOutput(cmd, OutputECloudSitesProvider(sites)) } diff --git a/cmd/ecloud_solution_site_test.go b/cmd/ecloud/ecloud_solution_site_test.go similarity index 63% rename from cmd/ecloud_solution_site_test.go rename to cmd/ecloud/ecloud_solution_site_test.go index b399adc..eff8577 100644 --- a/cmd/ecloud_solution_site_test.go +++ b/cmd/ecloud/ecloud_solution_site_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionSiteListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionSiteListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionSiteListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionSiteListCmd().Args(nil, []string{}) + err := ecloudSolutionSiteListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,18 +39,18 @@ func Test_ecloudSolutionSiteList(t *testing.T) { ecloudSolutionSiteList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionSiteList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionSiteList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -58,12 +58,12 @@ func Test_ecloudSolutionSiteList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionSiteList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionSiteList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSitesError_OutputsFatal", func(t *testing.T) { + t.Run("GetSitesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -71,8 +71,8 @@ func Test_ecloudSolutionSiteList(t *testing.T) { service.EXPECT().GetSolutionSites(123, gomock.Any()).Return([]ecloud.Site{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution sites: test error 1\n", func() { - ecloudSolutionSiteList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionSiteList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution sites: test error 1", err.Error()) }) } diff --git a/cmd/ecloud_solution_tag.go b/cmd/ecloud/ecloud_solution_tag.go similarity index 68% rename from cmd/ecloud_solution_tag.go rename to cmd/ecloud/ecloud_solution_tag.go index 0b4f61a..93117b2 100644 --- a/cmd/ecloud_solution_tag.go +++ b/cmd/ecloud/ecloud_solution_tag.go @@ -1,9 +1,11 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -11,23 +13,23 @@ import ( "github.com/spf13/cobra" ) -func ecloudSolutionTagRootCmd() *cobra.Command { +func ecloudSolutionTagRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "tag", Short: "sub-commands relating to solution tags", } // Child commands - cmd.AddCommand(ecloudSolutionTagListCmd()) - cmd.AddCommand(ecloudSolutionTagShowCmd()) - cmd.AddCommand(ecloudSolutionTagCreateCmd()) - cmd.AddCommand(ecloudSolutionTagUpdateCmd()) - cmd.AddCommand(ecloudSolutionTagDeleteCmd()) + cmd.AddCommand(ecloudSolutionTagListCmd(f)) + cmd.AddCommand(ecloudSolutionTagShowCmd(f)) + cmd.AddCommand(ecloudSolutionTagCreateCmd(f)) + cmd.AddCommand(ecloudSolutionTagUpdateCmd(f)) + cmd.AddCommand(ecloudSolutionTagDeleteCmd(f)) return cmd } -func ecloudSolutionTagListCmd() *cobra.Command { +func ecloudSolutionTagListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "lists solution tags", @@ -41,34 +43,31 @@ func ecloudSolutionTagListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTagList(getClient().ECloudService(), cmd, args) + ecloudSolutionTagList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionTagList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTagList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } tags, err := service.GetSolutionTags(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution tags: %s", err) - return + return fmt.Errorf("Error retrieving solution tags: %s", err) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudSolutionTagShowCmd() *cobra.Command { +func ecloudSolutionTagShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a solution tag", @@ -84,17 +83,16 @@ func ecloudSolutionTagShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTagShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTagShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionTagShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTagShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } var tags []ecloud.Tag @@ -109,10 +107,10 @@ func ecloudSolutionTagShow(service ecloud.ECloudService, cmd *cobra.Command, arg tags = append(tags, tag) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudSolutionTagCreateCmd() *cobra.Command { +func ecloudSolutionTagCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a solution tag", @@ -125,8 +123,8 @@ func ecloudSolutionTagCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTagCreate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTagCreate(f.NewClient().ECloudService(), cmd, args) }, } @@ -138,11 +136,10 @@ func ecloudSolutionTagCreateCmd() *cobra.Command { return cmd } -func ecloudSolutionTagCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTagCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } key, _ := cmd.Flags().GetString("key") @@ -155,20 +152,18 @@ func ecloudSolutionTagCreate(service ecloud.ECloudService, cmd *cobra.Command, a err = service.CreateSolutionTag(solutionID, createRequest) if err != nil { - output.Fatalf("Error creating solution tag: %s", err) - return + return fmt.Errorf("Error creating solution tag: %s", err) } tag, err := service.GetSolutionTag(solutionID, key) if err != nil { - output.Fatalf("Error retrieving new solution tag: %s", err) - return + return fmt.Errorf("Error retrieving new solution tag: %s", err) } - outputECloudTags([]ecloud.Tag{tag}) + return output.CommandOutput(cmd, OutputECloudTagsProvider([]ecloud.Tag{tag})) } -func ecloudSolutionTagUpdateCmd() *cobra.Command { +func ecloudSolutionTagUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a solution tag", @@ -184,8 +179,8 @@ func ecloudSolutionTagUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTagUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTagUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -194,11 +189,10 @@ func ecloudSolutionTagUpdateCmd() *cobra.Command { return cmd } -func ecloudSolutionTagUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTagUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } patchRequest := ecloud.PatchTagRequest{} @@ -226,10 +220,10 @@ func ecloudSolutionTagUpdate(service ecloud.ECloudService, cmd *cobra.Command, a tags = append(tags, tag) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudSolutionTagDeleteCmd() *cobra.Command { +func ecloudSolutionTagDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Removes a solution tag ", @@ -245,17 +239,16 @@ func ecloudSolutionTagDeleteCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTagDelete(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTagDelete(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionTagDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTagDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } for _, arg := range args[1:] { @@ -264,4 +257,6 @@ func ecloudSolutionTagDelete(service ecloud.ECloudService, cmd *cobra.Command, a output.OutputWithErrorLevelf("Error removing solution tag [%s]: %s", arg, err) } } + + return nil } diff --git a/cmd/ecloud_solution_tag_test.go b/cmd/ecloud/ecloud_solution_tag_test.go similarity index 76% rename from cmd/ecloud_solution_tag_test.go rename to cmd/ecloud/ecloud_solution_tag_test.go index 6241022..62293a2 100644 --- a/cmd/ecloud_solution_tag_test.go +++ b/cmd/ecloud/ecloud_solution_tag_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -14,13 +15,13 @@ import ( func Test_ecloudSolutionTagListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTagListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTagListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionTagListCmd().Args(nil, []string{}) + err := ecloudSolutionTagListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,19 +40,19 @@ func Test_ecloudSolutionTagList(t *testing.T) { ecloudSolutionTagList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTagList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionTagList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +60,12 @@ func Test_ecloudSolutionTagList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionTagList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionTagList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSolutionTagsError_OutputsFatal", func(t *testing.T) { + t.Run("GetSolutionTagsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,28 +74,28 @@ func Test_ecloudSolutionTagList(t *testing.T) { service.EXPECT().GetSolutionTags(123, gomock.Any()).Return([]ecloud.Tag{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution tags: test error 1\n", func() { - ecloudSolutionTagList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionTagList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution tags: test error 1", err.Error()) }) } func Test_ecloudSolutionTagShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTagShowCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudSolutionTagShowCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTagShowCmd().Args(nil, []string{}) + err := ecloudSolutionTagShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudSolutionTagShowCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTagShowCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -127,16 +128,16 @@ func Test_ecloudSolutionTagShow(t *testing.T) { ecloudSolutionTagShow(service, &cobra.Command{}, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTagShow(service, &cobra.Command{}, []string{"abc", "testkey1"}) - }) + err := ecloudSolutionTagShow(service, &cobra.Command{}, []string{"abc", "testkey1"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) t.Run("GetSolutionTagError_OutputsError", func(t *testing.T) { @@ -155,13 +156,13 @@ func Test_ecloudSolutionTagShow(t *testing.T) { func Test_ecloudSolutionTagCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTagCreateCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTagCreateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionTagCreateCmd().Args(nil, []string{}) + err := ecloudSolutionTagCreateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -174,7 +175,7 @@ func Test_ecloudSolutionTagCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTagCreateCmd() + cmd := ecloudSolutionTagCreateCmd(nil) cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("value", "testvalue1") @@ -191,19 +192,19 @@ func Test_ecloudSolutionTagCreate(t *testing.T) { ecloudSolutionTagCreate(service, cmd, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTagCreate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionTagCreate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("CreateSolutionTagError_OutputsFatal", func(t *testing.T) { + t.Run("CreateSolutionTagError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -212,18 +213,18 @@ func Test_ecloudSolutionTagCreate(t *testing.T) { service.EXPECT().CreateSolutionTag(123, gomock.Any()).Return(errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error creating solution tag: test error 1\n", func() { - ecloudSolutionTagCreate(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionTagCreate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error creating solution tag: test error 1", err.Error()) }) - t.Run("GetSolutionTagError_OutputsFatal", func(t *testing.T) { + t.Run("GetSolutionTagError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTagCreateCmd() + cmd := ecloudSolutionTagCreateCmd(nil) cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("value", "testvalue1") @@ -232,28 +233,28 @@ func Test_ecloudSolutionTagCreate(t *testing.T) { service.EXPECT().GetSolutionTag(123, "testkey1").Return(ecloud.Tag{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error retrieving new solution tag: test error 1\n", func() { - ecloudSolutionTagCreate(service, cmd, []string{"123"}) - }) + err := ecloudSolutionTagCreate(service, cmd, []string{"123"}) + + assert.Equal(t, "Error retrieving new solution tag: test error 1", err.Error()) }) } func Test_ecloudSolutionTagUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTagUpdateCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudSolutionTagUpdateCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTagUpdateCmd().Args(nil, []string{}) + err := ecloudSolutionTagUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudSolutionTagUpdateCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTagUpdateCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -266,7 +267,7 @@ func Test_ecloudSolutionTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTagUpdateCmd() + cmd := ecloudSolutionTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") expectedPatch := ecloud.PatchTagRequest{ @@ -286,7 +287,7 @@ func Test_ecloudSolutionTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTagUpdateCmd() + cmd := ecloudSolutionTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") expectedPatch := ecloud.PatchTagRequest{ @@ -303,16 +304,16 @@ func Test_ecloudSolutionTagUpdate(t *testing.T) { ecloudSolutionTagUpdate(service, cmd, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTagUpdate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionTagUpdate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) t.Run("PatchSolutionTag_OutputsError", func(t *testing.T) { @@ -335,7 +336,7 @@ func Test_ecloudSolutionTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTagUpdateCmd() + cmd := ecloudSolutionTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") gomock.InOrder( @@ -351,20 +352,20 @@ func Test_ecloudSolutionTagUpdate(t *testing.T) { func Test_ecloudSolutionTagDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTagDeleteCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudSolutionTagDeleteCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTagDeleteCmd().Args(nil, []string{}) + err := ecloudSolutionTagDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudSolutionTagDeleteCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTagDeleteCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -397,16 +398,16 @@ func Test_ecloudSolutionTagDelete(t *testing.T) { ecloudSolutionTagDelete(service, &cobra.Command{}, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTagDelete(service, &cobra.Command{}, []string{"abc", "testkey1"}) - }) + err := ecloudSolutionTagDelete(service, &cobra.Command{}, []string{"abc", "testkey1"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) t.Run("DeleteSolutionTagError_OutputsError", func(t *testing.T) { diff --git a/cmd/ecloud_solution_template.go b/cmd/ecloud/ecloud_solution_template.go similarity index 64% rename from cmd/ecloud_solution_template.go rename to cmd/ecloud/ecloud_solution_template.go index 5017a1b..d79613d 100644 --- a/cmd/ecloud_solution_template.go +++ b/cmd/ecloud/ecloud_solution_template.go @@ -1,31 +1,33 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionTemplateRootCmd() *cobra.Command { +func ecloudSolutionTemplateRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "template", Short: "sub-commands relating to solution templates", } // Child commands - cmd.AddCommand(ecloudSolutionTemplateListCmd()) - cmd.AddCommand(ecloudSolutionTemplateShowCmd()) - cmd.AddCommand(ecloudSolutionTemplateUpdateCmd()) - cmd.AddCommand(ecloudSolutionTemplateDeleteCmd()) + cmd.AddCommand(ecloudSolutionTemplateListCmd(f)) + cmd.AddCommand(ecloudSolutionTemplateShowCmd(f)) + cmd.AddCommand(ecloudSolutionTemplateUpdateCmd(f)) + cmd.AddCommand(ecloudSolutionTemplateDeleteCmd(f)) return cmd } -func ecloudSolutionTemplateListCmd() *cobra.Command { +func ecloudSolutionTemplateListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution templates", @@ -39,34 +41,31 @@ func ecloudSolutionTemplateListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTemplateList(getClient().ECloudService(), cmd, args) + ecloudSolutionTemplateList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionTemplateList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTemplateList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } templates, err := service.GetSolutionTemplates(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution templates: %s", err) - return + return fmt.Errorf("Error retrieving solution templates: %s", err) } - outputECloudTemplates(templates) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider(templates)) } -func ecloudSolutionTemplateShowCmd() *cobra.Command { +func ecloudSolutionTemplateShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a solution template", @@ -82,17 +81,16 @@ func ecloudSolutionTemplateShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTemplateShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTemplateShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionTemplateShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTemplateShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } var templates []ecloud.Template @@ -107,10 +105,10 @@ func ecloudSolutionTemplateShow(service ecloud.ECloudService, cmd *cobra.Command templates = append(templates, template) } - outputECloudTemplates(templates) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider(templates)) } -func ecloudSolutionTemplateUpdateCmd() *cobra.Command { +func ecloudSolutionTemplateUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a solution template", @@ -126,8 +124,8 @@ func ecloudSolutionTemplateUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTemplateUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTemplateUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -136,11 +134,10 @@ func ecloudSolutionTemplateUpdateCmd() *cobra.Command { return cmd } -func ecloudSolutionTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } templateName := args[1] @@ -153,14 +150,12 @@ func ecloudSolutionTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Comma err = service.RenameSolutionTemplate(solutionID, templateName, patchRequest) if err != nil { - output.Fatalf("Error updating solution template: %s", err) - return + return fmt.Errorf("Error updating solution template: %s", err) } - err := WaitForCommand(SolutionTemplateExistsWaitFunc(service, solutionID, name, true)) + err := helper.WaitForCommand(SolutionTemplateExistsWaitFunc(service, solutionID, name, true)) if err != nil { - output.Fatalf("Error waiting for solution template update: %s", err) - return + return fmt.Errorf("Error waiting for solution template update: %s", err) } templateName = name @@ -168,14 +163,13 @@ func ecloudSolutionTemplateUpdate(service ecloud.ECloudService, cmd *cobra.Comma template, err := service.GetSolutionTemplate(solutionID, templateName) if err != nil { - output.Fatalf("Error retrieving updated solution template: %s", err) - return + return fmt.Errorf("Error retrieving updated solution template: %s", err) } - outputECloudTemplates([]ecloud.Template{template}) + return output.CommandOutput(cmd, OutputECloudTemplatesProvider([]ecloud.Template{template})) } -func ecloudSolutionTemplateDeleteCmd() *cobra.Command { +func ecloudSolutionTemplateDeleteCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "delete ...", Short: "Removes a solution template ", @@ -191,8 +185,8 @@ func ecloudSolutionTemplateDeleteCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionTemplateDelete(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudSolutionTemplateDelete(f.NewClient().ECloudService(), cmd, args) }, } @@ -201,11 +195,10 @@ func ecloudSolutionTemplateDeleteCmd() *cobra.Command { return cmd } -func ecloudSolutionTemplateDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionTemplateDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } for _, arg := range args[1:] { @@ -217,10 +210,12 @@ func ecloudSolutionTemplateDelete(service ecloud.ECloudService, cmd *cobra.Comma waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(SolutionTemplateExistsWaitFunc(service, solutionID, arg, false)) + err := helper.WaitForCommand(SolutionTemplateExistsWaitFunc(service, solutionID, arg, false)) if err != nil { output.OutputWithErrorLevelf("Error removing solution template [%s]: %s", arg, err) } } } + + return nil } diff --git a/cmd/ecloud_solution_template_test.go b/cmd/ecloud/ecloud_solution_template_test.go similarity index 73% rename from cmd/ecloud_solution_template_test.go rename to cmd/ecloud/ecloud_solution_template_test.go index 3d21938..bc4252c 100644 --- a/cmd/ecloud_solution_template_test.go +++ b/cmd/ecloud/ecloud_solution_template_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -8,6 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -15,13 +17,13 @@ import ( func Test_ecloudSolutionTemplateListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTemplateListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTemplateListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionTemplateListCmd().Args(nil, []string{}) + err := ecloudSolutionTemplateListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -40,18 +42,18 @@ func Test_ecloudSolutionTemplateList(t *testing.T) { ecloudSolutionTemplateList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTemplateList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionTemplateList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +61,12 @@ func Test_ecloudSolutionTemplateList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionTemplateList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionTemplateList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -72,28 +74,28 @@ func Test_ecloudSolutionTemplateList(t *testing.T) { service.EXPECT().GetSolutionTemplates(123, gomock.Any()).Return([]ecloud.Template{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution templates: test error 1\n", func() { - ecloudSolutionTemplateList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionTemplateList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution templates: test error 1", err.Error()) }) } func Test_ecloudSolutionTemplateShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTemplateShowCmd().Args(nil, []string{"123", "testtemplate1"}) + err := ecloudSolutionTemplateShowCmd(nil).Args(nil, []string{"123", "testtemplate1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTemplateShowCmd().Args(nil, []string{}) + err := ecloudSolutionTemplateShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudSolutionTemplateShowCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTemplateShowCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -126,15 +128,15 @@ func Test_ecloudSolutionTemplateShow(t *testing.T) { ecloudSolutionTemplateShow(service, &cobra.Command{}, []string{"123", "testtemplate1", "testtemplate2"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTemplateShow(service, &cobra.Command{}, []string{"abc", "testtemplate1"}) - }) + err := ecloudSolutionTemplateShow(service, &cobra.Command{}, []string{"abc", "testtemplate1"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) t.Run("GetSolutionTemplateError_OutputsError", func(t *testing.T) { @@ -153,20 +155,20 @@ func Test_ecloudSolutionTemplateShow(t *testing.T) { func Test_ecloudSolutionTemplateUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTemplateUpdateCmd().Args(nil, []string{"123", "testname1"}) + err := ecloudSolutionTemplateUpdateCmd(nil).Args(nil, []string{"123", "testname1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTemplateUpdateCmd().Args(nil, []string{}) + err := ecloudSolutionTemplateUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudSolutionTemplateUpdateCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTemplateUpdateCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -180,10 +182,10 @@ func Test_ecloudSolutionTemplateUpdate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTemplateUpdateCmd() + cmd := ecloudSolutionTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") expectedPatch := ecloud.RenameTemplateRequest{ @@ -199,44 +201,44 @@ func Test_ecloudSolutionTemplateUpdate(t *testing.T) { ecloudSolutionTemplateUpdate(service, cmd, []string{"123", "testname1"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTemplateUpdate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionTemplateUpdate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("RenameSolutionTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("RenameSolutionTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTemplateUpdateCmd() + cmd := ecloudSolutionTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") gomock.InOrder( service.EXPECT().RenameSolutionTemplate(123, "testname1", gomock.Any()).Return(errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error updating solution template: test error 1\n", func() { - ecloudSolutionTemplateUpdate(service, cmd, []string{"123", "testname1"}) - }) + err := ecloudSolutionTemplateUpdate(service, cmd, []string{"123", "testname1"}) + + assert.Equal(t, "Error updating solution template: test error 1", err.Error()) }) - t.Run("WaitForCommandError_OutputsFatal", func(t *testing.T) { + t.Run("WaitForCommandError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTemplateUpdateCmd() + cmd := ecloudSolutionTemplateUpdateCmd(nil) cmd.Flags().Set("name", "newname") gomock.InOrder( @@ -244,12 +246,12 @@ func Test_ecloudSolutionTemplateUpdate(t *testing.T) { service.EXPECT().GetSolutionTemplate(123, "newname").Return(ecloud.Template{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error waiting for solution template update: Error waiting for command: Failed to retrieve solution template [newname]: test error 1\n", func() { - ecloudSolutionTemplateUpdate(service, cmd, []string{"123", "testname1"}) - }) + err := ecloudSolutionTemplateUpdate(service, cmd, []string{"123", "testname1"}) + + assert.Equal(t, "Error waiting for solution template update: Error waiting for command: Failed to retrieve solution template [newname]: test error 1", err.Error()) }) - t.Run("GetSolutionTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("GetSolutionTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -259,28 +261,28 @@ func Test_ecloudSolutionTemplateUpdate(t *testing.T) { service.EXPECT().GetSolutionTemplate(123, "testname1").Return(ecloud.Template{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error retrieving updated solution template: test error 1\n", func() { - ecloudSolutionTemplateUpdate(service, &cobra.Command{}, []string{"123", "testname1"}) - }) + err := ecloudSolutionTemplateUpdate(service, &cobra.Command{}, []string{"123", "testname1"}) + + assert.Equal(t, "Error retrieving updated solution template: test error 1", err.Error()) }) } func Test_ecloudSolutionTemplateDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionTemplateDeleteCmd().Args(nil, []string{"123", "testname1"}) + err := ecloudSolutionTemplateDeleteCmd(nil).Args(nil, []string{"123", "testname1"}) assert.Nil(t, err) }) t.Run("MissingSolution_Error", func(t *testing.T) { - err := ecloudSolutionTemplateDeleteCmd().Args(nil, []string{}) + err := ecloudSolutionTemplateDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - err := ecloudSolutionTemplateDeleteCmd().Args(nil, []string{"123"}) + err := ecloudSolutionTemplateDeleteCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -319,10 +321,10 @@ func Test_ecloudSolutionTemplateDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTemplateDeleteCmd() + cmd := ecloudSolutionTemplateDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -333,15 +335,15 @@ func Test_ecloudSolutionTemplateDelete(t *testing.T) { ecloudSolutionTemplateDelete(service, cmd, []string{"123", "testname1"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionTemplateDelete(service, &cobra.Command{}, []string{"abc", "testname1"}) - }) + err := ecloudSolutionTemplateDelete(service, &cobra.Command{}, []string{"abc", "testname1"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) t.Run("DeleteSolutionTemplateError_OutputsError", func(t *testing.T) { @@ -363,10 +365,10 @@ func Test_ecloudSolutionTemplateDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionTemplateDeleteCmd() + cmd := ecloudSolutionTemplateDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( diff --git a/cmd/ecloud_solution_test.go b/cmd/ecloud/ecloud_solution_test.go similarity index 76% rename from cmd/ecloud_solution_test.go rename to cmd/ecloud/ecloud_solution_test.go index ee11ee2..89a8b79 100644 --- a/cmd/ecloud_solution_test.go +++ b/cmd/ecloud/ecloud_solution_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -24,7 +25,7 @@ func Test_ecloudSolutionList(t *testing.T) { ecloudSolutionList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_ecloudSolutionList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionList(service, cmd, []string{}) - }) + err := ecloudSolutionList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSolutionsError_OutputsFatal", func(t *testing.T) { + t.Run("GetSolutionsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_ecloudSolutionList(t *testing.T) { service.EXPECT().GetSolutions(gomock.Any()).Return([]ecloud.Solution{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solutions: test error\n", func() { - ecloudSolutionList(service, &cobra.Command{}, []string{}) - }) + err := ecloudSolutionList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving solutions: test error", err.Error()) }) } func Test_ecloudSolutionShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionShowCmd().Args(nil, []string{"123"}) + err := ecloudSolutionShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionShowCmd().Args(nil, []string{}) + err := ecloudSolutionShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -120,13 +121,13 @@ func Test_ecloudSolutionShow(t *testing.T) { func Test_ecloudSolutionUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionUpdateCmd().Args(nil, []string{"123"}) + err := ecloudSolutionUpdateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionUpdateCmd().Args(nil, []string{}) + err := ecloudSolutionUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -139,7 +140,7 @@ func Test_ecloudSolutionUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudSolutionUpdateCmd() + cmd := ecloudSolutionUpdateCmd(nil) cmd.Flags().Set("name", "new solution name") gomock.InOrder( @@ -154,19 +155,19 @@ func Test_ecloudSolutionUpdate(t *testing.T) { ecloudSolutionUpdate(service, cmd, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionUpdate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionUpdate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("PatchSolutionError_OutputsFatal", func(t *testing.T) { + t.Run("PatchSolutionError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -175,12 +176,12 @@ func Test_ecloudSolutionUpdate(t *testing.T) { service.EXPECT().PatchSolution(123, gomock.Any()).Return(0, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error updating solution: test error\n", func() { - ecloudSolutionUpdate(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionUpdate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error updating solution: test error", err.Error()) }) - t.Run("GetSolutionError_OutputsError", func(t *testing.T) { + t.Run("GetSolutionError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -192,8 +193,8 @@ func Test_ecloudSolutionUpdate(t *testing.T) { service.EXPECT().GetSolution(123).Return(ecloud.Solution{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving updated solution: test error\n", func() { - ecloudSolutionUpdate(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionUpdate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving updated solution: test error", err.Error()) }) } diff --git a/cmd/ecloud_solution_vm.go b/cmd/ecloud/ecloud_solution_vm.go similarity index 62% rename from cmd/ecloud_solution_vm.go rename to cmd/ecloud/ecloud_solution_vm.go index 60c2175..ffc7955 100644 --- a/cmd/ecloud_solution_vm.go +++ b/cmd/ecloud/ecloud_solution_vm.go @@ -1,28 +1,30 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudSolutionVirtualMachineRootCmd() *cobra.Command { +func ecloudSolutionVirtualMachineRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "vm", Short: "sub-commands relating to solution virtual machines", } // Child commands - cmd.AddCommand(ecloudSolutionVirtualMachineListCmd()) + cmd.AddCommand(ecloudSolutionVirtualMachineListCmd(f)) return cmd } -func ecloudSolutionVirtualMachineListCmd() *cobra.Command { +func ecloudSolutionVirtualMachineListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solution virtual machines", @@ -36,29 +38,26 @@ func ecloudSolutionVirtualMachineListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudSolutionVirtualMachineList(getClient().ECloudService(), cmd, args) + ecloudSolutionVirtualMachineList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudSolutionVirtualMachineList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudSolutionVirtualMachineList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { solutionID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid solution ID [%s]", args[0]) - return + return fmt.Errorf("Invalid solution ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } vms, err := service.GetSolutionVirtualMachines(solutionID, params) if err != nil { - output.Fatalf("Error retrieving solution virtual machines: %s", err) - return + return fmt.Errorf("Error retrieving solution virtual machines: %s", err) } - outputECloudVirtualMachines(vms) + return output.CommandOutput(cmd, OutputECloudVirtualMachinesProvider(vms)) } diff --git a/cmd/ecloud_solution_vm_test.go b/cmd/ecloud/ecloud_solution_vm_test.go similarity index 63% rename from cmd/ecloud_solution_vm_test.go rename to cmd/ecloud/ecloud_solution_vm_test.go index 6fb3e21..90bc0ae 100644 --- a/cmd/ecloud_solution_vm_test.go +++ b/cmd/ecloud/ecloud_solution_vm_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,20 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudSolutionVirtualMachineListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudSolutionVirtualMachineListCmd().Args(nil, []string{"123"}) + err := ecloudSolutionVirtualMachineListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudSolutionVirtualMachineListCmd().Args(nil, []string{}) + err := ecloudSolutionVirtualMachineListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) @@ -39,19 +39,19 @@ func Test_ecloudSolutionVirtualMachineList(t *testing.T) { ecloudSolutionVirtualMachineList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidSolutionID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidSolutionID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid solution ID [abc]\n", func() { - ecloudSolutionVirtualMachineList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudSolutionVirtualMachineList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid solution ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +59,12 @@ func Test_ecloudSolutionVirtualMachineList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudSolutionVirtualMachineList(service, cmd, []string{"123"}) - }) + err := ecloudSolutionVirtualMachineList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetVirtualMachinesError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachinesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,8 +73,8 @@ func Test_ecloudSolutionVirtualMachineList(t *testing.T) { service.EXPECT().GetSolutionVirtualMachines(123, gomock.Any()).Return([]ecloud.VirtualMachine{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solution virtual machines: test error 1\n", func() { - ecloudSolutionVirtualMachineList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudSolutionVirtualMachineList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving solution virtual machines: test error 1", err.Error()) }) } diff --git a/cmd/ecloud/ecloud_test.go b/cmd/ecloud/ecloud_test.go new file mode 100644 index 0000000..a748c67 --- /dev/null +++ b/cmd/ecloud/ecloud_test.go @@ -0,0 +1,153 @@ +package ecloud + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetKeyValueFromStringFlag(t *testing.T) { + t.Run("Valid_NoError", func(t *testing.T) { + flag := "testkey=testvalue" + + key, value, err := GetKeyValueFromStringFlag(flag) + + assert.Nil(t, err) + assert.Equal(t, "testkey", key) + assert.Equal(t, "testvalue", value) + }) + + t.Run("Empty_Error", func(t *testing.T) { + flag := "" + + _, _, err := GetKeyValueFromStringFlag(flag) + + assert.NotNil(t, err) + }) + + t.Run("OnlyKey_Error", func(t *testing.T) { + flag := "testkey" + + _, _, err := GetKeyValueFromStringFlag(flag) + + assert.NotNil(t, err) + }) + + t.Run("MissingValue_Error", func(t *testing.T) { + flag := "testkey=" + + _, _, err := GetKeyValueFromStringFlag(flag) + + assert.NotNil(t, err) + }) + + t.Run("MissingKey_Error", func(t *testing.T) { + flag := "=testvalue" + + _, _, err := GetKeyValueFromStringFlag(flag) + + assert.NotNil(t, err) + }) + + t.Run("MultiValue_Error", func(t *testing.T) { + flag := "testkey=testvalue1=testvalue2" + + _, _, err := GetKeyValueFromStringFlag(flag) + + assert.NotNil(t, err) + }) +} + +func TestGetCreateTagRequestFromStringArrayFlag(t *testing.T) { + t.Run("None_NoError", func(t *testing.T) { + var tagFlags []string + + r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) + + assert.Nil(t, err) + assert.Len(t, r, 0) + }) + + t.Run("Single", func(t *testing.T) { + var tagFlags []string + tagFlags = append(tagFlags, "testkey1=testvalue1") + + r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) + + assert.Nil(t, err) + assert.Len(t, r, 1) + assert.Equal(t, "testkey1", r[0].Key) + assert.Equal(t, "testvalue1", r[0].Value) + }) + + t.Run("Multiple", func(t *testing.T) { + var tagFlags []string + tagFlags = append(tagFlags, "testkey1=testvalue1") + tagFlags = append(tagFlags, "testkey2=testvalue2") + + r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) + + assert.Nil(t, err) + assert.Len(t, r, 2) + assert.Equal(t, "testkey1", r[0].Key) + assert.Equal(t, "testvalue1", r[0].Value) + assert.Equal(t, "testkey2", r[1].Key) + assert.Equal(t, "testvalue2", r[1].Value) + }) + + t.Run("Invalid_ReturnsError", func(t *testing.T) { + tagFlags := []string{"invalid"} + + _, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) + + assert.NotNil(t, err) + assert.Equal(t, "Invalid format, expecting: key=value", err.Error()) + }) +} + +func TestGetCreateVirtualMachineRequestParameterFromStringArrayFlag(t *testing.T) { + t.Run("None_NoError", func(t *testing.T) { + var parameterFlags []string + + r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) + + assert.Nil(t, err) + assert.Len(t, r, 0) + }) + + t.Run("Single", func(t *testing.T) { + var parameterFlags []string + parameterFlags = append(parameterFlags, "testkey1=testvalue1") + + r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) + + assert.Nil(t, err) + assert.Len(t, r, 1) + assert.Equal(t, "testkey1", r[0].Key) + assert.Equal(t, "testvalue1", r[0].Value) + }) + + t.Run("Multiple", func(t *testing.T) { + var parameterFlags []string + parameterFlags = append(parameterFlags, "testkey1=testvalue1") + parameterFlags = append(parameterFlags, "testkey2=testvalue2") + + r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) + + assert.Nil(t, err) + assert.Len(t, r, 2) + assert.Equal(t, "testkey1", r[0].Key) + assert.Equal(t, "testvalue1", r[0].Value) + assert.Equal(t, "testkey2", r[1].Key) + assert.Equal(t, "testvalue2", r[1].Value) + }) + + t.Run("Invalid_ReturnsError", func(t *testing.T) { + parameterFlags := []string{"invalid"} + + _, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) + + assert.NotNil(t, err) + assert.Equal(t, "Invalid format, expecting: key=value", err.Error()) + }) +} diff --git a/cmd/ecloud_vm.go b/cmd/ecloud/ecloud_vm.go similarity index 81% rename from cmd/ecloud_vm.go rename to cmd/ecloud/ecloud_vm.go index d2530c4..4a64371 100644 --- a/cmd/ecloud_vm.go +++ b/cmd/ecloud/ecloud_vm.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -6,44 +6,45 @@ import ( "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudVirtualMachineRootCmd() *cobra.Command { +func ecloudVirtualMachineRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "vm", Short: "sub-commands relating to virtual machines", } // Child commands - cmd.AddCommand(ecloudVirtualMachineListCmd()) - cmd.AddCommand(ecloudVirtualMachineShowCmd()) - cmd.AddCommand(ecloudVirtualMachineCreateCmd()) - cmd.AddCommand(ecloudVirtualMachineUpdateCmd()) - cmd.AddCommand(ecloudVirtualMachineStartCmd()) - cmd.AddCommand(ecloudVirtualMachineStopCmd()) - cmd.AddCommand(ecloudVirtualMachineRestartCmd()) - cmd.AddCommand(ecloudVirtualMachineDeleteCmd()) + cmd.AddCommand(ecloudVirtualMachineListCmd(f)) + cmd.AddCommand(ecloudVirtualMachineShowCmd(f)) + cmd.AddCommand(ecloudVirtualMachineCreateCmd(f)) + cmd.AddCommand(ecloudVirtualMachineUpdateCmd(f)) + cmd.AddCommand(ecloudVirtualMachineStartCmd(f)) + cmd.AddCommand(ecloudVirtualMachineStopCmd(f)) + cmd.AddCommand(ecloudVirtualMachineRestartCmd(f)) + cmd.AddCommand(ecloudVirtualMachineDeleteCmd(f)) // Child root commands - cmd.AddCommand(ecloudVirtualMachineTagRootCmd()) - cmd.AddCommand(ecloudVirtualMachineDiskRootCmd()) - cmd.AddCommand(ecloudVirtualMachineTemplateRootCmd()) + cmd.AddCommand(ecloudVirtualMachineTagRootCmd(f)) + cmd.AddCommand(ecloudVirtualMachineDiskRootCmd(f)) + cmd.AddCommand(ecloudVirtualMachineTemplateRootCmd(f)) return cmd } -func ecloudVirtualMachineListCmd() *cobra.Command { +func ecloudVirtualMachineListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "Lists virtual machines", Long: "This command lists virtual machines", Example: "ukfast ecloud vm list", Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineList(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineList(f.NewClient().ECloudService(), cmd, args) }, } @@ -52,11 +53,10 @@ func ecloudVirtualMachineListCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -66,14 +66,13 @@ func ecloudVirtualMachineList(service ecloud.ECloudService, cmd *cobra.Command, vms, err := service.GetVirtualMachines(params) if err != nil { - output.Fatalf("Error retrieving virtual machines: %s", err) - return + return fmt.Errorf("Error retrieving virtual machines: %s", err) } - outputECloudVirtualMachines(vms) + return output.CommandOutput(cmd, OutputECloudVirtualMachinesProvider(vms)) } -func ecloudVirtualMachineShowCmd() *cobra.Command { +func ecloudVirtualMachineShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a virtual machine", @@ -86,13 +85,13 @@ func ecloudVirtualMachineShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudVirtualMachineShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { var vms []ecloud.VirtualMachine for _, arg := range args { vmID, err := strconv.Atoi(arg) @@ -110,17 +109,17 @@ func ecloudVirtualMachineShow(service ecloud.ECloudService, cmd *cobra.Command, vms = append(vms, vm) } - outputECloudVirtualMachines(vms) + return output.CommandOutput(cmd, OutputECloudVirtualMachinesProvider(vms)) } -func ecloudVirtualMachineCreateCmd() *cobra.Command { +func ecloudVirtualMachineCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a virtual machine", Long: "This command creates a virtual machine", Example: "ukfast ecloud vm create", - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineCreate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineCreate(f.NewClient().ECloudService(), cmd, args) }, } @@ -158,7 +157,7 @@ func ecloudVirtualMachineCreateCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { createRequest := ecloud.CreateVirtualMachineRequest{} createRequest.Environment, _ = cmd.Flags().GetString("environment") createRequest.Template, _ = cmd.Flags().GetString("template") @@ -185,8 +184,7 @@ func ecloudVirtualMachineCreate(service ecloud.ECloudService, cmd *cobra.Command tagsFlag, _ := cmd.Flags().GetStringSlice("tag") tagsReq, err := GetCreateTagRequestFromStringArrayFlag(tagsFlag) if err != nil { - output.Fatalf("Invalid tag data: %s", err) - return + return fmt.Errorf("Invalid tag data: %s", err) } createRequest.Tags = tagsReq @@ -196,8 +194,7 @@ func ecloudVirtualMachineCreate(service ecloud.ECloudService, cmd *cobra.Command parametersFlag, _ := cmd.Flags().GetStringSlice("parameter") parametersReq, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parametersFlag) if err != nil { - output.Fatalf("Invalid parameter data: %s", err) - return + return fmt.Errorf("Invalid parameter data: %s", err) } createRequest.Parameters = parametersReq @@ -216,29 +213,26 @@ func ecloudVirtualMachineCreate(service ecloud.ECloudService, cmd *cobra.Command id, err := service.CreateVirtualMachine(createRequest) if err != nil { - output.Fatalf("Error creating virtual machine: %s", err) - return + return fmt.Errorf("Error creating virtual machine: %s", err) } waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(VirtualMachineStatusWaitFunc(service, id, ecloud.VirtualMachineStatusComplete)) + err := helper.WaitForCommand(VirtualMachineStatusWaitFunc(service, id, ecloud.VirtualMachineStatusComplete)) if err != nil { - output.Fatalf(err.Error()) - return + return err } } vm, err := service.GetVirtualMachine(id) if err != nil { - output.Fatalf("Error retrieving new virtual machine: %s", err) - return + return fmt.Errorf("Error retrieving new virtual machine: %s", err) } - outputECloudVirtualMachines([]ecloud.VirtualMachine{vm}) + return output.CommandOutput(cmd, OutputECloudVirtualMachinesProvider([]ecloud.VirtualMachine{vm})) } -func ecloudVirtualMachineUpdateCmd() *cobra.Command { +func ecloudVirtualMachineUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a virtual machine", @@ -251,8 +245,8 @@ func ecloudVirtualMachineUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -264,7 +258,7 @@ func ecloudVirtualMachineUpdateCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { patchRequest := ecloud.PatchVirtualMachineRequest{} @@ -296,7 +290,7 @@ func ecloudVirtualMachineUpdate(service ecloud.ECloudService, cmd *cobra.Command continue } - err = WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) + err = helper.WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) if err != nil { output.OutputWithErrorLevelf("Error updating virtual machine [%d]: %s", vmID, err.Error()) continue @@ -305,16 +299,16 @@ func ecloudVirtualMachineUpdate(service ecloud.ECloudService, cmd *cobra.Command vm, err := service.GetVirtualMachine(vmID) if err != nil { output.OutputWithErrorLevelf("Error retrieving updated virtual machine [%d]: %s", vmID, err.Error()) - return + continue } vms = append(vms, vm) } - outputECloudVirtualMachines(vms) + return output.CommandOutput(cmd, OutputECloudVirtualMachinesProvider(vms)) } -func ecloudVirtualMachineStartCmd() *cobra.Command { +func ecloudVirtualMachineStartCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "start ...", Short: "Starts a virtual machine", @@ -328,7 +322,7 @@ func ecloudVirtualMachineStartCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineStart(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineStart(f.NewClient().ECloudService(), cmd, args) }, } } @@ -349,7 +343,7 @@ func ecloudVirtualMachineStart(service ecloud.ECloudService, cmd *cobra.Command, } } -func ecloudVirtualMachineStopCmd() *cobra.Command { +func ecloudVirtualMachineStopCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "stop ...", Short: "Stops a virtual machine", @@ -363,7 +357,7 @@ func ecloudVirtualMachineStopCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineStop(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineStop(f.NewClient().ECloudService(), cmd, args) }, } @@ -398,7 +392,7 @@ func ecloudVirtualMachineStop(service ecloud.ECloudService, cmd *cobra.Command, } } -func ecloudVirtualMachineRestartCmd() *cobra.Command { +func ecloudVirtualMachineRestartCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "restart ...", Short: "Restarts a virtual machine", @@ -412,7 +406,7 @@ func ecloudVirtualMachineRestartCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineRestart(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineRestart(f.NewClient().ECloudService(), cmd, args) }, } @@ -447,7 +441,7 @@ func ecloudVirtualMachineRestart(service ecloud.ECloudService, cmd *cobra.Comman } } -func ecloudVirtualMachineDeleteCmd() *cobra.Command { +func ecloudVirtualMachineDeleteCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "delete ...", Short: "Removes a virtual machine", @@ -461,7 +455,7 @@ func ecloudVirtualMachineDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineDelete(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineDelete(f.NewClient().ECloudService(), cmd, args) }, } @@ -486,7 +480,7 @@ func ecloudVirtualMachineDelete(service ecloud.ECloudService, cmd *cobra.Command waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(VirtualMachineNotFoundWaitFunc(service, vmID)) + err := helper.WaitForCommand(VirtualMachineNotFoundWaitFunc(service, vmID)) if err != nil { output.OutputWithErrorLevelf("Error removing virtual machine [%d]: %s", vmID, err) continue @@ -495,7 +489,7 @@ func ecloudVirtualMachineDelete(service ecloud.ECloudService, cmd *cobra.Command } } -func VirtualMachineNotFoundWaitFunc(service ecloud.ECloudService, vmID int) WaitFunc { +func VirtualMachineNotFoundWaitFunc(service ecloud.ECloudService, vmID int) helper.WaitFunc { return func() (finished bool, err error) { vm, err := service.GetVirtualMachine(vmID) if err != nil { @@ -515,7 +509,7 @@ func VirtualMachineNotFoundWaitFunc(service ecloud.ECloudService, vmID int) Wait } } -func VirtualMachineStatusWaitFunc(service ecloud.ECloudService, vmID int, status ecloud.VirtualMachineStatus) WaitFunc { +func VirtualMachineStatusWaitFunc(service ecloud.ECloudService, vmID int, status ecloud.VirtualMachineStatus) helper.WaitFunc { return func() (finished bool, err error) { vm, err := service.GetVirtualMachine(vmID) if err != nil { diff --git a/cmd/ecloud_vm_disk.go b/cmd/ecloud/ecloud_vm_disk.go similarity index 61% rename from cmd/ecloud_vm_disk.go rename to cmd/ecloud/ecloud_vm_disk.go index 9cb9157..8cfc994 100644 --- a/cmd/ecloud_vm_disk.go +++ b/cmd/ecloud/ecloud_vm_disk.go @@ -1,29 +1,32 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" "github.com/spf13/cobra" ) -func ecloudVirtualMachineDiskRootCmd() *cobra.Command { +func ecloudVirtualMachineDiskRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "disk", Short: "sub-commands relating to virtual machine disks", } // Child commands - cmd.AddCommand(ecloudVirtualMachineDiskListCmd()) - cmd.AddCommand(ecloudVirtualMachineDiskUpdateCmd()) + cmd.AddCommand(ecloudVirtualMachineDiskListCmd(f)) + cmd.AddCommand(ecloudVirtualMachineDiskUpdateCmd(f)) return cmd } -func ecloudVirtualMachineDiskListCmd() *cobra.Command { +func ecloudVirtualMachineDiskListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list ", Short: "lists virtual machine disks", @@ -37,7 +40,7 @@ func ecloudVirtualMachineDiskListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineDiskList(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineDiskList(f.NewClient().ECloudService(), cmd, args) }, } @@ -46,23 +49,21 @@ func ecloudVirtualMachineDiskListCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineDiskList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineDiskList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } vm, err := service.GetVirtualMachine(vmID) if err != nil { - output.Fatalf("Error retrieving virtual machine [%s]: %s", args[0], err) - return + return fmt.Errorf("Error retrieving virtual machine [%s]: %s", args[0], err) } - outputECloudVirtualMachineDisks(vm.Disks) + return output.CommandOutput(cmd, OutputECloudVirtualMachineDisksProvider(vm.Disks)) } -func ecloudVirtualMachineDiskUpdateCmd() *cobra.Command { +func ecloudVirtualMachineDiskUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ", Short: "Updates a virtual machine disk", @@ -78,8 +79,8 @@ func ecloudVirtualMachineDiskUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineDiskUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineDiskUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -89,12 +90,11 @@ func ecloudVirtualMachineDiskUpdateCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineDiskUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineDiskUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } diskPatch := ecloud.PatchVirtualMachineRequestDisk{ @@ -114,13 +114,13 @@ func ecloudVirtualMachineDiskUpdate(service ecloud.ECloudService, cmd *cobra.Com err = service.PatchVirtualMachine(vmID, patchRequest) if err != nil { - output.Fatalf("Error updating virtual machine [%d]: %s", vmID, err.Error()) - return + return fmt.Errorf("Error updating virtual machine [%d]: %s", vmID, err.Error()) } - err = WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) + err = helper.WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) if err != nil { - output.Fatalf("Error updating virtual machine [%d]: %s", vmID, err.Error()) - return + return fmt.Errorf("Error updating virtual machine [%d]: %s", vmID, err.Error()) } + + return nil } diff --git a/cmd/ecloud_vm_disk_test.go b/cmd/ecloud/ecloud_vm_disk_test.go similarity index 63% rename from cmd/ecloud_vm_disk_test.go rename to cmd/ecloud/ecloud_vm_disk_test.go index dbe5be5..8a4bb06 100644 --- a/cmd/ecloud_vm_disk_test.go +++ b/cmd/ecloud/ecloud_vm_disk_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -8,20 +8,20 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudVirtualMachineDiskListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineDiskListCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineDiskListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineDiskListCmd().Args(nil, []string{}) + err := ecloudVirtualMachineDiskListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -40,19 +40,19 @@ func Test_ecloudVirtualMachineDiskList(t *testing.T) { ecloudVirtualMachineDiskList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineDiskList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudVirtualMachineDiskList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) - t.Run("GetVirtualMachineError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachineError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -61,28 +61,28 @@ func Test_ecloudVirtualMachineDiskList(t *testing.T) { service.EXPECT().GetVirtualMachine(123).Return(ecloud.VirtualMachine{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving virtual machine [123]: test error 1\n", func() { - ecloudVirtualMachineDiskList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudVirtualMachineDiskList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving virtual machine [123]: test error 1", err.Error()) }) } func Test_ecloudVirtualMachineDiskUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineDiskUpdateCmd().Args(nil, []string{"123", "00000000-0000-0000-0000-000000000000"}) + err := ecloudVirtualMachineDiskUpdateCmd(nil).Args(nil, []string{"123", "00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("MissingVirtualMachine_Error", func(t *testing.T) { - err := ecloudVirtualMachineDiskUpdateCmd().Args(nil, []string{}) + err := ecloudVirtualMachineDiskUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) }) t.Run("MissingDisk_Error", func(t *testing.T) { - err := ecloudVirtualMachineDiskUpdateCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineDiskUpdateCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing disk", err.Error()) @@ -96,10 +96,10 @@ func Test_ecloudVirtualMachineDiskUpdate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineDiskUpdateCmd() + cmd := ecloudVirtualMachineDiskUpdateCmd(nil) cmd.Flags().Set("capacity", "25") gomock.InOrder( @@ -114,18 +114,18 @@ func Test_ecloudVirtualMachineDiskUpdate(t *testing.T) { ecloudVirtualMachineDiskUpdate(service, cmd, []string{"123", "00000000-0000-0000-0000-000000000000"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"abc", "00000000-0000-0000-0000-000000000000"}) - }) + err := ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"abc", "00000000-0000-0000-0000-000000000000"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) - t.Run("PatchVirtualMachineError_OutputsFatal", func(t *testing.T) { + t.Run("PatchVirtualMachineError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -133,18 +133,18 @@ func Test_ecloudVirtualMachineDiskUpdate(t *testing.T) { service.EXPECT().PatchVirtualMachine(123, gomock.Any()).Return(errors.New("test error")) - test_output.AssertFatalOutput(t, "Error updating virtual machine [123]: test error\n", func() { - ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"123", "00000000-0000-0000-0000-000000000000"}) - }) + err := ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"123", "00000000-0000-0000-0000-000000000000"}) + + assert.Equal(t, "Error updating virtual machine [123]: test error", err.Error()) }) - t.Run("WaitGetVirtualMachineError_OutputsFatal", func(t *testing.T) { + t.Run("WaitGetVirtualMachineError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -153,8 +153,8 @@ func Test_ecloudVirtualMachineDiskUpdate(t *testing.T) { service.EXPECT().GetVirtualMachine(123).Return(ecloud.VirtualMachine{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error updating virtual machine [123]: Error waiting for command: Failed to retrieve virtual machine [123]: test error\n", func() { - ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"123", "00000000-0000-0000-0000-000000000000"}) - }) + err := ecloudVirtualMachineDiskUpdate(service, &cobra.Command{}, []string{"123", "00000000-0000-0000-0000-000000000000"}) + + assert.Equal(t, "Error updating virtual machine [123]: Error waiting for command: Failed to retrieve virtual machine [123]: test error", err.Error()) }) } diff --git a/cmd/ecloud_vm_tag.go b/cmd/ecloud/ecloud_vm_tag.go similarity index 67% rename from cmd/ecloud_vm_tag.go rename to cmd/ecloud/ecloud_vm_tag.go index 8ebb0f2..8f04cdb 100644 --- a/cmd/ecloud_vm_tag.go +++ b/cmd/ecloud/ecloud_vm_tag.go @@ -1,9 +1,11 @@ -package cmd +package ecloud import ( "errors" + "fmt" "strconv" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -11,23 +13,23 @@ import ( "github.com/spf13/cobra" ) -func ecloudVirtualMachineTagRootCmd() *cobra.Command { +func ecloudVirtualMachineTagRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "tag", Short: "sub-commands relating to virtual machine tags", } // Child commands - cmd.AddCommand(ecloudVirtualMachineTagListCmd()) - cmd.AddCommand(ecloudVirtualMachineTagShowCmd()) - cmd.AddCommand(ecloudVirtualMachineTagCreateCmd()) - cmd.AddCommand(ecloudVirtualMachineTagUpdateCmd()) - cmd.AddCommand(ecloudVirtualMachineTagDeleteCmd()) + cmd.AddCommand(ecloudVirtualMachineTagListCmd(f)) + cmd.AddCommand(ecloudVirtualMachineTagShowCmd(f)) + cmd.AddCommand(ecloudVirtualMachineTagCreateCmd(f)) + cmd.AddCommand(ecloudVirtualMachineTagUpdateCmd(f)) + cmd.AddCommand(ecloudVirtualMachineTagDeleteCmd(f)) return cmd } -func ecloudVirtualMachineTagListCmd() *cobra.Command { +func ecloudVirtualMachineTagListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "lists virtual machine tags", @@ -41,34 +43,31 @@ func ecloudVirtualMachineTagListCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineTagList(getClient().ECloudService(), cmd, args) + ecloudVirtualMachineTagList(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudVirtualMachineTagList(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineTagList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } tags, err := service.GetVirtualMachineTags(vmID, params) if err != nil { - output.Fatalf("Error retrieving virtual machine tags: %s", err) - return + return fmt.Errorf("Error retrieving virtual machine tags: %s", err) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudVirtualMachineTagShowCmd() *cobra.Command { +func ecloudVirtualMachineTagShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a virtual machine tag", @@ -84,17 +83,16 @@ func ecloudVirtualMachineTagShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineTagShow(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineTagShow(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudVirtualMachineTagShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineTagShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } var tags []ecloud.Tag @@ -109,10 +107,10 @@ func ecloudVirtualMachineTagShow(service ecloud.ECloudService, cmd *cobra.Comman tags = append(tags, tag) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudVirtualMachineTagCreateCmd() *cobra.Command { +func ecloudVirtualMachineTagCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a virtual machine tag", @@ -125,8 +123,8 @@ func ecloudVirtualMachineTagCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineTagCreate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineTagCreate(f.NewClient().ECloudService(), cmd, args) }, } @@ -138,11 +136,10 @@ func ecloudVirtualMachineTagCreateCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineTagCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineTagCreate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } key, _ := cmd.Flags().GetString("key") @@ -155,20 +152,18 @@ func ecloudVirtualMachineTagCreate(service ecloud.ECloudService, cmd *cobra.Comm err = service.CreateVirtualMachineTag(vmID, createRequest) if err != nil { - output.Fatalf("Error creating virtual machine tag: %s", err) - return + return fmt.Errorf("Error creating virtual machine tag: %s", err) } tag, err := service.GetVirtualMachineTag(vmID, key) if err != nil { - output.Fatalf("Error retrieving new virtual machine tag: %s", err) - return + return fmt.Errorf("Error retrieving new virtual machine tag: %s", err) } - outputECloudTags([]ecloud.Tag{tag}) + return output.CommandOutput(cmd, OutputECloudTagsProvider([]ecloud.Tag{tag})) } -func ecloudVirtualMachineTagUpdateCmd() *cobra.Command { +func ecloudVirtualMachineTagUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a virtual machine tag", @@ -184,8 +179,8 @@ func ecloudVirtualMachineTagUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineTagUpdate(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineTagUpdate(f.NewClient().ECloudService(), cmd, args) }, } @@ -194,11 +189,10 @@ func ecloudVirtualMachineTagUpdateCmd() *cobra.Command { return cmd } -func ecloudVirtualMachineTagUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineTagUpdate(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } patchRequest := ecloud.PatchTagRequest{} @@ -226,10 +220,10 @@ func ecloudVirtualMachineTagUpdate(service ecloud.ECloudService, cmd *cobra.Comm tags = append(tags, tag) } - outputECloudTags(tags) + return output.CommandOutput(cmd, OutputECloudTagsProvider(tags)) } -func ecloudVirtualMachineTagDeleteCmd() *cobra.Command { +func ecloudVirtualMachineTagDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Removes a virtual machine tag ", @@ -245,17 +239,16 @@ func ecloudVirtualMachineTagDeleteCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - ecloudVirtualMachineTagDelete(getClient().ECloudService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return ecloudVirtualMachineTagDelete(f.NewClient().ECloudService(), cmd, args) }, } } -func ecloudVirtualMachineTagDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) { +func ecloudVirtualMachineTagDelete(service ecloud.ECloudService, cmd *cobra.Command, args []string) error { vmID, err := strconv.Atoi(args[0]) if err != nil { - output.Fatalf("Invalid virtual machine ID [%s]", args[0]) - return + return fmt.Errorf("Invalid virtual machine ID [%s]", args[0]) } for _, arg := range args[1:] { @@ -264,4 +257,6 @@ func ecloudVirtualMachineTagDelete(service ecloud.ECloudService, cmd *cobra.Comm output.OutputWithErrorLevelf("Error removing virtual machine tag [%s]: %s", arg, err) } } + + return nil } diff --git a/cmd/ecloud_vm_tag_test.go b/cmd/ecloud/ecloud_vm_tag_test.go similarity index 75% rename from cmd/ecloud_vm_tag_test.go rename to cmd/ecloud/ecloud_vm_tag_test.go index 747b225..7f893be 100644 --- a/cmd/ecloud_vm_tag_test.go +++ b/cmd/ecloud/ecloud_vm_tag_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ecloud" @@ -14,13 +15,13 @@ import ( func Test_ecloudVirtualMachineTagListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTagListCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTagListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagListCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTagListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -39,19 +40,19 @@ func Test_ecloudVirtualMachineTagList(t *testing.T) { ecloudVirtualMachineTagList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineTagList(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudVirtualMachineTagList(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -59,12 +60,12 @@ func Test_ecloudVirtualMachineTagList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudVirtualMachineTagList(service, cmd, []string{"123"}) - }) + err := ecloudVirtualMachineTagList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetVirtualMachineTagsError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachineTagsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,28 +74,28 @@ func Test_ecloudVirtualMachineTagList(t *testing.T) { service.EXPECT().GetVirtualMachineTags(123, gomock.Any()).Return([]ecloud.Tag{}, errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving virtual machine tags: test error 1\n", func() { - ecloudVirtualMachineTagList(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudVirtualMachineTagList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving virtual machine tags: test error 1", err.Error()) }) } func Test_ecloudVirtualMachineTagShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTagShowCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudVirtualMachineTagShowCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingVirtualMachine_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagShowCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTagShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagShowCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTagShowCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -127,15 +128,15 @@ func Test_ecloudVirtualMachineTagShow(t *testing.T) { ecloudVirtualMachineTagShow(service, &cobra.Command{}, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineTagShow(service, &cobra.Command{}, []string{"abc", "testkey1"}) - }) + err := ecloudVirtualMachineTagShow(service, &cobra.Command{}, []string{"abc", "testkey1"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) t.Run("GetVirtualMachineTagError_OutputsError", func(t *testing.T) { @@ -154,13 +155,13 @@ func Test_ecloudVirtualMachineTagShow(t *testing.T) { func Test_ecloudVirtualMachineTagCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTagCreateCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTagCreateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagCreateCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTagCreateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -173,7 +174,7 @@ func Test_ecloudVirtualMachineTagCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTagCreateCmd() + cmd := ecloudVirtualMachineTagCreateCmd(nil) cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("value", "testvalue1") @@ -190,19 +191,19 @@ func Test_ecloudVirtualMachineTagCreate(t *testing.T) { ecloudVirtualMachineTagCreate(service, cmd, []string{"123"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineTagCreate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudVirtualMachineTagCreate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) - t.Run("CreateVirtualMachineTagError_OutputsFatal", func(t *testing.T) { + t.Run("CreateVirtualMachineTagError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -211,18 +212,18 @@ func Test_ecloudVirtualMachineTagCreate(t *testing.T) { service.EXPECT().CreateVirtualMachineTag(123, gomock.Any()).Return(errors.New("test error 1")).Times(1) - test_output.AssertFatalOutput(t, "Error creating virtual machine tag: test error 1\n", func() { - ecloudVirtualMachineTagCreate(service, &cobra.Command{}, []string{"123"}) - }) + err := ecloudVirtualMachineTagCreate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error creating virtual machine tag: test error 1", err.Error()) }) - t.Run("GetVirtualMachineTagError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachineTagError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTagCreateCmd() + cmd := ecloudVirtualMachineTagCreateCmd(nil) cmd.Flags().Set("key", "testkey1") cmd.Flags().Set("value", "testvalue1") @@ -231,28 +232,28 @@ func Test_ecloudVirtualMachineTagCreate(t *testing.T) { service.EXPECT().GetVirtualMachineTag(123, "testkey1").Return(ecloud.Tag{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error retrieving new virtual machine tag: test error 1\n", func() { - ecloudVirtualMachineTagCreate(service, cmd, []string{"123"}) - }) + err := ecloudVirtualMachineTagCreate(service, cmd, []string{"123"}) + + assert.Equal(t, "Error retrieving new virtual machine tag: test error 1", err.Error()) }) } func Test_ecloudVirtualMachineTagUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTagUpdateCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudVirtualMachineTagUpdateCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingVirtualMachine_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagUpdateCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTagUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagUpdateCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTagUpdateCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -265,7 +266,7 @@ func Test_ecloudVirtualMachineTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTagUpdateCmd() + cmd := ecloudVirtualMachineTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") expectedPatch := ecloud.PatchTagRequest{ @@ -285,7 +286,7 @@ func Test_ecloudVirtualMachineTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTagUpdateCmd() + cmd := ecloudVirtualMachineTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") expectedPatch := ecloud.PatchTagRequest{ @@ -302,16 +303,16 @@ func Test_ecloudVirtualMachineTagUpdate(t *testing.T) { ecloudVirtualMachineTagUpdate(service, cmd, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineTagUpdate(service, &cobra.Command{}, []string{"abc"}) - }) + err := ecloudVirtualMachineTagUpdate(service, &cobra.Command{}, []string{"abc"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) t.Run("PatchVirtualMachineTag_OutputsError", func(t *testing.T) { @@ -334,7 +335,7 @@ func Test_ecloudVirtualMachineTagUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTagUpdateCmd() + cmd := ecloudVirtualMachineTagUpdateCmd(nil) cmd.Flags().Set("value", "testvalue1") gomock.InOrder( @@ -350,20 +351,20 @@ func Test_ecloudVirtualMachineTagUpdate(t *testing.T) { func Test_ecloudVirtualMachineTagDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTagDeleteCmd().Args(nil, []string{"123", "testkey1"}) + err := ecloudVirtualMachineTagDeleteCmd(nil).Args(nil, []string{"123", "testkey1"}) assert.Nil(t, err) }) t.Run("MissingVirtualMachine_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagDeleteCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTagDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) }) t.Run("MissingTag_Error", func(t *testing.T) { - err := ecloudVirtualMachineTagDeleteCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTagDeleteCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing tag", err.Error()) @@ -396,16 +397,16 @@ func Test_ecloudVirtualMachineTagDelete(t *testing.T) { ecloudVirtualMachineTagDelete(service, &cobra.Command{}, []string{"123", "testkey1", "testkey2"}) }) - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - test_output.AssertFatalOutput(t, "Invalid virtual machine ID [abc]\n", func() { - ecloudVirtualMachineTagDelete(service, &cobra.Command{}, []string{"abc", "testkey1"}) - }) + err := ecloudVirtualMachineTagDelete(service, &cobra.Command{}, []string{"abc", "testkey1"}) + + assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) t.Run("DeleteVirtualMachineTagError_OutputsError", func(t *testing.T) { diff --git a/cmd/ecloud_vm_template.go b/cmd/ecloud/ecloud_vm_template.go similarity index 84% rename from cmd/ecloud_vm_template.go rename to cmd/ecloud/ecloud_vm_template.go index 83dc23e..7998f1d 100644 --- a/cmd/ecloud_vm_template.go +++ b/cmd/ecloud/ecloud_vm_template.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -7,22 +7,25 @@ import ( "github.com/spf13/cobra" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/helper" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) -func ecloudVirtualMachineTemplateRootCmd() *cobra.Command { +func ecloudVirtualMachineTemplateRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "template", Short: "sub-commands relating to virtual machine templates", } // Child commands - cmd.AddCommand(ecloudVirtualMachineTemplateCreateCmd()) + cmd.AddCommand(ecloudVirtualMachineTemplateCreateCmd(f)) return cmd } -func ecloudVirtualMachineTemplateCreateCmd() *cobra.Command { +func ecloudVirtualMachineTemplateCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a virtual machine template", @@ -36,7 +39,7 @@ func ecloudVirtualMachineTemplateCreateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return ecloudVirtualMachineTemplateCreate(getClient().ECloudService(), cmd, args) + return ecloudVirtualMachineTemplateCreate(f.NewClient().ECloudService(), cmd, args) }, } @@ -74,7 +77,7 @@ func ecloudVirtualMachineTemplateCreate(service ecloud.ECloudService, cmd *cobra waitFlag, _ := cmd.Flags().GetBool("wait") if waitFlag { - err := WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) + err := helper.WaitForCommand(VirtualMachineStatusWaitFunc(service, vmID, ecloud.VirtualMachineStatusComplete)) if err != nil { return err } @@ -89,8 +92,7 @@ func ecloudVirtualMachineTemplateCreate(service ecloud.ECloudService, cmd *cobra return fmt.Errorf("Error retrieving new virtual machine template: %s", err) } - outputECloudTemplates([]ecloud.Template{template}) - return nil + return output.CommandOutput(cmd, OutputECloudTemplatesProvider([]ecloud.Template{template})) } func getVMTemplate(service ecloud.ECloudService, vmID int, templateName string, templateType ecloud.TemplateType) (ecloud.Template, error) { diff --git a/cmd/ecloud_vm_template_test.go b/cmd/ecloud/ecloud_vm_template_test.go similarity index 78% rename from cmd/ecloud_vm_template_test.go rename to cmd/ecloud/ecloud_vm_template_test.go index 7d69d31..ea4ac8f 100644 --- a/cmd/ecloud_vm_template_test.go +++ b/cmd/ecloud/ecloud_vm_template_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -9,19 +9,20 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/sdk-go/pkg/service/ecloud" ) func Test_ecloudVirtualMachineTemplateCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineTemplateCreateCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineTemplateCreateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineTemplateCreateCmd().Args(nil, []string{}) + err := ecloudVirtualMachineTemplateCreateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -29,7 +30,7 @@ func Test_ecloudVirtualMachineTemplateCreateCmd_Args(t *testing.T) { } func Test_ecloudVirtualMachineTemplateCreate(t *testing.T) { - t.Run("InvalidVirtualMachineID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidVirtualMachineID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -39,24 +40,24 @@ func Test_ecloudVirtualMachineTemplateCreate(t *testing.T) { assert.Equal(t, "Invalid virtual machine ID [abc]", err.Error()) }) - t.Run("InvalidType_OutputsFatal", func(t *testing.T) { + t.Run("InvalidType_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTemplateCreateCmd() + cmd := ecloudVirtualMachineTemplateCreateCmd(nil) cmd.Flags().Set("type", "invalid") err := ecloudVirtualMachineTemplateCreate(service, cmd, []string{"123"}) assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("CreateVirtualMachineTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("CreateVirtualMachineTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTemplateCreateCmd() + cmd := ecloudVirtualMachineTemplateCreateCmd(nil) cmd.Flags().Set("type", "solution") service.EXPECT().CreateVirtualMachineTemplate(123, gomock.Any()).Return(errors.New("test error 1")) @@ -65,16 +66,16 @@ func Test_ecloudVirtualMachineTemplateCreate(t *testing.T) { assert.Equal(t, "Error creating virtual machine template: test error 1", err.Error()) }) - t.Run("WaitForCommandError_OutputsFatal", func(t *testing.T) { + t.Run("WaitForCommandError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineTemplateCreateCmd() + cmd := ecloudVirtualMachineTemplateCreateCmd(nil) cmd.Flags().Set("type", "solution") cmd.Flags().Set("wait", "true") diff --git a/cmd/ecloud_vm_test.go b/cmd/ecloud/ecloud_vm_test.go similarity index 89% rename from cmd/ecloud_vm_test.go rename to cmd/ecloud/ecloud_vm_test.go index 83d8e7c..a7b9760 100644 --- a/cmd/ecloud_vm_test.go +++ b/cmd/ecloud/ecloud_vm_test.go @@ -1,4 +1,4 @@ -package cmd +package ecloud import ( "errors" @@ -8,6 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/test" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/connection" @@ -31,7 +33,7 @@ func Test_ecloudVirtualMachineList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := safednsZoneListCmd() + cmd := ecloudVirtualMachineListCmd(nil) cmd.Flags().Set("name", "test vm 1") expectedParameters := connection.APIRequestParameters{ @@ -49,7 +51,7 @@ func Test_ecloudVirtualMachineList(t *testing.T) { ecloudVirtualMachineList(service, cmd, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -57,12 +59,12 @@ func Test_ecloudVirtualMachineList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - ecloudVirtualMachineList(service, cmd, []string{}) - }) + err := ecloudVirtualMachineList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetVirtualMachinesError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachinesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -71,21 +73,21 @@ func Test_ecloudVirtualMachineList(t *testing.T) { service.EXPECT().GetVirtualMachines(gomock.Any()).Return([]ecloud.VirtualMachine{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving virtual machines: test error\n", func() { - ecloudVirtualMachineList(service, &cobra.Command{}, []string{}) - }) + err := ecloudVirtualMachineList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving virtual machines: test error", err.Error()) }) } func Test_ecloudVirtualMachineShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineShowCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineShowCmd().Args(nil, []string{}) + err := ecloudVirtualMachineShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -149,7 +151,7 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("name", "test vm 1") gomock.InOrder( @@ -169,7 +171,7 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("tag", "abc=123") gomock.InOrder( @@ -187,7 +189,7 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("parameter", "abc=123") gomock.InOrder( @@ -205,7 +207,7 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("ssh-key", "testkey1") gomock.InOrder( @@ -225,7 +227,7 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("encrypt", "true") gomock.InOrder( @@ -245,10 +247,10 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -260,16 +262,16 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { ecloudVirtualMachineCreate(service, cmd, []string{"123"}) }) - t.Run("CreateWithWaitFailedStatus_OutputsFatal", func(t *testing.T) { + t.Run("CreateWithWaitFailedStatus_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -277,21 +279,21 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { service.EXPECT().GetVirtualMachine(123).Return(ecloud.VirtualMachine{Status: ecloud.VirtualMachineStatusFailed}, nil), ) - test_output.AssertFatalOutput(t, "Error waiting for command: Virtual machine [123] in [Failed] state\n", func() { - ecloudVirtualMachineCreate(service, cmd, []string{"123"}) - }) + err := ecloudVirtualMachineCreate(service, cmd, []string{"123"}) + + assert.Equal(t, "Error waiting for command: Virtual machine [123] in [Failed] state", err.Error()) }) - t.Run("CreateWithWaitRetrieveStatusFailure_OutputsFatal", func(t *testing.T) { + t.Run("CreateWithWaitRetrieveStatusFailure_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineCreateCmd() + cmd := ecloudVirtualMachineCreateCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -299,12 +301,12 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { service.EXPECT().GetVirtualMachine(123).Return(ecloud.VirtualMachine{}, errors.New("test error 1")), ) - test_output.AssertFatalOutput(t, "Error waiting for command: Failed to retrieve virtual machine [123]: test error 1\n", func() { - ecloudVirtualMachineCreate(service, cmd, []string{"123"}) - }) + err := ecloudVirtualMachineCreate(service, cmd, []string{"123"}) + + assert.Equal(t, "Error waiting for command: Failed to retrieve virtual machine [123]: test error 1", err.Error()) }) - t.Run("CreateVirtualMachineError_OutputsFatal", func(t *testing.T) { + t.Run("CreateVirtualMachineError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -312,12 +314,12 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { service.EXPECT().CreateVirtualMachine(gomock.Any()).Return(0, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating virtual machine: test error\n", func() { - ecloudVirtualMachineCreate(service, &cobra.Command{}, []string{}) - }) + err := ecloudVirtualMachineCreate(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error creating virtual machine: test error", err.Error()) }) - t.Run("GetVirtualMachineError_OutputsFatal", func(t *testing.T) { + t.Run("GetVirtualMachineError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -328,21 +330,21 @@ func Test_ecloudVirtualMachineCreate(t *testing.T) { service.EXPECT().GetVirtualMachine(123).Return(ecloud.VirtualMachine{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new virtual machine: test error\n", func() { - ecloudVirtualMachineCreate(service, &cobra.Command{}, []string{}) - }) + err := ecloudVirtualMachineCreate(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving new virtual machine: test error", err.Error()) }) } func Test_ecloudVirtualMachineUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineUpdateCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineUpdateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineUpdateCmd().Args(nil, []string{}) + err := ecloudVirtualMachineUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -356,10 +358,10 @@ func Test_ecloudVirtualMachineUpdate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineUpdateCmd() + cmd := ecloudVirtualMachineUpdateCmd(nil) cmd.Flags().Set("cpu", "2") cmd.Flags().Set("ram", "4") cmd.Flags().Set("name", "test vm name 1") @@ -389,10 +391,10 @@ func Test_ecloudVirtualMachineUpdate(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineUpdateCmd() + cmd := ecloudVirtualMachineUpdateCmd(nil) cmd.Flags().Set("cpu", "2") expectedPatch := ecloud.PatchVirtualMachineRequest{ @@ -471,13 +473,13 @@ func Test_ecloudVirtualMachineUpdate(t *testing.T) { func Test_ecloudVirtualMachineStartCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineStartCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineStartCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineStartCmd().Args(nil, []string{}) + err := ecloudVirtualMachineStartCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -537,13 +539,13 @@ func Test_ecloudVirtualMachineStart(t *testing.T) { func Test_ecloudVirtualMachineStopCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineStopCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineStopCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineStopCmd().Args(nil, []string{}) + err := ecloudVirtualMachineStopCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -581,7 +583,7 @@ func Test_ecloudVirtualMachineStop(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineStopCmd() + cmd := ecloudVirtualMachineStopCmd(nil) cmd.Flags().Set("force", "true") service.EXPECT().PowerOffVirtualMachine(123).Return(nil).Times(1) @@ -594,7 +596,7 @@ func Test_ecloudVirtualMachineStop(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineStopCmd() + cmd := ecloudVirtualMachineStopCmd(nil) cmd.Flags().Set("force", "true") gomock.InOrder( @@ -634,7 +636,7 @@ func Test_ecloudVirtualMachineStop(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineStopCmd() + cmd := ecloudVirtualMachineStopCmd(nil) cmd.Flags().Set("force", "true") service.EXPECT().PowerOffVirtualMachine(123).Return(errors.New("test error")) @@ -647,13 +649,13 @@ func Test_ecloudVirtualMachineStop(t *testing.T) { func Test_ecloudVirtualMachineRestartCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineRestartCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineRestartCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineRestartCmd().Args(nil, []string{}) + err := ecloudVirtualMachineRestartCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -691,7 +693,7 @@ func Test_ecloudVirtualMachineRestart(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineRestartCmd() + cmd := ecloudVirtualMachineRestartCmd(nil) cmd.Flags().Set("force", "true") service.EXPECT().PowerResetVirtualMachine(123).Return(nil).Times(1) @@ -704,7 +706,7 @@ func Test_ecloudVirtualMachineRestart(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineRestartCmd() + cmd := ecloudVirtualMachineRestartCmd(nil) cmd.Flags().Set("force", "true") gomock.InOrder( @@ -744,7 +746,7 @@ func Test_ecloudVirtualMachineRestart(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineRestartCmd() + cmd := ecloudVirtualMachineRestartCmd(nil) cmd.Flags().Set("force", "true") service.EXPECT().PowerResetVirtualMachine(123).Return(errors.New("test error")) @@ -757,13 +759,13 @@ func Test_ecloudVirtualMachineRestart(t *testing.T) { func Test_ecloudVirtualMachineDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := ecloudVirtualMachineDeleteCmd().Args(nil, []string{"123"}) + err := ecloudVirtualMachineDeleteCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := ecloudVirtualMachineDeleteCmd().Args(nil, []string{}) + err := ecloudVirtualMachineDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing virtual machine", err.Error()) @@ -802,10 +804,10 @@ func Test_ecloudVirtualMachineDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineDeleteCmd() + cmd := ecloudVirtualMachineDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -822,10 +824,10 @@ func Test_ecloudVirtualMachineDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineDeleteCmd() + cmd := ecloudVirtualMachineDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -844,10 +846,10 @@ func Test_ecloudVirtualMachineDelete(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) - cmd := ecloudVirtualMachineDeleteCmd() + cmd := ecloudVirtualMachineDeleteCmd(nil) cmd.Flags().Set("wait", "true") gomock.InOrder( @@ -892,7 +894,7 @@ func TestVirtualMachineNotFoundWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -910,7 +912,7 @@ func TestVirtualMachineNotFoundWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -929,7 +931,7 @@ func TestVirtualMachineNotFoundWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -948,7 +950,7 @@ func TestVirtualMachineNotFoundWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -968,7 +970,7 @@ func TestVirtualMachineStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -987,7 +989,7 @@ func TestVirtualMachineStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -1006,7 +1008,7 @@ func TestVirtualMachineStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) @@ -1024,7 +1026,7 @@ func TestVirtualMachineStatusWaitFunc(t *testing.T) { viper.SetDefault("command_wait_timeout_seconds", 1200) viper.SetDefault("command_wait_sleep_seconds", 1) - defer testResetViper() + defer test.TestResetViper() service := mocks.NewMockECloudService(mockCtrl) diff --git a/cmd/ecloud/output.go b/cmd/ecloud/output.go new file mode 100644 index 0000000..db4df68 --- /dev/null +++ b/cmd/ecloud/output.go @@ -0,0 +1,300 @@ +package ecloud + +import ( + "strconv" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/ecloud" +) + +func OutputECloudVirtualMachinesProvider(vms []ecloud.VirtualMachine) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(vms), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, vm := range vms { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(vm.ID), true)) + fields.Set("name", output.NewFieldValue(vm.Name, true)) + fields.Set("hostname", output.NewFieldValue(vm.Hostname, false)) + fields.Set("computername", output.NewFieldValue(vm.ComputerName, false)) + fields.Set("cpu", output.NewFieldValue(strconv.Itoa(vm.CPU), true)) + fields.Set("ram_gb", output.NewFieldValue(strconv.Itoa(vm.RAM), true)) + fields.Set("hdd_gb", output.NewFieldValue(strconv.Itoa(vm.HDD), true)) + fields.Set("ip_internal", output.NewFieldValue(vm.IPInternal.String(), true)) + fields.Set("ip_external", output.NewFieldValue(vm.IPExternal.String(), true)) + fields.Set("platform", output.NewFieldValue(vm.Platform, false)) + fields.Set("template", output.NewFieldValue(vm.Template, false)) + fields.Set("backup", output.NewFieldValue(strconv.FormatBool(vm.Backup), false)) + fields.Set("support", output.NewFieldValue(strconv.FormatBool(vm.Support), false)) + fields.Set("environment", output.NewFieldValue(vm.Environment, false)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(vm.SolutionID), false)) + fields.Set("status", output.NewFieldValue(vm.Status.String(), true)) + fields.Set("power_status", output.NewFieldValue(vm.PowerStatus, true)) + fields.Set("tools_status", output.NewFieldValue(vm.ToolsStatus, false)) + fields.Set("encrypted", output.NewFieldValue(strconv.FormatBool(vm.Encrypted), false)) + fields.Set("role", output.NewFieldValue(vm.Role, false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudVirtualMachineDisksProvider(disks []ecloud.VirtualMachineDisk) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(disks), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, disk := range disks { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(disk.Name, true)) + fields.Set("capacity", output.NewFieldValue(strconv.Itoa(disk.Capacity), true)) + fields.Set("uuid", output.NewFieldValue(disk.UUID, true)) + fields.Set("type", output.NewFieldValue(disk.Type.String(), true)) + fields.Set("key", output.NewFieldValue(strconv.Itoa(disk.Key), false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudTagsProvider(tags []ecloud.Tag) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(tags), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, tag := range tags { + fields := output.NewOrderedFields() + fields.Set("key", output.NewFieldValue(tag.Key, true)) + fields.Set("value", output.NewFieldValue(tag.Value, true)) + fields.Set("created_at", output.NewFieldValue(tag.CreatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudSolutionsProvider(solutions []ecloud.Solution) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(solutions), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, solution := range solutions { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(solution.ID), true)) + fields.Set("name", output.NewFieldValue(solution.Name, true)) + fields.Set("environment", output.NewFieldValue(solution.Environment.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudSitesProvider(sites []ecloud.Site) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(sites), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, site := range sites { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(site.ID), true)) + fields.Set("state", output.NewFieldValue(site.State, true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(site.SolutionID), true)) + fields.Set("pod_id", output.NewFieldValue(strconv.Itoa(site.PodID), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudHostsProvider(hosts []ecloud.Host) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(hosts), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, host := range hosts { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(host.ID), true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(host.SolutionID), true)) + fields.Set("pod_id", output.NewFieldValue(strconv.Itoa(host.PodID), true)) + fields.Set("name", output.NewFieldValue(host.Name, true)) + fields.Set("cpu_quantity", output.NewFieldValue(strconv.Itoa(host.CPU.Quantity), true)) + fields.Set("cpu_cores", output.NewFieldValue(strconv.Itoa(host.CPU.Cores), true)) + fields.Set("cpu_speed", output.NewFieldValue(host.CPU.Speed, false)) + fields.Set("ram_capacity", output.NewFieldValue(strconv.Itoa(host.RAM.Capacity), true)) + fields.Set("ram_reserved", output.NewFieldValue(strconv.Itoa(host.RAM.Reserved), false)) + fields.Set("ram_allocated", output.NewFieldValue(strconv.Itoa(host.RAM.Allocated), false)) + fields.Set("ram_available", output.NewFieldValue(strconv.Itoa(host.RAM.Available), false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudDatastoresProvider(datastores []ecloud.Datastore) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(datastores), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, datastore := range datastores { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(datastore.ID), true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(datastore.SolutionID), true)) + fields.Set("site_id", output.NewFieldValue(strconv.Itoa(datastore.SiteID), true)) + fields.Set("name", output.NewFieldValue(datastore.Name, true)) + fields.Set("status", output.NewFieldValue(datastore.Status.String(), true)) + fields.Set("capacity", output.NewFieldValue(strconv.Itoa(datastore.Capacity), true)) + fields.Set("allocated", output.NewFieldValue(strconv.Itoa(datastore.Allocated), false)) + fields.Set("available", output.NewFieldValue(strconv.Itoa(datastore.Available), false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudTemplatesProvider(templates []ecloud.Template) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(templates), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, template := range templates { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(template.Name, true)) + fields.Set("cpu", output.NewFieldValue(strconv.Itoa(template.CPU), true)) + fields.Set("ram_gb", output.NewFieldValue(strconv.Itoa(template.RAM), true)) + fields.Set("hdd_gb", output.NewFieldValue(strconv.Itoa(template.HDD), true)) + fields.Set("platform", output.NewFieldValue(template.Platform, true)) + fields.Set("operating_system", output.NewFieldValue(template.OperatingSystem, true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(template.SolutionID), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudNetworksProvider(networks []ecloud.Network) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(networks), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, network := range networks { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(network.ID), true)) + fields.Set("name", output.NewFieldValue(network.Name, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudFirewallsProvider(firewalls []ecloud.Firewall) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(firewalls), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, firewall := range firewalls { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(firewall.ID), true)) + fields.Set("name", output.NewFieldValue(firewall.Name, true)) + fields.Set("hostname", output.NewFieldValue(firewall.Hostname, true)) + fields.Set("ip", output.NewFieldValue(firewall.IP.String(), true)) + fields.Set("role", output.NewFieldValue(firewall.Role.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudPodsProvider(pods []ecloud.Pod) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(pods), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, pod := range pods { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(pod.ID), true)) + fields.Set("name", output.NewFieldValue(pod.Name, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudAppliancesProvider(appliances []ecloud.Appliance) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(appliances), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, appliance := range appliances { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(appliance.ID, true)) + fields.Set("name", output.NewFieldValue(appliance.Name, true)) + fields.Set("logo_uri", output.NewFieldValue(appliance.LogoURI, false)) + fields.Set("description", output.NewFieldValue(appliance.Description, false)) + fields.Set("documentation_uri", output.NewFieldValue(appliance.DocumentationURI, false)) + fields.Set("publisher", output.NewFieldValue(appliance.Publisher, true)) + fields.Set("created_at", output.NewFieldValue(appliance.CreatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputECloudApplianceParametersProvider(parameters []ecloud.ApplianceParameter) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(parameters), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, parameter := range parameters { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(parameter.ID, true)) + fields.Set("name", output.NewFieldValue(parameter.Name, true)) + fields.Set("key", output.NewFieldValue(parameter.Key, true)) + fields.Set("type", output.NewFieldValue(parameter.Type, true)) + fields.Set("description", output.NewFieldValue(parameter.Description, true)) + fields.Set("required", output.NewFieldValue(strconv.FormatBool(parameter.Required), true)) + fields.Set("validation_rule", output.NewFieldValue(parameter.ValidationRule, false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/ecloud_test.go b/cmd/ecloud_test.go deleted file mode 100644 index 11d508b..0000000 --- a/cmd/ecloud_test.go +++ /dev/null @@ -1,924 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/service/ecloud" -) - -func TestGetKeyValueFromStringFlag(t *testing.T) { - t.Run("Valid_NoError", func(t *testing.T) { - flag := "testkey=testvalue" - - key, value, err := GetKeyValueFromStringFlag(flag) - - assert.Nil(t, err) - assert.Equal(t, "testkey", key) - assert.Equal(t, "testvalue", value) - }) - - t.Run("Empty_Error", func(t *testing.T) { - flag := "" - - _, _, err := GetKeyValueFromStringFlag(flag) - - assert.NotNil(t, err) - }) - - t.Run("OnlyKey_Error", func(t *testing.T) { - flag := "testkey" - - _, _, err := GetKeyValueFromStringFlag(flag) - - assert.NotNil(t, err) - }) - - t.Run("MissingValue_Error", func(t *testing.T) { - flag := "testkey=" - - _, _, err := GetKeyValueFromStringFlag(flag) - - assert.NotNil(t, err) - }) - - t.Run("MissingKey_Error", func(t *testing.T) { - flag := "=testvalue" - - _, _, err := GetKeyValueFromStringFlag(flag) - - assert.NotNil(t, err) - }) - - t.Run("MultiValue_Error", func(t *testing.T) { - flag := "testkey=testvalue1=testvalue2" - - _, _, err := GetKeyValueFromStringFlag(flag) - - assert.NotNil(t, err) - }) -} - -func TestGetCreateTagRequestFromStringArrayFlag(t *testing.T) { - t.Run("None_NoError", func(t *testing.T) { - var tagFlags []string - - r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) - - assert.Nil(t, err) - assert.Len(t, r, 0) - }) - - t.Run("Single", func(t *testing.T) { - var tagFlags []string - tagFlags = append(tagFlags, "testkey1=testvalue1") - - r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) - - assert.Nil(t, err) - assert.Len(t, r, 1) - assert.Equal(t, "testkey1", r[0].Key) - assert.Equal(t, "testvalue1", r[0].Value) - }) - - t.Run("Multiple", func(t *testing.T) { - var tagFlags []string - tagFlags = append(tagFlags, "testkey1=testvalue1") - tagFlags = append(tagFlags, "testkey2=testvalue2") - - r, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) - - assert.Nil(t, err) - assert.Len(t, r, 2) - assert.Equal(t, "testkey1", r[0].Key) - assert.Equal(t, "testvalue1", r[0].Value) - assert.Equal(t, "testkey2", r[1].Key) - assert.Equal(t, "testvalue2", r[1].Value) - }) - - t.Run("Invalid_ReturnsError", func(t *testing.T) { - tagFlags := []string{"invalid"} - - _, err := GetCreateTagRequestFromStringArrayFlag(tagFlags) - - assert.NotNil(t, err) - assert.Equal(t, "Invalid format, expecting: key=value", err.Error()) - }) -} - -func TestGetCreateVirtualMachineRequestParameterFromStringArrayFlag(t *testing.T) { - t.Run("None_NoError", func(t *testing.T) { - var parameterFlags []string - - r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) - - assert.Nil(t, err) - assert.Len(t, r, 0) - }) - - t.Run("Single", func(t *testing.T) { - var parameterFlags []string - parameterFlags = append(parameterFlags, "testkey1=testvalue1") - - r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) - - assert.Nil(t, err) - assert.Len(t, r, 1) - assert.Equal(t, "testkey1", r[0].Key) - assert.Equal(t, "testvalue1", r[0].Value) - }) - - t.Run("Multiple", func(t *testing.T) { - var parameterFlags []string - parameterFlags = append(parameterFlags, "testkey1=testvalue1") - parameterFlags = append(parameterFlags, "testkey2=testvalue2") - - r, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) - - assert.Nil(t, err) - assert.Len(t, r, 2) - assert.Equal(t, "testkey1", r[0].Key) - assert.Equal(t, "testvalue1", r[0].Value) - assert.Equal(t, "testkey2", r[1].Key) - assert.Equal(t, "testvalue2", r[1].Value) - }) - - t.Run("Invalid_ReturnsError", func(t *testing.T) { - parameterFlags := []string{"invalid"} - - _, err := GetCreateVirtualMachineRequestParameterFromStringArrayFlag(parameterFlags) - - assert.NotNil(t, err) - assert.Equal(t, "Invalid format, expecting: key=value", err.Error()) - }) -} - -func TestOutputECloudVirtualMachines_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudVirtualMachines{ - VirtualMachines: []ecloud.VirtualMachine{ - ecloud.VirtualMachine{ - Name: "testvm1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.VirtualMachine{}, data) - assert.Equal(t, "testvm1", data.([]ecloud.VirtualMachine)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudVirtualMachines{ - VirtualMachines: []ecloud.VirtualMachine{ - ecloud.VirtualMachine{ - Name: "testvm1", - }, - ecloud.VirtualMachine{ - Name: "testvm2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.VirtualMachine{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testvm1", data.([]ecloud.VirtualMachine)[0].Name) - assert.Equal(t, "testvm2", data.([]ecloud.VirtualMachine)[1].Name) - }) -} - -func TestOutputECloudVirtualMachines_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudVirtualMachines{ - VirtualMachines: []ecloud.VirtualMachine{ - ecloud.VirtualMachine{ - Name: "testvm1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testvm1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudVirtualMachines{ - VirtualMachines: []ecloud.VirtualMachine{ - ecloud.VirtualMachine{ - Name: "testvm1", - }, - ecloud.VirtualMachine{ - Name: "testvm2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testvm1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testvm2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudVirtualMachineDisks_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudVirtualMachineDisks{ - VirtualMachineDisks: []ecloud.VirtualMachineDisk{ - ecloud.VirtualMachineDisk{ - Name: "testvmdisk1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.VirtualMachineDisk{}, data) - assert.Equal(t, "testvmdisk1", data.([]ecloud.VirtualMachineDisk)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudVirtualMachineDisks{ - VirtualMachineDisks: []ecloud.VirtualMachineDisk{ - ecloud.VirtualMachineDisk{ - Name: "testvmdisk1", - }, - ecloud.VirtualMachineDisk{ - Name: "testvmdisk2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.VirtualMachineDisk{}, data) - assert.Equal(t, "testvmdisk1", data.([]ecloud.VirtualMachineDisk)[0].Name) - assert.Equal(t, "testvmdisk2", data.([]ecloud.VirtualMachineDisk)[1].Name) - }) -} - -func TestOutputECloudVirtualMachineDisks_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudVirtualMachineDisks{ - VirtualMachineDisks: []ecloud.VirtualMachineDisk{ - ecloud.VirtualMachineDisk{ - Name: "testvmdisk1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testvmdisk1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudVirtualMachineDisks{ - VirtualMachineDisks: []ecloud.VirtualMachineDisk{ - ecloud.VirtualMachineDisk{ - Name: "testvmdisk1", - }, - ecloud.VirtualMachineDisk{ - Name: "testvmdisk2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testvmdisk1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testvmdisk2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudTags_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudTags{ - Tags: []ecloud.Tag{ - ecloud.Tag{ - Key: "testkey1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Tag{}, data) - assert.Equal(t, "testkey1", data.([]ecloud.Tag)[0].Key) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudTags{ - Tags: []ecloud.Tag{ - ecloud.Tag{ - Key: "testkey1", - }, - ecloud.Tag{ - Key: "testkey2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Tag{}, data) - assert.Equal(t, "testkey1", data.([]ecloud.Tag)[0].Key) - assert.Equal(t, "testkey2", data.([]ecloud.Tag)[1].Key) - }) -} - -func TestOutputECloudTags_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudTags{ - Tags: []ecloud.Tag{ - ecloud.Tag{ - Key: "testkey1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("key")) - assert.Equal(t, "testkey1", data[0].Get("key").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudTags{ - Tags: []ecloud.Tag{ - ecloud.Tag{ - Key: "testkey1", - }, - ecloud.Tag{ - Key: "testkey2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("key")) - assert.Equal(t, "testkey1", data[0].Get("key").Value) - assert.True(t, data[1].Exists("key")) - assert.Equal(t, "testkey2", data[1].Get("key").Value) - }) -} - -func TestOutputECloudSolutions_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudSolutions{ - Solutions: []ecloud.Solution{ - ecloud.Solution{ - Name: "testsolution1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Solution{}, data) - assert.Equal(t, "testsolution1", data.([]ecloud.Solution)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudSolutions{ - Solutions: []ecloud.Solution{ - ecloud.Solution{ - Name: "testsolution1", - }, - ecloud.Solution{ - Name: "testsolution2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Solution{}, data) - assert.Equal(t, "testsolution1", data.([]ecloud.Solution)[0].Name) - assert.Equal(t, "testsolution2", data.([]ecloud.Solution)[1].Name) - }) -} - -func TestOutputECloudSolutions_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudSolutions{ - Solutions: []ecloud.Solution{ - ecloud.Solution{ - Name: "testsolution1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testsolution1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudSolutions{ - Solutions: []ecloud.Solution{ - ecloud.Solution{ - Name: "testsolution1", - }, - ecloud.Solution{ - Name: "testsolution2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testsolution1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testsolution2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudSites_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudSites{ - Sites: []ecloud.Site{ - ecloud.Site{ - SolutionID: 123, - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Site{}, data) - assert.Equal(t, 123, data.([]ecloud.Site)[0].SolutionID) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudSites{ - Sites: []ecloud.Site{ - ecloud.Site{ - SolutionID: 123, - }, - ecloud.Site{ - SolutionID: 456, - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Site{}, data) - assert.Equal(t, 123, data.([]ecloud.Site)[0].SolutionID) - assert.Equal(t, 456, data.([]ecloud.Site)[1].SolutionID) - }) -} - -func TestOutputECloudSites_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudSites{ - Sites: []ecloud.Site{ - ecloud.Site{ - SolutionID: 123, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("solution_id")) - assert.Equal(t, "123", data[0].Get("solution_id").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudSites{ - Sites: []ecloud.Site{ - ecloud.Site{ - SolutionID: 123, - }, - ecloud.Site{ - SolutionID: 456, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("solution_id")) - assert.Equal(t, "123", data[0].Get("solution_id").Value) - assert.True(t, data[1].Exists("solution_id")) - assert.Equal(t, "456", data[1].Get("solution_id").Value) - }) -} - -func TestOutputECloudHosts_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudHosts{ - Hosts: []ecloud.Host{ - ecloud.Host{ - Name: "testhost1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Host{}, data) - assert.Equal(t, "testhost1", data.([]ecloud.Host)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudHosts{ - Hosts: []ecloud.Host{ - ecloud.Host{ - Name: "testhost1", - }, - ecloud.Host{ - Name: "testhost2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Host{}, data) - assert.Equal(t, "testhost1", data.([]ecloud.Host)[0].Name) - assert.Equal(t, "testhost2", data.([]ecloud.Host)[1].Name) - }) -} - -func TestOutputECloudHosts_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudHosts{ - Hosts: []ecloud.Host{ - ecloud.Host{ - Name: "testhost1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testhost1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudHosts{ - Hosts: []ecloud.Host{ - ecloud.Host{ - Name: "testhost1", - }, - ecloud.Host{ - Name: "testhost2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testhost1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testhost2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudDatastores_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudDatastores{ - Datastores: []ecloud.Datastore{ - ecloud.Datastore{ - Name: "testdatastore1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Datastore{}, data) - assert.Equal(t, "testdatastore1", data.([]ecloud.Datastore)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudDatastores{ - Datastores: []ecloud.Datastore{ - ecloud.Datastore{ - Name: "testdatastore1", - }, - ecloud.Datastore{ - Name: "testdatastore2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Datastore{}, data) - assert.Equal(t, "testdatastore1", data.([]ecloud.Datastore)[0].Name) - assert.Equal(t, "testdatastore2", data.([]ecloud.Datastore)[1].Name) - }) -} - -func TestOutputECloudDatastores_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudDatastores{ - Datastores: []ecloud.Datastore{ - ecloud.Datastore{ - Name: "testdatastore1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdatastore1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudDatastores{ - Datastores: []ecloud.Datastore{ - ecloud.Datastore{ - Name: "testdatastore1", - }, - ecloud.Datastore{ - Name: "testdatastore2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdatastore1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testdatastore2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudTemplates_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudTemplates{ - Templates: []ecloud.Template{ - ecloud.Template{ - Name: "testtemplate1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Template{}, data) - assert.Equal(t, "testtemplate1", data.([]ecloud.Template)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudTemplates{ - Templates: []ecloud.Template{ - ecloud.Template{ - Name: "testtemplate1", - }, - ecloud.Template{ - Name: "testtemplate2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Template{}, data) - assert.Equal(t, "testtemplate1", data.([]ecloud.Template)[0].Name) - assert.Equal(t, "testtemplate2", data.([]ecloud.Template)[1].Name) - }) -} - -func TestOutputECloudTemplates_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudTemplates{ - Templates: []ecloud.Template{ - ecloud.Template{ - Name: "testtemplate1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testtemplate1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudTemplates{ - Templates: []ecloud.Template{ - ecloud.Template{ - Name: "testtemplate1", - }, - ecloud.Template{ - Name: "testtemplate2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testtemplate1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testtemplate2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudNetworks_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudNetworks{ - Networks: []ecloud.Network{ - ecloud.Network{ - Name: "testnetwork1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Network{}, data) - assert.Equal(t, "testnetwork1", data.([]ecloud.Network)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudNetworks{ - Networks: []ecloud.Network{ - ecloud.Network{ - Name: "testnetwork1", - }, - ecloud.Network{ - Name: "testnetwork2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Network{}, data) - assert.Equal(t, "testnetwork1", data.([]ecloud.Network)[0].Name) - assert.Equal(t, "testnetwork2", data.([]ecloud.Network)[1].Name) - }) -} - -func TestOutputECloudNetworks_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudNetworks{ - Networks: []ecloud.Network{ - ecloud.Network{ - Name: "testnetwork1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testnetwork1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudNetworks{ - Networks: []ecloud.Network{ - ecloud.Network{ - Name: "testnetwork1", - }, - ecloud.Network{ - Name: "testnetwork2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testnetwork1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testnetwork2", data[1].Get("name").Value) - }) -} - -func TestOutputECloudFirewalls_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputECloudFirewalls{ - Firewalls: []ecloud.Firewall{ - ecloud.Firewall{ - Name: "testfirewall1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ecloud.Firewall{}, data) - assert.Equal(t, "testfirewall1", data.([]ecloud.Firewall)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputECloudFirewalls{ - Firewalls: []ecloud.Firewall{ - ecloud.Firewall{ - Name: "testfirewall1", - }, - ecloud.Firewall{ - Name: "testfirewall2", - }, - }, - } - - data := o.GetData() - - assert.Len(t, data, 2) - assert.IsType(t, []ecloud.Firewall{}, data) - assert.Equal(t, "testfirewall1", data.([]ecloud.Firewall)[0].Name) - assert.Equal(t, "testfirewall2", data.([]ecloud.Firewall)[1].Name) - }) -} - -func TestOutputECloudFirewalls_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudFirewalls{ - Firewalls: []ecloud.Firewall{ - ecloud.Firewall{ - Name: "testfirewall1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testfirewall1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputECloudFirewalls{ - Firewalls: []ecloud.Firewall{ - ecloud.Firewall{ - Name: "testfirewall1", - }, - ecloud.Firewall{ - Name: "testfirewall2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testfirewall1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testfirewall2", data[1].Get("name").Value) - }) -} diff --git a/cmd/loadtest.go b/cmd/loadtest.go deleted file mode 100644 index 43a7f74..0000000 --- a/cmd/loadtest.go +++ /dev/null @@ -1,152 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/google/uuid" - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/cli/internal/pkg/resource" - "github.com/ukfast/sdk-go/pkg/connection" - "github.com/ukfast/sdk-go/pkg/service/ltaas" -) - -func loadtestRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "loadtest", - Short: "Commands relating to load testing service", - } - - // Child root commands - cmd.AddCommand(loadtestDomainRootCmd()) - cmd.AddCommand(loadtestTestRootCmd()) - cmd.AddCommand(loadtestJobRootCmd()) - cmd.AddCommand(loadtestThresholdRootCmd()) - cmd.AddCommand(loadtestScenarioRootCmd()) - cmd.AddCommand(loadtestAgreementRootCmd()) - cmd.AddCommand(loadtestAccountRootCmd()) - - return cmd -} - -// Currently non-functional, as domains aren't yet filterable server-side -type LoadTestDomainLocatorProvider struct { - service ltaas.LTaaSService -} - -func NewLoadTestDomainLocatorProvider(service ltaas.LTaaSService) *LoadTestDomainLocatorProvider { - return &LoadTestDomainLocatorProvider{service: service} -} - -func (p *LoadTestDomainLocatorProvider) SupportedProperties() []string { - return []string{"name"} -} - -func (p *LoadTestDomainLocatorProvider) Locate(property string, value string) (interface{}, error) { - params := connection.APIRequestParameters{} - params.WithFilter(connection.APIRequestFiltering{Property: property, Operator: connection.EQOperator, Value: []string{value}}) - - return p.service.GetDomains(params) -} - -func getLoadTestDomainByNameOrID(service ltaas.LTaaSService, nameOrID string) (ltaas.Domain, error) { - _, err := uuid.Parse(nameOrID) - if err != nil { - locator := resource.NewResourceLocator(NewLoadTestDomainLocatorProvider(service)) - - domain, err := locator.Invoke(nameOrID) - if err != nil { - return ltaas.Domain{}, fmt.Errorf("Error locating domain [%s]: %s", nameOrID, err) - } - - return domain.(ltaas.Domain), nil - } - - domain, err := service.GetDomain(nameOrID) - if err != nil { - return ltaas.Domain{}, fmt.Errorf("Error retrieving domain by ID [%s]: %s", nameOrID, err) - } - - return domain, nil -} - -func outputLoadTestDomains(domains []ltaas.Domain) error { - err := Output(output.NewGenericOutputHandlerProvider(domains, []string{"id", "name"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output domains: %s", err) - } - - return nil -} - -func outputLoadTestTests(tests []ltaas.Test) error { - err := Output(output.NewGenericOutputHandlerProvider(tests, []string{"id", "name", "number_of_users", "duration", "protocol", "path"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output tests: %s", err) - } - - return nil -} - -func outputLoadTestJobs(jobs []ltaas.Job) error { - err := Output(output.NewGenericOutputHandlerProvider(jobs, []string{"id", "status", "job_start_timestamp", "job_end_timestamp"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output jobs: %s", err) - } - - return nil -} - -func outputLoadTestJobResults(results []ltaas.JobResults) error { - err := Output(output.NewGenericOutputHandlerProvider(results, []string{"id", "status", "job_start_timestamp", "job_end_timestamp"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output job results: %s", err) - } - - return nil -} - -func outputLoadTestJobSettings(settings []ltaas.JobSettings) error { - err := Output(output.NewGenericOutputHandlerProvider(settings, []string{"date", "name", "duration", "max_users", "domain"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output job settings: %s", err) - } - - return nil -} - -func outputLoadTestThresholds(thresholds []ltaas.Threshold) error { - err := Output(output.NewGenericOutputHandlerProvider(thresholds, []string{"id", "name", "description", "query"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output thresholds: %s", err) - } - - return nil -} - -func outputLoadTestScenarios(scenarios []ltaas.Scenario) error { - err := Output(output.NewGenericOutputHandlerProvider(scenarios, []string{"id", "name", "description"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output scenarios: %s", err) - } - - return nil -} - -func outputLoadTestAgreements(agreements []ltaas.Agreement) error { - err := Output(output.NewGenericOutputHandlerProvider(agreements, []string{"version"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output agreements: %s", err) - } - - return nil -} - -func outputLoadTestAccounts(accounts []ltaas.Account) error { - err := Output(output.NewGenericOutputHandlerProvider(accounts, []string{"id"}, nil)) - if err != nil { - return fmt.Errorf("Failed to output accounts: %s", err) - } - - return nil -} diff --git a/cmd/loadtest/loadtest.go b/cmd/loadtest/loadtest.go new file mode 100644 index 0000000..690d8bb --- /dev/null +++ b/cmd/loadtest/loadtest.go @@ -0,0 +1,71 @@ +package loadtest + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/resource" + "github.com/ukfast/sdk-go/pkg/connection" + "github.com/ukfast/sdk-go/pkg/service/ltaas" +) + +func LoadTestRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "loadtest", + Short: "Commands relating to load testing service", + } + + // Child root commands + cmd.AddCommand(loadtestDomainRootCmd(f)) + cmd.AddCommand(loadtestTestRootCmd(f)) + cmd.AddCommand(loadtestJobRootCmd(f)) + cmd.AddCommand(loadtestThresholdRootCmd(f)) + cmd.AddCommand(loadtestScenarioRootCmd(f)) + cmd.AddCommand(loadtestAgreementRootCmd(f)) + cmd.AddCommand(loadtestAccountRootCmd(f)) + + return cmd +} + +// Currently non-functional, as domains aren't yet filterable server-side +type LoadTestDomainLocatorProvider struct { + service ltaas.LTaaSService +} + +func NewLoadTestDomainLocatorProvider(service ltaas.LTaaSService) *LoadTestDomainLocatorProvider { + return &LoadTestDomainLocatorProvider{service: service} +} + +func (p *LoadTestDomainLocatorProvider) SupportedProperties() []string { + return []string{"name"} +} + +func (p *LoadTestDomainLocatorProvider) Locate(property string, value string) (interface{}, error) { + params := connection.APIRequestParameters{} + params.WithFilter(connection.APIRequestFiltering{Property: property, Operator: connection.EQOperator, Value: []string{value}}) + + return p.service.GetDomains(params) +} + +func getLoadTestDomainByNameOrID(service ltaas.LTaaSService, nameOrID string) (ltaas.Domain, error) { + _, err := uuid.Parse(nameOrID) + if err != nil { + locator := resource.NewResourceLocator(NewLoadTestDomainLocatorProvider(service)) + + domain, err := locator.Invoke(nameOrID) + if err != nil { + return ltaas.Domain{}, fmt.Errorf("Error locating domain [%s]: %s", nameOrID, err) + } + + return domain.(ltaas.Domain), nil + } + + domain, err := service.GetDomain(nameOrID) + if err != nil { + return ltaas.Domain{}, fmt.Errorf("Error retrieving domain by ID [%s]: %s", nameOrID, err) + } + + return domain, nil +} diff --git a/cmd/loadtest_account.go b/cmd/loadtest/loadtest_account.go similarity index 69% rename from cmd/loadtest_account.go rename to cmd/loadtest/loadtest_account.go index 77e40ca..c917ed6 100644 --- a/cmd/loadtest_account.go +++ b/cmd/loadtest/loadtest_account.go @@ -1,33 +1,34 @@ -package cmd +package loadtest import ( "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestAccountRootCmd() *cobra.Command { +func loadtestAccountRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "account", Short: "sub-commands relating to accounts", } // Child commands - cmd.AddCommand(loadtestAccountCreateCmd()) + cmd.AddCommand(loadtestAccountCreateCmd(f)) return cmd } -func loadtestAccountCreateCmd() *cobra.Command { +func loadtestAccountCreateCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "create", Short: "Creates a account", Long: "This command creates a account ", Example: "ukfast loadtest account create", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestAccountCreate(getClient().LTaaSService(), cmd, args) + return loadtestAccountCreate(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -37,9 +38,7 @@ func loadtestAccountCreate(service ltaas.LTaaSService, cmd *cobra.Command, args if err != nil { return fmt.Errorf("Error creating account: %s", err) } - // return nil - // TODO: Retrieve account once account retrieval is possible - // return outputLoadTestAccounts([]ltaas.Account{ltaas.Account{ID: accountID}}) + var tests []ltaas.Test for _, arg := range args { test, err := service.GetTest(arg) @@ -51,5 +50,5 @@ func loadtestAccountCreate(service ltaas.LTaaSService, cmd *cobra.Command, args tests = append(tests, test) } - return outputLoadTestTests(tests) + return output.CommandOutput(cmd, OutputLoadTestTestsProvider(tests)) } diff --git a/cmd/loadtest_account_test.go b/cmd/loadtest/loadtest_account_test.go similarity index 83% rename from cmd/loadtest_account_test.go rename to cmd/loadtest/loadtest_account_test.go index 0532050..b643f54 100644 --- a/cmd/loadtest_account_test.go +++ b/cmd/loadtest/loadtest_account_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -15,19 +15,19 @@ func Test_loadtestAccountCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockLTaaSService(mockCtrl) - cmd := loadtestAccountCreateCmd() + cmd := loadtestAccountCreateCmd(nil) service.EXPECT().CreateAccount().Return("00000000-0000-0000-0000-000000000001", nil) loadtestAccountCreate(service, cmd, []string{}) }) - t.Run("CreateAccountError_OutputsFatal", func(t *testing.T) { + t.Run("CreateAccountError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockLTaaSService(mockCtrl) - cmd := loadtestAccountCreateCmd() + cmd := loadtestAccountCreateCmd(nil) service.EXPECT().CreateAccount().Return("", errors.New("test error")).Times(1) diff --git a/cmd/loadtest_agreement.go b/cmd/loadtest/loadtest_agreement.go similarity index 74% rename from cmd/loadtest_agreement.go rename to cmd/loadtest/loadtest_agreement.go index 6048d30..2415f8d 100644 --- a/cmd/loadtest_agreement.go +++ b/cmd/loadtest/loadtest_agreement.go @@ -1,26 +1,27 @@ -package cmd +package loadtest import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestAgreementRootCmd() *cobra.Command { +func loadtestAgreementRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "agreement", Short: "sub-commands relating to agreements", } // Child commands - cmd.AddCommand(loadtestAgreementShowCmd()) + cmd.AddCommand(loadtestAgreementShowCmd(f)) return cmd } -func loadtestAgreementShowCmd() *cobra.Command { +func loadtestAgreementShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a agreement", @@ -34,7 +35,7 @@ func loadtestAgreementShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestAgreementShow(getClient().LTaaSService(), cmd, args) + return loadtestAgreementShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -56,5 +57,5 @@ func loadtestAgreementShow(service ltaas.LTaaSService, cmd *cobra.Command, args agreements = append(agreements, agreement) } - return outputLoadTestAgreements(agreements) + return output.CommandOutput(cmd, OutputLoadTestAgreementsProvider(agreements)) } diff --git a/cmd/loadtest_agreement_test.go b/cmd/loadtest/loadtest_agreement_test.go similarity index 93% rename from cmd/loadtest_agreement_test.go rename to cmd/loadtest/loadtest_agreement_test.go index 3eeeab0..3fc0cd2 100644 --- a/cmd/loadtest_agreement_test.go +++ b/cmd/loadtest/loadtest_agreement_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -15,13 +15,13 @@ import ( func Test_loadtestAgreementShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestAgreementShowCmd().Args(nil, []string{"123"}) + err := loadtestAgreementShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestAgreementShowCmd().Args(nil, []string{}) + err := loadtestAgreementShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing agreement type", err.Error()) diff --git a/cmd/loadtest_domain.go b/cmd/loadtest/loadtest_domain.go similarity index 76% rename from cmd/loadtest_domain.go rename to cmd/loadtest/loadtest_domain.go index fc5438f..65e518a 100644 --- a/cmd/loadtest_domain.go +++ b/cmd/loadtest/loadtest_domain.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -6,37 +6,38 @@ import ( "github.com/spf13/cobra" "github.com/ukfast/cli/internal/pkg/clierrors" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestDomainRootCmd() *cobra.Command { +func loadtestDomainRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "domain", Short: "sub-commands relating to domains", } // Child commands - cmd.AddCommand(loadtestDomainListCmd()) - cmd.AddCommand(loadtestDomainShowCmd()) - cmd.AddCommand(loadtestDomainCreateCmd()) - cmd.AddCommand(loadtestDomainDeleteCmd()) + cmd.AddCommand(loadtestDomainListCmd(f)) + cmd.AddCommand(loadtestDomainShowCmd(f)) + cmd.AddCommand(loadtestDomainCreateCmd(f)) + cmd.AddCommand(loadtestDomainDeleteCmd(f)) // Child root commands - cmd.AddCommand(loadtestDomainVerificationRootCmd()) + cmd.AddCommand(loadtestDomainVerificationRootCmd(f)) return cmd } -func loadtestDomainListCmd() *cobra.Command { +func loadtestDomainListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists domains", Long: "This command lists domains", Example: "ukfast loadtest domain list", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestDomainList(getClient().LTaaSService(), cmd, args) + return loadtestDomainList(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -52,10 +53,10 @@ func loadtestDomainList(service ltaas.LTaaSService, cmd *cobra.Command, args []s return fmt.Errorf("Error retrieving domains: %s", err) } - return outputLoadTestDomains(domains) + return output.CommandOutput(cmd, OutputLoadTestDomainsProvider(domains)) } -func loadtestDomainShowCmd() *cobra.Command { +func loadtestDomainShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a domain", @@ -69,7 +70,7 @@ func loadtestDomainShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestDomainShow(getClient().LTaaSService(), cmd, args) + return loadtestDomainShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -86,17 +87,17 @@ func loadtestDomainShow(service ltaas.LTaaSService, cmd *cobra.Command, args []s domains = append(domains, domain) } - return outputLoadTestDomains(domains) + return output.CommandOutput(cmd, OutputLoadTestDomainsProvider(domains)) } -func loadtestDomainCreateCmd() *cobra.Command { +func loadtestDomainCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a domain", Long: "This command creates a domain ", Example: "ukfast loadtest domain create", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestDomainCreate(getClient().LTaaSService(), cmd, args) + return loadtestDomainCreate(f.NewClient().LTaaSService(), cmd, args) }, } @@ -131,10 +132,10 @@ func loadtestDomainCreate(service ltaas.LTaaSService, cmd *cobra.Command, args [ return fmt.Errorf("Error retrieving new domain: %s", err) } - return outputLoadTestDomains([]ltaas.Domain{domain}) + return output.CommandOutput(cmd, OutputLoadTestDomainsProvider([]ltaas.Domain{domain})) } -func loadtestDomainDeleteCmd() *cobra.Command { +func loadtestDomainDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a domain", @@ -148,7 +149,7 @@ func loadtestDomainDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - loadtestDomainDelete(getClient().LTaaSService(), cmd, args) + loadtestDomainDelete(f.NewClient().LTaaSService(), cmd, args) }, } } diff --git a/cmd/loadtest_domain_test.go b/cmd/loadtest/loadtest_domain_test.go similarity index 89% rename from cmd/loadtest_domain_test.go rename to cmd/loadtest/loadtest_domain_test.go index 6b69ff3..f816ffa 100644 --- a/cmd/loadtest_domain_test.go +++ b/cmd/loadtest/loadtest_domain_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ltaas" @@ -24,7 +25,7 @@ func Test_loadtestDomainList(t *testing.T) { loadtestDomainList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -35,10 +36,10 @@ func Test_loadtestDomainList(t *testing.T) { err := loadtestDomainList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -56,13 +57,13 @@ func Test_loadtestDomainList(t *testing.T) { func Test_loadtestDomainShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestDomainShowCmd().Args(nil, []string{"123"}) + err := loadtestDomainShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestDomainShowCmd().Args(nil, []string{}) + err := loadtestDomainShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/loadtest/loadtest_domain_verification.go b/cmd/loadtest/loadtest_domain_verification.go new file mode 100644 index 0000000..96278d0 --- /dev/null +++ b/cmd/loadtest/loadtest_domain_verification.go @@ -0,0 +1,19 @@ +package loadtest + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func loadtestDomainVerificationRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "verification", + Short: "sub-commands relating to domain verification", + } + + // Child root commands + cmd.AddCommand(loadtestDomainVerificationFileRootCmd(f)) + cmd.AddCommand(loadtestDomainVerificationDNSRootCmd(f)) + + return cmd +} diff --git a/cmd/loadtest_domain_verification_dns.go b/cmd/loadtest/loadtest_domain_verification_dns.go similarity index 74% rename from cmd/loadtest_domain_verification_dns.go rename to cmd/loadtest/loadtest_domain_verification_dns.go index 9c87458..64d091c 100644 --- a/cmd/loadtest_domain_verification_dns.go +++ b/cmd/loadtest/loadtest_domain_verification_dns.go @@ -1,26 +1,27 @@ -package cmd +package loadtest import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestDomainVerificationDNSRootCmd() *cobra.Command { +func loadtestDomainVerificationDNSRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "dns", Short: "sub-commands relating to DNS domain verification", } // Child commands - cmd.AddCommand(loadtestDomainVerificationDNSVerifyCmd()) + cmd.AddCommand(loadtestDomainVerificationDNSVerifyCmd(f)) return cmd } -func loadtestDomainVerificationDNSVerifyCmd() *cobra.Command { +func loadtestDomainVerificationDNSVerifyCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "verify ...", Short: "Verifies a domain via DNS verification method", @@ -34,7 +35,7 @@ func loadtestDomainVerificationDNSVerifyCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestDomainVerificationDNSVerify(getClient().LTaaSService(), cmd, args) + return loadtestDomainVerificationDNSVerify(f.NewClient().LTaaSService(), cmd, args) }, } } diff --git a/cmd/loadtest_domain_verification_dns_test.go b/cmd/loadtest/loadtest_domain_verification_dns_test.go similarity index 88% rename from cmd/loadtest_domain_verification_dns_test.go rename to cmd/loadtest/loadtest_domain_verification_dns_test.go index 5b2c12b..eee44f7 100644 --- a/cmd/loadtest_domain_verification_dns_test.go +++ b/cmd/loadtest/loadtest_domain_verification_dns_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -13,13 +13,13 @@ import ( func Test_loadtestDomainVerificationDNSVerifyCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestDomainVerificationDNSVerifyCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := loadtestDomainVerificationDNSVerifyCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestDomainVerificationDNSVerifyCmd().Args(nil, []string{}) + err := loadtestDomainVerificationDNSVerifyCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/loadtest_domain_verification_file.go b/cmd/loadtest/loadtest_domain_verification_file.go similarity index 74% rename from cmd/loadtest_domain_verification_file.go rename to cmd/loadtest/loadtest_domain_verification_file.go index f9ceb80..0df6ac9 100644 --- a/cmd/loadtest_domain_verification_file.go +++ b/cmd/loadtest/loadtest_domain_verification_file.go @@ -1,26 +1,27 @@ -package cmd +package loadtest import ( "errors" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestDomainVerificationFileRootCmd() *cobra.Command { +func loadtestDomainVerificationFileRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "file", Short: "sub-commands relating to File domain verification", } // Child commands - cmd.AddCommand(loadtestDomainVerificationFileVerifyCmd()) + cmd.AddCommand(loadtestDomainVerificationFileVerifyCmd(f)) return cmd } -func loadtestDomainVerificationFileVerifyCmd() *cobra.Command { +func loadtestDomainVerificationFileVerifyCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "verify ...", Short: "Verifies a domain via File verification method", @@ -34,7 +35,7 @@ func loadtestDomainVerificationFileVerifyCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestDomainVerificationFileVerify(getClient().LTaaSService(), cmd, args) + return loadtestDomainVerificationFileVerify(f.NewClient().LTaaSService(), cmd, args) }, } } diff --git a/cmd/loadtest_domain_verification_file_test.go b/cmd/loadtest/loadtest_domain_verification_file_test.go similarity index 88% rename from cmd/loadtest_domain_verification_file_test.go rename to cmd/loadtest/loadtest_domain_verification_file_test.go index 19e40b2..5cb91bd 100644 --- a/cmd/loadtest_domain_verification_file_test.go +++ b/cmd/loadtest/loadtest_domain_verification_file_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -13,13 +13,13 @@ import ( func Test_loadtestDomainVerificationFileVerifyCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestDomainVerificationFileVerifyCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := loadtestDomainVerificationFileVerifyCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestDomainVerificationFileVerifyCmd().Args(nil, []string{}) + err := loadtestDomainVerificationFileVerifyCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/loadtest_job.go b/cmd/loadtest/loadtest_job.go similarity index 75% rename from cmd/loadtest_job.go rename to cmd/loadtest/loadtest_job.go index e7e53cd..af707af 100644 --- a/cmd/loadtest_job.go +++ b/cmd/loadtest/loadtest_job.go @@ -1,44 +1,45 @@ -package cmd +package loadtest import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/connection" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestJobRootCmd() *cobra.Command { +func loadtestJobRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "job", Short: "sub-commands relating to jobs", } // Child commands - cmd.AddCommand(loadtestJobListCmd()) - cmd.AddCommand(loadtestJobShowCmd()) - cmd.AddCommand(loadtestJobCreateCmd()) - cmd.AddCommand(loadtestJobDeleteCmd()) - cmd.AddCommand(loadtestJobStopCmd()) + cmd.AddCommand(loadtestJobListCmd(f)) + cmd.AddCommand(loadtestJobShowCmd(f)) + cmd.AddCommand(loadtestJobCreateCmd(f)) + cmd.AddCommand(loadtestJobDeleteCmd(f)) + cmd.AddCommand(loadtestJobStopCmd(f)) // Child root commands - cmd.AddCommand(loadtestJobResultsRootCmd()) - cmd.AddCommand(loadtestJobSettingsRootCmd()) + cmd.AddCommand(loadtestJobResultsRootCmd(f)) + cmd.AddCommand(loadtestJobSettingsRootCmd(f)) return cmd } -func loadtestJobListCmd() *cobra.Command { +func loadtestJobListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists jobs", Long: "This command lists jobs", Example: "ukfast loadtest job list", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobList(getClient().LTaaSService(), cmd, args) + return loadtestJobList(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -54,10 +55,10 @@ func loadtestJobList(service ltaas.LTaaSService, cmd *cobra.Command, args []stri return fmt.Errorf("Error retrieving jobs: %s", err) } - return outputLoadTestJobs(jobs) + return output.CommandOutput(cmd, OutputLoadTestJobsProvider(jobs)) } -func loadtestJobShowCmd() *cobra.Command { +func loadtestJobShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a job", @@ -71,7 +72,7 @@ func loadtestJobShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobShow(getClient().LTaaSService(), cmd, args) + return loadtestJobShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -88,17 +89,17 @@ func loadtestJobShow(service ltaas.LTaaSService, cmd *cobra.Command, args []stri jobs = append(jobs, job) } - return outputLoadTestJobs(jobs) + return output.CommandOutput(cmd, OutputLoadTestJobsProvider(jobs)) } -func loadtestJobCreateCmd() *cobra.Command { +func loadtestJobCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a job", Long: "This command creates a job ", Example: "ukfast loadtest job create", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobCreate(getClient().LTaaSService(), cmd, args) + return loadtestJobCreate(f.NewClient().LTaaSService(), cmd, args) }, } @@ -130,10 +131,10 @@ func loadtestJobCreate(service ltaas.LTaaSService, cmd *cobra.Command, args []st return fmt.Errorf("Error retrieving new job [%s]: %s", jobID, err) } - return outputLoadTestJobs([]ltaas.Job{job}) + return output.CommandOutput(cmd, OutputLoadTestJobsProvider([]ltaas.Job{job})) } -func loadtestJobDeleteCmd() *cobra.Command { +func loadtestJobDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a job", @@ -147,7 +148,7 @@ func loadtestJobDeleteCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobDelete(getClient().LTaaSService(), cmd, args) + return loadtestJobDelete(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -164,10 +165,10 @@ func loadtestJobDelete(service ltaas.LTaaSService, cmd *cobra.Command, args []st jobs = append(jobs, job) } - return outputLoadTestJobs(jobs) + return output.CommandOutput(cmd, OutputLoadTestJobsProvider(jobs)) } -func loadtestJobStopCmd() *cobra.Command { +func loadtestJobStopCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "stop ...", Short: "Stops a running job", @@ -181,7 +182,7 @@ func loadtestJobStopCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - loadtestJobStop(getClient().LTaaSService(), cmd, args) + loadtestJobStop(f.NewClient().LTaaSService(), cmd, args) }, } } diff --git a/cmd/loadtest_job_results.go b/cmd/loadtest/loadtest_job_results.go similarity index 88% rename from cmd/loadtest_job_results.go rename to cmd/loadtest/loadtest_job_results.go index 0202f97..6bbecf4 100644 --- a/cmd/loadtest_job_results.go +++ b/cmd/loadtest/loadtest_job_results.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,22 +7,24 @@ import ( "github.com/guptarohit/asciigraph" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestJobResultsRootCmd() *cobra.Command { +func loadtestJobResultsRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "results", Short: "sub-commands relating to job results", } // Child commands - cmd.AddCommand(loadtestJobResultsShowCmd()) + cmd.AddCommand(loadtestJobResultsShowCmd(f)) return cmd } -func loadtestJobResultsShowCmd() *cobra.Command { +func loadtestJobResultsShowCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "show", Short: "Shows job results", @@ -36,7 +38,7 @@ func loadtestJobResultsShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobResultsShow(getClient().LTaaSService(), cmd, args) + return loadtestJobResultsShow(f.NewClient().LTaaSService(), cmd, args) }, } @@ -91,7 +93,7 @@ func loadtestJobResultsShow(service ltaas.LTaaSService, cmd *cobra.Command, args allResults = append(allResults, results) } - return outputLoadTestJobResults(allResults) + return output.CommandOutput(cmd, OutputLoadTestJobResultsProvider(allResults)) } // generateGraph returns an ASCII graph for given parameters diff --git a/cmd/loadtest_job_settings.go b/cmd/loadtest/loadtest_job_settings.go similarity index 67% rename from cmd/loadtest_job_settings.go rename to cmd/loadtest/loadtest_job_settings.go index 68b33ad..585a6e5 100644 --- a/cmd/loadtest_job_settings.go +++ b/cmd/loadtest/loadtest_job_settings.go @@ -1,26 +1,28 @@ -package cmd +package loadtest import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestJobSettingsRootCmd() *cobra.Command { +func loadtestJobSettingsRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "settings", Short: "sub-commands relating to job settings", } // Child commands - cmd.AddCommand(loadtestJobSettingsShowCmd()) + cmd.AddCommand(loadtestJobSettingsShowCmd(f)) return cmd } -func loadtestJobSettingsShowCmd() *cobra.Command { +func loadtestJobSettingsShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show", Short: "Shows job settings", @@ -34,7 +36,7 @@ func loadtestJobSettingsShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestJobSettingsShow(getClient().LTaaSService(), cmd, args) + return loadtestJobSettingsShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -50,5 +52,5 @@ func loadtestJobSettingsShow(service ltaas.LTaaSService, cmd *cobra.Command, arg allSettings = append(allSettings, settings) } - return outputLoadTestJobSettings(allSettings) + return output.CommandOutput(cmd, OutputLoadTestJobSettingsProvider(allSettings)) } diff --git a/cmd/loadtest_job_settings_test.go b/cmd/loadtest/loadtest_job_settings_test.go similarity index 90% rename from cmd/loadtest_job_settings_test.go rename to cmd/loadtest/loadtest_job_settings_test.go index 46bb318..164d6c3 100644 --- a/cmd/loadtest_job_settings_test.go +++ b/cmd/loadtest/loadtest_job_settings_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -13,13 +13,13 @@ import ( func Test_loadtestJobSettingsShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestJobSettingsShowCmd().Args(nil, []string{"123"}) + err := loadtestJobSettingsShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestJobSettingsShowCmd().Args(nil, []string{}) + err := loadtestJobSettingsShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing job", err.Error()) @@ -52,7 +52,7 @@ func Test_loadtestJobSettingsShow(t *testing.T) { loadtestJobSettingsShow(service, &cobra.Command{}, []string{"00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000001"}) }) - t.Run("GetJobError_OutputsError", func(t *testing.T) { + t.Run("GetJobError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() diff --git a/cmd/loadtest_job_test.go b/cmd/loadtest/loadtest_job_test.go similarity index 90% rename from cmd/loadtest_job_test.go rename to cmd/loadtest/loadtest_job_test.go index 92d1b06..99e0751 100644 --- a/cmd/loadtest_job_test.go +++ b/cmd/loadtest/loadtest_job_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ltaas" @@ -24,7 +25,7 @@ func Test_loadtestJobList(t *testing.T) { loadtestJobList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -35,10 +36,10 @@ func Test_loadtestJobList(t *testing.T) { err := loadtestJobList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetJobsError_OutputsFatal", func(t *testing.T) { + t.Run("GetJobsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -56,13 +57,13 @@ func Test_loadtestJobList(t *testing.T) { func Test_loadtestJobShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestJobShowCmd().Args(nil, []string{"123"}) + err := loadtestJobShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestJobShowCmd().Args(nil, []string{}) + err := loadtestJobShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing job", err.Error()) @@ -115,7 +116,7 @@ func Test_loadtestJobCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockLTaaSService(mockCtrl) - cmd := loadtestJobCreateCmd() + cmd := loadtestJobCreateCmd(nil) cmd.Flags().Set("test-id", "00000000-0000-0000-0000-000000000000") expectedRequest := ltaas.CreateJobRequest{ @@ -130,12 +131,12 @@ func Test_loadtestJobCreate(t *testing.T) { loadtestJobCreate(service, cmd, []string{}) }) - t.Run("CreateJobError_OutputsFatal", func(t *testing.T) { + t.Run("CreateJobError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockLTaaSService(mockCtrl) - cmd := loadtestJobCreateCmd() + cmd := loadtestJobCreateCmd(nil) service.EXPECT().CreateJob(gomock.Any()).Return("", errors.New("test error")).Times(1) @@ -143,12 +144,12 @@ func Test_loadtestJobCreate(t *testing.T) { assert.Equal(t, "Error creating job: test error", err.Error()) }) - t.Run("GetJobError_OutputsFatal", func(t *testing.T) { + t.Run("GetJobError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockLTaaSService(mockCtrl) - cmd := loadtestJobCreateCmd() + cmd := loadtestJobCreateCmd(nil) gomock.InOrder( service.EXPECT().CreateJob(gomock.Any()).Return("00000000-0000-0000-0000-000000000000", nil), @@ -162,13 +163,13 @@ func Test_loadtestJobCreate(t *testing.T) { func Test_loadtestJobDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestJobDeleteCmd().Args(nil, []string{"123"}) + err := loadtestJobDeleteCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestJobDeleteCmd().Args(nil, []string{}) + err := loadtestJobDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing job", err.Error()) @@ -217,13 +218,13 @@ func Test_loadtestJobDelete(t *testing.T) { func Test_loadtestJobStopCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestJobStopCmd().Args(nil, []string{"123"}) + err := loadtestJobStopCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestJobStopCmd().Args(nil, []string{}) + err := loadtestJobStopCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing job", err.Error()) diff --git a/cmd/loadtest_scenario.go b/cmd/loadtest/loadtest_scenario.go similarity index 64% rename from cmd/loadtest_scenario.go rename to cmd/loadtest/loadtest_scenario.go index a5d384e..60d06b2 100644 --- a/cmd/loadtest_scenario.go +++ b/cmd/loadtest/loadtest_scenario.go @@ -1,33 +1,35 @@ -package cmd +package loadtest import ( "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestScenarioRootCmd() *cobra.Command { +func loadtestScenarioRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "scenario", Short: "sub-commands relating to scenarios", } // Child commands - cmd.AddCommand(loadtestScenarioListCmd()) + cmd.AddCommand(loadtestScenarioListCmd(f)) return cmd } -func loadtestScenarioListCmd() *cobra.Command { +func loadtestScenarioListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists scenarios", Long: "This command lists scenarios", Example: "ukfast loadtest scenario list", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestScenarioList(getClient().LTaaSService(), cmd, args) + return loadtestScenarioList(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -43,5 +45,5 @@ func loadtestScenarioList(service ltaas.LTaaSService, cmd *cobra.Command, args [ return fmt.Errorf("Error retrieving scenarios: %s", err) } - return outputLoadTestScenarios(scenarios) + return output.CommandOutput(cmd, OutputLoadTestScenariosProvider(scenarios)) } diff --git a/cmd/loadtest_scenario_test.go b/cmd/loadtest/loadtest_scenario_test.go similarity index 84% rename from cmd/loadtest_scenario_test.go rename to cmd/loadtest/loadtest_scenario_test.go index c541439..80914a7 100644 --- a/cmd/loadtest_scenario_test.go +++ b/cmd/loadtest/loadtest_scenario_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) @@ -23,7 +24,7 @@ func Test_loadtestScenarioList(t *testing.T) { loadtestScenarioList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -34,10 +35,10 @@ func Test_loadtestScenarioList(t *testing.T) { err := loadtestScenarioList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetScenariosError_OutputsFatal", func(t *testing.T) { + t.Run("GetScenariosError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() diff --git a/cmd/loadtest_test_impl.go b/cmd/loadtest/loadtest_test_impl.go similarity index 83% rename from cmd/loadtest_test_impl.go rename to cmd/loadtest/loadtest_test_impl.go index 073077e..81593ba 100644 --- a/cmd/loadtest_test_impl.go +++ b/cmd/loadtest/loadtest_test_impl.go @@ -1,38 +1,39 @@ -package cmd +package loadtest import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestTestRootCmd() *cobra.Command { +func loadtestTestRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "test", Short: "sub-commands relating to tests", } // Child commands - cmd.AddCommand(loadtestTestListCmd()) - cmd.AddCommand(loadtestTestShowCmd()) - cmd.AddCommand(loadtestTestCreateCmd()) - cmd.AddCommand(loadtestTestDeleteCmd()) + cmd.AddCommand(loadtestTestListCmd(f)) + cmd.AddCommand(loadtestTestShowCmd(f)) + cmd.AddCommand(loadtestTestCreateCmd(f)) + cmd.AddCommand(loadtestTestDeleteCmd(f)) return cmd } -func loadtestTestListCmd() *cobra.Command { +func loadtestTestListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists tests", Long: "This command lists tests", Example: "ukfast loadtest test list", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestTestList(getClient().LTaaSService(), cmd, args) + return loadtestTestList(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -48,10 +49,10 @@ func loadtestTestList(service ltaas.LTaaSService, cmd *cobra.Command, args []str return fmt.Errorf("Error retrieving tests: %s", err) } - return outputLoadTestTests(tests) + return output.CommandOutput(cmd, OutputLoadTestTestsProvider(tests)) } -func loadtestTestShowCmd() *cobra.Command { +func loadtestTestShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a test", @@ -65,7 +66,7 @@ func loadtestTestShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestTestShow(getClient().LTaaSService(), cmd, args) + return loadtestTestShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -82,17 +83,17 @@ func loadtestTestShow(service ltaas.LTaaSService, cmd *cobra.Command, args []str tests = append(tests, test) } - return outputLoadTestTests(tests) + return output.CommandOutput(cmd, OutputLoadTestTestsProvider(tests)) } -func loadtestTestCreateCmd() *cobra.Command { +func loadtestTestCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a test", Long: "This command creates a test ", Example: "ukfast loadtest test create", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestTestCreate(getClient().LTaaSService(), cmd, args) + return loadtestTestCreate(f.NewClient().LTaaSService(), cmd, args) }, } @@ -162,10 +163,10 @@ func loadtestTestCreate(service ltaas.LTaaSService, cmd *cobra.Command, args []s return fmt.Errorf("Error retrieving new test [%s]: %s", testID, err) } - return outputLoadTestTests([]ltaas.Test{test}) + return output.CommandOutput(cmd, OutputLoadTestTestsProvider([]ltaas.Test{test})) } -func loadtestTestDeleteCmd() *cobra.Command { +func loadtestTestDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a test", @@ -179,7 +180,7 @@ func loadtestTestDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - loadtestTestDelete(getClient().LTaaSService(), cmd, args) + loadtestTestDelete(f.NewClient().LTaaSService(), cmd, args) }, } } diff --git a/cmd/loadtest_test_impl_test.go b/cmd/loadtest/loadtest_test_impl_test.go similarity index 90% rename from cmd/loadtest_test_impl_test.go rename to cmd/loadtest/loadtest_test_impl_test.go index f9bdb99..03fae3e 100644 --- a/cmd/loadtest_test_impl_test.go +++ b/cmd/loadtest/loadtest_test_impl_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ltaas" @@ -24,7 +25,7 @@ func Test_loadtestTestList(t *testing.T) { loadtestTestList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -35,10 +36,10 @@ func Test_loadtestTestList(t *testing.T) { err := loadtestTestList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetTestsError_OutputsFatal", func(t *testing.T) { + t.Run("GetTestsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -56,13 +57,13 @@ func Test_loadtestTestList(t *testing.T) { func Test_loadtestTestShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestTestShowCmd().Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) + err := loadtestTestShowCmd(nil).Args(nil, []string{"00000000-0000-0000-0000-000000000000"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestTestShowCmd().Args(nil, []string{}) + err := loadtestTestShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing test", err.Error()) @@ -111,13 +112,13 @@ func Test_loadtestTestShow(t *testing.T) { func Test_loadtestTestDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestTestDeleteCmd().Args(nil, []string{"123"}) + err := loadtestTestDeleteCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestTestDeleteCmd().Args(nil, []string{}) + err := loadtestTestDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing test", err.Error()) diff --git a/cmd/loadtest_threshold.go b/cmd/loadtest/loadtest_threshold.go similarity index 71% rename from cmd/loadtest_threshold.go rename to cmd/loadtest/loadtest_threshold.go index 4371acd..e004787 100644 --- a/cmd/loadtest_threshold.go +++ b/cmd/loadtest/loadtest_threshold.go @@ -1,36 +1,37 @@ -package cmd +package loadtest import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ltaas" ) -func loadtestThresholdRootCmd() *cobra.Command { +func loadtestThresholdRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "threshold", Short: "sub-commands relating to thresholds", } // Child commands - cmd.AddCommand(loadtestThresholdListCmd()) - cmd.AddCommand(loadtestThresholdShowCmd()) + cmd.AddCommand(loadtestThresholdListCmd(f)) + cmd.AddCommand(loadtestThresholdShowCmd(f)) return cmd } -func loadtestThresholdListCmd() *cobra.Command { +func loadtestThresholdListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists thresholds", Long: "This command lists thresholds", Example: "ukfast loadtest threshold list", RunE: func(cmd *cobra.Command, args []string) error { - return loadtestThresholdList(getClient().LTaaSService(), cmd, args) + return loadtestThresholdList(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -46,10 +47,10 @@ func loadtestThresholdList(service ltaas.LTaaSService, cmd *cobra.Command, args return fmt.Errorf("Error retrieving thresholds: %s", err) } - return outputLoadTestThresholds(thresholds) + return output.CommandOutput(cmd, OutputLoadTestThresholdsProvider(thresholds)) } -func loadtestThresholdShowCmd() *cobra.Command { +func loadtestThresholdShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a threshold", @@ -63,7 +64,7 @@ func loadtestThresholdShowCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return loadtestThresholdShow(getClient().LTaaSService(), cmd, args) + return loadtestThresholdShow(f.NewClient().LTaaSService(), cmd, args) }, } } @@ -80,5 +81,5 @@ func loadtestThresholdShow(service ltaas.LTaaSService, cmd *cobra.Command, args thresholds = append(thresholds, threshold) } - return outputLoadTestThresholds(thresholds) + return output.CommandOutput(cmd, OutputLoadTestThresholdsProvider(thresholds)) } diff --git a/cmd/loadtest_threshold_test.go b/cmd/loadtest/loadtest_threshold_test.go similarity index 89% rename from cmd/loadtest_threshold_test.go rename to cmd/loadtest/loadtest_threshold_test.go index e557d75..b5ff844 100644 --- a/cmd/loadtest_threshold_test.go +++ b/cmd/loadtest/loadtest_threshold_test.go @@ -1,4 +1,4 @@ -package cmd +package loadtest import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ltaas" @@ -24,7 +25,7 @@ func Test_loadtestThresholdList(t *testing.T) { loadtestThresholdList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -35,10 +36,10 @@ func Test_loadtestThresholdList(t *testing.T) { err := loadtestThresholdList(service, cmd, []string{}) assert.NotNil(t, err) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetThresholdsError_OutputsFatal", func(t *testing.T) { + t.Run("GetThresholdsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -56,13 +57,13 @@ func Test_loadtestThresholdList(t *testing.T) { func Test_loadtestThresholdShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := loadtestThresholdShowCmd().Args(nil, []string{"123"}) + err := loadtestThresholdShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := loadtestThresholdShowCmd().Args(nil, []string{}) + err := loadtestThresholdShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing threshold", err.Error()) diff --git a/cmd/loadtest/output.go b/cmd/loadtest/output.go new file mode 100644 index 0000000..128b102 --- /dev/null +++ b/cmd/loadtest/output.go @@ -0,0 +1,42 @@ +package loadtest + +import ( + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/ltaas" +) + +func OutputLoadTestDomainsProvider(domains []ltaas.Domain) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(domains, []string{"id", "name"}, nil) +} + +func OutputLoadTestTestsProvider(tests []ltaas.Test) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(tests, []string{"id", "name", "number_of_users", "duration", "protocol", "path"}, nil) +} + +func OutputLoadTestJobsProvider(jobs []ltaas.Job) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(jobs, []string{"id", "status", "job_start_timestamp", "job_end_timestamp"}, nil) +} + +func OutputLoadTestJobResultsProvider(results []ltaas.JobResults) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(results, []string{}, nil) +} + +func OutputLoadTestJobSettingsProvider(settings []ltaas.JobSettings) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(settings, []string{"date", "name", "duration", "max_users", "domain"}, nil) +} + +func OutputLoadTestThresholdsProvider(thresholds []ltaas.Threshold) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(thresholds, []string{"id", "name", "description", "query"}, nil) +} + +func OutputLoadTestScenariosProvider(scenarios []ltaas.Scenario) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(scenarios, []string{"id", "name", "description"}, nil) +} + +func OutputLoadTestAgreementsProvider(agreements []ltaas.Agreement) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(agreements, []string{"version"}, nil) +} + +func OutputLoadTestAccountsProvider(accounts []ltaas.Account) output.OutputHandlerProvider { + return output.NewSerializedOutputHandlerProvider(accounts, []string{"id"}, nil) +} diff --git a/cmd/loadtest_domain_verification.go b/cmd/loadtest_domain_verification.go deleted file mode 100644 index 265c4ea..0000000 --- a/cmd/loadtest_domain_verification.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import "github.com/spf13/cobra" - -func loadtestDomainVerificationRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "verification", - Short: "sub-commands relating to domain verification", - } - - // Child root commands - cmd.AddCommand(loadtestDomainVerificationFileRootCmd()) - cmd.AddCommand(loadtestDomainVerificationDNSRootCmd()) - - return cmd -} diff --git a/cmd/pss.go b/cmd/pss.go deleted file mode 100644 index 5cd4450..0000000 --- a/cmd/pss.go +++ /dev/null @@ -1,107 +0,0 @@ -package cmd - -import ( - "strconv" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/pss" -) - -func pssRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "pss", - Short: "Commands relating to PSS service", - } - - // Child root commands - cmd.AddCommand(pssRequestRootCmd()) - cmd.AddCommand(pssReplyRootCmd()) - - return cmd -} - -// OutputPSSRequests implements OutputDataProvider for outputting an array of Requests -type OutputPSSRequests struct { - Requests []pss.Request -} - -func outputPSSRequests(requests []pss.Request) { - err := Output(&OutputPSSRequests{Requests: requests}) - if err != nil { - output.Fatalf("Failed to output requests: %s", err) - } -} - -func (o *OutputPSSRequests) GetData() interface{} { - return o.Requests -} - -func (o *OutputPSSRequests) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, request := range o.Requests { - fields := o.getOrderedFields(request) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputPSSRequests) getOrderedFields(request pss.Request) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(request.ID), true)) - fields.Set("author_id", output.NewFieldValue(strconv.Itoa(request.Author.ID), false)) - fields.Set("author_name", output.NewFieldValue(request.Author.Name, true)) - fields.Set("type", output.NewFieldValue(request.Type, true)) - fields.Set("secure", output.NewFieldValue(strconv.FormatBool(request.Secure), false)) - fields.Set("subject", output.NewFieldValue(request.Subject, true)) - fields.Set("created_at", output.NewFieldValue(request.CreatedAt.String(), true)) - fields.Set("priority", output.NewFieldValue(request.Priority.String(), false)) - fields.Set("archived", output.NewFieldValue(strconv.FormatBool(request.Archived), false)) - fields.Set("status", output.NewFieldValue(request.Status.String(), true)) - fields.Set("request_sms", output.NewFieldValue(strconv.FormatBool(request.RequestSMS), false)) - fields.Set("version", output.NewFieldValue(strconv.Itoa(request.Version), false)) - fields.Set("customer_reference", output.NewFieldValue(request.CustomerReference, false)) - fields.Set("last_replied_at", output.NewFieldValue(request.LastRepliedAt.String(), true)) - fields.Set("product_id", output.NewFieldValue(strconv.Itoa(request.Product.ID), false)) - fields.Set("product_name", output.NewFieldValue(request.Product.Name, false)) - fields.Set("product_type", output.NewFieldValue(request.Product.Type, false)) - - return fields -} - -// OutputPSSReplies implements OutputDataProvider for outputting an array of Replies -type OutputPSSReplies struct { - Replies []pss.Reply -} - -func outputPSSReplies(replies []pss.Reply) { - err := Output(&OutputPSSReplies{Replies: replies}) - if err != nil { - output.Fatalf("Failed to output replies: %s", err) - } -} - -func (o *OutputPSSReplies) GetData() interface{} { - return o.Replies -} - -func (o *OutputPSSReplies) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, reply := range o.Replies { - fields := o.getOrderedFields(reply) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputPSSReplies) getOrderedFields(reply pss.Reply) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(reply.ID, true)) - fields.Set("author_name", output.NewFieldValue(reply.Author.Name, true)) - fields.Set("description", output.NewFieldValue(reply.Description, false)) - fields.Set("created_at", output.NewFieldValue(reply.CreatedAt.String(), true)) - - return fields -} diff --git a/cmd/pss/output.go b/cmd/pss/output.go new file mode 100644 index 0000000..1204881 --- /dev/null +++ b/cmd/pss/output.go @@ -0,0 +1,61 @@ +package pss + +import ( + "strconv" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/pss" +) + +func OutputPSSRequestsProvider(requests []pss.Request) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(requests), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, request := range requests { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(request.ID), true)) + fields.Set("author_id", output.NewFieldValue(strconv.Itoa(request.Author.ID), false)) + fields.Set("author_name", output.NewFieldValue(request.Author.Name, true)) + fields.Set("type", output.NewFieldValue(request.Type, true)) + fields.Set("secure", output.NewFieldValue(strconv.FormatBool(request.Secure), false)) + fields.Set("subject", output.NewFieldValue(request.Subject, true)) + fields.Set("created_at", output.NewFieldValue(request.CreatedAt.String(), true)) + fields.Set("priority", output.NewFieldValue(request.Priority.String(), false)) + fields.Set("archived", output.NewFieldValue(strconv.FormatBool(request.Archived), false)) + fields.Set("status", output.NewFieldValue(request.Status.String(), true)) + fields.Set("request_sms", output.NewFieldValue(strconv.FormatBool(request.RequestSMS), false)) + fields.Set("version", output.NewFieldValue(strconv.Itoa(request.Version), false)) + fields.Set("customer_reference", output.NewFieldValue(request.CustomerReference, false)) + fields.Set("last_replied_at", output.NewFieldValue(request.LastRepliedAt.String(), true)) + fields.Set("product_id", output.NewFieldValue(strconv.Itoa(request.Product.ID), false)) + fields.Set("product_name", output.NewFieldValue(request.Product.Name, false)) + fields.Set("product_type", output.NewFieldValue(request.Product.Type, false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputPSSRepliesProvider(replies []pss.Reply) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(replies), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, reply := range replies { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(reply.ID, true)) + fields.Set("author_name", output.NewFieldValue(reply.Author.Name, true)) + fields.Set("description", output.NewFieldValue(reply.Description, false)) + fields.Set("created_at", output.NewFieldValue(reply.CreatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/pss/pss.go b/cmd/pss/pss.go new file mode 100644 index 0000000..99c5ea9 --- /dev/null +++ b/cmd/pss/pss.go @@ -0,0 +1,20 @@ +package pss + +import ( + "github.com/spf13/afero" + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func PSSRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { + cmd := &cobra.Command{ + Use: "pss", + Short: "Commands relating to PSS service", + } + + // Child root commands + cmd.AddCommand(pssRequestRootCmd(f)) + cmd.AddCommand(pssReplyRootCmd(f, appFilesystem)) + + return cmd +} diff --git a/cmd/pss_reply.go b/cmd/pss/pss_reply.go similarity index 63% rename from cmd/pss_reply.go rename to cmd/pss/pss_reply.go index d0f9823..9e77561 100644 --- a/cmd/pss_reply.go +++ b/cmd/pss/pss_reply.go @@ -1,29 +1,31 @@ -package cmd +package pss import ( "errors" + "github.com/spf13/afero" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/pss" ) -func pssReplyRootCmd() *cobra.Command { +func pssReplyRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "reply", Short: "sub-commands relating to replies", } // Child commands - cmd.AddCommand(pssReplyShowCmd()) + cmd.AddCommand(pssReplyShowCmd(f)) // Child root commands - cmd.AddCommand(pssReplyAttachmentRootCmd()) + cmd.AddCommand(pssReplyAttachmentRootCmd(f, appFilesystem)) return cmd } -func pssReplyShowCmd() *cobra.Command { +func pssReplyShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a reply", @@ -36,13 +38,13 @@ func pssReplyShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - pssReplyShow(getClient().PSSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return pssReplyShow(f.NewClient().PSSService(), cmd, args) }, } } -func pssReplyShow(service pss.PSSService, cmd *cobra.Command, args []string) { +func pssReplyShow(service pss.PSSService, cmd *cobra.Command, args []string) error { var replies []pss.Reply for _, arg := range args { reply, err := service.GetReply(arg) @@ -54,5 +56,5 @@ func pssReplyShow(service pss.PSSService, cmd *cobra.Command, args []string) { replies = append(replies, reply) } - outputPSSReplies(replies) + return output.CommandOutput(cmd, OutputPSSRepliesProvider(replies)) } diff --git a/cmd/pss_reply_attachment.go b/cmd/pss/pss_reply_attachment.go similarity index 76% rename from cmd/pss_reply_attachment.go rename to cmd/pss/pss_reply_attachment.go index 2005831..7882f2c 100644 --- a/cmd/pss_reply_attachment.go +++ b/cmd/pss/pss_reply_attachment.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "errors" @@ -8,26 +8,27 @@ import ( "github.com/spf13/afero" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/pss" ) -func pssReplyAttachmentRootCmd() *cobra.Command { +func pssReplyAttachmentRootCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "attachment", Short: "sub-commands relating to reply attachments", } // Child commands - cmd.AddCommand(pssReplyAttachmentDownloadCmd()) - cmd.AddCommand(pssReplyAttachmentUploadCmd()) - cmd.AddCommand(pssReplyAttachmentDeleteCmd()) + cmd.AddCommand(pssReplyAttachmentDownloadCmd(f, appFilesystem)) + cmd.AddCommand(pssReplyAttachmentUploadCmd(f, appFilesystem)) + cmd.AddCommand(pssReplyAttachmentDeleteCmd(f)) return cmd } -func pssReplyAttachmentDownloadCmd() *cobra.Command { +func pssReplyAttachmentDownloadCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "download ", Short: "Downloads a reply attachment", @@ -44,7 +45,7 @@ func pssReplyAttachmentDownloadCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return pssReplyAttachmentDownload(getClient().PSSService(), cmd, args) + return pssReplyAttachmentDownload(f.NewClient().PSSService(), appFilesystem, cmd, args) }, } @@ -53,7 +54,7 @@ func pssReplyAttachmentDownloadCmd() *cobra.Command { return cmd } -func pssReplyAttachmentDownload(service pss.PSSService, cmd *cobra.Command, args []string) error { +func pssReplyAttachmentDownload(service pss.PSSService, appFilesystem afero.Fs, cmd *cobra.Command, args []string) error { attachmentStream, err := service.DownloadReplyAttachmentStream(args[0], args[1]) if err != nil { return fmt.Errorf("Error downloading reply attachment: %s", err) @@ -78,7 +79,7 @@ func pssReplyAttachmentDownload(service pss.PSSService, cmd *cobra.Command, args return nil } -func pssReplyAttachmentUploadCmd() *cobra.Command { +func pssReplyAttachmentUploadCmd(f factory.ClientFactory, appFilesystem afero.Fs) *cobra.Command { cmd := &cobra.Command{ Use: "upload ", Short: "Uploads a reply attachment", @@ -92,7 +93,7 @@ func pssReplyAttachmentUploadCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return pssReplyAttachmentUpload(getClient().PSSService(), cmd, args) + return pssReplyAttachmentUpload(f.NewClient().PSSService(), appFilesystem, cmd, args) }, } @@ -102,7 +103,7 @@ func pssReplyAttachmentUploadCmd() *cobra.Command { return cmd } -func pssReplyAttachmentUpload(service pss.PSSService, cmd *cobra.Command, args []string) error { +func pssReplyAttachmentUpload(service pss.PSSService, appFilesystem afero.Fs, cmd *cobra.Command, args []string) error { path, _ := cmd.Flags().GetString("path") fileStream, err := appFilesystem.Open(path) @@ -118,7 +119,7 @@ func pssReplyAttachmentUpload(service pss.PSSService, cmd *cobra.Command, args [ return nil } -func pssReplyAttachmentDeleteCmd() *cobra.Command { +func pssReplyAttachmentDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Deletes a reply attachment", @@ -135,7 +136,7 @@ func pssReplyAttachmentDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - pssReplyAttachmentDelete(getClient().PSSService(), cmd, args) + pssReplyAttachmentDelete(f.NewClient().PSSService(), cmd, args) }, } } diff --git a/cmd/pss_reply_attachment_test.go b/cmd/pss/pss_reply_attachment_test.go similarity index 74% rename from cmd/pss_reply_attachment_test.go rename to cmd/pss/pss_reply_attachment_test.go index 91a067a..985b657 100644 --- a/cmd/pss_reply_attachment_test.go +++ b/cmd/pss/pss_reply_attachment_test.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "bytes" @@ -8,6 +8,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/afero" + "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" @@ -16,20 +17,20 @@ import ( func Test_pssReplyAttachmentDownloadCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssReplyAttachmentDownloadCmd().Args(nil, []string{"123", "test.txt"}) + err := pssReplyAttachmentDownloadCmd(nil, nil).Args(nil, []string{"123", "test.txt"}) assert.Nil(t, err) }) t.Run("MissingReply_Error", func(t *testing.T) { - err := pssReplyAttachmentDownloadCmd().Args(nil, []string{}) + err := pssReplyAttachmentDownloadCmd(nil, nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing reply", err.Error()) }) t.Run("MissingAttachment_Error", func(t *testing.T) { - err := pssReplyAttachmentDownloadCmd().Args(nil, []string{"123"}) + err := pssReplyAttachmentDownloadCmd(nil, nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing attachment", err.Error()) @@ -38,7 +39,7 @@ func Test_pssReplyAttachmentDownloadCmd_Args(t *testing.T) { func Test_pssReplyAttachmentDownload(t *testing.T) { t.Run("Valid_DownloadsFile", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -50,7 +51,7 @@ func Test_pssReplyAttachmentDownload(t *testing.T) { service.EXPECT().DownloadReplyAttachmentStream("C123", "test1.txt").Return(attachmentStream, nil), ) - pssReplyAttachmentDownload(service, pssReplyAttachmentDownloadCmd(), []string{"C123", "test1.txt"}) + pssReplyAttachmentDownload(service, appFilesystem, &cobra.Command{}, []string{"C123", "test1.txt"}) }) t.Run("DownloadReplyAttachmentStreamError_ReturnsFatal", func(t *testing.T) { @@ -63,12 +64,12 @@ func Test_pssReplyAttachmentDownload(t *testing.T) { service.EXPECT().DownloadReplyAttachmentStream("C123", "test1.txt").Return(nil, errors.New("test error")), ) - err := pssReplyAttachmentDownload(service, pssReplyAttachmentDownloadCmd(), []string{"C123", "test1.txt"}) + err := pssReplyAttachmentDownload(service, nil, &cobra.Command{}, []string{"C123", "test1.txt"}) assert.Equal(t, "Error downloading reply attachment: test error", err.Error()) }) t.Run("FileExists_ReturnsFatal", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() afero.WriteFile(appFilesystem, "test1.txt", []byte{}, 0644) mockCtrl := gomock.NewController(t) @@ -80,12 +81,12 @@ func Test_pssReplyAttachmentDownload(t *testing.T) { service.EXPECT().DownloadReplyAttachmentStream("C123", "test1.txt").Return(nil, nil), ) - err := pssReplyAttachmentDownload(service, pssReplyAttachmentDownloadCmd(), []string{"C123", "test1.txt"}) + err := pssReplyAttachmentDownload(service, appFilesystem, &cobra.Command{}, []string{"C123", "test1.txt"}) assert.Equal(t, "Destination file [test1.txt] exists", err.Error()) }) t.Run("WriteReaderError_ReturnsFatal", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() b := test.TestReadCloser{ ReadError: errors.New("test reader error 1"), } @@ -94,27 +95,27 @@ func Test_pssReplyAttachmentDownload(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssReplyAttachmentDownloadCmd() + cmd := pssReplyAttachmentDownloadCmd(nil, nil) cmd.Flags().Set("path", "/some/path/test.txt") gomock.InOrder( service.EXPECT().DownloadReplyAttachmentStream("C123", "test1.txt").Return(&b, nil), ) - err := pssReplyAttachmentDownload(service, cmd, []string{"C123", "test1.txt"}) + err := pssReplyAttachmentDownload(service, appFilesystem, cmd, []string{"C123", "test1.txt"}) assert.Contains(t, err.Error(), "test reader error 1") }) } func Test_pssReplyAttachmentUploadCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssReplyAttachmentUploadCmd().Args(nil, []string{"123"}) + err := pssReplyAttachmentUploadCmd(nil, nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("MissingReply_Error", func(t *testing.T) { - err := pssReplyAttachmentUploadCmd().Args(nil, []string{}) + err := pssReplyAttachmentUploadCmd(nil, nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing reply", err.Error()) @@ -123,7 +124,7 @@ func Test_pssReplyAttachmentUploadCmd_Args(t *testing.T) { func Test_pssReplyAttachmentUpload(t *testing.T) { t.Run("Valid_UploadsFile", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() afero.WriteFile(appFilesystem, "/test/test1.txt", []byte("test content"), 644) mockCtrl := gomock.NewController(t) @@ -131,30 +132,30 @@ func Test_pssReplyAttachmentUpload(t *testing.T) { service := mocks.NewMockPSSService(mockCtrl) - cmd := pssReplyAttachmentUploadCmd() + cmd := pssReplyAttachmentUploadCmd(nil, nil) cmd.Flags().Set("path", "/test/test1.txt") gomock.InOrder( service.EXPECT().UploadReplyAttachmentStream("C123", "test1.txt", gomock.Any()).Return(nil), ) - pssReplyAttachmentUpload(service, cmd, []string{"C123"}) + pssReplyAttachmentUpload(service, appFilesystem, cmd, []string{"C123"}) }) t.Run("FileOpenError_ReturnsError", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() - cmd := pssReplyAttachmentUploadCmd() + cmd := pssReplyAttachmentUploadCmd(nil, nil) cmd.Flags().Set("path", "/test/test1.txt") - err := pssReplyAttachmentUpload(nil, cmd, []string{"C123"}) + err := pssReplyAttachmentUpload(nil, appFilesystem, cmd, []string{"C123"}) assert.NotNil(t, err) assert.Contains(t, err.Error(), "Failed to open file") }) t.Run("UploadReplyAttachmentStream_ReturnsError", func(t *testing.T) { - appFilesystem = afero.NewMemMapFs() + appFilesystem := afero.NewMemMapFs() afero.WriteFile(appFilesystem, "/test/test1.txt", []byte("test content"), 644) mockCtrl := gomock.NewController(t) @@ -162,14 +163,14 @@ func Test_pssReplyAttachmentUpload(t *testing.T) { service := mocks.NewMockPSSService(mockCtrl) - cmd := pssReplyAttachmentUploadCmd() + cmd := pssReplyAttachmentUploadCmd(nil, nil) cmd.Flags().Set("path", "/test/test1.txt") gomock.InOrder( service.EXPECT().UploadReplyAttachmentStream("C123", "test1.txt", gomock.Any()).Return(errors.New("test error")), ) - err := pssReplyAttachmentUpload(service, cmd, []string{"C123"}) + err := pssReplyAttachmentUpload(service, appFilesystem, cmd, []string{"C123"}) assert.NotNil(t, err) assert.Contains(t, err.Error(), "Failed to upload attachment") }) @@ -177,20 +178,20 @@ func Test_pssReplyAttachmentUpload(t *testing.T) { func Test_pssReplyAttachmentDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssReplyAttachmentDeleteCmd().Args(nil, []string{"123", "test.txt"}) + err := pssReplyAttachmentDeleteCmd(nil).Args(nil, []string{"123", "test.txt"}) assert.Nil(t, err) }) t.Run("MissingReply_Error", func(t *testing.T) { - err := pssReplyAttachmentDeleteCmd().Args(nil, []string{}) + err := pssReplyAttachmentDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing reply", err.Error()) }) t.Run("MissingAttachment_Error", func(t *testing.T) { - err := pssReplyAttachmentDeleteCmd().Args(nil, []string{"123"}) + err := pssReplyAttachmentDeleteCmd(nil).Args(nil, []string{"123"}) assert.NotNil(t, err) assert.Equal(t, "Missing attachment", err.Error()) @@ -208,7 +209,7 @@ func Test_pssReplyAttachmentDelete(t *testing.T) { service.EXPECT().DeleteReplyAttachment("C123", "test1.txt").Return(nil), ) - pssReplyAttachmentDelete(service, pssReplyAttachmentDeleteCmd(), []string{"C123", "test1.txt"}) + pssReplyAttachmentDelete(service, pssReplyAttachmentDeleteCmd(nil), []string{"C123", "test1.txt"}) }) t.Run("DeleteReplyAttachmentError_OutputsError", func(t *testing.T) { @@ -222,7 +223,7 @@ func Test_pssReplyAttachmentDelete(t *testing.T) { ) test_output.AssertErrorOutput(t, "Error deleting reply attachment [test1.txt]: test error\n", func() { - pssReplyAttachmentDelete(service, pssReplyAttachmentDeleteCmd(), []string{"C123", "test1.txt"}) + pssReplyAttachmentDelete(service, pssReplyAttachmentDeleteCmd(nil), []string{"C123", "test1.txt"}) }) }) } diff --git a/cmd/pss_request.go b/cmd/pss/pss_request.go similarity index 84% rename from cmd/pss_request.go rename to cmd/pss/pss_request.go index a9134b7..8aa1c7e 100644 --- a/cmd/pss_request.go +++ b/cmd/pss/pss_request.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "errors" @@ -6,38 +6,39 @@ import ( "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/input" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/pss" ) -func pssRequestRootCmd() *cobra.Command { +func pssRequestRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "request", Short: "sub-commands relating to requests", } // Child commands - cmd.AddCommand(pssRequestListCmd()) - cmd.AddCommand(pssRequestShowCmd()) - cmd.AddCommand(pssRequestCreateCmd()) - cmd.AddCommand(pssRequestUpdateCmd()) + cmd.AddCommand(pssRequestListCmd(f)) + cmd.AddCommand(pssRequestShowCmd(f)) + cmd.AddCommand(pssRequestCreateCmd(f)) + cmd.AddCommand(pssRequestUpdateCmd(f)) // Child root commands - cmd.AddCommand(pssRequestReplyRootCmd()) + cmd.AddCommand(pssRequestReplyRootCmd(f)) return cmd } -func pssRequestListCmd() *cobra.Command { +func pssRequestListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists requests", Long: "This command lists requests", Example: "ukfast pss request list", RunE: func(cmd *cobra.Command, args []string) error { - return pssRequestList(getClient().PSSService(), cmd, args) + return pssRequestList(f.NewClient().PSSService(), cmd, args) }, } } @@ -53,11 +54,10 @@ func pssRequestList(service pss.PSSService, cmd *cobra.Command, args []string) e return err } - outputPSSRequests(requests) - return nil + return output.CommandOutput(cmd, OutputPSSRequestsProvider(requests)) } -func pssRequestShowCmd() *cobra.Command { +func pssRequestShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a request", @@ -70,13 +70,13 @@ func pssRequestShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - pssRequestShow(getClient().PSSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return pssRequestShow(f.NewClient().PSSService(), cmd, args) }, } } -func pssRequestShow(service pss.PSSService, cmd *cobra.Command, args []string) { +func pssRequestShow(service pss.PSSService, cmd *cobra.Command, args []string) error { var requests []pss.Request for _, arg := range args { requestID, err := strconv.Atoi(arg) @@ -94,17 +94,17 @@ func pssRequestShow(service pss.PSSService, cmd *cobra.Command, args []string) { requests = append(requests, request) } - outputPSSRequests(requests) + return output.CommandOutput(cmd, OutputPSSRequestsProvider(requests)) } -func pssRequestCreateCmd() *cobra.Command { +func pssRequestCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a request", Long: "This command creates a new request", Example: "ukfast pss request create --subject 'example ticket' --details 'example' --author 123", RunE: func(cmd *cobra.Command, args []string) error { - return pssRequestCreate(getClient().PSSService(), cmd, args) + return pssRequestCreate(f.NewClient().PSSService(), cmd, args) }, } @@ -169,11 +169,10 @@ func pssRequestCreate(service pss.PSSService, cmd *cobra.Command, args []string) return fmt.Errorf("Error retrieving new request: %s", err) } - outputPSSRequests([]pss.Request{request}) - return nil + return output.CommandOutput(cmd, OutputPSSRequestsProvider([]pss.Request{request})) } -func pssRequestUpdateCmd() *cobra.Command { +func pssRequestUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates requests", @@ -187,7 +186,7 @@ func pssRequestUpdateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return pssRequestUpdate(getClient().PSSService(), cmd, args) + return pssRequestUpdate(f.NewClient().PSSService(), cmd, args) }, } @@ -254,6 +253,5 @@ func pssRequestUpdate(service pss.PSSService, cmd *cobra.Command, args []string) requests = append(requests, request) } - outputPSSRequests(requests) - return nil + return output.CommandOutput(cmd, OutputPSSRequestsProvider(requests)) } diff --git a/cmd/pss_request_reply.go b/cmd/pss/pss_request_reply.go similarity index 79% rename from cmd/pss_request_reply.go rename to cmd/pss/pss_request_reply.go index 36313e9..885e680 100644 --- a/cmd/pss_request_reply.go +++ b/cmd/pss/pss_request_reply.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "errors" @@ -6,27 +6,29 @@ import ( "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/input" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/pss" ) -func pssRequestReplyRootCmd() *cobra.Command { +func pssRequestReplyRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "reply", Short: "sub-commands relating to request replies", } // Child commands - cmd.AddCommand(pssRequestReplyListCmd()) - cmd.AddCommand(pssRequestReplyCreateCmd()) + cmd.AddCommand(pssRequestReplyListCmd(f)) + cmd.AddCommand(pssRequestReplyCreateCmd(f)) // Child root commands return cmd } -func pssRequestReplyListCmd() *cobra.Command { +func pssRequestReplyListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list ", Short: "Lists a request", @@ -40,7 +42,7 @@ func pssRequestReplyListCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return pssRequestReplyList(getClient().PSSService(), cmd, args) + return pssRequestReplyList(f.NewClient().PSSService(), cmd, args) }, } } @@ -53,7 +55,7 @@ func pssRequestReplyList(service pss.PSSService, cmd *cobra.Command, args []stri params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - return fmt.Errorf(err.Error()) + return err } replies, err := service.GetRequestConversation(requestID, params) @@ -61,11 +63,10 @@ func pssRequestReplyList(service pss.PSSService, cmd *cobra.Command, args []stri return fmt.Errorf("Error retrieving request replies: %s", err) } - outputPSSReplies(replies) - return nil + return output.CommandOutput(cmd, OutputPSSRepliesProvider(replies)) } -func pssRequestReplyCreateCmd() *cobra.Command { +func pssRequestReplyCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a reply", @@ -79,7 +80,7 @@ func pssRequestReplyCreateCmd() *cobra.Command { return nil }, RunE: func(cmd *cobra.Command, args []string) error { - return pssRequestReplyCreate(getClient().PSSService(), cmd, args) + return pssRequestReplyCreate(f.NewClient().PSSService(), cmd, args) }, } @@ -119,6 +120,5 @@ func pssRequestReplyCreate(service pss.PSSService, cmd *cobra.Command, args []st return fmt.Errorf("Error retrieving new reply: %s", err) } - outputPSSReplies([]pss.Reply{reply}) - return nil + return output.CommandOutput(cmd, OutputPSSRepliesProvider([]pss.Reply{reply})) } diff --git a/cmd/pss_request_reply_test.go b/cmd/pss/pss_request_reply_test.go similarity index 80% rename from cmd/pss_request_reply_test.go rename to cmd/pss/pss_request_reply_test.go index 7100459..4ec56cc 100644 --- a/cmd/pss_request_reply_test.go +++ b/cmd/pss/pss_request_reply_test.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "errors" @@ -7,19 +7,20 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/sdk-go/pkg/service/pss" ) func Test_pssRequestReplyListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssRequestReplyListCmd().Args(nil, []string{"123"}) + err := pssRequestReplyListCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := pssRequestReplyListCmd().Args(nil, []string{}) + err := pssRequestReplyListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing request", err.Error()) @@ -38,7 +39,7 @@ func Test_pssRequestReplyList(t *testing.T) { pssRequestReplyList(service, &cobra.Command{}, []string{"123"}) }) - t.Run("GetRequestID_OutputsFatal", func(t *testing.T) { + t.Run("GetRequestID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -48,7 +49,7 @@ func Test_pssRequestReplyList(t *testing.T) { assert.Equal(t, "Invalid request ID [abc]", err.Error()) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -57,10 +58,10 @@ func Test_pssRequestReplyList(t *testing.T) { cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") err := pssRequestReplyList(service, cmd, []string{"123"}) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetRequestConversationError_OutputsFatal", func(t *testing.T) { + t.Run("GetRequestConversationError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -76,13 +77,13 @@ func Test_pssRequestReplyList(t *testing.T) { func Test_pssRequestReplyCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssRequestReplyCreateCmd().Args(nil, []string{"123"}) + err := pssRequestReplyCreateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := pssRequestReplyCreateCmd().Args(nil, []string{}) + err := pssRequestReplyCreateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing request", err.Error()) @@ -95,7 +96,7 @@ func Test_pssRequestReplyCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestReplyCreateCmd() + cmd := pssRequestReplyCreateCmd(nil) cmd.Flags().Set("description", "test description") cmd.Flags().Set("author", "456") @@ -114,23 +115,23 @@ func Test_pssRequestReplyCreate(t *testing.T) { pssRequestReplyCreate(service, cmd, []string{"123"}) }) - t.Run("InvalidRequestID_OutputsFatal", func(t *testing.T) { + t.Run("InvalidRequestID_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestReplyCreateCmd() + cmd := pssRequestReplyCreateCmd(nil) err := pssRequestReplyCreate(service, cmd, []string{"invalid"}) assert.Contains(t, err.Error(), "Invalid request ID [invalid]") }) - t.Run("CreateRequestReplyError_OutputsFatal", func(t *testing.T) { + t.Run("CreateRequestReplyError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestReplyCreateCmd() + cmd := pssRequestReplyCreateCmd(nil) service.EXPECT().CreateRequestReply(123, gomock.Any()).Return("", errors.New("test error")).Times(1) @@ -138,12 +139,12 @@ func Test_pssRequestReplyCreate(t *testing.T) { assert.Equal(t, "Error creating reply: test error", err.Error()) }) - t.Run("GetRequestError_OutputsFatal", func(t *testing.T) { + t.Run("GetRequestError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestReplyCreateCmd() + cmd := pssRequestReplyCreateCmd(nil) gomock.InOrder( service.EXPECT().CreateRequestReply(123, gomock.Any()).Return("C123", nil), diff --git a/cmd/pss_request_test.go b/cmd/pss/pss_request_test.go similarity index 87% rename from cmd/pss_request_test.go rename to cmd/pss/pss_request_test.go index 5447c83..f993e80 100644 --- a/cmd/pss_request_test.go +++ b/cmd/pss/pss_request_test.go @@ -1,4 +1,4 @@ -package cmd +package pss import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/pss" @@ -24,7 +25,7 @@ func Test_pssRequestList(t *testing.T) { pssRequestList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -33,10 +34,10 @@ func Test_pssRequestList(t *testing.T) { cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") err := pssRequestList(service, cmd, []string{}) - assert.Equal(t, "Missing value for filtering", err.Error()) + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetRequestsError_OutputsFatal", func(t *testing.T) { + t.Run("GetRequestsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -52,13 +53,13 @@ func Test_pssRequestList(t *testing.T) { func Test_pssRequestShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssRequestShowCmd().Args(nil, []string{"123"}) + err := pssRequestShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := pssRequestShowCmd().Args(nil, []string{}) + err := pssRequestShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing request", err.Error()) @@ -122,7 +123,7 @@ func Test_pssRequestCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestCreateCmd() + cmd := pssRequestCreateCmd(nil) cmd.Flags().Set("subject", "test subject") cmd.Flags().Set("product-id", "456") cmd.Flags().Set("product-name", "testname") @@ -141,24 +142,24 @@ func Test_pssRequestCreate(t *testing.T) { pssRequestCreate(service, cmd, []string{}) }) - t.Run("InvalidPriority_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPriority_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestCreateCmd() + cmd := pssRequestCreateCmd(nil) cmd.Flags().Set("priority", "invalid") err := pssRequestCreate(service, cmd, []string{}) assert.Contains(t, err.Error(), "Invalid pss.RequestPriority") }) - t.Run("CreateRequestError_OutputsFatal", func(t *testing.T) { + t.Run("CreateRequestError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestCreateCmd() + cmd := pssRequestCreateCmd(nil) service.EXPECT().CreateRequest(gomock.Any()).Return(0, errors.New("test error")).Times(1) @@ -166,12 +167,12 @@ func Test_pssRequestCreate(t *testing.T) { assert.Equal(t, "Error creating request: test error", err.Error()) }) - t.Run("GetRequestError_OutputsFatal", func(t *testing.T) { + t.Run("GetRequestError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestCreateCmd() + cmd := pssRequestCreateCmd(nil) gomock.InOrder( service.EXPECT().CreateRequest(gomock.Any()).Return(123, nil), @@ -185,13 +186,13 @@ func Test_pssRequestCreate(t *testing.T) { func Test_pssRequestUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := pssRequestUpdateCmd().Args(nil, []string{"123"}) + err := pssRequestUpdateCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := pssRequestUpdateCmd().Args(nil, []string{}) + err := pssRequestUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing request", err.Error()) @@ -204,7 +205,7 @@ func Test_pssRequestUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestUpdateCmd() + cmd := pssRequestUpdateCmd(nil) cmd.Flags().Set("secure", "true") cmd.Flags().Set("read", "true") cmd.Flags().Set("request-sms", "true") @@ -226,12 +227,12 @@ func Test_pssRequestUpdate(t *testing.T) { pssRequestUpdate(service, cmd, []string{"123"}) }) - t.Run("InvalidPriority_OutputsFatal", func(t *testing.T) { + t.Run("InvalidPriority_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestUpdateCmd() + cmd := pssRequestUpdateCmd(nil) cmd.Flags().Set("priority", "invalid") err := pssRequestUpdate(service, cmd, []string{"123"}) @@ -243,7 +244,7 @@ func Test_pssRequestUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestUpdateCmd() + cmd := pssRequestUpdateCmd(nil) test_output.AssertErrorOutput(t, "Invalid request ID [abc]\n", func() { pssRequestUpdate(service, cmd, []string{"abc"}) @@ -255,7 +256,7 @@ func Test_pssRequestUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestUpdateCmd() + cmd := pssRequestUpdateCmd(nil) service.EXPECT().PatchRequest(123, gomock.Any()).Return(errors.New("test error")).Times(1) @@ -269,7 +270,7 @@ func Test_pssRequestUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockPSSService(mockCtrl) - cmd := pssRequestUpdateCmd() + cmd := pssRequestUpdateCmd(nil) gomock.InOrder( service.EXPECT().PatchRequest(123, gomock.Any()).Return(nil), diff --git a/cmd/pss_test.go b/cmd/pss_test.go deleted file mode 100644 index 10f6087..0000000 --- a/cmd/pss_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/service/pss" -) - -func TestOutputPSSRequests_GetData_ExpectedData(t *testing.T) { - o := OutputPSSRequests{ - Requests: []pss.Request{ - pss.Request{ - ID: 123, - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []pss.Request{}, data) - assert.Equal(t, 123, data.([]pss.Request)[0].ID) -} - -func TestOutputPSSRequests_GetFieldData(t *testing.T) { - t.Run("ExpectedFieldData", func(t *testing.T) { - o := OutputPSSRequests{ - Requests: []pss.Request{ - pss.Request{ - ID: 123, - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("id")) - assert.Equal(t, "123", data[0].Get("id").Value) - }) -} - -func TestOutputPSSRequestReplies_GetData_ExpectedData(t *testing.T) { - o := OutputPSSReplies{ - Replies: []pss.Reply{ - pss.Reply{ - Description: "test reply", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []pss.Reply{}, data) - assert.Equal(t, "test reply", data.([]pss.Reply)[0].Description) -} - -func TestOutputPSSReplies_GetFieldData_ExpectedFieldData(t *testing.T) { - o := OutputPSSReplies{ - Replies: []pss.Reply{ - pss.Reply{ - Description: "test reply", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("description")) - assert.Equal(t, "test reply", data[0].Get("description").Value) -} diff --git a/cmd/registrar.go b/cmd/registrar.go deleted file mode 100644 index 6d7446a..0000000 --- a/cmd/registrar.go +++ /dev/null @@ -1,137 +0,0 @@ -package cmd - -import ( - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/registrar" -) - -func registrarRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "registrar", - Short: "Commands relating to Registrar service", - } - - // Child root commands - cmd.AddCommand(registrarDomainRootCmd()) - cmd.AddCommand(registrarWhoisRootCmd()) - - return cmd -} - -// OutputRegistrarDomains implements OutputDataProvider for outputting an array of Domains -type OutputRegistrarDomains struct { - Domains []registrar.Domain -} - -func outputRegistrarDomains(domains []registrar.Domain) { - err := Output(&OutputRegistrarDomains{Domains: domains}) - if err != nil { - output.Fatalf("Failed to output domains: %s", err) - } -} - -func (o *OutputRegistrarDomains) GetData() interface{} { - return o.Domains -} - -func (o *OutputRegistrarDomains) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, domain := range o.Domains { - fields := o.getOrderedFields(domain) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputRegistrarDomains) getOrderedFields(domain registrar.Domain) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("name", output.NewFieldValue(domain.Name, true)) - fields.Set("status", output.NewFieldValue(domain.Status, true)) - fields.Set("registrar", output.NewFieldValue(domain.Registrar, true)) - fields.Set("registered_at", output.NewFieldValue(domain.RegisteredAt.String(), true)) - fields.Set("updated_at", output.NewFieldValue(domain.UpdatedAt.String(), true)) - fields.Set("renewal_at", output.NewFieldValue(domain.RenewalAt.String(), true)) - fields.Set("auto_renew", output.NewFieldValue(strconv.FormatBool(domain.AutoRenew), true)) - fields.Set("whois_privacy", output.NewFieldValue(strconv.FormatBool(domain.WHOISPrivacy), false)) - - return fields -} - -// OutputRegistrarNameservers implements OutputDataProvider for outputting an array of Nameservers -type OutputRegistrarNameservers struct { - Nameservers []registrar.Nameserver -} - -func outputRegistrarNameservers(domains []registrar.Nameserver) { - err := Output(&OutputRegistrarNameservers{Nameservers: domains}) - if err != nil { - output.Fatalf("Failed to output nameservers: %s", err) - } -} - -func (o *OutputRegistrarNameservers) GetData() interface{} { - return o.Nameservers -} - -func (o *OutputRegistrarNameservers) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, domain := range o.Nameservers { - fields := o.getOrderedFields(domain) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputRegistrarNameservers) getOrderedFields(domain registrar.Nameserver) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("host", output.NewFieldValue(domain.Host, true)) - fields.Set("ip", output.NewFieldValue(domain.IP.String(), true)) - - return fields -} - -// OutputRegistrarWhois implements OutputDataProvider for outputting an array of Whois -type OutputRegistrarWhois struct { - Whois []registrar.Whois -} - -func outputRegistrarWhois(whois []registrar.Whois) { - err := Output(&OutputRegistrarWhois{Whois: whois}) - if err != nil { - output.Fatalf("Failed to output whois: %s", err) - } -} - -func (o *OutputRegistrarWhois) GetData() interface{} { - return o.Whois -} - -func (o *OutputRegistrarWhois) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, whois := range o.Whois { - fields := o.getOrderedFields(whois) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputRegistrarWhois) getOrderedFields(whois registrar.Whois) *output.OrderedFields { - fields := output.NewOrderedFields() - - fields.Set("name", output.NewFieldValue(whois.Name, true)) - fields.Set("status", output.NewFieldValue(strings.Join(whois.Status, ", "), true)) - fields.Set("created_at", output.NewFieldValue(whois.CreatedAt.String(), true)) - fields.Set("updated_at", output.NewFieldValue(whois.UpdatedAt.String(), true)) - fields.Set("expires_at", output.NewFieldValue(whois.ExpiresAt.String(), true)) - - return fields -} diff --git a/cmd/registrar/output.go b/cmd/registrar/output.go new file mode 100644 index 0000000..e671642 --- /dev/null +++ b/cmd/registrar/output.go @@ -0,0 +1,72 @@ +package registrar + +import ( + "strconv" + "strings" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/registrar" +) + +func OutputRegistrarDomainsProvider(domains []registrar.Domain) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(domains), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, domain := range domains { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(domain.Name, true)) + fields.Set("status", output.NewFieldValue(domain.Status, true)) + fields.Set("registrar", output.NewFieldValue(domain.Registrar, true)) + fields.Set("registered_at", output.NewFieldValue(domain.RegisteredAt.String(), true)) + fields.Set("updated_at", output.NewFieldValue(domain.UpdatedAt.String(), true)) + fields.Set("renewal_at", output.NewFieldValue(domain.RenewalAt.String(), true)) + fields.Set("auto_renew", output.NewFieldValue(strconv.FormatBool(domain.AutoRenew), true)) + fields.Set("whois_privacy", output.NewFieldValue(strconv.FormatBool(domain.WHOISPrivacy), false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputRegistrarNameserversProvider(nameservers []registrar.Nameserver) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(nameservers), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, nameserver := range nameservers { + fields := output.NewOrderedFields() + fields.Set("host", output.NewFieldValue(nameserver.Host, true)) + fields.Set("ip", output.NewFieldValue(nameserver.IP.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputRegistrarWhoisProvider(whoisArr []registrar.Whois) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(whoisArr), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, whois := range whoisArr { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(whois.Name, true)) + fields.Set("status", output.NewFieldValue(strings.Join(whois.Status, ", "), true)) + fields.Set("created_at", output.NewFieldValue(whois.CreatedAt.String(), true)) + fields.Set("updated_at", output.NewFieldValue(whois.UpdatedAt.String(), true)) + fields.Set("expires_at", output.NewFieldValue(whois.ExpiresAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/registrar/registrar.go b/cmd/registrar/registrar.go new file mode 100644 index 0000000..17e2a81 --- /dev/null +++ b/cmd/registrar/registrar.go @@ -0,0 +1,19 @@ +package registrar + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func RegistrarRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "registrar", + Short: "Commands relating to Registrar service", + } + + // Child root commands + cmd.AddCommand(registrarDomainRootCmd(f)) + cmd.AddCommand(registrarWhoisRootCmd(f)) + + return cmd +} diff --git a/cmd/registrar_domain.go b/cmd/registrar/registrar_domain.go similarity index 58% rename from cmd/registrar_domain.go rename to cmd/registrar/registrar_domain.go index 6130c87..5e01f59 100644 --- a/cmd/registrar_domain.go +++ b/cmd/registrar/registrar_domain.go @@ -1,59 +1,59 @@ -package cmd +package registrar import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/registrar" ) -func registrarDomainRootCmd() *cobra.Command { +func registrarDomainRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "domain", Short: "sub-commands relating to domains", } // Child commands - cmd.AddCommand(registrarDomainListCmd()) - cmd.AddCommand(registrarDomainShowCmd()) + cmd.AddCommand(registrarDomainListCmd(f)) + cmd.AddCommand(registrarDomainShowCmd(f)) // Child root commands - cmd.AddCommand(registrarDomainNameserverRootCmd()) + cmd.AddCommand(registrarDomainNameserverRootCmd(f)) return cmd } -func registrarDomainListCmd() *cobra.Command { +func registrarDomainListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists domains", Long: "This command lists domains", Example: "ukfast registrar domain list", - Run: func(cmd *cobra.Command, args []string) { - registrarDomainList(getClient().RegistrarService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return registrarDomainList(f.NewClient().RegistrarService(), cmd, args) }, } } -func registrarDomainList(service registrar.RegistrarService, cmd *cobra.Command, args []string) { +func registrarDomainList(service registrar.RegistrarService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } domains, err := service.GetDomains(params) if err != nil { - output.Fatalf("Error retrieving domains: %s", err) - return + return fmt.Errorf("Error retrieving domains: %s", err) } - outputRegistrarDomains(domains) + return output.CommandOutput(cmd, OutputRegistrarDomainsProvider(domains)) } -func registrarDomainShowCmd() *cobra.Command { +func registrarDomainShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a domain", @@ -66,13 +66,13 @@ func registrarDomainShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - registrarDomainShow(getClient().RegistrarService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return registrarDomainShow(f.NewClient().RegistrarService(), cmd, args) }, } } -func registrarDomainShow(service registrar.RegistrarService, cmd *cobra.Command, args []string) { +func registrarDomainShow(service registrar.RegistrarService, cmd *cobra.Command, args []string) error { var domains []registrar.Domain for _, arg := range args { domain, err := service.GetDomain(arg) @@ -84,5 +84,5 @@ func registrarDomainShow(service registrar.RegistrarService, cmd *cobra.Command, domains = append(domains, domain) } - outputRegistrarDomains(domains) + return output.CommandOutput(cmd, OutputRegistrarDomainsProvider(domains)) } diff --git a/cmd/registrar_domain_nameserver.go b/cmd/registrar/registrar_domain_nameserver.go similarity index 55% rename from cmd/registrar_domain_nameserver.go rename to cmd/registrar/registrar_domain_nameserver.go index 7907be4..063364a 100644 --- a/cmd/registrar_domain_nameserver.go +++ b/cmd/registrar/registrar_domain_nameserver.go @@ -1,26 +1,28 @@ -package cmd +package registrar import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/registrar" ) -func registrarDomainNameserverRootCmd() *cobra.Command { +func registrarDomainNameserverRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "nameserver", Short: "sub-commands relating to domain nameservers", } // Child commands - cmd.AddCommand(registrarDomainNameserverListCmd()) + cmd.AddCommand(registrarDomainNameserverListCmd(f)) return cmd } -func registrarDomainNameserverListCmd() *cobra.Command { +func registrarDomainNameserverListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists domain nameservers", @@ -33,18 +35,17 @@ func registrarDomainNameserverListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - registrarDomainNameserverList(getClient().RegistrarService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return registrarDomainNameserverList(f.NewClient().RegistrarService(), cmd, args) }, } } -func registrarDomainNameserverList(service registrar.RegistrarService, cmd *cobra.Command, args []string) { +func registrarDomainNameserverList(service registrar.RegistrarService, cmd *cobra.Command, args []string) error { nameservers, err := service.GetDomainNameservers(args[0]) if err != nil { - output.Fatalf("Error retrieving domain nameservers: %s", err) - return + return fmt.Errorf("Error retrieving domain nameservers: %s", err) } - outputRegistrarNameservers(nameservers) + return output.CommandOutput(cmd, OutputRegistrarNameserversProvider(nameservers)) } diff --git a/cmd/registrar_domain_nameserver_test.go b/cmd/registrar/registrar_domain_nameserver_test.go similarity index 71% rename from cmd/registrar_domain_nameserver_test.go rename to cmd/registrar/registrar_domain_nameserver_test.go index 7fa4a18..0314960 100644 --- a/cmd/registrar_domain_nameserver_test.go +++ b/cmd/registrar/registrar_domain_nameserver_test.go @@ -1,4 +1,4 @@ -package cmd +package registrar import ( "errors" @@ -8,19 +8,18 @@ import ( "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/ukfast/cli/test/mocks" - "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/registrar" ) func Test_registrarDomainNameserverListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := registrarDomainNameserverListCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := registrarDomainNameserverListCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := registrarDomainNameserverListCmd().Args(nil, []string{}) + err := registrarDomainNameserverListCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) @@ -39,7 +38,7 @@ func Test_registrarDomainNameserverList(t *testing.T) { registrarDomainNameserverList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) }) - t.Run("GetDomainNameserversError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainNameserversError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -48,8 +47,8 @@ func Test_registrarDomainNameserverList(t *testing.T) { service.EXPECT().GetDomainNameservers(gomock.Any()).Return([]registrar.Nameserver{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domain nameservers: test error\n", func() { - registrarDomainNameserverList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) - }) + err := registrarDomainNameserverList(service, &cobra.Command{}, []string{"testdomain1.co.uk"}) + + assert.Equal(t, "Error retrieving domain nameservers: test error", err.Error()) }) } diff --git a/cmd/registrar_domain_test.go b/cmd/registrar/registrar_domain_test.go similarity index 82% rename from cmd/registrar_domain_test.go rename to cmd/registrar/registrar_domain_test.go index cee1e69..8b0036c 100644 --- a/cmd/registrar_domain_test.go +++ b/cmd/registrar/registrar_domain_test.go @@ -1,4 +1,4 @@ -package cmd +package registrar import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/registrar" @@ -24,7 +25,7 @@ func Test_registrarDomainList(t *testing.T) { registrarDomainList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_registrarDomainList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - registrarDomainList(service, cmd, []string{}) - }) + err := registrarDomainList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetDomainsError_OutputsFatal", func(t *testing.T) { + t.Run("GetDomainsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_registrarDomainList(t *testing.T) { service.EXPECT().GetDomains(gomock.Any()).Return([]registrar.Domain{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving domains: test error\n", func() { - registrarDomainList(service, &cobra.Command{}, []string{}) - }) + err := registrarDomainList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving domains: test error", err.Error()) }) } func Test_registrarDomainShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := registrarDomainShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := registrarDomainShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := registrarDomainShowCmd().Args(nil, []string{}) + err := registrarDomainShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/registrar_whois.go b/cmd/registrar/registrar_whois.go similarity index 71% rename from cmd/registrar_whois.go rename to cmd/registrar/registrar_whois.go index 25aa845..86a2bd3 100644 --- a/cmd/registrar_whois.go +++ b/cmd/registrar/registrar_whois.go @@ -1,27 +1,28 @@ -package cmd +package registrar import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/registrar" ) -func registrarWhoisRootCmd() *cobra.Command { +func registrarWhoisRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "whois", Short: "sub-commands relating to whois", } // Child commands - cmd.AddCommand(registrarWhoisShowCmd()) + cmd.AddCommand(registrarWhoisShowCmd(f)) return cmd } -func registrarWhoisShowCmd() *cobra.Command { +func registrarWhoisShowCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "show ...", Short: "Shows whois for a domain", @@ -34,13 +35,14 @@ func registrarWhoisShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { raw, _ := cmd.Flags().GetBool("raw") if raw { - registrarWhoisShowRaw(getClient().RegistrarService(), cmd, args) - } else { - registrarWhoisShow(getClient().RegistrarService(), cmd, args) + registrarWhoisShowRaw(f.NewClient().RegistrarService(), cmd, args) + return nil } + + return registrarWhoisShow(f.NewClient().RegistrarService(), cmd, args) }, } @@ -49,7 +51,7 @@ func registrarWhoisShowCmd() *cobra.Command { return cmd } -func registrarWhoisShow(service registrar.RegistrarService, cmd *cobra.Command, args []string) { +func registrarWhoisShow(service registrar.RegistrarService, cmd *cobra.Command, args []string) error { var whoisArr []registrar.Whois for _, arg := range args { whois, err := service.GetWhois(arg) @@ -61,7 +63,7 @@ func registrarWhoisShow(service registrar.RegistrarService, cmd *cobra.Command, whoisArr = append(whoisArr, whois) } - outputRegistrarWhois(whoisArr) + return output.CommandOutput(cmd, OutputRegistrarWhoisProvider(whoisArr)) } func registrarWhoisShowRaw(service registrar.RegistrarService, cmd *cobra.Command, args []string) { diff --git a/cmd/registrar_whois_test.go b/cmd/registrar/registrar_whois_test.go similarity index 94% rename from cmd/registrar_whois_test.go rename to cmd/registrar/registrar_whois_test.go index 310c2bd..6929693 100644 --- a/cmd/registrar_whois_test.go +++ b/cmd/registrar/registrar_whois_test.go @@ -1,4 +1,4 @@ -package cmd +package registrar import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_registrarWhoisShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := registrarWhoisShowCmd().Args(nil, []string{"testdomain1.co.uk"}) + err := registrarWhoisShowCmd(nil).Args(nil, []string{"testdomain1.co.uk"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := registrarWhoisShowCmd().Args(nil, []string{}) + err := registrarWhoisShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing domain", err.Error()) diff --git a/cmd/root.go b/cmd/root.go index 4b31d7f..1982fb2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,10 +1,8 @@ package cmd import ( - "crypto/tls" + "errors" "fmt" - "net/http" - "time" "github.com/blang/semver" homedir "github.com/mitchellh/go-homedir" @@ -12,11 +10,18 @@ import ( "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/viper" + accountcmd "github.com/ukfast/cli/cmd/account" + ddosxcmd "github.com/ukfast/cli/cmd/ddosx" + ecloudcmd "github.com/ukfast/cli/cmd/ecloud" + loadtestcmd "github.com/ukfast/cli/cmd/loadtest" + psscmd "github.com/ukfast/cli/cmd/pss" + registrarcmd "github.com/ukfast/cli/cmd/registrar" + safednscmd "github.com/ukfast/cli/cmd/safedns" + sslcmd "github.com/ukfast/cli/cmd/ssl" + storagecmd "github.com/ukfast/cli/cmd/storage" "github.com/ukfast/cli/internal/pkg/build" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" - apiclient "github.com/ukfast/sdk-go/pkg/client" - "github.com/ukfast/sdk-go/pkg/connection" - "github.com/ukfast/sdk-go/pkg/logging" ) var flagConfig string @@ -43,16 +48,6 @@ func Execute(build build.BuildInfo) { rootCmd.SilenceErrors = true rootCmd.SilenceUsage = true - if err := rootCmd.Execute(); err != nil { - output.Fatal(err.Error()) - } - - output.ExitWithErrorLevel() -} - -func init() { - cobra.OnInitialize(initConfig) - // Global flags rootCmd.PersistentFlags().StringVar(&flagConfig, "config", "", "config file (default is $HOME/.ukfast.yaml)") rootCmd.PersistentFlags().StringVarP(&flagFormat, "format", "f", "", "output format {table, json, template, value, csv, list}") @@ -61,22 +56,35 @@ func init() { rootCmd.PersistentFlags().StringSliceVar(&flagProperty, "property", []string{}, "property to output (used with several formats), can be repeated") rootCmd.PersistentFlags().StringArrayVar(&flagFilter, "filter", []string{}, "filter for list commands, can be repeated, e.g. 'property=somevalue', 'property:gt=3', 'property=valu*'") + initConfig() + + appFilesystem = afero.NewOsFs() + + clientFactory, err := getClientFactory() + if err != nil { + output.Fatal(err.Error()) + } + // Child commands rootCmd.AddCommand(updateCmd()) // Child root commands - rootCmd.AddCommand(completionRootCmd()) - rootCmd.AddCommand(safednsRootCmd()) - rootCmd.AddCommand(ecloudRootCmd()) - rootCmd.AddCommand(sslRootCmd()) - rootCmd.AddCommand(ddosxRootCmd()) - rootCmd.AddCommand(accountRootCmd()) - rootCmd.AddCommand(registrarRootCmd()) - rootCmd.AddCommand(pssRootCmd()) - rootCmd.AddCommand(storageRootCmd()) - rootCmd.AddCommand(loadtestRootCmd()) + rootCmd.AddCommand(CompletionRootCmd()) + rootCmd.AddCommand(accountcmd.AccountRootCmd(clientFactory)) + rootCmd.AddCommand(ddosxcmd.DDoSXRootCmd(clientFactory, appFilesystem)) + rootCmd.AddCommand(ecloudcmd.ECloudRootCmd(clientFactory)) + rootCmd.AddCommand(loadtestcmd.LoadTestRootCmd(clientFactory)) + rootCmd.AddCommand(psscmd.PSSRootCmd(clientFactory, appFilesystem)) + rootCmd.AddCommand(registrarcmd.RegistrarRootCmd(clientFactory)) + rootCmd.AddCommand(safednscmd.SafeDNSRootCmd(clientFactory)) + rootCmd.AddCommand(sslcmd.SSLRootCmd(clientFactory)) + rootCmd.AddCommand(storagecmd.StorageRootCmd(clientFactory)) - appFilesystem = afero.NewOsFs() + if err := rootCmd.Execute(); err != nil { + output.Fatal(err.Error()) + } + + output.ExitWithErrorLevel() } // initConfig reads in config file and ENV variables if set. @@ -107,45 +115,20 @@ func initConfig() { viper.ReadInConfig() } -func getClient() apiclient.Client { +func getClientFactory() (factory.ClientFactory, error) { apiKey := viper.GetString("api_key") if apiKey == "" { - output.Fatal("UKF_API_KEY not set") - } - - apiTimeout := viper.GetInt("api_timeout_seconds") - apiURI := viper.GetString("api_uri") - apiInsecure := viper.GetBool("api_insecure") - apiHeaders := viper.GetStringMapString("api_headers") - apiDebug := viper.GetBool("api_debug") - - conn := connection.NewAPIConnection(&connection.APIKeyCredentials{APIKey: apiKey}) - conn.UserAgent = "ukfast-cli" - if apiURI != "" { - conn.APIURI = apiURI - } - if apiTimeout > 0 { - conn.HTTPClient.Timeout = (time.Duration(apiTimeout) * time.Second) - } - if apiInsecure { - conn.HTTPClient.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - } - } - if apiHeaders != nil { - conn.Headers = http.Header{} - for headerKey, headerValue := range apiHeaders { - conn.Headers.Add(headerKey, headerValue) - } - } - - if apiDebug { - logging.SetLogger(&output.DebugLogger{}) + return nil, errors.New("UKF_API_KEY not set") } - return apiclient.NewClient(conn) + return factory.NewUKFastClientFactory( + factory.WithAPIKey(apiKey), + factory.WithTimeout(viper.GetInt("api_timeout_seconds")), + factory.WithURI(viper.GetString("api_uri")), + factory.WithInsecure(viper.GetBool("api_insecure")), + factory.WithHeaders(viper.GetStringMapString("api_headers")), + factory.WithDebug(viper.GetBool("api_debug")), + ), nil } func updateCmd() *cobra.Command { diff --git a/cmd/safedns.go b/cmd/safedns.go deleted file mode 100644 index 1b55d80..0000000 --- a/cmd/safedns.go +++ /dev/null @@ -1,273 +0,0 @@ -package cmd - -import ( - "fmt" - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/cli/internal/pkg/resource" - "github.com/ukfast/sdk-go/pkg/connection" - "github.com/ukfast/sdk-go/pkg/service/safedns" -) - -func safednsRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "safedns", - Short: "Commands relating to SafeDNS service", - } - - // Child root commands - cmd.AddCommand(safednsZoneRootCmd()) - cmd.AddCommand(safednsZoneRecordRootCmd()) - cmd.AddCommand(safednsZoneNoteRootCmd()) - cmd.AddCommand(safednsTemplateRootCmd()) - cmd.AddCommand(safednsSettingsRootCmd()) - - return cmd -} - -type SafeDNSTemplateLocatorProvider struct { - service safedns.SafeDNSService -} - -func NewSafeDNSTemplateLocatorProvider(service safedns.SafeDNSService) *SafeDNSTemplateLocatorProvider { - return &SafeDNSTemplateLocatorProvider{service: service} -} - -func (p *SafeDNSTemplateLocatorProvider) SupportedProperties() []string { - return []string{"name"} -} - -func (p *SafeDNSTemplateLocatorProvider) Locate(property string, value string) (interface{}, error) { - params := connection.APIRequestParameters{} - params.WithFilter(connection.APIRequestFiltering{Property: property, Operator: connection.EQOperator, Value: []string{value}}) - - return p.service.GetTemplates(params) -} - -func getSafeDNSTemplateByNameOrID(service safedns.SafeDNSService, nameOrID string) (safedns.Template, error) { - templateID, err := strconv.Atoi(nameOrID) - if err != nil { - locator := resource.NewResourceLocator(NewSafeDNSTemplateLocatorProvider(service)) - - template, err := locator.Invoke(nameOrID) - if err != nil { - return safedns.Template{}, fmt.Errorf("Error locating template [%s]: %s", nameOrID, err) - } - - return template.(safedns.Template), nil - } - - template, err := service.GetTemplate(templateID) - if err != nil { - return safedns.Template{}, fmt.Errorf("Error retrieving template by ID [%d]: %s", templateID, err) - } - - return template, nil -} - -func getSafeDNSTemplateIDByNameOrID(service safedns.SafeDNSService, nameOrID string) (int, error) { - templateID, err := strconv.Atoi(nameOrID) - if err != nil { - locator := resource.NewResourceLocator(NewSafeDNSTemplateLocatorProvider(service)) - - template, err := locator.Invoke(nameOrID) - if err != nil { - return 0, fmt.Errorf("Error locating template [%s]: %s", nameOrID, err) - } - - return template.(safedns.Template).ID, nil - } - - return templateID, nil -} - -// OutputSafeDNSZones implements OutputDataProvider for outputting an array of Zones -type OutputSafeDNSZones struct { - Zones []safedns.Zone -} - -func outputSafeDNSZones(zones []safedns.Zone) { - err := Output(&OutputSafeDNSZones{Zones: zones}) - if err != nil { - output.Fatalf("Failed to output zones: %s", err) - } -} - -func (o *OutputSafeDNSZones) GetData() interface{} { - return o.Zones -} - -func (o *OutputSafeDNSZones) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, zone := range o.Zones { - fields := o.getOrderedFields(zone) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSafeDNSZones) getOrderedFields(zone safedns.Zone) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("name", output.NewFieldValue(zone.Name, true)) - fields.Set("description", output.NewFieldValue(zone.Description, true)) - - return fields -} - -// OutputSafeDNSRecords implements OutputDataProvider for outputting an array of Records -type OutputSafeDNSRecords struct { - Records []safedns.Record -} - -func outputSafeDNSRecords(records []safedns.Record) { - err := Output(&OutputSafeDNSRecords{Records: records}) - if err != nil { - output.Fatalf("Failed to output records: %s", err) - } -} - -func (o *OutputSafeDNSRecords) GetData() interface{} { - return o.Records -} - -func (o *OutputSafeDNSRecords) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, record := range o.Records { - OutputSafeDNSRecords := o.getOrderedFields(record) - data = append(data, OutputSafeDNSRecords) - } - - return data, nil -} - -func (o *OutputSafeDNSRecords) getOrderedFields(record safedns.Record) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(record.ID), true)) - fields.Set("name", output.NewFieldValue(record.Name, true)) - fields.Set("type", output.NewFieldValue(record.Type.String(), true)) - fields.Set("content", output.NewFieldValue(record.Content, true)) - fields.Set("updated_at", output.NewFieldValue(record.UpdatedAt.String(), true)) - fields.Set("priority", output.NewFieldValue(strconv.Itoa(record.Priority), true)) - fields.Set("ttl", output.NewFieldValue(strconv.Itoa(int(record.TTL)), true)) - - return fields -} - -// OutputSafeDNSNotes implements OutputDataProvider for outputting an array of Notes -type OutputSafeDNSNotes struct { - Notes []safedns.Note -} - -func outputSafeDNSNotes(notes []safedns.Note) { - err := Output(&OutputSafeDNSNotes{Notes: notes}) - if err != nil { - output.Fatalf("Failed to output notes: %s", err) - } -} - -func (o *OutputSafeDNSNotes) GetData() interface{} { - return o.Notes -} - -func (o *OutputSafeDNSNotes) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, note := range o.Notes { - fields := o.getOrderedFields(note) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSafeDNSNotes) getOrderedFields(note safedns.Note) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(note.ID), true)) - fields.Set("notes", output.NewFieldValue(note.Notes, true)) - fields.Set("ip", output.NewFieldValue(note.IP.String(), true)) - - return fields -} - -// OutputSafeDNSTemplates implements OutputDataProvider for outputting an array of Templates -type OutputSafeDNSTemplates struct { - Templates []safedns.Template -} - -func outputSafeDNSTemplates(templates []safedns.Template) { - err := Output(&OutputSafeDNSTemplates{Templates: templates}) - if err != nil { - output.Fatalf("Failed to output templates: %s", err) - } -} - -func (o *OutputSafeDNSTemplates) GetData() interface{} { - return o.Templates -} - -func (o *OutputSafeDNSTemplates) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, template := range o.Templates { - fields := o.getOrderedFields(template) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSafeDNSTemplates) getOrderedFields(template safedns.Template) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(template.ID), true)) - fields.Set("name", output.NewFieldValue(template.Name, true)) - fields.Set("default", output.NewFieldValue(strconv.FormatBool(template.Default), true)) - fields.Set("created_at", output.NewFieldValue(template.CreatedAt.String(), true)) - - return fields -} - -// OutputSafeDNSSettings implements OutputDataProvider for outputting an array of Settings -type OutputSafeDNSSettings struct { - Settings []safedns.Settings -} - -func outputSafeDNSSettings(settings []safedns.Settings) { - err := Output(&OutputSafeDNSSettings{Settings: settings}) - if err != nil { - output.Fatalf("Failed to output settings: %s", err) - } -} - -func (o *OutputSafeDNSSettings) GetData() interface{} { - return o.Settings -} - -func (o *OutputSafeDNSSettings) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, settings := range o.Settings { - fields := o.getOrderedFields(settings) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSafeDNSSettings) getOrderedFields(settings safedns.Settings) *output.OrderedFields { - nameservers := []string{} - for _, nameserver := range settings.Nameservers { - nameservers = append(nameservers, nameserver.Name) - } - - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(settings.ID), true)) - fields.Set("email", output.NewFieldValue(settings.Email, false)) - fields.Set("nameservers", output.NewFieldValue(strings.Join(nameservers, ", "), false)) - fields.Set("custom_soa_allowed", output.NewFieldValue(strconv.FormatBool(settings.CustomSOAAllowed), true)) - fields.Set("custom_base_ns_allowed", output.NewFieldValue(strconv.FormatBool(settings.CustomBaseNSAllowed), true)) - fields.Set("delegation_allowed", output.NewFieldValue(strconv.FormatBool(settings.DelegationAllowed), true)) - fields.Set("product", output.NewFieldValue(settings.Product, true)) - - return fields -} diff --git a/cmd/safedns/output.go b/cmd/safedns/output.go new file mode 100644 index 0000000..422d518 --- /dev/null +++ b/cmd/safedns/output.go @@ -0,0 +1,117 @@ +package safedns + +import ( + "strconv" + "strings" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/safedns" +) + +func OutputSafeDNSZonesProvider(zones []safedns.Zone) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(zones), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, zone := range zones { + fields := output.NewOrderedFields() + fields.Set("name", output.NewFieldValue(zone.Name, true)) + fields.Set("description", output.NewFieldValue(zone.Description, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSafeDNSRecordsProvider(records []safedns.Record) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(records), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, record := range records { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(record.ID), true)) + fields.Set("name", output.NewFieldValue(record.Name, true)) + fields.Set("type", output.NewFieldValue(record.Type.String(), true)) + fields.Set("content", output.NewFieldValue(record.Content, true)) + fields.Set("updated_at", output.NewFieldValue(record.UpdatedAt.String(), true)) + fields.Set("priority", output.NewFieldValue(strconv.Itoa(record.Priority), true)) + fields.Set("ttl", output.NewFieldValue(strconv.Itoa(int(record.TTL)), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSafeDNSNotesProvider(notes []safedns.Note) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(notes), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, note := range notes { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(note.ID), true)) + fields.Set("notes", output.NewFieldValue(note.Notes, true)) + fields.Set("ip", output.NewFieldValue(note.IP.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSafeDNSTemplatesProvider(templates []safedns.Template) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(templates), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, template := range templates { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(template.ID), true)) + fields.Set("name", output.NewFieldValue(template.Name, true)) + fields.Set("default", output.NewFieldValue(strconv.FormatBool(template.Default), true)) + fields.Set("created_at", output.NewFieldValue(template.CreatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSafeDNSSettingsProvider(settings []safedns.Settings) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(settings), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, setting := range settings { + nameservers := []string{} + for _, nameserver := range setting.Nameservers { + nameservers = append(nameservers, nameserver.Name) + } + + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(setting.ID), true)) + fields.Set("email", output.NewFieldValue(setting.Email, false)) + fields.Set("nameservers", output.NewFieldValue(strings.Join(nameservers, ", "), false)) + fields.Set("custom_soa_allowed", output.NewFieldValue(strconv.FormatBool(setting.CustomSOAAllowed), true)) + fields.Set("custom_base_ns_allowed", output.NewFieldValue(strconv.FormatBool(setting.CustomBaseNSAllowed), true)) + fields.Set("delegation_allowed", output.NewFieldValue(strconv.FormatBool(setting.DelegationAllowed), true)) + fields.Set("product", output.NewFieldValue(setting.Product, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/safedns/safedns.go b/cmd/safedns/safedns.go new file mode 100644 index 0000000..5763390 --- /dev/null +++ b/cmd/safedns/safedns.go @@ -0,0 +1,84 @@ +package safedns + +import ( + "fmt" + "strconv" + + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/resource" + "github.com/ukfast/sdk-go/pkg/connection" + "github.com/ukfast/sdk-go/pkg/service/safedns" +) + +func SafeDNSRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "safedns", + Short: "Commands relating to SafeDNS service", + } + + // Child root commands + cmd.AddCommand(safednsZoneRootCmd(f)) + cmd.AddCommand(safednsZoneRecordRootCmd(f)) + cmd.AddCommand(safednsZoneNoteRootCmd(f)) + cmd.AddCommand(safednsTemplateRootCmd(f)) + cmd.AddCommand(safednsSettingsRootCmd(f)) + + return cmd +} + +type SafeDNSTemplateLocatorProvider struct { + service safedns.SafeDNSService +} + +func NewSafeDNSTemplateLocatorProvider(service safedns.SafeDNSService) *SafeDNSTemplateLocatorProvider { + return &SafeDNSTemplateLocatorProvider{service: service} +} + +func (p *SafeDNSTemplateLocatorProvider) SupportedProperties() []string { + return []string{"name"} +} + +func (p *SafeDNSTemplateLocatorProvider) Locate(property string, value string) (interface{}, error) { + params := connection.APIRequestParameters{} + params.WithFilter(connection.APIRequestFiltering{Property: property, Operator: connection.EQOperator, Value: []string{value}}) + + return p.service.GetTemplates(params) +} + +func getSafeDNSTemplateByNameOrID(service safedns.SafeDNSService, nameOrID string) (safedns.Template, error) { + templateID, err := strconv.Atoi(nameOrID) + if err != nil { + locator := resource.NewResourceLocator(NewSafeDNSTemplateLocatorProvider(service)) + + template, err := locator.Invoke(nameOrID) + if err != nil { + return safedns.Template{}, fmt.Errorf("Error locating template [%s]: %s", nameOrID, err) + } + + return template.(safedns.Template), nil + } + + template, err := service.GetTemplate(templateID) + if err != nil { + return safedns.Template{}, fmt.Errorf("Error retrieving template by ID [%d]: %s", templateID, err) + } + + return template, nil +} + +func getSafeDNSTemplateIDByNameOrID(service safedns.SafeDNSService, nameOrID string) (int, error) { + templateID, err := strconv.Atoi(nameOrID) + if err != nil { + locator := resource.NewResourceLocator(NewSafeDNSTemplateLocatorProvider(service)) + + template, err := locator.Invoke(nameOrID) + if err != nil { + return 0, fmt.Errorf("Error locating template [%s]: %s", nameOrID, err) + } + + return template.(safedns.Template).ID, nil + } + + return templateID, nil +} diff --git a/cmd/safedns_settings.go b/cmd/safedns/safedns_settings.go similarity index 60% rename from cmd/safedns_settings.go rename to cmd/safedns/safedns_settings.go index 8b524d5..b6a2999 100644 --- a/cmd/safedns_settings.go +++ b/cmd/safedns/safedns_settings.go @@ -1,32 +1,34 @@ -package cmd +package safedns import ( "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" + "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsSettingsRootCmd() *cobra.Command { +func safednsSettingsRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "settings", Short: "sub-commands relating to settings", } // Child commands - cmd.AddCommand(safednsSettingsShowCmd()) + cmd.AddCommand(safednsSettingsShowCmd(f)) return cmd } -func safednsSettingsShowCmd() *cobra.Command { +func safednsSettingsShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show", Short: "Shows settings for account", Long: "This command shows SafeDNS settings for account", Example: "ukfast safedns settings show", RunE: func(cmd *cobra.Command, args []string) error { - return safednsSettingsShow(getClient().SafeDNSService(), cmd, args) + return safednsSettingsShow(f.NewClient().SafeDNSService(), cmd, args) }, } } @@ -37,6 +39,5 @@ func safednsSettingsShow(service safedns.SafeDNSService, cmd *cobra.Command, arg return fmt.Errorf("Error retrieving settings: %s", err) } - outputSafeDNSSettings([]safedns.Settings{settings}) - return nil + return output.CommandOutput(cmd, OutputSafeDNSSettingsProvider([]safedns.Settings{settings})) } diff --git a/cmd/safedns_settings_test.go b/cmd/safedns/safedns_settings_test.go similarity index 98% rename from cmd/safedns_settings_test.go rename to cmd/safedns/safedns_settings_test.go index 1a5c9c1..7f43a69 100644 --- a/cmd/safedns_settings_test.go +++ b/cmd/safedns/safedns_settings_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" diff --git a/cmd/safedns_template.go b/cmd/safedns/safedns_template.go similarity index 70% rename from cmd/safedns_template.go rename to cmd/safedns/safedns_template.go index 2f02bcf..d931d96 100644 --- a/cmd/safedns_template.go +++ b/cmd/safedns/safedns_template.go @@ -1,42 +1,44 @@ -package cmd +package safedns import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsTemplateRootCmd() *cobra.Command { +func safednsTemplateRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "template", Short: "sub-commands relating to templates", } // Child commands - cmd.AddCommand(safednsTemplateListCmd()) - cmd.AddCommand(safednsTemplateShowCmd()) - cmd.AddCommand(safednsTemplateCreateCmd()) - cmd.AddCommand(safednsTemplateUpdateCmd()) - cmd.AddCommand(safednsTemplateDeleteCmd()) + cmd.AddCommand(safednsTemplateListCmd(f)) + cmd.AddCommand(safednsTemplateShowCmd(f)) + cmd.AddCommand(safednsTemplateCreateCmd(f)) + cmd.AddCommand(safednsTemplateUpdateCmd(f)) + cmd.AddCommand(safednsTemplateDeleteCmd(f)) // Child root commands - cmd.AddCommand(safednsTemplateRecordRootCmd()) + cmd.AddCommand(safednsTemplateRecordRootCmd(f)) return cmd } -func safednsTemplateListCmd() *cobra.Command { +func safednsTemplateListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "Lists templates", Long: "This command lists templates", Example: "ukfast safedns template list", - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateList(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateList(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -45,11 +47,10 @@ func safednsTemplateListCmd() *cobra.Command { return cmd } -func safednsTemplateList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -59,15 +60,14 @@ func safednsTemplateList(service safedns.SafeDNSService, cmd *cobra.Command, arg templates, err := service.GetTemplates(params) if err != nil { - output.Fatalf("Error retrieving templates: %s", err) - return + return fmt.Errorf("Error retrieving templates: %s", err) } - outputSafeDNSTemplates(templates) + return output.CommandOutput(cmd, OutputSafeDNSTemplatesProvider(templates)) } -func safednsTemplateShowCmd() *cobra.Command { +func safednsTemplateShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a template", @@ -80,13 +80,13 @@ func safednsTemplateShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateShow(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateShow(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsTemplateShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { var templates []safedns.Template for _, arg := range args { template, err := getSafeDNSTemplateByNameOrID(service, arg) @@ -98,17 +98,17 @@ func safednsTemplateShow(service safedns.SafeDNSService, cmd *cobra.Command, arg templates = append(templates, template) } - outputSafeDNSTemplates(templates) + return output.CommandOutput(cmd, OutputSafeDNSTemplatesProvider(templates)) } -func safednsTemplateCreateCmd() *cobra.Command { +func safednsTemplateCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a template", Long: "This command creates a template", Example: "ukfast safedns template create --name \"main template\"", - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateCreate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateCreate(f.NewClient().SafeDNSService(), cmd, args) }, } cmd.Flags().String("name", "", "Name of template") @@ -118,7 +118,7 @@ func safednsTemplateCreateCmd() *cobra.Command { return cmd } -func safednsTemplateCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateName, _ := cmd.Flags().GetString("name") templateDefault, _ := cmd.Flags().GetBool("default") @@ -129,20 +129,18 @@ func safednsTemplateCreate(service safedns.SafeDNSService, cmd *cobra.Command, a id, err := service.CreateTemplate(createRequest) if err != nil { - output.Fatalf("Error creating template: %s", err) - return + return fmt.Errorf("Error creating template: %s", err) } template, err := service.GetTemplate(id) if err != nil { - output.Fatalf("Error retrieving new template: %s", err) - return + return fmt.Errorf("Error retrieving new template: %s", err) } - outputSafeDNSTemplates([]safedns.Template{template}) + return output.CommandOutput(cmd, OutputSafeDNSTemplatesProvider([]safedns.Template{template})) } -func safednsTemplateUpdateCmd() *cobra.Command { +func safednsTemplateUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a template", @@ -155,8 +153,8 @@ func safednsTemplateUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateUpdate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateUpdate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -166,7 +164,7 @@ func safednsTemplateUpdateCmd() *cobra.Command { return cmd } -func safednsTemplateUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { patchRequest := safedns.PatchTemplateRequest{} if cmd.Flags().Changed("name") { @@ -202,10 +200,10 @@ func safednsTemplateUpdate(service safedns.SafeDNSService, cmd *cobra.Command, a templates = append(templates, template) } - outputSafeDNSTemplates(templates) + return output.CommandOutput(cmd, OutputSafeDNSTemplatesProvider(templates)) } -func safednsTemplateDeleteCmd() *cobra.Command { +func safednsTemplateDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Removes a template", @@ -219,7 +217,7 @@ func safednsTemplateDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - safednsTemplateDelete(getClient().SafeDNSService(), cmd, args) + safednsTemplateDelete(f.NewClient().SafeDNSService(), cmd, args) }, } } diff --git a/cmd/safedns_template_record.go b/cmd/safedns/safedns_template_record.go similarity index 76% rename from cmd/safedns_template_record.go rename to cmd/safedns/safedns_template_record.go index dc88623..3067716 100644 --- a/cmd/safedns_template_record.go +++ b/cmd/safedns/safedns_template_record.go @@ -1,33 +1,35 @@ -package cmd +package safedns import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsTemplateRecordRootCmd() *cobra.Command { +func safednsTemplateRecordRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "record", Short: "sub-commands relating to template records", } // Child commands - cmd.AddCommand(safednsTemplateRecordListCmd()) - cmd.AddCommand(safednsTemplateRecordShowCmd()) - cmd.AddCommand(safednsTemplateRecordCreateCmd()) - cmd.AddCommand(safednsTemplateRecordUpdateCmd()) - cmd.AddCommand(safednsTemplateRecordDeleteCmd()) + cmd.AddCommand(safednsTemplateRecordListCmd(f)) + cmd.AddCommand(safednsTemplateRecordShowCmd(f)) + cmd.AddCommand(safednsTemplateRecordCreateCmd(f)) + cmd.AddCommand(safednsTemplateRecordUpdateCmd(f)) + cmd.AddCommand(safednsTemplateRecordDeleteCmd(f)) return cmd } -func safednsTemplateRecordListCmd() *cobra.Command { +func safednsTemplateRecordListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list ", Short: "Lists template records", @@ -40,8 +42,8 @@ func safednsTemplateRecordListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateRecordList(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateRecordList(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -52,17 +54,15 @@ func safednsTemplateRecordListCmd() *cobra.Command { return cmd } -func safednsTemplateRecordList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateRecordList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateID, err := getSafeDNSTemplateIDByNameOrID(service, args[0]) if err != nil { - output.Fatal(err.Error()) - return + return err } params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -82,13 +82,13 @@ func safednsTemplateRecordList(service safedns.SafeDNSService, cmd *cobra.Comman templateRecords, err := service.GetTemplateRecords(templateID, params) if err != nil { - output.Fatalf("Error retrieving records for template: %s", err) + return fmt.Errorf("Error retrieving records for template: %s", err) } - outputSafeDNSRecords(templateRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(templateRecords)) } -func safednsTemplateRecordShowCmd() *cobra.Command { +func safednsTemplateRecordShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a template record", @@ -104,17 +104,16 @@ func safednsTemplateRecordShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateRecordShow(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateRecordShow(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsTemplateRecordShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateRecordShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateID, err := getSafeDNSTemplateIDByNameOrID(service, args[0]) if err != nil { - output.Fatal(err.Error()) - return + return err } var templateRecords []safedns.Record @@ -135,10 +134,10 @@ func safednsTemplateRecordShow(service safedns.SafeDNSService, cmd *cobra.Comman templateRecords = append(templateRecords, templateRecord) } - outputSafeDNSRecords(templateRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(templateRecords)) } -func safednsTemplateRecordCreateCmd() *cobra.Command { +func safednsTemplateRecordCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a template record", @@ -151,8 +150,8 @@ func safednsTemplateRecordCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateRecordCreate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateRecordCreate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -169,11 +168,10 @@ func safednsTemplateRecordCreateCmd() *cobra.Command { return cmd } -func safednsTemplateRecordCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateRecordCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateID, err := getSafeDNSTemplateIDByNameOrID(service, args[0]) if err != nil { - output.Fatal(err.Error()) - return + return err } recordName, _ := cmd.Flags().GetString("name") @@ -193,20 +191,18 @@ func safednsTemplateRecordCreate(service safedns.SafeDNSService, cmd *cobra.Comm id, err := service.CreateTemplateRecord(templateID, createRequest) if err != nil { - output.Fatalf("Error creating record: %s", err) - return + return fmt.Errorf("Error creating record: %s", err) } templateRecord, err := service.GetTemplateRecord(templateID, id) if err != nil { - output.Fatalf("Error retrieving new record: %s", err) - return + return fmt.Errorf("Error retrieving new record: %s", err) } - outputSafeDNSRecords([]safedns.Record{templateRecord}) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider([]safedns.Record{templateRecord})) } -func safednsTemplateRecordUpdateCmd() *cobra.Command { +func safednsTemplateRecordUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a template record", @@ -222,8 +218,8 @@ func safednsTemplateRecordUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateRecordUpdate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateRecordUpdate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -235,11 +231,10 @@ func safednsTemplateRecordUpdateCmd() *cobra.Command { return cmd } -func safednsTemplateRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateID, err := getSafeDNSTemplateIDByNameOrID(service, args[0]) if err != nil { - output.Fatal(err.Error()) - return + return err } patchRequest := safedns.PatchRecordRequest{} @@ -285,10 +280,10 @@ func safednsTemplateRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Comm templateRecords = append(templateRecords, templateRecord) } - outputSafeDNSRecords(templateRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(templateRecords)) } -func safednsTemplateRecordDeleteCmd() *cobra.Command { +func safednsTemplateRecordDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Removes a template record", @@ -304,17 +299,16 @@ func safednsTemplateRecordDeleteCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsTemplateRecordDelete(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsTemplateRecordDelete(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsTemplateRecordDelete(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsTemplateRecordDelete(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { templateID, err := getSafeDNSTemplateIDByNameOrID(service, args[0]) if err != nil { - output.Fatal(err.Error()) - return + return err } for _, arg := range args[1:] { @@ -329,4 +323,6 @@ func safednsTemplateRecordDelete(service safedns.SafeDNSService, cmd *cobra.Comm output.OutputWithErrorLevelf("Error removing record [%d]: %s", recordID, err) } } + + return nil } diff --git a/cmd/safedns_template_record_test.go b/cmd/safedns/safedns_template_record_test.go similarity index 84% rename from cmd/safedns_template_record_test.go rename to cmd/safedns/safedns_template_record_test.go index b081a3a..af173c2 100644 --- a/cmd/safedns_template_record_test.go +++ b/cmd/safedns/safedns_template_record_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/connection" @@ -16,14 +17,14 @@ import ( func Test_safednsTemplateRecordListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsTemplateRecordListCmd() + cmd := safednsTemplateRecordListCmd(nil) err := cmd.Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - cmd := safednsTemplateRecordListCmd() + cmd := safednsTemplateRecordListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -72,7 +73,7 @@ func Test_safednsTemplateRecordList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateRecordListCmd() + cmd := safednsTemplateRecordListCmd(nil) cmd.Flags().Set("name", "test.testdomain1.co.uk") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -102,7 +103,7 @@ func Test_safednsTemplateRecordList(t *testing.T) { safednsTemplateRecordList(service, cmd, []string{"123"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -110,12 +111,12 @@ func Test_safednsTemplateRecordList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - safednsTemplateRecordList(service, cmd, []string{"123"}) - }) + err := safednsTemplateRecordList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -124,12 +125,12 @@ func Test_safednsTemplateRecordList(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error locating template [test template 1]: Error retrieving items: test error\n", func() { - safednsTemplateRecordList(service, &cobra.Command{}, []string{"test template 1"}) - }) + err := safednsTemplateRecordList(service, &cobra.Command{}, []string{"test template 1"}) + + assert.Equal(t, "Error locating template [test template 1]: Error retrieving items: test error", err.Error()) }) - t.Run("GetTemplateRecordsError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplateRecordsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -138,22 +139,22 @@ func Test_safednsTemplateRecordList(t *testing.T) { service.EXPECT().GetTemplateRecords(123, gomock.Any()).Return([]safedns.Record{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving records for template: test error\n", func() { - safednsTemplateRecordList(service, &cobra.Command{}, []string{"123"}) - }) + err := safednsTemplateRecordList(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving records for template: test error", err.Error()) }) } func Test_safednsTemplateRecordShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsTemplateRecordShowCmd() + cmd := safednsTemplateRecordShowCmd(nil) err := cmd.Args(nil, []string{"123", "456"}) assert.Nil(t, err) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - cmd := safednsTemplateRecordShowCmd() + cmd := safednsTemplateRecordShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -161,7 +162,7 @@ func Test_safednsTemplateRecordShowCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsTemplateRecordShowCmd() + cmd := safednsTemplateRecordShowCmd(nil) err := cmd.Args(nil, []string{"123"}) assert.NotNil(t, err) @@ -219,7 +220,7 @@ func Test_safednsTemplateRecordShow(t *testing.T) { safednsTemplateRecordShow(service, &cobra.Command{}, []string{"test template 1", "456"}) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -228,9 +229,9 @@ func Test_safednsTemplateRecordShow(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error locating template [test template 1]: Error retrieving items: test error\n", func() { - safednsTemplateRecordShow(service, &cobra.Command{}, []string{"test template 1"}) - }) + err := safednsTemplateRecordShow(service, &cobra.Command{}, []string{"test template 1"}) + + assert.Equal(t, "Error locating template [test template 1]: Error retrieving items: test error", err.Error()) }) t.Run("InvalidRecordID_OutputsError", func(t *testing.T) { @@ -260,14 +261,14 @@ func Test_safednsTemplateRecordShow(t *testing.T) { func Test_safednsTemplateRecordCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsTemplateRecordCreateCmd() + cmd := safednsTemplateRecordCreateCmd(nil) err := cmd.Args(nil, []string{"123", "456"}) assert.Nil(t, err) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - cmd := safednsTemplateRecordCreateCmd() + cmd := safednsTemplateRecordCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -281,7 +282,7 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateRecordCreateCmd() + cmd := safednsTemplateRecordCreateCmd(nil) cmd.Flags().Set("name", "test.testdomain.co.uk") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -305,7 +306,7 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateRecordCreateCmd() + cmd := safednsTemplateRecordCreateCmd(nil) cmd.Flags().Set("name", "test.testdomain.co.uk") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -337,7 +338,7 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { safednsTemplateRecordCreate(service, cmd, []string{"test template 1"}) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -346,12 +347,12 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error locating template [test template 1]: Error retrieving items: test error\n", func() { - safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"test template 1"}) - }) + err := safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"test template 1"}) + + assert.Equal(t, "Error locating template [test template 1]: Error retrieving items: test error", err.Error()) }) - t.Run("CreateTemplateRecordError_OutputsFatal", func(t *testing.T) { + t.Run("CreateTemplateRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -362,12 +363,12 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { service.EXPECT().CreateTemplateRecord(123, gomock.Any()).Return(456, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error creating record: test error\n", func() { - safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"123"}) - }) + err := safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error creating record: test error", err.Error()) }) - t.Run("GetTemplateRecordError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplateRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -379,22 +380,22 @@ func Test_safednsTemplateRecordCreate(t *testing.T) { service.EXPECT().GetTemplateRecord(123, 456).Return(safedns.Record{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new record: test error\n", func() { - safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"123"}) - }) + err := safednsTemplateRecordCreate(service, &cobra.Command{}, []string{"123"}) + + assert.Equal(t, "Error retrieving new record: test error", err.Error()) }) } func Test_safednsTemplateRecordUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsTemplateRecordUpdateCmd() + cmd := safednsTemplateRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"123", "456"}) assert.Nil(t, err) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - cmd := safednsTemplateRecordUpdateCmd() + cmd := safednsTemplateRecordUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -402,7 +403,7 @@ func Test_safednsTemplateRecordUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsTemplateRecordUpdateCmd() + cmd := safednsTemplateRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"123"}) assert.NotNil(t, err) @@ -446,7 +447,7 @@ func Test_safednsTemplateRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateRecordUpdateCmd() + cmd := safednsTemplateRecordUpdateCmd(nil) cmd.Flags().Set("name", "test.testdomain.co.uk") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -489,7 +490,7 @@ func Test_safednsTemplateRecordUpdate(t *testing.T) { safednsTemplateRecordUpdate(service, &cobra.Command{}, []string{"test template 1", "456"}) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -498,9 +499,9 @@ func Test_safednsTemplateRecordUpdate(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error locating template [test template 1]: Error retrieving items: test error\n", func() { - safednsTemplateRecordUpdate(service, &cobra.Command{}, []string{"test template 1"}) - }) + err := safednsTemplateRecordUpdate(service, &cobra.Command{}, []string{"test template 1"}) + + assert.Equal(t, "Error locating template [test template 1]: Error retrieving items: test error", err.Error()) }) t.Run("InvalidRecordID_OutputsError", func(t *testing.T) { @@ -546,14 +547,14 @@ func Test_safednsTemplateRecordUpdate(t *testing.T) { func Test_safednsTemplateRecordDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsTemplateRecordDeleteCmd() + cmd := safednsTemplateRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"123", "456"}) assert.Nil(t, err) }) t.Run("MissingTemplate_Error", func(t *testing.T) { - cmd := safednsTemplateRecordDeleteCmd() + cmd := safednsTemplateRecordDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -561,7 +562,7 @@ func Test_safednsTemplateRecordDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsTemplateRecordDeleteCmd() + cmd := safednsTemplateRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"123"}) assert.NotNil(t, err) @@ -619,7 +620,7 @@ func Test_safednsTemplateRecordDelete(t *testing.T) { safednsTemplateRecordDelete(service, &cobra.Command{}, []string{"test template 1", "456"}) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -628,8 +629,8 @@ func Test_safednsTemplateRecordDelete(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error locating template [test template 1]: Error retrieving items: test error\n", func() { - safednsTemplateRecordDelete(service, &cobra.Command{}, []string{"test template 1"}) - }) + err := safednsTemplateRecordDelete(service, &cobra.Command{}, []string{"test template 1"}) + + assert.Equal(t, "Error locating template [test template 1]: Error retrieving items: test error", err.Error()) }) } diff --git a/cmd/safedns_template_test.go b/cmd/safedns/safedns_template_test.go similarity index 91% rename from cmd/safedns_template_test.go rename to cmd/safedns/safedns_template_test.go index a4d4a06..fdcbddf 100644 --- a/cmd/safedns_template_test.go +++ b/cmd/safedns/safedns_template_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/connection" @@ -30,7 +31,7 @@ func Test_safednsTemplateList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateListCmd() + cmd := safednsTemplateListCmd(nil) cmd.Flags().Set("name", "test template 1") expectedParams := connection.APIRequestParameters{ @@ -48,7 +49,7 @@ func Test_safednsTemplateList(t *testing.T) { safednsTemplateList(service, cmd, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -56,12 +57,12 @@ func Test_safednsTemplateList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - safednsTemplateList(service, cmd, []string{"123"}) - }) + err := safednsTemplateList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetTemplatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -70,21 +71,21 @@ func Test_safednsTemplateList(t *testing.T) { service.EXPECT().GetTemplates(gomock.Any()).Return([]safedns.Template{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving templates: test error\n", func() { - safednsTemplateList(service, &cobra.Command{}, []string{}) - }) + err := safednsTemplateList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving templates: test error", err.Error()) }) } func Test_safednsTemplateShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsTemplateShowCmd().Args(nil, []string{"test template 1"}) + err := safednsTemplateShowCmd(nil).Args(nil, []string{"test template 1"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsTemplateShowCmd().Args(nil, []string{}) + err := safednsTemplateShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -194,7 +195,7 @@ func Test_safednsTemplateCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateCreateCmd() + cmd := safednsTemplateCreateCmd(nil) cmd.Flags().Set("name", "test template 1") cmd.Flags().Set("default", "true") @@ -211,12 +212,12 @@ func Test_safednsTemplateCreate(t *testing.T) { safednsTemplateCreate(service, cmd, []string{}) }) - t.Run("CreateTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("CreateTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateCreateCmd() + cmd := safednsTemplateCreateCmd(nil) cmd.Flags().Set("name", "test template 1") cmd.Flags().Set("default", "true") @@ -227,17 +228,17 @@ func Test_safednsTemplateCreate(t *testing.T) { service.EXPECT().CreateTemplate(expectedRequest).Return(0, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating template: test error\n", func() { - safednsTemplateCreate(service, cmd, []string{}) - }) + err := safednsTemplateCreate(service, cmd, []string{}) + + assert.Equal(t, "Error creating template: test error", err.Error()) }) - t.Run("GetTemplateError_OutputsFatal", func(t *testing.T) { + t.Run("GetTemplateError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateCreateCmd() + cmd := safednsTemplateCreateCmd(nil) cmd.Flags().Set("name", "test template 1") cmd.Flags().Set("default", "true") @@ -251,21 +252,21 @@ func Test_safednsTemplateCreate(t *testing.T) { service.EXPECT().GetTemplate(123).Return(safedns.Template{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new template: test error\n", func() { - safednsTemplateCreate(service, cmd, []string{}) - }) + err := safednsTemplateCreate(service, cmd, []string{}) + + assert.Equal(t, "Error retrieving new template: test error", err.Error()) }) } func Test_safednsTemplateUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsTemplateUpdateCmd().Args(nil, []string{"testdomain.com"}) + err := safednsTemplateUpdateCmd(nil).Args(nil, []string{"testdomain.com"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsTemplateUpdateCmd().Args(nil, []string{}) + err := safednsTemplateUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) @@ -278,7 +279,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("default", "false") gomock.InOrder( @@ -301,7 +302,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("default", "false") gomock.InOrder( @@ -333,7 +334,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("default", "false") service.EXPECT().PatchTemplate(123, gomock.Any()).Return(0, errors.New("test error")).Times(1) @@ -348,7 +349,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("default", "false") gomock.InOrder( @@ -382,7 +383,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("default", "false") gomock.InOrder( @@ -437,7 +438,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("name", "new test template 1") service.EXPECT().PatchTemplate(123, gomock.Any()).Return(0, errors.New("test error")).Times(1) @@ -477,7 +478,7 @@ func Test_safednsTemplateUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsTemplateUpdateCmd() + cmd := safednsTemplateUpdateCmd(nil) cmd.Flags().Set("name", "new test template 1") gomock.InOrder( @@ -493,13 +494,13 @@ func Test_safednsTemplateUpdate(t *testing.T) { func Test_safednsTemplateDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsTemplateDeleteCmd().Args(nil, []string{"test template 1"}) + err := safednsTemplateDeleteCmd(nil).Args(nil, []string{"test template 1"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsTemplateDeleteCmd().Args(nil, []string{}) + err := safednsTemplateDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing template", err.Error()) diff --git a/cmd/safedns_zone.go b/cmd/safedns/safedns_zone.go similarity index 68% rename from cmd/safedns_zone.go rename to cmd/safedns/safedns_zone.go index 387c80a..2539d36 100644 --- a/cmd/safedns_zone.go +++ b/cmd/safedns/safedns_zone.go @@ -1,41 +1,43 @@ -package cmd +package safedns import ( "errors" + "fmt" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsZoneRootCmd() *cobra.Command { +func safednsZoneRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "zone", Short: "sub-commands relating to zones", } // Child commands - cmd.AddCommand(safednsZoneListCmd()) - cmd.AddCommand(safednsZoneShowCmd()) - cmd.AddCommand(safednsZoneCreateCmd()) - cmd.AddCommand(safednsZoneUpdateCmd()) - cmd.AddCommand(safednsZoneDeleteCmd()) + cmd.AddCommand(safednsZoneListCmd(f)) + cmd.AddCommand(safednsZoneShowCmd(f)) + cmd.AddCommand(safednsZoneCreateCmd(f)) + cmd.AddCommand(safednsZoneUpdateCmd(f)) + cmd.AddCommand(safednsZoneDeleteCmd(f)) // Child root commands - cmd.AddCommand(safednsZoneRecordRootCmd()) + cmd.AddCommand(safednsZoneRecordRootCmd(f)) return cmd } -func safednsZoneListCmd() *cobra.Command { +func safednsZoneListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "Lists zones", Long: "This command lists zones", Example: "ukfast safedns zone list", - Run: func(cmd *cobra.Command, args []string) { - safednsZoneList(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneList(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -44,11 +46,10 @@ func safednsZoneListCmd() *cobra.Command { return cmd } -func safednsZoneList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -58,14 +59,13 @@ func safednsZoneList(service safedns.SafeDNSService, cmd *cobra.Command, args [] zones, err := service.GetZones(params) if err != nil { - output.Fatalf("Error retrieving zones: %s", err) - return + return fmt.Errorf("Error retrieving zones: %s", err) } - outputSafeDNSZones(zones) + return output.CommandOutput(cmd, OutputSafeDNSZonesProvider(zones)) } -func safednsZoneShowCmd() *cobra.Command { +func safednsZoneShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a zone", @@ -78,13 +78,13 @@ func safednsZoneShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneShow(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneShow(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsZoneShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { var zones []safedns.Zone for _, arg := range args { zone, err := service.GetZone(arg) @@ -96,17 +96,17 @@ func safednsZoneShow(service safedns.SafeDNSService, cmd *cobra.Command, args [] zones = append(zones, zone) } - outputSafeDNSZones(zones) + return output.CommandOutput(cmd, OutputSafeDNSZonesProvider(zones)) } -func safednsZoneCreateCmd() *cobra.Command { +func safednsZoneCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Creates a zone", Long: "This command creates a zone", Example: "ukfast safedns zone create", - Run: func(cmd *cobra.Command, args []string) { - safednsZoneCreate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneCreate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -118,7 +118,7 @@ func safednsZoneCreateCmd() *cobra.Command { return cmd } -func safednsZoneCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { name, _ := cmd.Flags().GetString("name") description, _ := cmd.Flags().GetString("description") @@ -129,20 +129,18 @@ func safednsZoneCreate(service safedns.SafeDNSService, cmd *cobra.Command, args err := service.CreateZone(createRequest) if err != nil { - output.Fatalf("Error creating zone: %s", err) - return + return fmt.Errorf("Error creating zone: %s", err) } zone, err := service.GetZone(name) if err != nil { - output.Fatalf("Error retrieving new zone: %s", err) - return + return fmt.Errorf("Error retrieving new zone: %s", err) } - outputSafeDNSZones([]safedns.Zone{zone}) + return output.CommandOutput(cmd, OutputSafeDNSZonesProvider([]safedns.Zone{zone})) } -func safednsZoneUpdateCmd() *cobra.Command { +func safednsZoneUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a zone", @@ -155,8 +153,8 @@ func safednsZoneUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneUpdate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneUpdate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -165,7 +163,7 @@ func safednsZoneUpdateCmd() *cobra.Command { return cmd } -func safednsZoneUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { patchRequest := safedns.PatchZoneRequest{} patchRequest.Description, _ = cmd.Flags().GetString("description") @@ -186,10 +184,10 @@ func safednsZoneUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args zones = append(zones, zone) } - outputSafeDNSZones(zones) + return output.CommandOutput(cmd, OutputSafeDNSZonesProvider(zones)) } -func safednsZoneDeleteCmd() *cobra.Command { +func safednsZoneDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ", Short: "Removes a zone", @@ -203,7 +201,7 @@ func safednsZoneDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - safednsZoneDelete(getClient().SafeDNSService(), cmd, args) + safednsZoneDelete(f.NewClient().SafeDNSService(), cmd, args) }, } } diff --git a/cmd/safedns_zone_note.go b/cmd/safedns/safedns_zone_note.go similarity index 68% rename from cmd/safedns_zone_note.go rename to cmd/safedns/safedns_zone_note.go index 175d13f..737d6bc 100644 --- a/cmd/safedns_zone_note.go +++ b/cmd/safedns/safedns_zone_note.go @@ -1,30 +1,32 @@ -package cmd +package safedns import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsZoneNoteRootCmd() *cobra.Command { +func safednsZoneNoteRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "note", Short: "sub-commands relating to zone notes", } // Child commands - cmd.AddCommand(safednsZoneNoteListCmd()) - cmd.AddCommand(safednsZoneNoteShowCmd()) - cmd.AddCommand(safednsZoneNoteCreateCmd()) + cmd.AddCommand(safednsZoneNoteListCmd(f)) + cmd.AddCommand(safednsZoneNoteShowCmd(f)) + cmd.AddCommand(safednsZoneNoteCreateCmd(f)) return cmd } -func safednsZoneNoteListCmd() *cobra.Command { +func safednsZoneNoteListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list ", Short: "Lists zone notes", @@ -37,8 +39,8 @@ func safednsZoneNoteListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneNoteList(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneNoteList(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -47,11 +49,10 @@ func safednsZoneNoteListCmd() *cobra.Command { return cmd } -func safednsZoneNoteList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneNoteList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("ip") { @@ -61,14 +62,13 @@ func safednsZoneNoteList(service safedns.SafeDNSService, cmd *cobra.Command, arg zoneNotes, err := service.GetZoneNotes(args[0], params) if err != nil { - output.Fatalf("Error retrieving notes for zone: %s", err) - return + return fmt.Errorf("Error retrieving notes for zone: %s", err) } - outputSafeDNSNotes(zoneNotes) + return output.CommandOutput(cmd, OutputSafeDNSNotesProvider(zoneNotes)) } -func safednsZoneNoteShowCmd() *cobra.Command { +func safednsZoneNoteShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a zone note", @@ -84,13 +84,13 @@ func safednsZoneNoteShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneNoteShow(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneNoteShow(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsZoneNoteShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneNoteShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { var zoneNotes []safedns.Note for _, arg := range args[1:] { @@ -109,10 +109,10 @@ func safednsZoneNoteShow(service safedns.SafeDNSService, cmd *cobra.Command, arg zoneNotes = append(zoneNotes, zoneNote) } - outputSafeDNSNotes(zoneNotes) + return output.CommandOutput(cmd, OutputSafeDNSNotesProvider(zoneNotes)) } -func safednsZoneNoteCreateCmd() *cobra.Command { +func safednsZoneNoteCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a zone note", @@ -125,8 +125,8 @@ func safednsZoneNoteCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneNoteCreate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneNoteCreate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -137,22 +137,20 @@ func safednsZoneNoteCreateCmd() *cobra.Command { return cmd } -func safednsZoneNoteCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneNoteCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { createRequest := safedns.CreateNoteRequest{} createRequest.ContactID, _ = cmd.Flags().GetInt("contact-id") createRequest.Notes, _ = cmd.Flags().GetString("notes") id, err := service.CreateZoneNote(args[0], createRequest) if err != nil { - output.Fatalf("Error creating note: %s", err) - return + return fmt.Errorf("Error creating note: %s", err) } zoneNote, err := service.GetZoneNote(args[0], id) if err != nil { - output.Fatalf("Error retrieving new note: %s", err) - return + return fmt.Errorf("Error retrieving new note: %s", err) } - outputSafeDNSNotes([]safedns.Note{zoneNote}) + return output.CommandOutput(cmd, OutputSafeDNSNotesProvider([]safedns.Note{zoneNote})) } diff --git a/cmd/safedns_zone_note_test.go b/cmd/safedns/safedns_zone_note_test.go similarity index 82% rename from cmd/safedns_zone_note_test.go rename to cmd/safedns/safedns_zone_note_test.go index 28d8888..f6a3204 100644 --- a/cmd/safedns_zone_note_test.go +++ b/cmd/safedns/safedns_zone_note_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/connection" @@ -15,14 +16,14 @@ import ( func Test_safednsZoneNoteListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneNoteListCmd() + cmd := safednsZoneNoteListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneNoteListCmd() + cmd := safednsZoneNoteListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -47,7 +48,7 @@ func Test_safednsZoneNoteList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneNoteListCmd() + cmd := safednsZoneNoteListCmd(nil) cmd.Flags().Set("ip", "1.2.3.4") expectedParams := connection.APIRequestParameters{ @@ -65,7 +66,7 @@ func Test_safednsZoneNoteList(t *testing.T) { safednsZoneNoteList(service, cmd, []string{"testdomain1.com"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -73,12 +74,12 @@ func Test_safednsZoneNoteList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - safednsZoneNoteList(service, cmd, []string{"123"}) - }) + err := safednsZoneNoteList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetZonesError_OutputsFatal", func(t *testing.T) { + t.Run("GetZonesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -87,22 +88,22 @@ func Test_safednsZoneNoteList(t *testing.T) { service.EXPECT().GetZoneNotes("testdomain1.com", gomock.Any()).Return([]safedns.Note{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving notes for zone: test error\n", func() { - safednsZoneNoteList(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneNoteList(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error retrieving notes for zone: test error", err.Error()) }) } func Test_safednsZoneNoteShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneNoteShowCmd() + cmd := safednsZoneNoteShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com", "123"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneNoteShowCmd() + cmd := safednsZoneNoteShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -110,7 +111,7 @@ func Test_safednsZoneNoteShowCmd_Args(t *testing.T) { }) t.Run("MissingNote_Error", func(t *testing.T) { - cmd := safednsZoneNoteShowCmd() + cmd := safednsZoneNoteShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.NotNil(t, err) @@ -171,14 +172,14 @@ func Test_safednsZoneNoteShow(t *testing.T) { func Test_safednsZoneNoteCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneNoteCreateCmd() + cmd := safednsZoneNoteCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneNoteCreateCmd() + cmd := safednsZoneNoteCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -192,7 +193,7 @@ func Test_safednsZoneNoteCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneNoteCreateCmd() + cmd := safednsZoneNoteCreateCmd(nil) cmd.Flags().Set("notes", "test note 1") cmd.Flags().Set("ip", "1.2.3.4") @@ -208,7 +209,7 @@ func Test_safednsZoneNoteCreate(t *testing.T) { safednsZoneNoteCreate(service, cmd, []string{"testdomain1.com"}) }) - t.Run("CreateZoneNoteError_OutputsFatal", func(t *testing.T) { + t.Run("CreateZoneNoteError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -217,12 +218,12 @@ func Test_safednsZoneNoteCreate(t *testing.T) { service.EXPECT().CreateZoneNote("testdomain1.com", gomock.Any()).Return(0, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating note: test error\n", func() { - safednsZoneNoteCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneNoteCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error creating note: test error", err.Error()) }) - t.Run("GetZoneNoteError_OutputsFatal", func(t *testing.T) { + t.Run("GetZoneNoteError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -233,8 +234,8 @@ func Test_safednsZoneNoteCreate(t *testing.T) { service.EXPECT().GetZoneNote("testdomain1.com", 123).Return(safedns.Note{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new note: test error\n", func() { - safednsZoneNoteCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneNoteCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error retrieving new note: test error", err.Error()) }) } diff --git a/cmd/safedns_zone_record.go b/cmd/safedns/safedns_zone_record.go similarity index 77% rename from cmd/safedns_zone_record.go rename to cmd/safedns/safedns_zone_record.go index 69e4ef7..f9644e1 100644 --- a/cmd/safedns_zone_record.go +++ b/cmd/safedns/safedns_zone_record.go @@ -1,32 +1,35 @@ -package cmd +package safedns import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/ptr" "github.com/ukfast/sdk-go/pkg/service/safedns" ) -func safednsZoneRecordRootCmd() *cobra.Command { +func safednsZoneRecordRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "record", Short: "sub-commands relating to zone records", } // Child commands - cmd.AddCommand(safednsZoneRecordListCmd()) - cmd.AddCommand(safednsZoneRecordShowCmd()) - cmd.AddCommand(safednsZoneRecordCreateCmd()) - cmd.AddCommand(safednsZoneRecordUpdateCmd()) - cmd.AddCommand(safednsZoneRecordDeleteCmd()) + cmd.AddCommand(safednsZoneRecordListCmd(f)) + cmd.AddCommand(safednsZoneRecordShowCmd(f)) + cmd.AddCommand(safednsZoneRecordCreateCmd(f)) + cmd.AddCommand(safednsZoneRecordUpdateCmd(f)) + cmd.AddCommand(safednsZoneRecordDeleteCmd(f)) return cmd } -func safednsZoneRecordListCmd() *cobra.Command { + +func safednsZoneRecordListCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "list ", Short: "Lists zone records", @@ -39,8 +42,8 @@ func safednsZoneRecordListCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneRecordList(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneRecordList(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -52,11 +55,10 @@ func safednsZoneRecordListCmd() *cobra.Command { return cmd } -func safednsZoneRecordList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneRecordList(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } if cmd.Flags().Changed("name") { @@ -76,14 +78,13 @@ func safednsZoneRecordList(service safedns.SafeDNSService, cmd *cobra.Command, a zoneRecords, err := service.GetZoneRecords(args[0], params) if err != nil { - output.Fatalf("Error retrieving records for zone: %s", err) - return + return fmt.Errorf("Error retrieving records for zone: %s", err) } - outputSafeDNSRecords(zoneRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(zoneRecords)) } -func safednsZoneRecordShowCmd() *cobra.Command { +func safednsZoneRecordShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a zone record", @@ -99,13 +100,13 @@ func safednsZoneRecordShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneRecordShow(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneRecordShow(f.NewClient().SafeDNSService(), cmd, args) }, } } -func safednsZoneRecordShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneRecordShow(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { var zoneRecords []safedns.Record for _, arg := range args[1:] { @@ -124,10 +125,10 @@ func safednsZoneRecordShow(service safedns.SafeDNSService, cmd *cobra.Command, a zoneRecords = append(zoneRecords, zoneRecord) } - outputSafeDNSRecords(zoneRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(zoneRecords)) } -func safednsZoneRecordCreateCmd() *cobra.Command { +func safednsZoneRecordCreateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Creates a zone record", @@ -140,8 +141,8 @@ func safednsZoneRecordCreateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneRecordCreate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneRecordCreate(f.NewClient().SafeDNSService(), cmd, args) }, } @@ -157,7 +158,7 @@ func safednsZoneRecordCreateCmd() *cobra.Command { return cmd } -func safednsZoneRecordCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneRecordCreate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { recordName, _ := cmd.Flags().GetString("name") recordType, _ := cmd.Flags().GetString("type") recordContent, _ := cmd.Flags().GetString("content") @@ -175,20 +176,18 @@ func safednsZoneRecordCreate(service safedns.SafeDNSService, cmd *cobra.Command, id, err := service.CreateZoneRecord(args[0], createRequest) if err != nil { - output.Fatalf("Error creating record: %s", err) - return + return fmt.Errorf("Error creating record: %s", err) } zoneRecord, err := service.GetZoneRecord(args[0], id) if err != nil { - output.Fatalf("Error retrieving new record: %s", err) - return + return fmt.Errorf("Error retrieving new record: %s", err) } - outputSafeDNSRecords([]safedns.Record{zoneRecord}) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider([]safedns.Record{zoneRecord})) } -func safednsZoneRecordUpdateCmd() *cobra.Command { +func safednsZoneRecordUpdateCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "update ...", Short: "Updates a zone record", @@ -204,8 +203,8 @@ func safednsZoneRecordUpdateCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - safednsZoneRecordUpdate(getClient().SafeDNSService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return safednsZoneRecordUpdate(f.NewClient().SafeDNSService(), cmd, args) }, } cmd.Flags().String("name", "", "Name of record") @@ -216,7 +215,7 @@ func safednsZoneRecordUpdateCmd() *cobra.Command { return cmd } -func safednsZoneRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) { +func safednsZoneRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Command, args []string) error { patchRequest := safedns.PatchRecordRequest{} if cmd.Flags().Changed("name") { @@ -260,10 +259,10 @@ func safednsZoneRecordUpdate(service safedns.SafeDNSService, cmd *cobra.Command, zoneRecords = append(zoneRecords, zoneRecord) } - outputSafeDNSRecords(zoneRecords) + return output.CommandOutput(cmd, OutputSafeDNSRecordsProvider(zoneRecords)) } -func safednsZoneRecordDeleteCmd() *cobra.Command { +func safednsZoneRecordDeleteCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "delete ...", Short: "Removes a zone record", @@ -280,7 +279,7 @@ func safednsZoneRecordDeleteCmd() *cobra.Command { return nil }, Run: func(cmd *cobra.Command, args []string) { - safednsZoneRecordDelete(getClient().SafeDNSService(), cmd, args) + safednsZoneRecordDelete(f.NewClient().SafeDNSService(), cmd, args) }, } } diff --git a/cmd/safedns_zone_record_test.go b/cmd/safedns/safedns_zone_record_test.go similarity index 89% rename from cmd/safedns_zone_record_test.go rename to cmd/safedns/safedns_zone_record_test.go index 144fa9d..982e86c 100644 --- a/cmd/safedns_zone_record_test.go +++ b/cmd/safedns/safedns_zone_record_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/connection" @@ -15,14 +16,14 @@ import ( func Test_safednsZoneRecordListCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneRecordListCmd() + cmd := safednsZoneRecordListCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneRecordListCmd() + cmd := safednsZoneRecordListCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -47,7 +48,7 @@ func Test_safednsZoneRecordList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordListCmd() + cmd := safednsZoneRecordListCmd(nil) cmd.Flags().Set("name", "testdomain1.com") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -77,7 +78,7 @@ func Test_safednsZoneRecordList(t *testing.T) { safednsZoneRecordList(service, cmd, []string{"testdomain1.com"}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -85,12 +86,12 @@ func Test_safednsZoneRecordList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - safednsZoneRecordList(service, cmd, []string{"123"}) - }) + err := safednsZoneRecordList(service, cmd, []string{"123"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetZonesError_OutputsFatal", func(t *testing.T) { + t.Run("GetZonesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -99,22 +100,22 @@ func Test_safednsZoneRecordList(t *testing.T) { service.EXPECT().GetZoneRecords("testdomain1.com", gomock.Any()).Return([]safedns.Record{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving records for zone: test error\n", func() { - safednsZoneRecordList(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneRecordList(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error retrieving records for zone: test error", err.Error()) }) } func Test_safednsZoneRecordShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneRecordShowCmd() + cmd := safednsZoneRecordShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com", "123"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneRecordShowCmd() + cmd := safednsZoneRecordShowCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -122,7 +123,7 @@ func Test_safednsZoneRecordShowCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsZoneRecordShowCmd() + cmd := safednsZoneRecordShowCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.NotNil(t, err) @@ -183,14 +184,14 @@ func Test_safednsZoneRecordShow(t *testing.T) { func Test_safednsZoneRecordCreateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneRecordCreateCmd() + cmd := safednsZoneRecordCreateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneRecordCreateCmd() + cmd := safednsZoneRecordCreateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -204,7 +205,7 @@ func Test_safednsZoneRecordCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordCreateCmd() + cmd := safednsZoneRecordCreateCmd(nil) cmd.Flags().Set("name", "www.testdomain1.com") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -228,7 +229,7 @@ func Test_safednsZoneRecordCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordCreateCmd() + cmd := safednsZoneRecordCreateCmd(nil) cmd.Flags().Set("priority", "0") gomock.InOrder( @@ -246,7 +247,7 @@ func Test_safednsZoneRecordCreate(t *testing.T) { safednsZoneRecordCreate(service, cmd, []string{"testdomain1.com"}) }) - t.Run("CreateZoneRecordError_OutputsFatal", func(t *testing.T) { + t.Run("CreateZoneRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -255,12 +256,12 @@ func Test_safednsZoneRecordCreate(t *testing.T) { service.EXPECT().CreateZoneRecord("testdomain1.com", gomock.Any()).Return(0, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating record: test error\n", func() { - safednsZoneRecordCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneRecordCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error creating record: test error", err.Error()) }) - t.Run("GetZoneRecordError_OutputsFatal", func(t *testing.T) { + t.Run("GetZoneRecordError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -271,22 +272,22 @@ func Test_safednsZoneRecordCreate(t *testing.T) { service.EXPECT().GetZoneRecord("testdomain1.com", 123).Return(safedns.Record{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new record: test error\n", func() { - safednsZoneRecordCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) - }) + err := safednsZoneRecordCreate(service, &cobra.Command{}, []string{"testdomain1.com"}) + + assert.Equal(t, "Error retrieving new record: test error", err.Error()) }) } func Test_safednsZoneRecordUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com", "123"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -294,7 +295,7 @@ func Test_safednsZoneRecordUpdateCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.NotNil(t, err) @@ -308,7 +309,7 @@ func Test_safednsZoneRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) cmd.Flags().Set("name", "www.testdomain1.com") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -332,7 +333,7 @@ func Test_safednsZoneRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) cmd.Flags().Set("name", "www.testdomain1.com") cmd.Flags().Set("type", "A") cmd.Flags().Set("content", "1.2.3.4") @@ -358,7 +359,7 @@ func Test_safednsZoneRecordUpdate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneRecordUpdateCmd() + cmd := safednsZoneRecordUpdateCmd(nil) cmd.Flags().Set("priority", "0") gomock.InOrder( @@ -416,14 +417,14 @@ func Test_safednsZoneRecordUpdate(t *testing.T) { func Test_safednsZoneRecordDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - cmd := safednsZoneRecordDeleteCmd() + cmd := safednsZoneRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com", "123"}) assert.Nil(t, err) }) t.Run("MissingZone_Error", func(t *testing.T) { - cmd := safednsZoneRecordDeleteCmd() + cmd := safednsZoneRecordDeleteCmd(nil) err := cmd.Args(nil, []string{}) assert.NotNil(t, err) @@ -431,7 +432,7 @@ func Test_safednsZoneRecordDeleteCmd_Args(t *testing.T) { }) t.Run("MissingRecord_Error", func(t *testing.T) { - cmd := safednsZoneRecordDeleteCmd() + cmd := safednsZoneRecordDeleteCmd(nil) err := cmd.Args(nil, []string{"testdomain1.com"}) assert.NotNil(t, err) diff --git a/cmd/safedns_zone_test.go b/cmd/safedns/safedns_zone_test.go similarity index 86% rename from cmd/safedns_zone_test.go rename to cmd/safedns/safedns_zone_test.go index 5c8648d..e5d4e0c 100644 --- a/cmd/safedns_zone_test.go +++ b/cmd/safedns/safedns_zone_test.go @@ -1,4 +1,4 @@ -package cmd +package safedns import ( "errors" @@ -9,6 +9,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/safedns" @@ -31,7 +32,7 @@ func Test_safednsZoneList(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneListCmd() + cmd := safednsZoneListCmd(nil) cmd.Flags().Set("name", "testdomain1.co.uk") expectedParams := connection.APIRequestParameters{ @@ -49,7 +50,7 @@ func Test_safednsZoneList(t *testing.T) { safednsZoneList(service, cmd, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -57,12 +58,12 @@ func Test_safednsZoneList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - safednsZoneList(service, cmd, []string{"testdomain1.co.uk"}) - }) + err := safednsZoneList(service, cmd, []string{"testdomain1.co.uk"}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetZonesError_OutputsFatal", func(t *testing.T) { + t.Run("GetZonesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -70,21 +71,21 @@ func Test_safednsZoneList(t *testing.T) { service.EXPECT().GetZones(gomock.Any()).Return([]safedns.Zone{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving zones: test error\n", func() { - safednsZoneList(service, &cobra.Command{}, []string{}) - }) + err := safednsZoneList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving zones: test error", err.Error()) }) } func Test_safednsZoneShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsZoneShowCmd().Args(nil, []string{"testdomain.com"}) + err := safednsZoneShowCmd(nil).Args(nil, []string{"testdomain.com"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsZoneShowCmd().Args(nil, []string{}) + err := safednsZoneShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing zone", err.Error()) @@ -137,7 +138,7 @@ func Test_safednsZoneCreate(t *testing.T) { defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneCreateCmd() + cmd := safednsZoneCreateCmd(nil) cmd.Flags().Set("name", "testdomain1.com") cmd.Flags().Set("description", "test description") @@ -154,12 +155,12 @@ func Test_safednsZoneCreate(t *testing.T) { safednsZoneCreate(service, cmd, []string{}) }) - t.Run("CreateZoneError_OutputsFatal", func(t *testing.T) { + t.Run("CreateZoneError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneCreateCmd() + cmd := safednsZoneCreateCmd(nil) cmd.Flags().Set("name", "testdomain1.com") cmd.Flags().Set("description", "test description") @@ -170,17 +171,17 @@ func Test_safednsZoneCreate(t *testing.T) { service.EXPECT().CreateZone(expectedRequest).Return(errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error creating zone: test error\n", func() { - safednsZoneCreate(service, cmd, []string{}) - }) + err := safednsZoneCreate(service, cmd, []string{}) + + assert.Equal(t, "Error creating zone: test error", err.Error()) }) - t.Run("GetZoneError_OutputsFatal", func(t *testing.T) { + t.Run("GetZoneError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneCreateCmd() + cmd := safednsZoneCreateCmd(nil) cmd.Flags().Set("name", "testdomain1.com") cmd.Flags().Set("description", "test description") @@ -194,21 +195,21 @@ func Test_safednsZoneCreate(t *testing.T) { service.EXPECT().GetZone("testdomain1.com").Return(safedns.Zone{}, errors.New("test error")), ) - test_output.AssertFatalOutput(t, "Error retrieving new zone: test error\n", func() { - safednsZoneCreate(service, cmd, []string{}) - }) + err := safednsZoneCreate(service, cmd, []string{}) + + assert.Equal(t, "Error retrieving new zone: test error", err.Error()) }) } func Test_safednsZoneUpdateCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsZoneUpdateCmd().Args(nil, []string{"testdomain.com"}) + err := safednsZoneUpdateCmd(nil).Args(nil, []string{"testdomain.com"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsZoneUpdateCmd().Args(nil, []string{}) + err := safednsZoneUpdateCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing zone", err.Error()) @@ -222,7 +223,7 @@ func Test_safednsZoneUpdate(t *testing.T) { service := mocks.NewMockSafeDNSService(mockCtrl) - cmd := safednsZoneCreateCmd() + cmd := safednsZoneCreateCmd(nil) cmd.Flags().Set("description", "test description") expectedRequest := safedns.PatchZoneRequest{ @@ -285,13 +286,13 @@ func Test_safednsZoneUpdate(t *testing.T) { func Test_safednsZoneDeleteCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := safednsZoneDeleteCmd().Args(nil, []string{"testdomain.com"}) + err := safednsZoneDeleteCmd(nil).Args(nil, []string{"testdomain.com"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := safednsZoneDeleteCmd().Args(nil, []string{}) + err := safednsZoneDeleteCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing zone", err.Error()) diff --git a/cmd/safedns_test.go b/cmd/safedns_test.go deleted file mode 100644 index ed9f45b..0000000 --- a/cmd/safedns_test.go +++ /dev/null @@ -1,316 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/service/safedns" -) - -func TestOutputSafeDNSZones_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSZones{ - Zones: []safedns.Zone{ - safedns.Zone{ - Name: "testdomain1.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Zone{}, data) - assert.Equal(t, "testdomain1.com", data.([]safedns.Zone)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSZones{ - Zones: []safedns.Zone{ - safedns.Zone{ - Name: "testdomain1.com", - }, - safedns.Zone{ - Name: "testdomain2.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Zone{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testdomain1.com", data.([]safedns.Zone)[0].Name) - assert.Equal(t, "testdomain2.com", data.([]safedns.Zone)[1].Name) - }) -} - -func TestOutputSafeDNSZones_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSZones{ - Zones: []safedns.Zone{ - safedns.Zone{ - Name: "testdomain1.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain1.com", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSZones{ - Zones: []safedns.Zone{ - safedns.Zone{ - Name: "testdomain1.com", - }, - safedns.Zone{ - Name: "testdomain2.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testdomain1.com", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testdomain2.com", data[1].Get("name").Value) - }) -} - -func TestOutputSafeDNSRecords_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSRecords{ - Records: []safedns.Record{ - safedns.Record{ - Name: "www.testdomain1.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Record{}, data) - assert.Equal(t, "www.testdomain1.com", data.([]safedns.Record)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSRecords{ - Records: []safedns.Record{ - safedns.Record{ - Name: "www.testdomain1.com", - }, - safedns.Record{ - Name: "www.testdomain2.com", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Record{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "www.testdomain1.com", data.([]safedns.Record)[0].Name) - assert.Equal(t, "www.testdomain2.com", data.([]safedns.Record)[1].Name) - }) -} - -func TestOutputSafeDNSRecords_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSRecords{ - Records: []safedns.Record{ - safedns.Record{ - Name: "www.testdomain1.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "www.testdomain1.com", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSRecords{ - Records: []safedns.Record{ - safedns.Record{ - Name: "www.testdomain1.com", - }, - safedns.Record{ - Name: "www.testdomain2.com", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "www.testdomain1.com", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "www.testdomain2.com", data[1].Get("name").Value) - }) -} - -func TestOutputSafeDNSNotes_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSNotes{ - Notes: []safedns.Note{ - safedns.Note{ - Notes: "testnote1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Note{}, data) - assert.Equal(t, "testnote1", data.([]safedns.Note)[0].Notes) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSNotes{ - Notes: []safedns.Note{ - safedns.Note{ - Notes: "testnote1", - }, - safedns.Note{ - Notes: "testnote2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Note{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testnote1", data.([]safedns.Note)[0].Notes) - assert.Equal(t, "testnote2", data.([]safedns.Note)[1].Notes) - }) -} - -func TestOutputSafeDNSNotes_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSNotes{ - Notes: []safedns.Note{ - safedns.Note{ - Notes: "testnote1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("notes")) - assert.Equal(t, "testnote1", data[0].Get("notes").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSNotes{ - Notes: []safedns.Note{ - safedns.Note{ - Notes: "testnote1", - }, - safedns.Note{ - Notes: "testnote2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("notes")) - assert.Equal(t, "testnote1", data[0].Get("notes").Value) - assert.True(t, data[1].Exists("notes")) - assert.Equal(t, "testnote2", data[1].Get("notes").Value) - }) -} - -func TestOutputSafeDNSTemplates_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSTemplates{ - Templates: []safedns.Template{ - safedns.Template{ - Name: "testtemplate1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Template{}, data) - assert.Equal(t, "testtemplate1", data.([]safedns.Template)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSafeDNSTemplates{ - Templates: []safedns.Template{ - safedns.Template{ - Name: "testtemplate1", - }, - safedns.Template{ - Name: "testtemplate2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []safedns.Template{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testtemplate1", data.([]safedns.Template)[0].Name) - assert.Equal(t, "testtemplate2", data.([]safedns.Template)[1].Name) - }) -} - -func TestOutputSafeDNSTemplates_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSTemplates{ - Templates: []safedns.Template{ - safedns.Template{ - Name: "testtemplate1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testtemplate1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSafeDNSTemplates{ - Templates: []safedns.Template{ - safedns.Template{ - Name: "testtemplate1", - }, - safedns.Template{ - Name: "testtemplate2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testtemplate1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testtemplate2", data[1].Get("name").Value) - }) -} diff --git a/cmd/ssl.go b/cmd/ssl.go deleted file mode 100644 index adcfc00..0000000 --- a/cmd/ssl.go +++ /dev/null @@ -1,132 +0,0 @@ -package cmd - -import ( - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/ssl" -) - -func sslRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "ssl", - Short: "Commands relating to SSL service", - } - - // Child root commands - cmd.AddCommand(sslCertificateRootCmd()) - - return cmd -} - -// OutputSSLCertificates implements OutputDataProvider for outputting an array of Certificates -type OutputSSLCertificates struct { - Certificates []ssl.Certificate -} - -func outputSSLCertificates(certificates []ssl.Certificate) { - err := Output(&OutputSSLCertificates{Certificates: certificates}) - if err != nil { - output.Fatalf("Failed to output certificates: %s", err) - } -} - -func (o *OutputSSLCertificates) GetData() interface{} { - return o.Certificates -} - -func (o *OutputSSLCertificates) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, certificate := range o.Certificates { - fields := o.getOrderedFields(certificate) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSSLCertificates) getOrderedFields(certificate ssl.Certificate) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(certificate.ID), true)) - fields.Set("name", output.NewFieldValue(certificate.Name, true)) - fields.Set("status", output.NewFieldValue(certificate.Status.String(), true)) - fields.Set("common_name", output.NewFieldValue(certificate.CommonName, true)) - fields.Set("alternative_names", output.NewFieldValue(strings.Join(certificate.AlternativeNames, ", "), false)) - fields.Set("valid_days", output.NewFieldValue(strconv.Itoa(certificate.ValidDays), true)) - fields.Set("ordered_date", output.NewFieldValue(certificate.OrderedDate.String(), true)) - fields.Set("renewal_date", output.NewFieldValue(certificate.RenewalDate.String(), true)) - - return fields -} - -// OutputSSLCertificateContents implements OutputDataProvider for outputting an array of certificates contents -type OutputSSLCertificateContents struct { - CertificateContents []ssl.CertificateContent -} - -func outputSSLCertificatesContents(certificatesContent []ssl.CertificateContent) { - err := Output(&OutputSSLCertificateContents{CertificateContents: certificatesContent}) - if err != nil { - output.Fatalf("Failed to output certificate contents: %s", err) - } -} - -func (o *OutputSSLCertificateContents) GetData() interface{} { - return o.CertificateContents -} - -func (o *OutputSSLCertificateContents) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, certificateContent := range o.CertificateContents { - fields := o.getOrderedFields(certificateContent) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSSLCertificateContents) getOrderedFields(certificateContent ssl.CertificateContent) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("combined", output.NewFieldValue(certificateContent.Server+"\n"+certificateContent.Intermediate, true)) - fields.Set("server", output.NewFieldValue(certificateContent.Server, false)) - fields.Set("intermediate", output.NewFieldValue(certificateContent.Intermediate, false)) - - return fields -} - -// OutputSSLCertificatePrivateKeys implements OutputDataProvider for outputting an array of Certificates -type OutputSSLCertificatePrivateKeys struct { - CertificatePrivateKeys []ssl.CertificatePrivateKey -} - -func outputSSLCertificatesPrivateKeys(certificatesPrivateKey []ssl.CertificatePrivateKey) { - err := Output(&OutputSSLCertificatePrivateKeys{ - CertificatePrivateKeys: certificatesPrivateKey, - }) - if err != nil { - output.Fatalf("Failed to output certificate private keys: %s", err) - } -} - -func (o *OutputSSLCertificatePrivateKeys) GetData() interface{} { - return o.CertificatePrivateKeys -} - -func (o *OutputSSLCertificatePrivateKeys) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, certificatePrivateKey := range o.CertificatePrivateKeys { - fields := o.getOrderedFields(certificatePrivateKey) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputSSLCertificatePrivateKeys) getOrderedFields(certificatePrivateKey ssl.CertificatePrivateKey) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("key", output.NewFieldValue(certificatePrivateKey.Key, true)) - - return fields -} diff --git a/cmd/ssl/output.go b/cmd/ssl/output.go new file mode 100644 index 0000000..39c97a1 --- /dev/null +++ b/cmd/ssl/output.go @@ -0,0 +1,69 @@ +package ssl + +import ( + "strconv" + "strings" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/ssl" +) + +func OutputSSLCertificatesProvider(certificates []ssl.Certificate) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(certificates), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, certificate := range certificates { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(certificate.ID), true)) + fields.Set("name", output.NewFieldValue(certificate.Name, true)) + fields.Set("status", output.NewFieldValue(certificate.Status.String(), true)) + fields.Set("common_name", output.NewFieldValue(certificate.CommonName, true)) + fields.Set("alternative_names", output.NewFieldValue(strings.Join(certificate.AlternativeNames, ", "), false)) + fields.Set("valid_days", output.NewFieldValue(strconv.Itoa(certificate.ValidDays), true)) + fields.Set("ordered_date", output.NewFieldValue(certificate.OrderedDate.String(), true)) + fields.Set("renewal_date", output.NewFieldValue(certificate.RenewalDate.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSSLCertificatesContentsProvider(certificatesContent []ssl.CertificateContent) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(certificatesContent), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, certificateContent := range certificatesContent { + fields := output.NewOrderedFields() + fields.Set("combined", output.NewFieldValue(certificateContent.Server+"\n"+certificateContent.Intermediate, true)) + fields.Set("server", output.NewFieldValue(certificateContent.Server, false)) + fields.Set("intermediate", output.NewFieldValue(certificateContent.Intermediate, false)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputSSLCertificatesPrivateKeysProvider(certificatesPrivateKey []ssl.CertificatePrivateKey) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(certificatesPrivateKey), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, certificatePrivateKey := range certificatesPrivateKey { + fields := output.NewOrderedFields() + fields.Set("key", output.NewFieldValue(certificatePrivateKey.Key, true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/ssl/ssl.go b/cmd/ssl/ssl.go new file mode 100644 index 0000000..51ad78a --- /dev/null +++ b/cmd/ssl/ssl.go @@ -0,0 +1,18 @@ +package ssl + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func SSLRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "ssl", + Short: "Commands relating to SSL service", + } + + // Child root commands + cmd.AddCommand(sslCertificateRootCmd(f)) + + return cmd +} diff --git a/cmd/ssl_certificate.go b/cmd/ssl/ssl_certificate.go similarity index 62% rename from cmd/ssl_certificate.go rename to cmd/ssl/ssl_certificate.go index bd9e601..209461e 100644 --- a/cmd/ssl_certificate.go +++ b/cmd/ssl/ssl_certificate.go @@ -1,61 +1,61 @@ -package cmd +package ssl import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ssl" ) -func sslCertificateRootCmd() *cobra.Command { +func sslCertificateRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "certificate", Short: "sub-commands relating to certificates", } // Child commands - cmd.AddCommand(sslCertificateListCmd()) - cmd.AddCommand(sslCertificateShowCmd()) + cmd.AddCommand(sslCertificateListCmd(f)) + cmd.AddCommand(sslCertificateShowCmd(f)) // Child root commands - cmd.AddCommand(sslCertificateContentRootCmd()) - cmd.AddCommand(sslCertificatePrivateKeyRootCmd()) + cmd.AddCommand(sslCertificateContentRootCmd(f)) + cmd.AddCommand(sslCertificatePrivateKeyRootCmd(f)) return cmd } -func sslCertificateListCmd() *cobra.Command { +func sslCertificateListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists certificates", Long: "This command lists certificates", Example: "ukfast ssl certificate list", - Run: func(cmd *cobra.Command, args []string) { - sslCertificateList(getClient().SSLService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return sslCertificateList(f.NewClient().SSLService(), cmd, args) }, } } -func sslCertificateList(service ssl.SSLService, cmd *cobra.Command, args []string) { +func sslCertificateList(service ssl.SSLService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } certificates, err := service.GetCertificates(params) if err != nil { - output.Fatalf("Error retrieving certificates: %s", err) - return + return fmt.Errorf("Error retrieving certificates: %s", err) } - outputSSLCertificates(certificates) + return output.CommandOutput(cmd, OutputSSLCertificatesProvider(certificates)) } -func sslCertificateShowCmd() *cobra.Command { +func sslCertificateShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a certificate", @@ -68,13 +68,13 @@ func sslCertificateShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - sslCertificateShow(getClient().SSLService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return sslCertificateShow(f.NewClient().SSLService(), cmd, args) }, } } -func sslCertificateShow(service ssl.SSLService, cmd *cobra.Command, args []string) { +func sslCertificateShow(service ssl.SSLService, cmd *cobra.Command, args []string) error { var certificates []ssl.Certificate for _, arg := range args { certificateID, err := strconv.Atoi(arg) @@ -92,5 +92,5 @@ func sslCertificateShow(service ssl.SSLService, cmd *cobra.Command, args []strin certificates = append(certificates, certificate) } - outputSSLCertificates(certificates) + return output.CommandOutput(cmd, OutputSSLCertificatesProvider(certificates)) } diff --git a/cmd/ssl_certificate_content.go b/cmd/ssl/ssl_certificate_content.go similarity index 70% rename from cmd/ssl_certificate_content.go rename to cmd/ssl/ssl_certificate_content.go index 9751802..cf48b0e 100644 --- a/cmd/ssl_certificate_content.go +++ b/cmd/ssl/ssl_certificate_content.go @@ -1,15 +1,16 @@ -package cmd +package ssl import ( "errors" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ssl" ) -func sslCertificateContentRootCmd() *cobra.Command { +func sslCertificateContentRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "content", @@ -17,12 +18,12 @@ func sslCertificateContentRootCmd() *cobra.Command { } // Child commands - cmd.AddCommand(sslCertificateContentShowCmd()) + cmd.AddCommand(sslCertificateContentShowCmd(f)) return cmd } -func sslCertificateContentShowCmd() *cobra.Command { +func sslCertificateContentShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a certificate content", @@ -35,13 +36,13 @@ func sslCertificateContentShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - sslCertificateContentShow(getClient().SSLService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return sslCertificateContentShow(f.NewClient().SSLService(), cmd, args) }, } } -func sslCertificateContentShow(service ssl.SSLService, cmd *cobra.Command, args []string) { +func sslCertificateContentShow(service ssl.SSLService, cmd *cobra.Command, args []string) error { var certificateContents []ssl.CertificateContent for _, arg := range args { certificateID, err := strconv.Atoi(arg) @@ -59,5 +60,5 @@ func sslCertificateContentShow(service ssl.SSLService, cmd *cobra.Command, args certificateContents = append(certificateContents, certificateContent) } - outputSSLCertificatesContents(certificateContents) + return output.CommandOutput(cmd, OutputSSLCertificatesContentsProvider(certificateContents)) } diff --git a/cmd/ssl_certificate_content_test.go b/cmd/ssl/ssl_certificate_content_test.go similarity index 93% rename from cmd/ssl_certificate_content_test.go rename to cmd/ssl/ssl_certificate_content_test.go index 1dcc18e..c39c530 100644 --- a/cmd/ssl_certificate_content_test.go +++ b/cmd/ssl/ssl_certificate_content_test.go @@ -1,4 +1,4 @@ -package cmd +package ssl import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_sslCertificateContentShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := sslCertificateContentShowCmd().Args(nil, []string{"123"}) + err := sslCertificateContentShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := sslCertificateContentShowCmd().Args(nil, []string{}) + err := sslCertificateContentShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing certificate", err.Error()) diff --git a/cmd/ssl_certificate_privatekey.go b/cmd/ssl/ssl_certificate_privatekey.go similarity index 70% rename from cmd/ssl_certificate_privatekey.go rename to cmd/ssl/ssl_certificate_privatekey.go index f39b75a..e621e35 100644 --- a/cmd/ssl_certificate_privatekey.go +++ b/cmd/ssl/ssl_certificate_privatekey.go @@ -1,27 +1,28 @@ -package cmd +package ssl import ( "errors" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/ssl" ) -func sslCertificatePrivateKeyRootCmd() *cobra.Command { +func sslCertificatePrivateKeyRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "privatekey", Short: "sub-commands relating to certificate private keys", } // Child commands - cmd.AddCommand(sslCertificatePrivateKeyShowCmd()) + cmd.AddCommand(sslCertificatePrivateKeyShowCmd(f)) return cmd } -func sslCertificatePrivateKeyShowCmd() *cobra.Command { +func sslCertificatePrivateKeyShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a certificate private key", @@ -34,13 +35,13 @@ func sslCertificatePrivateKeyShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - sslCertificatePrivateKeyShow(getClient().SSLService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return sslCertificatePrivateKeyShow(f.NewClient().SSLService(), cmd, args) }, } } -func sslCertificatePrivateKeyShow(service ssl.SSLService, cmd *cobra.Command, args []string) { +func sslCertificatePrivateKeyShow(service ssl.SSLService, cmd *cobra.Command, args []string) error { var certificatePrivateKeys []ssl.CertificatePrivateKey for _, arg := range args { certificateID, err := strconv.Atoi(arg) @@ -58,5 +59,5 @@ func sslCertificatePrivateKeyShow(service ssl.SSLService, cmd *cobra.Command, ar certificatePrivateKeys = append(certificatePrivateKeys, certificatePrivateKey) } - outputSSLCertificatesPrivateKeys(certificatePrivateKeys) + return output.CommandOutput(cmd, OutputSSLCertificatesPrivateKeysProvider(certificatePrivateKeys)) } diff --git a/cmd/ssl_certificate_privatekey_test.go b/cmd/ssl/ssl_certificate_privatekey_test.go similarity index 93% rename from cmd/ssl_certificate_privatekey_test.go rename to cmd/ssl/ssl_certificate_privatekey_test.go index 4e8fdfa..2687255 100644 --- a/cmd/ssl_certificate_privatekey_test.go +++ b/cmd/ssl/ssl_certificate_privatekey_test.go @@ -1,4 +1,4 @@ -package cmd +package ssl import ( "errors" @@ -14,13 +14,13 @@ import ( func Test_sslCertificatePrivateKeyShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := sslCertificatePrivateKeyShowCmd().Args(nil, []string{"123"}) + err := sslCertificatePrivateKeyShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := sslCertificatePrivateKeyShowCmd().Args(nil, []string{}) + err := sslCertificatePrivateKeyShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing certificate", err.Error()) diff --git a/cmd/ssl_certificate_test.go b/cmd/ssl/ssl_certificate_test.go similarity index 83% rename from cmd/ssl_certificate_test.go rename to cmd/ssl/ssl_certificate_test.go index 736edad..a672ad4 100644 --- a/cmd/ssl_certificate_test.go +++ b/cmd/ssl/ssl_certificate_test.go @@ -1,4 +1,4 @@ -package cmd +package ssl import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/ssl" @@ -24,7 +25,7 @@ func Test_sslCertificateList(t *testing.T) { sslCertificateList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_sslCertificateList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - sslCertificateList(service, cmd, []string{}) - }) + err := sslCertificateList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetCertificatesError_OutputsFatal", func(t *testing.T) { + t.Run("GetCertificatesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_sslCertificateList(t *testing.T) { service.EXPECT().GetCertificates(gomock.Any()).Return([]ssl.Certificate{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving certificates: test error\n", func() { - sslCertificateList(service, &cobra.Command{}, []string{}) - }) + err := sslCertificateList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving certificates: test error", err.Error()) }) } func Test_sslCertificateShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := sslCertificateShowCmd().Args(nil, []string{"123"}) + err := sslCertificateShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := sslCertificateShowCmd().Args(nil, []string{}) + err := sslCertificateShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing certificate", err.Error()) diff --git a/cmd/ssl_test.go b/cmd/ssl_test.go deleted file mode 100644 index 002b894..0000000 --- a/cmd/ssl_test.go +++ /dev/null @@ -1,239 +0,0 @@ -package cmd - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ukfast/sdk-go/pkg/service/ssl" -) - -func TestOutputSSLCertificates_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificates{ - Certificates: []ssl.Certificate{ - ssl.Certificate{ - Name: "testcertificate1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.Certificate{}, data) - assert.Equal(t, "testcertificate1", data.([]ssl.Certificate)[0].Name) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificates{ - Certificates: []ssl.Certificate{ - ssl.Certificate{ - Name: "testcertificate1", - }, - ssl.Certificate{ - Name: "testcertificate2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.Certificate{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testcertificate1", data.([]ssl.Certificate)[0].Name) - assert.Equal(t, "testcertificate2", data.([]ssl.Certificate)[1].Name) - }) -} - -func TestOutputSSLCertificates_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificates{ - Certificates: []ssl.Certificate{ - ssl.Certificate{ - Name: "testcertificate1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testcertificate1", data[0].Get("name").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificates{ - Certificates: []ssl.Certificate{ - ssl.Certificate{ - Name: "testcertificate1", - }, - ssl.Certificate{ - Name: "testcertificate2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("name")) - assert.Equal(t, "testcertificate1", data[0].Get("name").Value) - assert.True(t, data[1].Exists("name")) - assert.Equal(t, "testcertificate2", data[1].Get("name").Value) - }) -} - -func TestOutputSSLCertificateContents_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificateContents{ - CertificateContents: []ssl.CertificateContent{ - ssl.CertificateContent{ - Server: "testservercontent1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.CertificateContent{}, data) - assert.Equal(t, "testservercontent1", data.([]ssl.CertificateContent)[0].Server) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificateContents{ - CertificateContents: []ssl.CertificateContent{ - ssl.CertificateContent{ - Server: "testservercontent1", - }, - ssl.CertificateContent{ - Server: "testservercontent2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.CertificateContent{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testservercontent1", data.([]ssl.CertificateContent)[0].Server) - assert.Equal(t, "testservercontent2", data.([]ssl.CertificateContent)[1].Server) - }) -} - -func TestOutputSSLCertificateContents_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificateContents{ - CertificateContents: []ssl.CertificateContent{ - ssl.CertificateContent{ - Server: "testservercontent1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("server")) - assert.Equal(t, "testservercontent1", data[0].Get("server").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificateContents{ - CertificateContents: []ssl.CertificateContent{ - ssl.CertificateContent{ - Server: "testservercontent1", - }, - ssl.CertificateContent{ - Server: "testservercontent2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("server")) - assert.Equal(t, "testservercontent1", data[0].Get("server").Value) - assert.True(t, data[1].Exists("server")) - assert.Equal(t, "testservercontent2", data[1].Get("server").Value) - }) -} - -func TestOutputSSLCertificatePrivateKeys_GetData(t *testing.T) { - t.Run("Single_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificatePrivateKeys{ - CertificatePrivateKeys: []ssl.CertificatePrivateKey{ - ssl.CertificatePrivateKey{ - Key: "testkey1", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.CertificatePrivateKey{}, data) - assert.Equal(t, "testkey1", data.([]ssl.CertificatePrivateKey)[0].Key) - }) - - t.Run("Multiple_ExpectedData", func(t *testing.T) { - o := OutputSSLCertificatePrivateKeys{ - CertificatePrivateKeys: []ssl.CertificatePrivateKey{ - ssl.CertificatePrivateKey{ - Key: "testkey1", - }, - ssl.CertificatePrivateKey{ - Key: "testkey2", - }, - }, - } - - data := o.GetData() - - assert.IsType(t, []ssl.CertificatePrivateKey{}, data) - assert.Len(t, data, 2) - assert.Equal(t, "testkey1", data.([]ssl.CertificatePrivateKey)[0].Key) - assert.Equal(t, "testkey2", data.([]ssl.CertificatePrivateKey)[1].Key) - }) -} - -func TestOutputSSLCertificatePrivateKeys_GetFieldData(t *testing.T) { - t.Run("Single_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificatePrivateKeys{ - CertificatePrivateKeys: []ssl.CertificatePrivateKey{ - ssl.CertificatePrivateKey{ - Key: "testkey1", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.True(t, data[0].Exists("key")) - assert.Equal(t, "testkey1", data[0].Get("key").Value) - }) - - t.Run("Multiple_ExpectedFieldData", func(t *testing.T) { - o := OutputSSLCertificatePrivateKeys{ - CertificatePrivateKeys: []ssl.CertificatePrivateKey{ - ssl.CertificatePrivateKey{ - Key: "testkey1", - }, - ssl.CertificatePrivateKey{ - Key: "testkey2", - }, - }, - } - - data, err := o.GetFieldData() - - assert.Nil(t, err) - assert.Len(t, data, 2) - assert.True(t, data[0].Exists("key")) - assert.Equal(t, "testkey1", data[0].Get("key").Value) - assert.True(t, data[1].Exists("key")) - assert.Equal(t, "testkey2", data[1].Get("key").Value) - }) -} diff --git a/cmd/storage.go b/cmd/storage.go deleted file mode 100644 index 4704de5..0000000 --- a/cmd/storage.go +++ /dev/null @@ -1,141 +0,0 @@ -package cmd - -import ( - "strconv" - - "github.com/spf13/cobra" - "github.com/ukfast/cli/internal/pkg/output" - "github.com/ukfast/sdk-go/pkg/service/storage" -) - -func storageRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "storage", - Short: "Commands relating to Storage service", - } - - // Child root commands - cmd.AddCommand(storageSolutionRootCmd()) - cmd.AddCommand(storageHostRootCmd()) - cmd.AddCommand(storageVolumeRootCmd()) - - return cmd -} - -func outputStorageSolutions(solutions []storage.Solution) { - err := Output(&OutputStorageSolutions{Solutions: solutions}) - if err != nil { - output.Fatalf("Failed to output solutions: %s", err) - } -} - -// OutputStorageSolutions implements OutputDataProvider for outputting an array of Solutions -type OutputStorageSolutions struct { - Solutions []storage.Solution -} - -func (o *OutputStorageSolutions) GetData() interface{} { - return o.Solutions -} - -func (o *OutputStorageSolutions) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, solution := range o.Solutions { - fields := o.getOrderedFields(solution) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputStorageSolutions) getOrderedFields(solution storage.Solution) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(solution.ID), true)) - fields.Set("name", output.NewFieldValue(solution.Name, true)) - fields.Set("san_id", output.NewFieldValue(strconv.Itoa(solution.SanID), true)) - fields.Set("created_at", output.NewFieldValue(solution.CreatedAt.String(), true)) - fields.Set("updated_at", output.NewFieldValue(solution.UpdatedAt.String(), true)) - - return fields -} - -func outputStorageVolumes(volumes []storage.Volume) { - err := Output(&OutputStorageVolumes{Volumes: volumes}) - if err != nil { - output.Fatalf("Failed to output volumes: %s", err) - } -} - -// OutputStorageVolumes implements OutputDataProvider for outputting an array of Volumes -type OutputStorageVolumes struct { - Volumes []storage.Volume -} - -func (o *OutputStorageVolumes) GetData() interface{} { - return o.Volumes -} - -func (o *OutputStorageVolumes) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, volume := range o.Volumes { - fields := o.getOrderedFields(volume) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputStorageVolumes) getOrderedFields(volume storage.Volume) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(volume.ID), true)) - fields.Set("name", output.NewFieldValue(volume.Name, true)) - fields.Set("wwn", output.NewFieldValue(volume.WWN, false)) - fields.Set("size_gb", output.NewFieldValue(strconv.Itoa(volume.SizeGB), true)) - fields.Set("status", output.NewFieldValue(volume.Status, true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(volume.SolutionID), true)) - fields.Set("created_at", output.NewFieldValue(volume.CreatedAt.String(), true)) - fields.Set("updated_at", output.NewFieldValue(volume.UpdatedAt.String(), true)) - - return fields -} - -func outputStorageHosts(hosts []storage.Host) { - err := Output(&OutputStorageHosts{Hosts: hosts}) - if err != nil { - output.Fatalf("Failed to output hosts: %s", err) - } -} - -// OutputStorageHosts implements OutputDataProvider for outputting an array of Hosts -type OutputStorageHosts struct { - Hosts []storage.Host -} - -func (o *OutputStorageHosts) GetData() interface{} { - return o.Hosts -} - -func (o *OutputStorageHosts) GetFieldData() ([]*output.OrderedFields, error) { - var data []*output.OrderedFields - for _, host := range o.Hosts { - fields := o.getOrderedFields(host) - data = append(data, fields) - } - - return data, nil -} - -func (o *OutputStorageHosts) getOrderedFields(host storage.Host) *output.OrderedFields { - fields := output.NewOrderedFields() - fields.Set("id", output.NewFieldValue(strconv.Itoa(host.ID), true)) - fields.Set("name", output.NewFieldValue(host.Name, true)) - fields.Set("os_type", output.NewFieldValue(host.OSType, false)) - fields.Set("iqn", output.NewFieldValue(host.IQN, false)) - fields.Set("server_id", output.NewFieldValue(strconv.Itoa(host.ServerID), true)) - fields.Set("status", output.NewFieldValue(host.Status, true)) - fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(host.SolutionID), true)) - fields.Set("created_at", output.NewFieldValue(host.CreatedAt.String(), true)) - fields.Set("updated_at", output.NewFieldValue(host.UpdatedAt.String(), true)) - - return fields -} diff --git a/cmd/storage/output.go b/cmd/storage/output.go new file mode 100644 index 0000000..8b50a6f --- /dev/null +++ b/cmd/storage/output.go @@ -0,0 +1,78 @@ +package storage + +import ( + "strconv" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/service/storage" +) + +func OutputStorageSolutionsProvider(solutions []storage.Solution) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(solutions), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, solution := range solutions { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(solution.ID), true)) + fields.Set("name", output.NewFieldValue(solution.Name, true)) + fields.Set("san_id", output.NewFieldValue(strconv.Itoa(solution.SanID), true)) + fields.Set("created_at", output.NewFieldValue(solution.CreatedAt.String(), true)) + fields.Set("updated_at", output.NewFieldValue(solution.UpdatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputStorageVolumesProvider(volumes []storage.Volume) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(volumes), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, volume := range volumes { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(volume.ID), true)) + fields.Set("name", output.NewFieldValue(volume.Name, true)) + fields.Set("wwn", output.NewFieldValue(volume.WWN, false)) + fields.Set("size_gb", output.NewFieldValue(strconv.Itoa(volume.SizeGB), true)) + fields.Set("status", output.NewFieldValue(volume.Status, true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(volume.SolutionID), true)) + fields.Set("created_at", output.NewFieldValue(volume.CreatedAt.String(), true)) + fields.Set("updated_at", output.NewFieldValue(volume.UpdatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} + +func OutputStorageHostsProvider(hosts []storage.Host) output.OutputHandlerProvider { + return output.NewGenericOutputHandlerProvider( + output.WithData(hosts), + output.WithFieldDataFunc(func() ([]*output.OrderedFields, error) { + var data []*output.OrderedFields + for _, host := range hosts { + fields := output.NewOrderedFields() + fields.Set("id", output.NewFieldValue(strconv.Itoa(host.ID), true)) + fields.Set("name", output.NewFieldValue(host.Name, true)) + fields.Set("os_type", output.NewFieldValue(host.OSType, false)) + fields.Set("iqn", output.NewFieldValue(host.IQN, false)) + fields.Set("server_id", output.NewFieldValue(strconv.Itoa(host.ServerID), true)) + fields.Set("status", output.NewFieldValue(host.Status, true)) + fields.Set("solution_id", output.NewFieldValue(strconv.Itoa(host.SolutionID), true)) + fields.Set("created_at", output.NewFieldValue(host.CreatedAt.String(), true)) + fields.Set("updated_at", output.NewFieldValue(host.UpdatedAt.String(), true)) + + data = append(data, fields) + } + + return data, nil + }), + ) +} diff --git a/cmd/storage/storage.go b/cmd/storage/storage.go new file mode 100644 index 0000000..b28559c --- /dev/null +++ b/cmd/storage/storage.go @@ -0,0 +1,20 @@ +package storage + +import ( + "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" +) + +func StorageRootCmd(f factory.ClientFactory) *cobra.Command { + cmd := &cobra.Command{ + Use: "storage", + Short: "Commands relating to Storage service", + } + + // Child root commands + cmd.AddCommand(storageSolutionRootCmd(f)) + cmd.AddCommand(storageHostRootCmd(f)) + cmd.AddCommand(storageVolumeRootCmd(f)) + + return cmd +} diff --git a/cmd/storage_host.go b/cmd/storage/storage_host.go similarity index 62% rename from cmd/storage_host.go rename to cmd/storage/storage_host.go index 4e44bdc..e49987b 100644 --- a/cmd/storage_host.go +++ b/cmd/storage/storage_host.go @@ -1,57 +1,57 @@ -package cmd +package storage import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/storage" ) -func storageHostRootCmd() *cobra.Command { +func storageHostRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "host", Short: "sub-commands relating to hosts", } // Child commands - cmd.AddCommand(storageHostListCmd()) - cmd.AddCommand(storageHostShowCmd()) + cmd.AddCommand(storageHostListCmd(f)) + cmd.AddCommand(storageHostShowCmd(f)) return cmd } -func storageHostListCmd() *cobra.Command { +func storageHostListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists hosts", Long: "This command lists hosts", Example: "ukfast storage host list", - Run: func(cmd *cobra.Command, args []string) { - storageHostList(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageHostList(f.NewClient().StorageService(), cmd, args) }, } } -func storageHostList(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageHostList(service storage.StorageService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } hosts, err := service.GetHosts(params) if err != nil { - output.Fatalf("Error retrieving hosts: %s", err) - return + return fmt.Errorf("Error retrieving hosts: %s", err) } - outputStorageHosts(hosts) + return output.CommandOutput(cmd, OutputStorageHostsProvider(hosts)) } -func storageHostShowCmd() *cobra.Command { +func storageHostShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a host", @@ -64,13 +64,13 @@ func storageHostShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - storageHostShow(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageHostShow(f.NewClient().StorageService(), cmd, args) }, } } -func storageHostShow(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageHostShow(service storage.StorageService, cmd *cobra.Command, args []string) error { var hosts []storage.Host for _, arg := range args { hostID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func storageHostShow(service storage.StorageService, cmd *cobra.Command, args [] hosts = append(hosts, host) } - outputStorageHosts(hosts) + return output.CommandOutput(cmd, OutputStorageHostsProvider(hosts)) } diff --git a/cmd/storage_host_test.go b/cmd/storage/storage_host_test.go similarity index 83% rename from cmd/storage_host_test.go rename to cmd/storage/storage_host_test.go index e29eb70..69c8d73 100644 --- a/cmd/storage_host_test.go +++ b/cmd/storage/storage_host_test.go @@ -1,4 +1,4 @@ -package cmd +package storage import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/storage" @@ -24,7 +25,7 @@ func Test_storageHostList(t *testing.T) { storageHostList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_storageHostList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - storageHostList(service, cmd, []string{}) - }) + err := storageHostList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetHostsError_OutputsFatal", func(t *testing.T) { + t.Run("GetHostsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_storageHostList(t *testing.T) { service.EXPECT().GetHosts(gomock.Any()).Return([]storage.Host{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving hosts: test error\n", func() { - storageHostList(service, &cobra.Command{}, []string{}) - }) + err := storageHostList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving hosts: test error", err.Error()) }) } func Test_storageHostShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := storageHostShowCmd().Args(nil, []string{"123"}) + err := storageHostShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := storageHostShowCmd().Args(nil, []string{}) + err := storageHostShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing host", err.Error()) diff --git a/cmd/storage_solution.go b/cmd/storage/storage_solution.go similarity index 62% rename from cmd/storage_solution.go rename to cmd/storage/storage_solution.go index 8549118..a532c8b 100644 --- a/cmd/storage_solution.go +++ b/cmd/storage/storage_solution.go @@ -1,57 +1,57 @@ -package cmd +package storage import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/storage" ) -func storageSolutionRootCmd() *cobra.Command { +func storageSolutionRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "solution", Short: "sub-commands relating to solutions", } // Child commands - cmd.AddCommand(storageSolutionListCmd()) - cmd.AddCommand(storageSolutionShowCmd()) + cmd.AddCommand(storageSolutionListCmd(f)) + cmd.AddCommand(storageSolutionShowCmd(f)) return cmd } -func storageSolutionListCmd() *cobra.Command { +func storageSolutionListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists solutions", Long: "This command lists solutions", Example: "ukfast storage solution list", - Run: func(cmd *cobra.Command, args []string) { - storageSolutionList(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageSolutionList(f.NewClient().StorageService(), cmd, args) }, } } -func storageSolutionList(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageSolutionList(service storage.StorageService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } solutions, err := service.GetSolutions(params) if err != nil { - output.Fatalf("Error retrieving solutions: %s", err) - return + return fmt.Errorf("Error retrieving solutions: %s", err) } - outputStorageSolutions(solutions) + return output.CommandOutput(cmd, OutputStorageSolutionsProvider(solutions)) } -func storageSolutionShowCmd() *cobra.Command { +func storageSolutionShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a solution", @@ -64,13 +64,13 @@ func storageSolutionShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - storageSolutionShow(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageSolutionShow(f.NewClient().StorageService(), cmd, args) }, } } -func storageSolutionShow(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageSolutionShow(service storage.StorageService, cmd *cobra.Command, args []string) error { var solutions []storage.Solution for _, arg := range args { solutionID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func storageSolutionShow(service storage.StorageService, cmd *cobra.Command, arg solutions = append(solutions, solution) } - outputStorageSolutions(solutions) + return output.CommandOutput(cmd, OutputStorageSolutionsProvider(solutions)) } diff --git a/cmd/storage_solution_test.go b/cmd/storage/storage_solution_test.go similarity index 83% rename from cmd/storage_solution_test.go rename to cmd/storage/storage_solution_test.go index 6267e1b..7c4a2f5 100644 --- a/cmd/storage_solution_test.go +++ b/cmd/storage/storage_solution_test.go @@ -1,4 +1,4 @@ -package cmd +package storage import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/storage" @@ -24,7 +25,7 @@ func Test_storageSolutionList(t *testing.T) { storageSolutionList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_storageSolutionList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - storageSolutionList(service, cmd, []string{}) - }) + err := storageSolutionList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetSolutionsError_OutputsFatal", func(t *testing.T) { + t.Run("GetSolutionsError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_storageSolutionList(t *testing.T) { service.EXPECT().GetSolutions(gomock.Any()).Return([]storage.Solution{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving solutions: test error\n", func() { - storageSolutionList(service, &cobra.Command{}, []string{}) - }) + err := storageSolutionList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving solutions: test error", err.Error()) }) } func Test_storageSolutionShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := storageSolutionShowCmd().Args(nil, []string{"123"}) + err := storageSolutionShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := storageSolutionShowCmd().Args(nil, []string{}) + err := storageSolutionShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing solution", err.Error()) diff --git a/cmd/storage_volume.go b/cmd/storage/storage_volume.go similarity index 62% rename from cmd/storage_volume.go rename to cmd/storage/storage_volume.go index 921d545..4508b67 100644 --- a/cmd/storage_volume.go +++ b/cmd/storage/storage_volume.go @@ -1,57 +1,57 @@ -package cmd +package storage import ( "errors" + "fmt" "strconv" "github.com/spf13/cobra" + "github.com/ukfast/cli/internal/pkg/factory" "github.com/ukfast/cli/internal/pkg/helper" "github.com/ukfast/cli/internal/pkg/output" "github.com/ukfast/sdk-go/pkg/service/storage" ) -func storageVolumeRootCmd() *cobra.Command { +func storageVolumeRootCmd(f factory.ClientFactory) *cobra.Command { cmd := &cobra.Command{ Use: "volume", Short: "sub-commands relating to volumes", } // Child commands - cmd.AddCommand(storageVolumeListCmd()) - cmd.AddCommand(storageVolumeShowCmd()) + cmd.AddCommand(storageVolumeListCmd(f)) + cmd.AddCommand(storageVolumeShowCmd(f)) return cmd } -func storageVolumeListCmd() *cobra.Command { +func storageVolumeListCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "list", Short: "Lists volumes", Long: "This command lists volumes", Example: "ukfast storage volume list", - Run: func(cmd *cobra.Command, args []string) { - storageVolumeList(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageVolumeList(f.NewClient().StorageService(), cmd, args) }, } } -func storageVolumeList(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageVolumeList(service storage.StorageService, cmd *cobra.Command, args []string) error { params, err := helper.GetAPIRequestParametersFromFlags(cmd) if err != nil { - output.Fatal(err.Error()) - return + return err } volumes, err := service.GetVolumes(params) if err != nil { - output.Fatalf("Error retrieving volumes: %s", err) - return + return fmt.Errorf("Error retrieving volumes: %s", err) } - outputStorageVolumes(volumes) + return output.CommandOutput(cmd, OutputStorageVolumesProvider(volumes)) } -func storageVolumeShowCmd() *cobra.Command { +func storageVolumeShowCmd(f factory.ClientFactory) *cobra.Command { return &cobra.Command{ Use: "show ...", Short: "Shows a volume", @@ -64,13 +64,13 @@ func storageVolumeShowCmd() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - storageVolumeShow(getClient().StorageService(), cmd, args) + RunE: func(cmd *cobra.Command, args []string) error { + return storageVolumeShow(f.NewClient().StorageService(), cmd, args) }, } } -func storageVolumeShow(service storage.StorageService, cmd *cobra.Command, args []string) { +func storageVolumeShow(service storage.StorageService, cmd *cobra.Command, args []string) error { var volumes []storage.Volume for _, arg := range args { volumeID, err := strconv.Atoi(arg) @@ -88,5 +88,5 @@ func storageVolumeShow(service storage.StorageService, cmd *cobra.Command, args volumes = append(volumes, volume) } - outputStorageVolumes(volumes) + return output.CommandOutput(cmd, OutputStorageVolumesProvider(volumes)) } diff --git a/cmd/storage_volume_test.go b/cmd/storage/storage_volume_test.go similarity index 83% rename from cmd/storage_volume_test.go rename to cmd/storage/storage_volume_test.go index 81506eb..94b450f 100644 --- a/cmd/storage_volume_test.go +++ b/cmd/storage/storage_volume_test.go @@ -1,4 +1,4 @@ -package cmd +package storage import ( "errors" @@ -7,6 +7,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/cli/test/mocks" "github.com/ukfast/cli/test/test_output" "github.com/ukfast/sdk-go/pkg/service/storage" @@ -24,7 +25,7 @@ func Test_storageVolumeList(t *testing.T) { storageVolumeList(service, &cobra.Command{}, []string{}) }) - t.Run("MalformedFlag_OutputsFatal", func(t *testing.T) { + t.Run("MalformedFlag_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -32,12 +33,12 @@ func Test_storageVolumeList(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "") - test_output.AssertFatalOutput(t, "Missing value for filtering\n", func() { - storageVolumeList(service, cmd, []string{}) - }) + err := storageVolumeList(service, cmd, []string{}) + + assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err) }) - t.Run("GetVolumesError_OutputsFatal", func(t *testing.T) { + t.Run("GetVolumesError_ReturnsError", func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() @@ -46,21 +47,21 @@ func Test_storageVolumeList(t *testing.T) { service.EXPECT().GetVolumes(gomock.Any()).Return([]storage.Volume{}, errors.New("test error")).Times(1) - test_output.AssertFatalOutput(t, "Error retrieving volumes: test error\n", func() { - storageVolumeList(service, &cobra.Command{}, []string{}) - }) + err := storageVolumeList(service, &cobra.Command{}, []string{}) + + assert.Equal(t, "Error retrieving volumes: test error", err.Error()) }) } func Test_storageVolumeShowCmd_Args(t *testing.T) { t.Run("ValidArgs_NoError", func(t *testing.T) { - err := storageVolumeShowCmd().Args(nil, []string{"123"}) + err := storageVolumeShowCmd(nil).Args(nil, []string{"123"}) assert.Nil(t, err) }) t.Run("InvalidArgs_Error", func(t *testing.T) { - err := storageVolumeShowCmd().Args(nil, []string{}) + err := storageVolumeShowCmd(nil).Args(nil, []string{}) assert.NotNil(t, err) assert.Equal(t, "Missing volume", err.Error()) diff --git a/go.mod b/go.mod index f4da3dc..d0eb09a 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/spf13/viper v1.3.2 github.com/stretchr/testify v1.3.0 github.com/ukfast/sdk-go v1.3.4 + golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b // indirect gopkg.in/go-playground/assert.v1 v1.2.1 ) diff --git a/go.sum b/go.sum index 5990fd7..b71c22b 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,8 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk= diff --git a/internal/pkg/factory/client_factory.go b/internal/pkg/factory/client_factory.go new file mode 100644 index 0000000..e10930c --- /dev/null +++ b/internal/pkg/factory/client_factory.go @@ -0,0 +1,101 @@ +package factory + +import ( + "crypto/tls" + "net/http" + "time" + + "github.com/ukfast/cli/internal/pkg/output" + "github.com/ukfast/sdk-go/pkg/client" + "github.com/ukfast/sdk-go/pkg/connection" + "github.com/ukfast/sdk-go/pkg/logging" +) + +type ClientFactory interface { + NewClient() client.Client +} + +type UKFastClientFactoryOption func(f *UKFastClientFactory) + +type UKFastClientFactory struct { + apiKey string + apiTimeout int + apiURI string + apiInsecure bool + apiHeaders map[string]string + apiDebug bool +} + +func WithAPIKey(apiKey string) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiKey = apiKey + } +} + +func WithTimeout(apiTimeout int) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiTimeout = apiTimeout + } +} + +func WithURI(apiURI string) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiURI = apiURI + } +} + +func WithInsecure(apiInsecure bool) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiInsecure = apiInsecure + } +} + +func WithHeaders(apiHeaders map[string]string) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiHeaders = apiHeaders + } +} + +func WithDebug(apiDebug bool) UKFastClientFactoryOption { + return func(p *UKFastClientFactory) { + p.apiDebug = apiDebug + } +} + +func NewUKFastClientFactory(opts ...UKFastClientFactoryOption) *UKFastClientFactory { + f := &UKFastClientFactory{} + for _, opt := range opts { + opt(f) + } + return f +} + +func (f *UKFastClientFactory) NewClient() client.Client { + conn := connection.NewAPIConnection(&connection.APIKeyCredentials{APIKey: f.apiKey}) + conn.UserAgent = "ukfast-cli" + if f.apiURI != "" { + conn.APIURI = f.apiURI + } + if f.apiTimeout > 0 { + conn.HTTPClient.Timeout = (time.Duration(f.apiTimeout) * time.Second) + } + if f.apiInsecure { + conn.HTTPClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + } + if f.apiHeaders != nil { + conn.Headers = http.Header{} + for headerKey, headerValue := range f.apiHeaders { + conn.Headers.Add(headerKey, headerValue) + } + } + + if f.apiDebug { + logging.SetLogger(&output.DebugLogger{}) + } + + return client.NewClient(conn) +} diff --git a/internal/pkg/helper/flag.go b/internal/pkg/helper/flag.go index 0498ef1..a68c23d 100644 --- a/internal/pkg/helper/flag.go +++ b/internal/pkg/helper/flag.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/ukfast/cli/internal/pkg/clierrors" "github.com/ukfast/sdk-go/pkg/connection" ) @@ -56,7 +57,7 @@ func GetFilteringArrayFromStringArrayFlag(filters []string) ([]connection.APIReq for _, filter := range filters { f, err := GetFilteringFromStringFlag(filter) if err != nil { - return filtering, err + return filtering, clierrors.NewErrInvalidFlagValue("filter", filter, err) } filtering = append(filtering, f) @@ -144,7 +145,7 @@ func GetSortingFromStringFlag(sort string) connection.APIRequestSorting { } func GetAPIRequestParametersFromFlags(cmd *cobra.Command) (connection.APIRequestParameters, error) { - flagFilter, err := cmd.Flags().GetStringArray("filter") + flagFilter, _ := cmd.Flags().GetStringArray("filter") filtering, err := GetFilteringArrayFromStringArrayFlag(flagFilter) if err != nil { return connection.APIRequestParameters{}, err diff --git a/cmd/util.go b/internal/pkg/helper/wait.go similarity index 98% rename from cmd/util.go rename to internal/pkg/helper/wait.go index c8424e9..0f17fce 100644 --- a/cmd/util.go +++ b/internal/pkg/helper/wait.go @@ -1,4 +1,4 @@ -package cmd +package helper import ( "errors" diff --git a/cmd/root_test.go b/internal/pkg/helper/wait_test.go similarity index 80% rename from cmd/root_test.go rename to internal/pkg/helper/wait_test.go index 8ffe707..f1e2fd9 100644 --- a/cmd/root_test.go +++ b/internal/pkg/helper/wait_test.go @@ -1,4 +1,4 @@ -package cmd +package helper import ( "errors" @@ -6,18 +6,14 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "github.com/ukfast/cli/test" ) -func testResetViper() { - viper.SetDefault("command_wait_timeout_seconds", 1200) - viper.SetDefault("command_wait_sleep_seconds", 5) -} - func TestWaitForCommand(t *testing.T) { t.Run("SuccessAfter3Attempts", func(t *testing.T) { - testResetViper() - defer testResetViper() + test.TestResetViper() + defer test.TestResetViper() viper.SetDefault("command_wait_sleep_seconds", 1) attempt := 1 @@ -37,8 +33,8 @@ func TestWaitForCommand(t *testing.T) { }) t.Run("ErrorAfter3Attempts", func(t *testing.T) { - testResetViper() - defer testResetViper() + test.TestResetViper() + defer test.TestResetViper() viper.SetDefault("command_wait_sleep_seconds", 1) attempt := 1 @@ -58,8 +54,8 @@ func TestWaitForCommand(t *testing.T) { }) t.Run("InvalidWaitTimeout", func(t *testing.T) { - testResetViper() - defer testResetViper() + test.TestResetViper() + defer test.TestResetViper() viper.SetDefault("command_wait_timeout_seconds", 0) attempt := 1 @@ -75,8 +71,8 @@ func TestWaitForCommand(t *testing.T) { }) t.Run("InvalidWaitSleep", func(t *testing.T) { - testResetViper() - defer testResetViper() + test.TestResetViper() + defer test.TestResetViper() viper.SetDefault("command_wait_sleep_seconds", 0) attempt := 1 diff --git a/internal/pkg/output/output.go b/internal/pkg/output/output.go index 2ffb411..cd9028c 100644 --- a/internal/pkg/output/output.go +++ b/internal/pkg/output/output.go @@ -12,6 +12,7 @@ import ( "github.com/olekukonko/tablewriter" "github.com/ryanuber/go-glob" + "github.com/spf13/cobra" ) var outputExit func(code int) = os.Exit @@ -351,3 +352,12 @@ func NewFieldValue(value string, def bool) FieldValue { Default: def, } } + +func CommandOutput(cmd *cobra.Command, out OutputHandlerProvider) error { + format, _ := cmd.Flags().GetString("format") + handler := NewOutputHandler(out, format) + handler.Properties, _ = cmd.Flags().GetStringSlice("property") + handler.Template, _ = cmd.Flags().GetString("outputtemplate") + + return handler.Handle() +} diff --git a/internal/pkg/output/output_handler.go b/internal/pkg/output/output_handler.go index 968e16c..80f4a1d 100644 --- a/internal/pkg/output/output_handler.go +++ b/internal/pkg/output/output_handler.go @@ -12,7 +12,6 @@ type OutputHandler struct { Provider OutputHandlerProvider Properties []string Template string - SupportedFormats []string UnsupportedFormatHandler UnsupportedFormatHandler } @@ -35,7 +34,7 @@ func (o *OutputHandler) Handle() error { return o.UnsupportedFormatHandler() } - return fmt.Errorf("Unsupported output format [%s], supported formats: %s", o.Format, strings.Join(o.SupportedFormats, ", ")) + return fmt.Errorf("Unsupported output format [%s], supported formats: %s", o.Format, strings.Join(o.Provider.SupportedFormats(), ", ")) } switch o.Format { @@ -74,11 +73,11 @@ func (o *OutputHandler) Handle() error { } func (o *OutputHandler) supportedFormat() bool { - if o.SupportedFormats == nil { + if o.Provider.SupportedFormats() == nil { return true } - for _, supportedFormat := range o.SupportedFormats { + for _, supportedFormat := range o.Provider.SupportedFormats() { if strings.ToLower(supportedFormat) == o.Format { return true } diff --git a/internal/pkg/output/output_handler_provider.go b/internal/pkg/output/output_handler_provider.go index 0c6a2c2..8c7325e 100644 --- a/internal/pkg/output/output_handler_provider.go +++ b/internal/pkg/output/output_handler_provider.go @@ -12,27 +12,76 @@ import ( type OutputHandlerProvider interface { GetData() interface{} GetFieldData() ([]*OrderedFields, error) + SupportedFormats() []string } +type ProviderOption func(p *GenericOutputHandlerProvider) + type GenericOutputHandlerProvider struct { - items interface{} - DefaultFields []string - IgnoredFields []string + data interface{} + fieldDataFunc func() ([]*OrderedFields, error) + supportedFormats []string +} + +func NewGenericOutputHandlerProvider(opts ...ProviderOption) *GenericOutputHandlerProvider { + p := &GenericOutputHandlerProvider{} + for _, opt := range opts { + opt(p) + } + return p +} + +func WithData(data interface{}) ProviderOption { + return func(p *GenericOutputHandlerProvider) { + p.data = data + } +} + +func WithSupportedFormats(supportedFormats []string) ProviderOption { + return func(p *GenericOutputHandlerProvider) { + p.supportedFormats = supportedFormats + } } -func NewGenericOutputHandlerProvider(items interface{}, defaultFields []string, ignoredFields []string) *GenericOutputHandlerProvider { - return &GenericOutputHandlerProvider{items: items, DefaultFields: defaultFields, IgnoredFields: ignoredFields} +func WithFieldDataFunc(fieldDataFunc func() ([]*OrderedFields, error)) ProviderOption { + return func(p *GenericOutputHandlerProvider) { + p.fieldDataFunc = fieldDataFunc + } +} + +func (p *GenericOutputHandlerProvider) GetData() interface{} { + return p.data +} + +func (p *GenericOutputHandlerProvider) GetFieldData() ([]*OrderedFields, error) { + return p.fieldDataFunc() +} + +func (p *GenericOutputHandlerProvider) SupportedFormats() []string { + return p.supportedFormats +} + +type SerializedOutputHandlerProvider struct { + *GenericOutputHandlerProvider + DefaultFields []string + IgnoredFields []string } -func (o *GenericOutputHandlerProvider) GetData() interface{} { - return o.items +func NewSerializedOutputHandlerProvider(items interface{}, defaultFields []string, ignoredFields []string) *SerializedOutputHandlerProvider { + return &SerializedOutputHandlerProvider{ + GenericOutputHandlerProvider: NewGenericOutputHandlerProvider( + WithData(items), + ), + DefaultFields: defaultFields, + IgnoredFields: ignoredFields, + } } -func (o *GenericOutputHandlerProvider) GetFieldData() ([]*OrderedFields, error) { - return o.convert(reflect.ValueOf(o.items)), nil +func (o *SerializedOutputHandlerProvider) GetFieldData() ([]*OrderedFields, error) { + return o.convert(reflect.ValueOf(o.GetData())), nil } -func (o *GenericOutputHandlerProvider) convert(reflectedValue reflect.Value) []*OrderedFields { +func (o *SerializedOutputHandlerProvider) convert(reflectedValue reflect.Value) []*OrderedFields { fields := []*OrderedFields{} switch reflectedValue.Kind() { @@ -47,7 +96,7 @@ func (o *GenericOutputHandlerProvider) convert(reflectedValue reflect.Value) []* return fields } -func (o *GenericOutputHandlerProvider) convertStruct(reflectedValue reflect.Value) *OrderedFields { +func (o *SerializedOutputHandlerProvider) convertStruct(reflectedValue reflect.Value) *OrderedFields { fields := NewOrderedFields() reflectedValueType := reflectedValue.Type() @@ -76,7 +125,7 @@ func (o *GenericOutputHandlerProvider) convertStruct(reflectedValue reflect.Valu return fields } -func (o *GenericOutputHandlerProvider) fieldToString(reflectedValue reflect.Value) string { +func (o *SerializedOutputHandlerProvider) fieldToString(reflectedValue reflect.Value) string { switch reflectedValue.Kind() { case reflect.Slice: var items []string @@ -100,15 +149,15 @@ func (o *GenericOutputHandlerProvider) fieldToString(reflectedValue reflect.Valu return fmt.Sprintf("%v", reflectedValue.Interface()) } -func (o *GenericOutputHandlerProvider) isDefaultField(name string) bool { +func (o *SerializedOutputHandlerProvider) isDefaultField(name string) bool { return o.fieldInFields(name, o.DefaultFields) } -func (o *GenericOutputHandlerProvider) isIgnoredField(name string) bool { +func (o *SerializedOutputHandlerProvider) isIgnoredField(name string) bool { return o.fieldInFields(name, o.IgnoredFields) } -func (o *GenericOutputHandlerProvider) fieldInFields(name string, fields []string) bool { +func (o *SerializedOutputHandlerProvider) fieldInFields(name string, fields []string) bool { for _, field := range fields { if strings.ToLower(field) == strings.ToLower(name) { return true diff --git a/internal/pkg/output/output_handler_provider_test.go b/internal/pkg/output/output_handler_provider_test.go index f88cf04..e9aec23 100644 --- a/internal/pkg/output/output_handler_provider_test.go +++ b/internal/pkg/output/output_handler_provider_test.go @@ -7,44 +7,24 @@ import ( "github.com/stretchr/testify/assert" ) -type testOutputDataProvider struct { - GetFieldDataError error -} type testOutputData struct { TestProperty1 string TestProperty2 string } -func (o testOutputDataProvider) GetData() interface{} { - return testOutputData{TestProperty1: "testvalue1", TestProperty2: "testvalue2"} -} - -func (o testOutputDataProvider) GetFieldData() ([]*OrderedFields, error) { - var data []*OrderedFields - fields1 := NewOrderedFields() - fields1.Set("test_property_1", NewFieldValue("fields1 test value 1", true)) - fields1.Set("test_property_2", NewFieldValue("fields1 test value 2", true)) - fields2 := NewOrderedFields() - fields2.Set("test_property_1", NewFieldValue("fields2 test value 1", true)) - fields2.Set("test_property_2", NewFieldValue("fields2 test value 2", true)) - - data = append(data, fields1, fields2) - return data, o.GetFieldDataError -} - -func TestGenericOutputHandlerProvider_GetData_ReturnsData(t *testing.T) { +func TestSerializedOutputHandlerProvider_GetData_ReturnsData(t *testing.T) { data := testOutputData{} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output := o.GetData() assert.Equal(t, data, output) } -func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { +func TestSerializedOutputHandlerProvider_GetFieldData(t *testing.T) { t.Run("SingleStruct_ReturnsExpectedFields", func(t *testing.T) { data := testOutputData{} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output, err := o.GetFieldData() @@ -56,7 +36,7 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { t.Run("MultipleStructs_ReturnsExpectedFields", func(t *testing.T) { data1 := testOutputData{} data2 := testOutputData{} - o := NewGenericOutputHandlerProvider([]testOutputData{data1, data2}, nil, nil) + o := NewSerializedOutputHandlerProvider([]testOutputData{data1, data2}, nil, nil) output, err := o.GetFieldData() @@ -71,7 +51,7 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { } data := testType{} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output, err := o.GetFieldData() @@ -86,7 +66,7 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { } data := testType{} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output, err := o.GetFieldData() @@ -102,7 +82,7 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { } data := testType{} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output, err := o.GetFieldData() @@ -117,7 +97,7 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { } data := testType{Property1: []string{"some", "value"}} - o := NewGenericOutputHandlerProvider(data, nil, nil) + o := NewSerializedOutputHandlerProvider(data, nil, nil) output, err := o.GetFieldData() @@ -127,41 +107,41 @@ func TestGenericOutputHandlerProvider_GetFieldData(t *testing.T) { }) } -func TestGenericOutputHandlerProvider_isDefaultField(t *testing.T) { +func TestSerializedOutputHandlerProvider_isDefaultField(t *testing.T) { t.Run("ItemInDefaultFields_ReturnsTrue", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, []string{"field1", "field2", "field3"}, nil) + o := NewSerializedOutputHandlerProvider(nil, []string{"field1", "field2", "field3"}, nil) defaultField := o.isDefaultField("field2") assert.True(t, defaultField) }) t.Run("ItemNotInDefaultFields_ReturnsFalse", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, []string{"field1", "field2", "field3"}, nil) + o := NewSerializedOutputHandlerProvider(nil, []string{"field1", "field2", "field3"}, nil) defaultField := o.isDefaultField("somefield") assert.False(t, defaultField) }) } -func TestGenericOutputHandlerProvider_isIgnoredField(t *testing.T) { +func TestSerializedOutputHandlerProvider_isIgnoredField(t *testing.T) { t.Run("ItemInIgnoredFields_ReturnsTrue", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, []string{"field1", "field2", "field3"}) + o := NewSerializedOutputHandlerProvider(nil, nil, []string{"field1", "field2", "field3"}) defaultField := o.isIgnoredField("field2") assert.True(t, defaultField) }) t.Run("ItemNotInIgnoredFields_ReturnsFalse", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, []string{"field1", "field2", "field3"}) + o := NewSerializedOutputHandlerProvider(nil, nil, []string{"field1", "field2", "field3"}) defaultField := o.isIgnoredField("somefield") assert.False(t, defaultField) }) } -func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { +func TestSerializedOutputHandlerProvider_fieldToString(t *testing.T) { t.Run("StringType_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := "somestring" output := o.fieldToString(reflect.ValueOf(v)) @@ -170,7 +150,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("BoolType_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := true output := o.fieldToString(reflect.ValueOf(v)) @@ -179,7 +159,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("IntType_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := int(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -188,7 +168,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Int8Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := int8(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -197,7 +177,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Int16Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := int16(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -206,7 +186,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Int32Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := int32(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -215,7 +195,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Int64Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := int64(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -224,7 +204,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("UintType_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := uint(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -233,7 +213,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Uint8Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := uint8(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -242,7 +222,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Uint16Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := uint16(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -251,7 +231,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Uint32Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := uint32(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -260,7 +240,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Uint64Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := uint64(123) output := o.fieldToString(reflect.ValueOf(v)) @@ -269,7 +249,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Float32Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := 123.4 output := o.fieldToString(reflect.ValueOf(v)) @@ -278,7 +258,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("Float64Type_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) v := float64(123.4) output := o.fieldToString(reflect.ValueOf(v)) @@ -287,7 +267,7 @@ func TestGenericOutputHandlerProvider_fieldToString(t *testing.T) { }) t.Run("UnknownType_ReturnsExpectedString", func(t *testing.T) { - o := NewGenericOutputHandlerProvider(nil, nil, nil) + o := NewSerializedOutputHandlerProvider(nil, nil, nil) type somestruct struct{} v := somestruct{} diff --git a/internal/pkg/output/output_handler_test.go b/internal/pkg/output/output_handler_test.go index 4303a09..2075125 100644 --- a/internal/pkg/output/output_handler_test.go +++ b/internal/pkg/output/output_handler_test.go @@ -8,9 +8,25 @@ import ( "github.com/ukfast/cli/test" ) +var testOutputHandlerProvider = NewGenericOutputHandlerProvider( + WithData(testOutputData{TestProperty1: "testvalue1", TestProperty2: "testvalue2"}), + WithFieldDataFunc(func() ([]*OrderedFields, error) { + var data []*OrderedFields + fields1 := NewOrderedFields() + fields1.Set("test_property_1", NewFieldValue("fields1 test value 1", true)) + fields1.Set("test_property_2", NewFieldValue("fields1 test value 2", true)) + fields2 := NewOrderedFields() + fields2.Set("test_property_1", NewFieldValue("fields2 test value 1", true)) + fields2.Set("test_property_2", NewFieldValue("fields2 test value 2", true)) + + data = append(data, fields1, fields2) + return data, nil + }), +) + func TestOutputHandler_Handle(t *testing.T) { t.Run("JSONFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "json") + handler := NewOutputHandler(testOutputHandlerProvider, "json") output := test.CatchStdOut(t, func() { handler.Handle() @@ -20,7 +36,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("TemplateFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "template") + handler := NewOutputHandler(testOutputHandlerProvider, "template") handler.Template = "{{ .TestProperty1 }}" output := test.CatchStdOut(t, func() { @@ -31,7 +47,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("ValueFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "value") + handler := NewOutputHandler(testOutputHandlerProvider, "value") output := test.CatchStdOut(t, func() { handler.Handle() @@ -41,9 +57,11 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("ValueFormat_GetFieldDataError_ReturnsError", func(t *testing.T) { - prov := testOutputDataProvider{ - GetFieldDataError: errors.New("test error 1"), - } + prov := NewGenericOutputHandlerProvider( + WithFieldDataFunc(func() ([]*OrderedFields, error) { + return nil, errors.New("test error 1") + }), + ) handler := NewOutputHandler(prov, "value") @@ -54,7 +72,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("CSVFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "csv") + handler := NewOutputHandler(testOutputHandlerProvider, "csv") output := test.CatchStdOut(t, func() { handler.Handle() @@ -64,9 +82,11 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("CSVFormat_GetFieldDataError_ReturnsError", func(t *testing.T) { - prov := testOutputDataProvider{ - GetFieldDataError: errors.New("test error 1"), - } + prov := NewGenericOutputHandlerProvider( + WithFieldDataFunc(func() ([]*OrderedFields, error) { + return nil, errors.New("test error 1") + }), + ) handler := NewOutputHandler(prov, "csv") @@ -77,7 +97,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("TableFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "table") + handler := NewOutputHandler(testOutputHandlerProvider, "table") output := test.CatchStdOut(t, func() { handler.Handle() @@ -87,9 +107,11 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("TableFormat_GetFieldDataError_ReturnsError", func(t *testing.T) { - prov := testOutputDataProvider{ - GetFieldDataError: errors.New("test error 1"), - } + prov := NewGenericOutputHandlerProvider( + WithFieldDataFunc(func() ([]*OrderedFields, error) { + return nil, errors.New("test error 1") + }), + ) handler := NewOutputHandler(prov, "table") @@ -100,7 +122,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("EmptyFormat_ExpectedTableOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "") + handler := NewOutputHandler(testOutputHandlerProvider, "") output := test.CatchStdOut(t, func() { handler.Handle() @@ -110,7 +132,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("InvalidFormat_ExpectedTableOutputWithStdErrError", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "invalidformat") + handler := NewOutputHandler(testOutputHandlerProvider, "invalidformat") stdOut, stdErr := test.CatchStdOutStdErr(t, func() { handler.Handle() @@ -121,8 +143,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("UnsupportedFormat_NoUnsupportedHandler_ExpectedError", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "table") - handler.SupportedFormats = []string{"json"} + handler := NewOutputHandler(NewGenericOutputHandlerProvider(WithSupportedFormats([]string{"json"})), "table") err := handler.Handle() @@ -130,8 +151,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("UnsupportedFormat_NoUnsupportedHandler_ExpectedError", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "table") - handler.SupportedFormats = []string{"json"} + handler := NewOutputHandler(NewGenericOutputHandlerProvider(WithSupportedFormats([]string{"json"})), "table") err := handler.Handle() @@ -141,8 +161,7 @@ func TestOutputHandler_Handle(t *testing.T) { t.Run("UnsupportedFormat_WithUnsupportedHandler_CallsHandler", func(t *testing.T) { called := false - handler := NewOutputHandler(testOutputDataProvider{}, "table") - handler.SupportedFormats = []string{"json"} + handler := NewOutputHandler(NewGenericOutputHandlerProvider(WithSupportedFormats([]string{"json"})), "table") handler.UnsupportedFormatHandler = func() error { called = true return nil @@ -154,8 +173,7 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("UnsupportedFormat_Error_ReturnsError", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "table") - handler.SupportedFormats = []string{"json"} + handler := NewOutputHandler(NewGenericOutputHandlerProvider(WithSupportedFormats([]string{"json"})), "table") handler.UnsupportedFormatHandler = func() error { return errors.New("test error 1") } @@ -166,8 +184,10 @@ func TestOutputHandler_Handle(t *testing.T) { }) t.Run("SupportedFormat_ExpectedOutput", func(t *testing.T) { - handler := NewOutputHandler(testOutputDataProvider{}, "value") - handler.SupportedFormats = []string{"value"} + prov := testOutputHandlerProvider + prov.supportedFormats = []string{"value"} + + handler := NewOutputHandler(prov, "value") output := test.CatchStdOut(t, func() { handler.Handle() diff --git a/test/helpers.go b/test/helpers.go index 1970467..cb4ab7a 100644 --- a/test/helpers.go +++ b/test/helpers.go @@ -4,6 +4,8 @@ import ( "io/ioutil" "os" "testing" + + "github.com/spf13/viper" ) func dieOn(err error, t *testing.T) { @@ -55,3 +57,8 @@ func CatchStdOutStdErr(t *testing.T, f func()) (stdOut string, stdErr string) { return stdOut, stdErr } + +func TestResetViper() { + viper.SetDefault("command_wait_timeout_seconds", 1200) + viper.SetDefault("command_wait_sleep_seconds", 5) +}