diff --git a/internal/cli/cloud_manager.go b/internal/cli/cloud_manager.go index 6778440dc5..5b84b6f65b 100644 --- a/internal/cli/cloud_manager.go +++ b/internal/cli/cloud_manager.go @@ -29,6 +29,7 @@ func CloudManagerBuilder() *cobra.Command { cmd.AddCommand(AtlasAlertsBuilder()) cmd.AddCommand(AtlasBackupsBuilder()) cmd.AddCommand(OpsManagerServersBuilder()) + cmd.AddCommand(OpsManagerAutomationBuilder()) return cmd } diff --git a/internal/cli/ops_manager.go b/internal/cli/ops_manager.go index e868eb2ef6..5789ca978d 100644 --- a/internal/cli/ops_manager.go +++ b/internal/cli/ops_manager.go @@ -30,6 +30,7 @@ func OpsManagerBuilder() *cobra.Command { cmd.AddCommand(OpsManagerOwnerBuilder()) cmd.AddCommand(AtlasBackupsBuilder()) cmd.AddCommand(OpsManagerServersBuilder()) + cmd.AddCommand(OpsManagerAutomationBuilder()) return cmd } diff --git a/internal/cli/ops_manager_automation.go b/internal/cli/ops_manager_automation.go new file mode 100644 index 0000000000..823d124c2f --- /dev/null +++ b/internal/cli/ops_manager_automation.go @@ -0,0 +1,29 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "github.com/spf13/cobra" +) + +func OpsManagerAutomationBuilder() *cobra.Command { + cmd := &cobra.Command{ + Use: "automation", + Short: "Manage Ops Manager automation config.", + } + + cmd.AddCommand(OpsManagerAutomationStatusBuilder()) + return cmd +} diff --git a/internal/cli/ops_manager_automation_status.go b/internal/cli/ops_manager_automation_status.go new file mode 100644 index 0000000000..0e14b7cfc8 --- /dev/null +++ b/internal/cli/ops_manager_automation_status.go @@ -0,0 +1,69 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "github.com/mongodb/mongocli/internal/flags" + "github.com/mongodb/mongocli/internal/json" + "github.com/mongodb/mongocli/internal/store" + "github.com/mongodb/mongocli/internal/usage" + "github.com/spf13/cobra" +) + +type opsManagerAutomationStatusOpts struct { + *globalOpts + store store.AutomationStatusGetter +} + +func (opts *opsManagerAutomationStatusOpts) init() error { + if opts.ProjectID() == "" { + return errMissingProjectID + } + var err error + opts.store, err = store.New() + return err +} + +func (opts *opsManagerAutomationStatusOpts) Run() error { + result, err := opts.store.GetAutomationStatus(opts.projectID) + + if err != nil { + return err + } + + return json.PrettyPrint(result) +} + +// mongocli ops-manager automation status [--projectId projectId] +func OpsManagerAutomationStatusBuilder() *cobra.Command { + opts := &opsManagerAutomationStatusOpts{ + globalOpts: newGlobalOpts(), + } + cmd := &cobra.Command{ + Use: "status", + Short: "Show the current status of the automation config.", + Args: cobra.NoArgs, + PreRunE: func(cmd *cobra.Command, args []string) error { + return opts.init() + }, + RunE: func(cmd *cobra.Command, args []string) error { + return opts.Run() + }, + } + + cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID) + + return cmd +} diff --git a/internal/cli/ops_manager_automation_status_test.go b/internal/cli/ops_manager_automation_status_test.go new file mode 100644 index 0000000000..4e7dd21c96 --- /dev/null +++ b/internal/cli/ops_manager_automation_status_test.go @@ -0,0 +1,48 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "testing" + + "github.com/golang/mock/gomock" + "github.com/mongodb/mongocli/internal/fixtures" + "github.com/mongodb/mongocli/internal/mocks" +) + +func TestOpsManagerAutomationStatus_Run(t *testing.T) { + ctrl := gomock.NewController(t) + mockStore := mocks.NewMockAutomationStatusGetter(ctrl) + + defer ctrl.Finish() + + expected := fixtures.AutomationStatus() + + opts := &opsManagerAutomationStatusOpts{ + globalOpts: newGlobalOpts(), + store: mockStore, + } + + mockStore. + EXPECT(). + GetAutomationStatus(opts.projectID). + Return(expected, nil). + Times(1) + + err := opts.Run() + if err != nil { + t.Fatalf("Run() unexpected error: %v", err) + } +} diff --git a/internal/fixtures/automation_status.go b/internal/fixtures/automation_status.go new file mode 100644 index 0000000000..3d4eb7781c --- /dev/null +++ b/internal/fixtures/automation_status.go @@ -0,0 +1,43 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fixtures + +import om "github.com/mongodb/go-client-mongodb-ops-manager/opsmngr" + +func AutomationStatus() *om.AutomationStatus { + return &om.AutomationStatus{ + GoalVersion: 2, + Processes: []om.ProcessStatus{ + { + Name: "shardedCluster_myShard_0_0", + Hostname: "testDeploy-0", + Plan: []string{}, + LastGoalVersionAchieved: 2, + }, + { + Name: "shardedCluster_myShard_0_1", + Hostname: "testDeploy-1", + Plan: []string{}, + LastGoalVersionAchieved: 2, + }, + { + Name: "shardedCluster_myShard_0_2", + Plan: []string{"Download", "Start", "WaitRsInit"}, + Hostname: "testDeploy-2", + LastGoalVersionAchieved: 2, + }, + }, + } +} diff --git a/internal/mocks/mock_automation.go b/internal/mocks/mock_automation.go index a6aed5baed..b14cf5ca8d 100644 --- a/internal/mocks/mock_automation.go +++ b/internal/mocks/mock_automation.go @@ -85,6 +85,44 @@ func (mr *MockAutomationUpdaterMockRecorder) UpdateAutomationConfig(arg0, arg1 i return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAutomationConfig", reflect.TypeOf((*MockAutomationUpdater)(nil).UpdateAutomationConfig), arg0, arg1) } +// MockAutomationStatusGetter is a mock of AutomationStatusGetter interface +type MockAutomationStatusGetter struct { + ctrl *gomock.Controller + recorder *MockAutomationStatusGetterMockRecorder +} + +// MockAutomationStatusGetterMockRecorder is the mock recorder for MockAutomationStatusGetter +type MockAutomationStatusGetterMockRecorder struct { + mock *MockAutomationStatusGetter +} + +// NewMockAutomationStatusGetter creates a new mock instance +func NewMockAutomationStatusGetter(ctrl *gomock.Controller) *MockAutomationStatusGetter { + mock := &MockAutomationStatusGetter{ctrl: ctrl} + mock.recorder = &MockAutomationStatusGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockAutomationStatusGetter) EXPECT() *MockAutomationStatusGetterMockRecorder { + return m.recorder +} + +// GetAutomationStatus mocks base method +func (m *MockAutomationStatusGetter) GetAutomationStatus(arg0 string) (*opsmngr.AutomationStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAutomationStatus", arg0) + ret0, _ := ret[0].(*opsmngr.AutomationStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAutomationStatus indicates an expected call of GetAutomationStatus +func (mr *MockAutomationStatusGetterMockRecorder) GetAutomationStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAutomationStatus", reflect.TypeOf((*MockAutomationStatusGetter)(nil).GetAutomationStatus), arg0) +} + // MockAllClusterLister is a mock of AllClusterLister interface type MockAllClusterLister struct { ctrl *gomock.Controller @@ -175,6 +213,21 @@ func (mr *MockAutomationStoreMockRecorder) UpdateAutomationConfig(arg0, arg1 int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAutomationConfig", reflect.TypeOf((*MockAutomationStore)(nil).UpdateAutomationConfig), arg0, arg1) } +// GetAutomationStatus mocks base method +func (m *MockAutomationStore) GetAutomationStatus(arg0 string) (*opsmngr.AutomationStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAutomationStatus", arg0) + ret0, _ := ret[0].(*opsmngr.AutomationStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAutomationStatus indicates an expected call of GetAutomationStatus +func (mr *MockAutomationStoreMockRecorder) GetAutomationStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAutomationStatus", reflect.TypeOf((*MockAutomationStore)(nil).GetAutomationStatus), arg0) +} + // MockCloudManagerClustersLister is a mock of CloudManagerClustersLister interface type MockCloudManagerClustersLister struct { ctrl *gomock.Controller diff --git a/internal/store/automation.go b/internal/store/automation.go index a23dd95114..86255b9585 100644 --- a/internal/store/automation.go +++ b/internal/store/automation.go @@ -30,6 +30,10 @@ type AutomationUpdater interface { UpdateAutomationConfig(string, *om.AutomationConfig) error } +type AutomationStatusGetter interface { + GetAutomationStatus(string) (*om.AutomationStatus, error) +} + type AllClusterLister interface { ListAllClustersProjects() (*om.AllClustersProjects, error) } @@ -37,6 +41,7 @@ type AllClusterLister interface { type AutomationStore interface { AutomationGetter AutomationUpdater + AutomationStatusGetter } type CloudManagerClustersLister interface { @@ -44,6 +49,16 @@ type CloudManagerClustersLister interface { AllClusterLister } +func (s *Store) GetAutomationStatus(projectID string) (*om.AutomationStatus, error) { + switch s.service { + case config.CloudManagerService, config.OpsManagerService: + result, _, err := s.client.(*om.Client).AutomationStatus.Get(context.Background(), projectID) + return result, err + default: + return nil, fmt.Errorf("unsupported service: %s", s.service) + } +} + // GetAutomationConfig encapsulate the logic to manage different cloud providers func (s *Store) GetAutomationConfig(projectID string) (*om.AutomationConfig, error) { switch s.service {