From a12d0396a090b7df41e4125fc8be77c4e31049de Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Mon, 5 Jun 2023 09:22:06 +0530 Subject: [PATCH 01/13] Infrastructure command on bastion Signed-off-by: Sunanda-Boorla --- .../cmd/chef-automate/infrastructure.go | 55 ++++++-------- .../cmd/chef-automate/infrastructure_test.go | 74 +++++++++++++++++++ .../pkg/infrastructure/infrastructure.go | 54 ++++++++++++++ components/ingest-service/server/chef.go | 3 +- 4 files changed, 151 insertions(+), 35 deletions(-) create mode 100644 components/automate-cli/cmd/chef-automate/infrastructure_test.go create mode 100644 components/automate-cli/pkg/infrastructure/infrastructure.go diff --git a/components/automate-cli/cmd/chef-automate/infrastructure.go b/components/automate-cli/cmd/chef-automate/infrastructure.go index 33af2860aef..ec015e85ac0 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure.go @@ -1,15 +1,12 @@ package main import ( - "context" + "os" - "github.com/gofrs/uuid" - "github.com/spf13/cobra" - - api "github.com/chef/automate/api/interservice/deployment" "github.com/chef/automate/components/automate-cli/pkg/docs" + "github.com/chef/automate/components/automate-cli/pkg/infrastructure" "github.com/chef/automate/components/automate-cli/pkg/status" - "github.com/chef/automate/components/automate-deployment/pkg/client" + "github.com/spf13/cobra" ) func init() { @@ -19,9 +16,10 @@ func init() { } var infrastructureCmd = &cobra.Command{ - Use: "infrastructure COMMAND", - Short: "Chef Automate infrastructure", - Long: "Commands for automation infrastructure management, for data related to chef-client runs and chef-server actions.", + Use: "infrastructure COMMAND", + Short: "Chef Automate infrastructure", + Long: "Commands for automation infrastructure management, for data related to chef-client runs and chef-server actions.", + PersistentPreRunE: preInfrastructureCmd, Annotations: map[string]string{ docs.Tag: docs.Automate, }, @@ -39,36 +37,25 @@ var nodeDeleteCmd = &cobra.Command{ } func runDeleteNodeCmd(cmd *cobra.Command, args []string) error { - connection, err := client.Connection(client.DefaultClientTimeout) - + ifw, err := infrastructure.NewDeleteNode(writer) if err != nil { return err } + return ifw.RunDeleteNode(args[0]) +} - defer func() { - _ = connection.Close() - }() - - nodeID := args[0] - if !isValidUUID(nodeID) { - return status.New(status.InvalidCommandArgsError, "argument in not a valid node UUID") - } - deleteReq := &api.InfrastructureNodeDeleteRequest{NodeId: nodeID} - - _, err = connection.InfrastructureNodeDelete(context.Background(), deleteReq) +func preInfrastructureCmd(cmd *cobra.Command, args []string) error { + err := commandPrePersistent(cmd) if err != nil { - return status.Wrap( - err, - status.DeploymentServiceCallError, - "Request to delete node failed", - ) + return status.Wrap(err, status.CommandExecutionError, "unable to set command parent settings") + } + if isA2HARBFileExist() { + err = RunCmdOnSingleAutomateNode(cmd, args) + if err != nil { + return err + } + // NOTE: used os.exit as need to stop next lifecycle method to execute + os.Exit(1) } - - writer.Println("Node successfully deleted") return nil } - -func isValidUUID(id string) bool { - _, err := uuid.FromString(id) - return err == nil -} diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go new file mode 100644 index 00000000000..779923e3d4f --- /dev/null +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "errors" + "testing" + + api "github.com/chef/automate/api/interservice/deployment" + "github.com/chef/automate/components/automate-cli/pkg/infrastructure" + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" +) + +type MockDSClient struct { + InfrastructureNodeDeleteFunc func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) + CloseFunc func() error +} + +func (mds *MockDSClient) InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return mds.InfrastructureNodeDeleteFunc(ctx, in, opts...) +} + +func (mds *MockDSClient) Close() error { + return mds.CloseFunc() +} + +func TestRunDeleteNode(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &infrastructure.InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Equal(t, err, nil) + +} + +func TestRunDeleteNodeFailed(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &infrastructure.InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return nil, errors.New("DeploymentServiceCallError") + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Request to delete node failed: DeploymentServiceCallError") +} + +func TestRunDeleteNodeFailedForInvaliUUID(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &infrastructure.InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "not-a-valid-uuid" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "argument in not a valid node UUID") +} diff --git a/components/automate-cli/pkg/infrastructure/infrastructure.go b/components/automate-cli/pkg/infrastructure/infrastructure.go new file mode 100644 index 00000000000..1da96fb85a2 --- /dev/null +++ b/components/automate-cli/pkg/infrastructure/infrastructure.go @@ -0,0 +1,54 @@ +package infrastructure + +import ( + "context" + + api "github.com/chef/automate/api/interservice/deployment" + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/client" + "github.com/gofrs/uuid" + "google.golang.org/grpc" +) + +type DSClient interface { + InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) + Close() error +} + +type InfraFlow struct { + DsClient DSClient + Writer *cli.Writer +} + +func NewDeleteNode(writer *cli.Writer) (*InfraFlow, error) { + connection, err := client.Connection(client.DefaultClientTimeout) + + if err != nil { + return nil, err + } + return &InfraFlow{DsClient: connection, Writer: writer}, nil +} + +func (ifw *InfraFlow) RunDeleteNode(nodeID string) error { + + defer ifw.DsClient.Close() + + if !isValidUUID(nodeID) { + return status.New(status.InvalidCommandArgsError, "argument in not a valid node UUID") + } + deleteReq := &api.InfrastructureNodeDeleteRequest{NodeId: nodeID} + + _, err := ifw.DsClient.InfrastructureNodeDelete(context.Background(), deleteReq) + if err != nil { + return status.Wrap(err, status.DeploymentServiceCallError, "Request to delete node failed") + } + + ifw.Writer.Println("Node successfully deleted") + return nil +} + +func isValidUUID(id string) bool { + _, err := uuid.FromString(id) + return err == nil +} diff --git a/components/ingest-service/server/chef.go b/components/ingest-service/server/chef.go index c9505210467..620848441bc 100644 --- a/components/ingest-service/server/chef.go +++ b/components/ingest-service/server/chef.go @@ -2,6 +2,7 @@ package server import ( "context" + "errors" "time" log "github.com/sirupsen/logrus" @@ -204,7 +205,7 @@ func (s *ChefIngestServer) ProcessNodeDelete(ctx context.Context, } if len(nodeIDs) == 0 { - return &response.ProcessNodeDeleteResponse{}, nil + return &response.ProcessNodeDeleteResponse{}, errors.New("NodeId not found") } for _, nodeID := range nodeIDs { From 010ed6542c229e1b84e269566d928b4c8f0fdadb Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Mon, 5 Jun 2023 10:38:36 +0530 Subject: [PATCH 02/13] Infrastructure command on bastion Signed-off-by: Sunanda-Boorla --- components/automate-cli/cmd/chef-automate/infrastructure.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure.go b/components/automate-cli/cmd/chef-automate/infrastructure.go index ec015e85ac0..64bf18c1973 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure.go @@ -21,7 +21,7 @@ var infrastructureCmd = &cobra.Command{ Long: "Commands for automation infrastructure management, for data related to chef-client runs and chef-server actions.", PersistentPreRunE: preInfrastructureCmd, Annotations: map[string]string{ - docs.Tag: docs.Automate, + docs.Tag: docs.BastionHost, }, } @@ -32,7 +32,7 @@ var nodeDeleteCmd = &cobra.Command{ RunE: runDeleteNodeCmd, Args: cobra.ExactArgs(1), Annotations: map[string]string{ - docs.Tag: docs.Automate, + docs.Tag: docs.BastionHost, }, } From 64abed6caec34fa56f51daefba3460fab40e1b6b Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Mon, 5 Jun 2023 11:45:19 +0530 Subject: [PATCH 03/13] infrastructure command Signed-off-by: Sunanda-Boorla --- .../commands/chef-automate_infrastructure.yaml | 2 +- .../commands/chef-automate_infrastructure_node-delete.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml index aff95fad0c6..b4b8db17916 100644 --- a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml +++ b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml @@ -21,4 +21,4 @@ inherited_options: see_also: - chef-automate - Chef Automate CLI - node-delete - Delete node by node uuid -supported_on: Automate +supported_on: Bastion diff --git a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml index 2df220ead2b..a863dee8954 100644 --- a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml +++ b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml @@ -18,4 +18,4 @@ inherited_options: usage: Write command result as JSON to PATH see_also: - chef-automate infrastructure - Chef Automate infrastructure -supported_on: Automate +supported_on: Bastion From 5abd2660d95194c94dbbe74213b828e450e35e0a Mon Sep 17 00:00:00 2001 From: sandhi Date: Tue, 6 Jun 2023 16:53:44 +0530 Subject: [PATCH 04/13] Changes to increase the coverage Signed-off-by: sandhi --- .../cmd/chef-automate/infrastructure_test.go | 84 +++++-------------- .../pkg/infrastructure/infrastructure_test.go | 73 ++++++++++++++++ 2 files changed, 95 insertions(+), 62 deletions(-) create mode 100644 components/automate-cli/pkg/infrastructure/infrastructure_test.go diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index 779923e3d4f..bc566565f35 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -1,74 +1,34 @@ package main import ( - "context" - "errors" "testing" - api "github.com/chef/automate/api/interservice/deployment" - "github.com/chef/automate/components/automate-cli/pkg/infrastructure" - "github.com/chef/automate/lib/majorupgrade_utils" - "github.com/stretchr/testify/assert" - "google.golang.org/grpc" + "github.com/spf13/cobra" ) -type MockDSClient struct { - InfrastructureNodeDeleteFunc func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) - CloseFunc func() error +var nodeDelCmd = &cobra.Command{ + // use getClient in the command implementation } -func (mds *MockDSClient) InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return mds.InfrastructureNodeDeleteFunc(ctx, in, opts...) -} - -func (mds *MockDSClient) Close() error { - return mds.CloseFunc() -} - -func TestRunDeleteNode(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &infrastructure.InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return &api.InfrastructureNodeDeleteResponse{}, nil - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, - } - nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" - err := i.RunDeleteNode(nodeId) - assert.Equal(t, err, nil) - -} - -func TestRunDeleteNodeFailed(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &infrastructure.InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return nil, errors.New("DeploymentServiceCallError") - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, +// var argsAws = []string{"aws"} +// var argsExistingNodes = []string{"existing_infra"} +// var argsSomeThingElse = []string{"something_else"} +// var argsEmpty = []string{} + +func Test_runpreInfrastructureCmd(t *testing.T) { + tests := []struct { + testName string + cmd *cobra.Command + args []string + wantErr bool + }{ + {"Test node delete", nodeDelCmd, []string{"argsEmpty"}, true}, } - nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" - err := i.RunDeleteNode(nodeId) - assert.Error(t, err) - assert.Contains(t, err.Error(), "Request to delete node failed: DeploymentServiceCallError") -} - -func TestRunDeleteNodeFailedForInvaliUUID(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &infrastructure.InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return &api.InfrastructureNodeDeleteResponse{}, nil - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + if err := runDeleteNodeCmd(tt.cmd, tt.args); (err != nil) != tt.wantErr { + t.Errorf("runDeleteNodeCmd() error = %v, wantErr %v", err, tt.wantErr) + } + }) } - nodeId := "not-a-valid-uuid" - err := i.RunDeleteNode(nodeId) - assert.Error(t, err) - assert.Contains(t, err.Error(), "argument in not a valid node UUID") } diff --git a/components/automate-cli/pkg/infrastructure/infrastructure_test.go b/components/automate-cli/pkg/infrastructure/infrastructure_test.go new file mode 100644 index 00000000000..f4eb4cbce6a --- /dev/null +++ b/components/automate-cli/pkg/infrastructure/infrastructure_test.go @@ -0,0 +1,73 @@ +package infrastructure + +import ( + "context" + "errors" + "testing" + + api "github.com/chef/automate/api/interservice/deployment" + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" +) + +type MockDSClient struct { + InfrastructureNodeDeleteFunc func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) + CloseFunc func() error +} + +func (mds *MockDSClient) InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return mds.InfrastructureNodeDeleteFunc(ctx, in, opts...) +} + +func (mds *MockDSClient) Close() error { + return mds.CloseFunc() +} + +func TestRunDeleteNode(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Equal(t, err, nil) + +} + +func TestRunDeleteNodeFailed(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return nil, errors.New("DeploymentServiceCallError") + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Request to delete node failed: DeploymentServiceCallError") +} + +func TestRunDeleteNodeFailedForInvaliUUID(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "not-a-valid-uuid" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "argument in not a valid node UUID") +} From a483c5b1b5abc5d58ce505143879e8232106189c Mon Sep 17 00:00:00 2001 From: sandhi Date: Wed, 7 Jun 2023 15:14:38 +0530 Subject: [PATCH 05/13] changes for coverage increase Signed-off-by: sandhi --- .../cmd/chef-automate/infrastructure.go | 51 ++++++++++- .../cmd/chef-automate/infrastructure_test.go | 85 +++++++++++++++++-- .../pkg/infrastructure/infrastructure.go | 54 ------------ .../pkg/infrastructure/infrastructure_test.go | 73 ---------------- 4 files changed, 127 insertions(+), 136 deletions(-) delete mode 100644 components/automate-cli/pkg/infrastructure/infrastructure.go delete mode 100644 components/automate-cli/pkg/infrastructure/infrastructure_test.go diff --git a/components/automate-cli/cmd/chef-automate/infrastructure.go b/components/automate-cli/cmd/chef-automate/infrastructure.go index 64bf18c1973..0ac28da02de 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure.go @@ -1,12 +1,17 @@ package main import ( + "context" "os" + api "github.com/chef/automate/api/interservice/deployment" "github.com/chef/automate/components/automate-cli/pkg/docs" - "github.com/chef/automate/components/automate-cli/pkg/infrastructure" "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/client" + "github.com/gofrs/uuid" "github.com/spf13/cobra" + "google.golang.org/grpc" ) func init() { @@ -36,8 +41,18 @@ var nodeDeleteCmd = &cobra.Command{ }, } +type DSClient interface { + InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) + Close() error +} + +type InfraFlow struct { + DsClient DSClient + Writer *cli.Writer +} + func runDeleteNodeCmd(cmd *cobra.Command, args []string) error { - ifw, err := infrastructure.NewDeleteNode(writer) + ifw, err := NewDeleteNode(writer) if err != nil { return err } @@ -59,3 +74,35 @@ func preInfrastructureCmd(cmd *cobra.Command, args []string) error { } return nil } + +func NewDeleteNode(writer *cli.Writer) (*InfraFlow, error) { + connection, err := client.Connection(client.DefaultClientTimeout) + + if err != nil { + return nil, err + } + return &InfraFlow{DsClient: connection, Writer: writer}, nil +} + +func (ifw *InfraFlow) RunDeleteNode(nodeID string) error { + + defer ifw.DsClient.Close() + + if !isValidUUID(nodeID) { + return status.New(status.InvalidCommandArgsError, "argument in not a valid node UUID") + } + deleteReq := &api.InfrastructureNodeDeleteRequest{NodeId: nodeID} + + _, err := ifw.DsClient.InfrastructureNodeDelete(context.Background(), deleteReq) + if err != nil { + return status.Wrap(err, status.DeploymentServiceCallError, "Request to delete node failed") + } + + ifw.Writer.Println("Node successfully deleted") + return nil +} + +func isValidUUID(id string) bool { + _, err := uuid.FromString(id) + return err == nil +} diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index bc566565f35..c3b4c697e3f 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -1,20 +1,25 @@ package main import ( + "context" "testing" + api "github.com/chef/automate/api/interservice/deployment" + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" ) var nodeDelCmd = &cobra.Command{ - // use getClient in the command implementation + Use: "node-delete [uuid]", + Short: "Delete node by node uuid", + Long: "", + RunE: runDeleteNodeCmd, + Args: cobra.ExactArgs(1), } -// var argsAws = []string{"aws"} -// var argsExistingNodes = []string{"existing_infra"} -// var argsSomeThingElse = []string{"something_else"} -// var argsEmpty = []string{} - func Test_runpreInfrastructureCmd(t *testing.T) { tests := []struct { testName string @@ -22,7 +27,7 @@ func Test_runpreInfrastructureCmd(t *testing.T) { args []string wantErr bool }{ - {"Test node delete", nodeDelCmd, []string{"argsEmpty"}, true}, + {"Test node delete", nodeDelCmd, []string{"uuid of node"}, true}, } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { @@ -30,5 +35,71 @@ func Test_runpreInfrastructureCmd(t *testing.T) { t.Errorf("runDeleteNodeCmd() error = %v, wantErr %v", err, tt.wantErr) } }) + t.Run(tt.testName, func(t *testing.T) { + if err := preInfrastructureCmd(tt.cmd, tt.args); (err != nil) != tt.wantErr { + t.Errorf("preInfrastructureCmd() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +type MockDSClient struct { + InfrastructureNodeDeleteFunc func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) + CloseFunc func() error +} + +func (mds *MockDSClient) InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return mds.InfrastructureNodeDeleteFunc(ctx, in, opts...) +} + +func (mds *MockDSClient) Close() error { + return mds.CloseFunc() +} + +func TestRunDeleteNode(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Equal(t, err, nil) + +} + +func TestRunDeleteNodeFailed(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return nil, errors.New("DeploymentServiceCallError") + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, + } + nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Request to delete node failed: DeploymentServiceCallError") +} + +func TestRunDeleteNodeFailedForInvaliUUID(t *testing.T) { + customWriter := majorupgrade_utils.NewCustomWriter() + i := &InfraFlow{ + DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { + return &api.InfrastructureNodeDeleteResponse{}, nil + }, CloseFunc: func() error { + return nil + }}, + Writer: customWriter.CliWriter, } + nodeId := "not-a-valid-uuid" + err := i.RunDeleteNode(nodeId) + assert.Error(t, err) + assert.Contains(t, err.Error(), "argument in not a valid node UUID") } diff --git a/components/automate-cli/pkg/infrastructure/infrastructure.go b/components/automate-cli/pkg/infrastructure/infrastructure.go deleted file mode 100644 index 1da96fb85a2..00000000000 --- a/components/automate-cli/pkg/infrastructure/infrastructure.go +++ /dev/null @@ -1,54 +0,0 @@ -package infrastructure - -import ( - "context" - - api "github.com/chef/automate/api/interservice/deployment" - "github.com/chef/automate/components/automate-cli/pkg/status" - "github.com/chef/automate/components/automate-deployment/pkg/cli" - "github.com/chef/automate/components/automate-deployment/pkg/client" - "github.com/gofrs/uuid" - "google.golang.org/grpc" -) - -type DSClient interface { - InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) - Close() error -} - -type InfraFlow struct { - DsClient DSClient - Writer *cli.Writer -} - -func NewDeleteNode(writer *cli.Writer) (*InfraFlow, error) { - connection, err := client.Connection(client.DefaultClientTimeout) - - if err != nil { - return nil, err - } - return &InfraFlow{DsClient: connection, Writer: writer}, nil -} - -func (ifw *InfraFlow) RunDeleteNode(nodeID string) error { - - defer ifw.DsClient.Close() - - if !isValidUUID(nodeID) { - return status.New(status.InvalidCommandArgsError, "argument in not a valid node UUID") - } - deleteReq := &api.InfrastructureNodeDeleteRequest{NodeId: nodeID} - - _, err := ifw.DsClient.InfrastructureNodeDelete(context.Background(), deleteReq) - if err != nil { - return status.Wrap(err, status.DeploymentServiceCallError, "Request to delete node failed") - } - - ifw.Writer.Println("Node successfully deleted") - return nil -} - -func isValidUUID(id string) bool { - _, err := uuid.FromString(id) - return err == nil -} diff --git a/components/automate-cli/pkg/infrastructure/infrastructure_test.go b/components/automate-cli/pkg/infrastructure/infrastructure_test.go deleted file mode 100644 index f4eb4cbce6a..00000000000 --- a/components/automate-cli/pkg/infrastructure/infrastructure_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package infrastructure - -import ( - "context" - "errors" - "testing" - - api "github.com/chef/automate/api/interservice/deployment" - "github.com/chef/automate/lib/majorupgrade_utils" - "github.com/stretchr/testify/assert" - "google.golang.org/grpc" -) - -type MockDSClient struct { - InfrastructureNodeDeleteFunc func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) - CloseFunc func() error -} - -func (mds *MockDSClient) InfrastructureNodeDelete(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return mds.InfrastructureNodeDeleteFunc(ctx, in, opts...) -} - -func (mds *MockDSClient) Close() error { - return mds.CloseFunc() -} - -func TestRunDeleteNode(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return &api.InfrastructureNodeDeleteResponse{}, nil - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, - } - nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" - err := i.RunDeleteNode(nodeId) - assert.Equal(t, err, nil) - -} - -func TestRunDeleteNodeFailed(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return nil, errors.New("DeploymentServiceCallError") - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, - } - nodeId := "3d8ffe06-6281-494a-9957-34c6f3f50154" - err := i.RunDeleteNode(nodeId) - assert.Error(t, err) - assert.Contains(t, err.Error(), "Request to delete node failed: DeploymentServiceCallError") -} - -func TestRunDeleteNodeFailedForInvaliUUID(t *testing.T) { - customWriter := majorupgrade_utils.NewCustomWriter() - i := &InfraFlow{ - DsClient: &MockDSClient{InfrastructureNodeDeleteFunc: func(ctx context.Context, in *api.InfrastructureNodeDeleteRequest, opts ...grpc.CallOption) (*api.InfrastructureNodeDeleteResponse, error) { - return &api.InfrastructureNodeDeleteResponse{}, nil - }, CloseFunc: func() error { - return nil - }}, - Writer: customWriter.CliWriter, - } - nodeId := "not-a-valid-uuid" - err := i.RunDeleteNode(nodeId) - assert.Error(t, err) - assert.Contains(t, err.Error(), "argument in not a valid node UUID") -} From de332ee86c95b11eda5bc6743d6c2225b7b8aac0 Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Fri, 9 Jun 2023 13:26:29 +0530 Subject: [PATCH 06/13] Increasing code coverage Signed-off-by: Sunanda-Boorla --- components/automate-cli/cmd/chef-automate/infrastructure.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure.go b/components/automate-cli/cmd/chef-automate/infrastructure.go index 0ac28da02de..225571b0c8a 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure.go @@ -65,11 +65,9 @@ func preInfrastructureCmd(cmd *cobra.Command, args []string) error { return status.Wrap(err, status.CommandExecutionError, "unable to set command parent settings") } if isA2HARBFileExist() { - err = RunCmdOnSingleAutomateNode(cmd, args) - if err != nil { + if err = RunCmdOnSingleAutomateNode(cmd, args); err != nil { return err } - // NOTE: used os.exit as need to stop next lifecycle method to execute os.Exit(1) } return nil From d5ef09915efc4f955a8183da4f8f16db861a3168 Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Fri, 9 Jun 2023 16:57:06 +0530 Subject: [PATCH 07/13] Reverting the node-delete change Signed-off-by: Sunanda-Boorla --- components/ingest-service/server/chef.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/ingest-service/server/chef.go b/components/ingest-service/server/chef.go index 620848441bc..c9505210467 100644 --- a/components/ingest-service/server/chef.go +++ b/components/ingest-service/server/chef.go @@ -2,7 +2,6 @@ package server import ( "context" - "errors" "time" log "github.com/sirupsen/logrus" @@ -205,7 +204,7 @@ func (s *ChefIngestServer) ProcessNodeDelete(ctx context.Context, } if len(nodeIDs) == 0 { - return &response.ProcessNodeDeleteResponse{}, errors.New("NodeId not found") + return &response.ProcessNodeDeleteResponse{}, nil } for _, nodeID := range nodeIDs { From aebf8305fd2c0a73736a490193213353e738ff11 Mon Sep 17 00:00:00 2001 From: sandhi Date: Tue, 13 Jun 2023 11:20:06 +0530 Subject: [PATCH 08/13] Changes for test case failure Signed-off-by: sandhi --- .../cmd/chef-automate/infrastructure_test.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index c3b4c697e3f..a354e0888f9 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -31,14 +31,12 @@ func Test_runpreInfrastructureCmd(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - if err := runDeleteNodeCmd(tt.cmd, tt.args); (err != nil) != tt.wantErr { - t.Errorf("runDeleteNodeCmd() error = %v, wantErr %v", err, tt.wantErr) - } + err := runDeleteNodeCmd(tt.cmd, tt.args) + assert.Error(t, err) }) t.Run(tt.testName, func(t *testing.T) { - if err := preInfrastructureCmd(tt.cmd, tt.args); (err != nil) != tt.wantErr { - t.Errorf("preInfrastructureCmd() error = %v, wantErr %v", err, tt.wantErr) - } + err := preInfrastructureCmd(tt.cmd, tt.args) + assert.Error(t, err) }) } } From bfe54a4453a42853705a3e07fa870058533e4cf7 Mon Sep 17 00:00:00 2001 From: sandhi Date: Tue, 13 Jun 2023 11:22:59 +0530 Subject: [PATCH 09/13] Revert doc changes Signed-off-by: sandhi --- .../commands/chef-automate_infrastructure.yaml | 2 +- .../commands/chef-automate_infrastructure_node-delete.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml index b4b8db17916..aff95fad0c6 100644 --- a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml +++ b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure.yaml @@ -21,4 +21,4 @@ inherited_options: see_also: - chef-automate - Chef Automate CLI - node-delete - Delete node by node uuid -supported_on: Bastion +supported_on: Automate diff --git a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml index a863dee8954..2df220ead2b 100644 --- a/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml +++ b/components/docs-chef-io/data/automate/cli_chef_automate/commands/chef-automate_infrastructure_node-delete.yaml @@ -18,4 +18,4 @@ inherited_options: usage: Write command result as JSON to PATH see_also: - chef-automate infrastructure - Chef Automate infrastructure -supported_on: Bastion +supported_on: Automate From 2169b115a9e0d28bf557c1c7fb9c28a1ef3347b6 Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Tue, 13 Jun 2023 11:39:17 +0530 Subject: [PATCH 10/13] changes for test case failure Signed-off-by: Sunanda-Boorla --- .../cmd/chef-automate/infrastructure_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index a354e0888f9..ac04c3c9a2a 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -25,17 +25,22 @@ func Test_runpreInfrastructureCmd(t *testing.T) { testName string cmd *cobra.Command args []string - wantErr bool }{ - {"Test node delete", nodeDelCmd, []string{"uuid of node"}, true}, + {"Test node delete", nodeDelCmd, []string{"uuid of node"}}, } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { err := runDeleteNodeCmd(tt.cmd, tt.args) + if err == nil{ + assert.NoError(t, err) + } assert.Error(t, err) }) t.Run(tt.testName, func(t *testing.T) { err := preInfrastructureCmd(tt.cmd, tt.args) + if err == nil{ + assert.NoError(t, err) + } assert.Error(t, err) }) } From 62a1a5059b51d0c15df6e8e427bd41722382672d Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Tue, 13 Jun 2023 11:55:12 +0530 Subject: [PATCH 11/13] changes for test case failure Signed-off-by: Sunanda-Boorla --- .../automate-cli/cmd/chef-automate/infrastructure_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index ac04c3c9a2a..9496b3fddf8 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -36,13 +36,6 @@ func Test_runpreInfrastructureCmd(t *testing.T) { } assert.Error(t, err) }) - t.Run(tt.testName, func(t *testing.T) { - err := preInfrastructureCmd(tt.cmd, tt.args) - if err == nil{ - assert.NoError(t, err) - } - assert.Error(t, err) - }) } } From 93f7acb3955ac13a5c5f9ec67a9d168f41cdcfac Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Tue, 13 Jun 2023 12:12:26 +0530 Subject: [PATCH 12/13] changes for test case failure Signed-off-by: Sunanda-Boorla --- .../cmd/chef-automate/infrastructure_test.go | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index 9496b3fddf8..00e3ffc414a 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -20,7 +20,34 @@ var nodeDelCmd = &cobra.Command{ Args: cobra.ExactArgs(1), } +var infrastructureCmdTest = &cobra.Command{ + Use: "infrastructure COMMAND", + Short: "Chef Automate infrastructure", + Long: "Test for infra cmd", + PersistentPreRunE: preInfrastructureCmd, +} + + func Test_runpreInfrastructureCmd(t *testing.T) { + tests := []struct { + testName string + cmd *cobra.Command + args []string + }{ + {"Test node delete", infrastructureCmdTest, []string{"uuid of node"}}, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + err := preInfrastructureCmd(tt.cmd, tt.args) + if err == nil{ + assert.NoError(t, err) + } + assert.Error(t, err) + }) + } +} + +func Test_runDeleteNodeCmd(t *testing.T) { tests := []struct { testName string cmd *cobra.Command From e2b5b9fdfc7852fe6d9a41dfb66a5c48da52c8e5 Mon Sep 17 00:00:00 2001 From: Sunanda-Boorla Date: Tue, 13 Jun 2023 12:18:14 +0530 Subject: [PATCH 13/13] Formatting Signed-off-by: Sunanda-Boorla --- .../cmd/chef-automate/infrastructure_test.go | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/components/automate-cli/cmd/chef-automate/infrastructure_test.go b/components/automate-cli/cmd/chef-automate/infrastructure_test.go index 00e3ffc414a..e570e3b7116 100644 --- a/components/automate-cli/cmd/chef-automate/infrastructure_test.go +++ b/components/automate-cli/cmd/chef-automate/infrastructure_test.go @@ -21,30 +21,29 @@ var nodeDelCmd = &cobra.Command{ } var infrastructureCmdTest = &cobra.Command{ - Use: "infrastructure COMMAND", - Short: "Chef Automate infrastructure", - Long: "Test for infra cmd", - PersistentPreRunE: preInfrastructureCmd, + Use: "infrastructure COMMAND", + Short: "Chef Automate infrastructure", + Long: "Test for infra cmd", + PersistentPreRunE: preInfrastructureCmd, } - func Test_runpreInfrastructureCmd(t *testing.T) { - tests := []struct { - testName string - cmd *cobra.Command - args []string - }{ - {"Test node delete", infrastructureCmdTest, []string{"uuid of node"}}, - } - for _, tt := range tests { - t.Run(tt.testName, func(t *testing.T) { - err := preInfrastructureCmd(tt.cmd, tt.args) - if err == nil{ + tests := []struct { + testName string + cmd *cobra.Command + args []string + }{ + {"Test node delete", infrastructureCmdTest, []string{"uuid of node"}}, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + err := preInfrastructureCmd(tt.cmd, tt.args) + if err == nil { assert.NoError(t, err) } assert.Error(t, err) - }) - } + }) + } } func Test_runDeleteNodeCmd(t *testing.T) { @@ -58,7 +57,7 @@ func Test_runDeleteNodeCmd(t *testing.T) { for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { err := runDeleteNodeCmd(tt.cmd, tt.args) - if err == nil{ + if err == nil { assert.NoError(t, err) } assert.Error(t, err)