Skip to content

Commit

Permalink
CLOUDP-228590: Migrate Project Settings to new Atlas SDK (#1666)
Browse files Browse the repository at this point in the history
* Update Project Settings to use new SDK

* Add unit tests
  • Loading branch information
roothorp authored Jun 28, 2024
1 parent 4ad3f68 commit 6b8f28d
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 16 deletions.
32 changes: 25 additions & 7 deletions pkg/api/v1/project_settings.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package v1

import (
"go.mongodb.org/atlas/mongodbatlas"

"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/compat"
"go.mongodb.org/atlas-sdk/v20231115008/admin"
)

type ProjectSettings struct {
Expand All @@ -15,8 +13,28 @@ type ProjectSettings struct {
IsSchemaAdvisorEnabled *bool `json:"isSchemaAdvisorEnabled,omitempty"`
}

func (s ProjectSettings) ToAtlas() (*mongodbatlas.ProjectSettings, error) {
result := &mongodbatlas.ProjectSettings{}
err := compat.JSONCopy(result, s)
return result, err
func (s ProjectSettings) ToAtlas() *admin.GroupSettings {
atlas := &admin.GroupSettings{}

atlas.IsCollectDatabaseSpecificsStatisticsEnabled = s.IsCollectDatabaseSpecificsStatisticsEnabled
atlas.IsDataExplorerEnabled = s.IsDataExplorerEnabled
atlas.IsExtendedStorageSizesEnabled = s.IsExtendedStorageSizesEnabled
atlas.IsPerformanceAdvisorEnabled = s.IsPerformanceAdvisorEnabled
atlas.IsRealtimePerformancePanelEnabled = s.IsRealtimePerformancePanelEnabled
atlas.IsSchemaAdvisorEnabled = s.IsSchemaAdvisorEnabled

return atlas
}

func ProjectSettingsFromAtlas(atlas *admin.GroupSettings) *ProjectSettings {
ps := &ProjectSettings{}

ps.IsCollectDatabaseSpecificsStatisticsEnabled = atlas.IsCollectDatabaseSpecificsStatisticsEnabled
ps.IsDataExplorerEnabled = atlas.IsDataExplorerEnabled
ps.IsExtendedStorageSizesEnabled = atlas.IsExtendedStorageSizesEnabled
ps.IsPerformanceAdvisorEnabled = atlas.IsPerformanceAdvisorEnabled
ps.IsRealtimePerformancePanelEnabled = atlas.IsRealtimePerformancePanelEnabled
ps.IsSchemaAdvisorEnabled = atlas.IsSchemaAdvisorEnabled

return ps
}
2 changes: 1 addition & 1 deletion pkg/controller/atlasproject/backupcompliancepolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import (
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
)

func TestEnsureBackupCompliance2(t *testing.T) {
func TestEnsureBackupCompliance(t *testing.T) {
testBCP := &akov2.AtlasBackupCompliancePolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "test-bcp",
Expand Down
12 changes: 4 additions & 8 deletions pkg/controller/atlasproject/project_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,20 @@ func areSettingsInSync(atlas, spec *akov2.ProjectSettings) bool {
}

func patchSettings(ctx *workflow.Context, projectID string, spec *akov2.ProjectSettings) error {
specAsAtlas, err := spec.ToAtlas()
if err != nil {
return err
}
specAsAtlas := spec.ToAtlas()

_, _, err = ctx.Client.Projects.UpdateProjectSettings(ctx.Context, projectID, specAsAtlas)
_, _, err := ctx.SdkClient.ProjectsApi.UpdateProjectSettings(ctx.Context, projectID, specAsAtlas).Execute()
return err
}

func fetchSettings(ctx *workflow.Context, projectID string) (*akov2.ProjectSettings, error) {
data, _, err := ctx.Client.Projects.GetProjectSettings(ctx.Context, projectID)
data, _, err := ctx.SdkClient.ProjectsApi.GetProjectSettings(ctx.Context, projectID).Execute()
if err != nil {
return nil, err
}
ctx.Log.Debugw("Got Project Settings", "data", data)

settings := akov2.ProjectSettings(*data)
return &settings, nil
return akov2.ProjectSettingsFromAtlas(data), nil
}

func isOneContainedInOther(one, other *akov2.ProjectSettings) bool {
Expand Down
208 changes: 208 additions & 0 deletions pkg/controller/atlasproject/project_settings_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package atlasproject

import (
"context"
"errors"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.mongodb.org/atlas-sdk/v20231115008/admin"
"go.mongodb.org/atlas-sdk/v20231115008/mockadmin"
"go.uber.org/zap/zaptest"

"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/pointer"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api"
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
)

func TestAreSettingsInSync(t *testing.T) {
Expand All @@ -29,3 +38,202 @@ func TestAreSettingsInSync(t *testing.T) {
areEqual = areSettingsInSync(atlasDef, specDef)
assert.False(t, areEqual, "Field values should be the same ")
}

func TestEnsureProjectSettings(t *testing.T) {
for _, tc := range []struct {
name string
settings *akov2.ProjectSettings
projectAPI *mockadmin.ProjectsApi

isOK bool
isWarning bool

wantReadyType bool // whether the ProjectSettingsReadyType is expected
wantStatus string // the expected status of ProjectSettingsReadyType ("True", "False")
}{
{
name: "Project Settings unset in AKO & Atlas",
settings: nil,
projectAPI: func() *mockadmin.ProjectsApi {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProjectSettings(context.Background(), "").
Return(admin.GetProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectSettingsExecute(mock.Anything).
Return(
&admin.GroupSettings{ // These are the default settings on a fresh project
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(true),
IsDataExplorerEnabled: pointer.MakePtr(true),
IsExtendedStorageSizesEnabled: pointer.MakePtr(false),
IsPerformanceAdvisorEnabled: pointer.MakePtr(true),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(true),
IsSchemaAdvisorEnabled: pointer.MakePtr(true),
},
&http.Response{},
nil,
)
return projectAPI
}(),
isOK: true,
isWarning: false,

wantReadyType: false,
},
{
name: "GET Atlas Project Settings errors",
settings: nil,
projectAPI: func() *mockadmin.ProjectsApi {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProjectSettings(context.Background(), "").
Return(admin.GetProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectSettingsExecute(mock.Anything).
Return(
&admin.GroupSettings{},
&http.Response{},
errors.New("TEST GET ERROR"),
)
return projectAPI
}(),
isOK: false,
isWarning: true,
wantReadyType: true,
wantStatus: "False",
},
{
name: "Project Settings are equal in AKO & Atlas",
settings: &akov2.ProjectSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(false),
IsExtendedStorageSizesEnabled: pointer.MakePtr(false),
IsPerformanceAdvisorEnabled: pointer.MakePtr(true),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(false),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
projectAPI: func() *mockadmin.ProjectsApi {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProjectSettings(context.Background(), "").
Return(admin.GetProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectSettingsExecute(mock.Anything).
Return(
&admin.GroupSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(false),
IsExtendedStorageSizesEnabled: pointer.MakePtr(false),
IsPerformanceAdvisorEnabled: pointer.MakePtr(true),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(false),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
&http.Response{},
nil,
)
return projectAPI
}(),
isOK: true,
isWarning: false,

wantReadyType: true,
wantStatus: "True",
},
{
name: "Project Settings are different in AKO & Atlas",
settings: &akov2.ProjectSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(false),
IsExtendedStorageSizesEnabled: pointer.MakePtr(false),
IsPerformanceAdvisorEnabled: pointer.MakePtr(true),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(true),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
projectAPI: func() *mockadmin.ProjectsApi {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProjectSettings(context.Background(), "").
Return(admin.GetProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectSettingsExecute(mock.Anything).
Return(
&admin.GroupSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(true),
IsExtendedStorageSizesEnabled: pointer.MakePtr(true),
IsPerformanceAdvisorEnabled: pointer.MakePtr(false),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(false),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
&http.Response{},
nil,
)
projectAPI.EXPECT().UpdateProjectSettings(context.Background(), "", mock.AnythingOfType("*admin.GroupSettings")).
Return(admin.UpdateProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().UpdateProjectSettingsExecute(mock.Anything).
Return(&admin.GroupSettings{}, &http.Response{}, nil)

return projectAPI
}(),
isOK: true,
isWarning: false,

wantReadyType: true,
wantStatus: "True",
},
{
name: "PATCH Atlas Project Settings errors",
settings: &akov2.ProjectSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(false),
IsExtendedStorageSizesEnabled: pointer.MakePtr(false),
IsPerformanceAdvisorEnabled: pointer.MakePtr(true),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(true),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
projectAPI: func() *mockadmin.ProjectsApi {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProjectSettings(context.Background(), "").
Return(admin.GetProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectSettingsExecute(mock.Anything).
Return(
&admin.GroupSettings{
IsCollectDatabaseSpecificsStatisticsEnabled: pointer.MakePtr(false),
IsDataExplorerEnabled: pointer.MakePtr(true),
IsExtendedStorageSizesEnabled: pointer.MakePtr(true),
IsPerformanceAdvisorEnabled: pointer.MakePtr(false),
IsRealtimePerformancePanelEnabled: pointer.MakePtr(false),
IsSchemaAdvisorEnabled: pointer.MakePtr(false),
},
&http.Response{},
nil,
)
projectAPI.EXPECT().UpdateProjectSettings(context.Background(), "", mock.AnythingOfType("*admin.GroupSettings")).
Return(admin.UpdateProjectSettingsApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().UpdateProjectSettingsExecute(mock.Anything).
Return(&admin.GroupSettings{}, &http.Response{}, errors.New("TEST PATCH ERROR"))

return projectAPI
}(),
isOK: false,
isWarning: true,

wantReadyType: true,
wantStatus: "False",
},
} {
t.Run(tc.name, func(t *testing.T) {
ctx := &workflow.Context{
SdkClient: &admin.APIClient{
ProjectsApi: tc.projectAPI,
},
Context: context.Background(),
Log: zaptest.NewLogger(t).Sugar(),
}

project := akov2.DefaultProject("test-ns", "test-conn")
project.Spec.Settings = tc.settings

result := ensureProjectSettings(ctx, project)
assert.Equal(t, tc.isOK, result.IsOk())
assert.Equal(t, tc.isWarning, result.IsWarning())

con, ok := ctx.GetCondition(api.ProjectSettingsReadyType)
assert.Equal(t, tc.wantReadyType, ok)

assert.Equal(t, tc.wantStatus, string(con.Status))
})
}
}

0 comments on commit 6b8f28d

Please sign in to comment.