Skip to content

Commit

Permalink
CLOUDP-247450: Update atlas deployment ls command to list Atlas Clu…
Browse files Browse the repository at this point in the history
…ster in case of failures (#2934)
  • Loading branch information
andreaangiolillo authored May 7, 2024
1 parent 7ffa7d0 commit 1dcc389
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 20 deletions.
71 changes: 51 additions & 20 deletions internal/cli/deployments/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"errors"
"fmt"
"os"

"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/deployments/options"
Expand All @@ -38,38 +39,68 @@ const listTemplate = `NAME TYPE MDB VER STATE
{{range valueOrEmptySlice .}}{{.Name}} {{.Type}} {{.MongoDBVersion}} {{.StateName}}
{{end}}`

const errAtlas = "failed to retrieve Atlas deployments with: %s"
const errAtlas = "failed to retrieve Atlas deployments with: %w"
const errLocal = "failed to retrieve local deployments with: %w"

func (opts *ListOpts) Run(ctx context.Context) error {
if err := opts.LocalDeploymentPreRun(ctx); err != nil {
return err
localDeployments, localErr := opts.runLocal(ctx)
if localErr != nil {
_, _ = fmt.Fprintln(os.Stderr, localErr)
}

var mdbContainers []options.Deployment
if opts.IsLocalDeploymentType() || opts.NoDeploymentTypeSet() {
var err error
mdbContainers, err = opts.GetLocalDeployments(ctx)
if err != nil && !errors.Is(err, podman.ErrPodmanNotFound) {
return err
}
atlasClusters, atlasErr := opts.runAtlas()
if atlasErr != nil {
_, _ = fmt.Fprintln(os.Stderr, atlasErr)
}
var atlasClusters []options.Deployment
var atlasErr error
if opts.IsAtlasDeploymentType() || opts.NoDeploymentTypeSet() {
if opts.IsCliAuthenticated() && cli.TokenRefreshed {
atlasClusters, atlasErr = opts.AtlasDeployments(opts.ProjectID)
}

if localErr == nil && atlasErr == nil {
return opts.Print(append(atlasClusters, localDeployments...))
}
if err := opts.Print(append(atlasClusters, mdbContainers...)); err != nil {
return err

if atlasErr != nil && localErr == nil {
return opts.Print(localDeployments)
}
if atlasErr != nil {
return fmt.Errorf(errAtlas, atlasErr.Error())

if localErr != nil && atlasErr == nil {
return opts.Print(atlasClusters)
}

return nil
}

func (opts *ListOpts) runLocal(ctx context.Context) ([]options.Deployment, error) {
if !opts.IsLocalDeploymentType() && !opts.NoDeploymentTypeSet() {
return nil, nil
}

if err := opts.LocalDeploymentPreRun(ctx); err != nil {
return nil, fmt.Errorf(errLocal, err)
}

mdbContainers, err := opts.GetLocalDeployments(ctx)
if err != nil && !errors.Is(err, podman.ErrPodmanNotFound) {
return nil, fmt.Errorf(errLocal, err)
}
return mdbContainers, nil
}

func (opts *ListOpts) runAtlas() ([]options.Deployment, error) {
if !opts.IsAtlasDeploymentType() && !opts.NoDeploymentTypeSet() {
return nil, nil
}

if !opts.IsCliAuthenticated() {
return nil, nil
}

atlasClusters, err := opts.AtlasDeployments(opts.ProjectID)
if err != nil {
return nil, fmt.Errorf(errAtlas, err)
}

return atlasClusters, nil
}

func (opts *ListOpts) PostRun() error {
opts.UpdateDeploymentTelemetry()
return opts.PostRunMessages()
Expand Down
179 changes: 179 additions & 0 deletions internal/cli/deployments/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package deployments
import (
"bytes"
"context"
"errors"
"testing"

"github.com/golang/mock/gomock"
Expand Down Expand Up @@ -140,6 +141,184 @@ localTest2 LOCAL 6.0.9 IDLE
t.Log(buf.String())
}

func TestList_Run_NoLocal(t *testing.T) {
ctrl := gomock.NewController(t)
mockStore := mocks.NewMockClusterLister(ctrl)
mockCredentialsGetter := mocks.NewMockCredentialsGetter(ctrl)
mockProfileReader := mocks.NewMockProfileReader(ctrl)
mockPodman := mocks.NewMockClient(ctrl)
ctx := context.Background()

cli.TokenRefreshed = true
t.Cleanup(func() {
cli.TokenRefreshed = false
})

expectedAtlasClusters := &admin.PaginatedAdvancedClusterDescription{
Results: &[]admin.AdvancedClusterDescription{
{
Name: pointer.Get("atlasCluster2"),
Id: pointer.Get("123"),
MongoDBVersion: pointer.Get("7.0.0"),
StateName: pointer.Get("IDLE"),
Paused: pointer.Get(false),
},
{
Name: pointer.Get("atlasCluster1"),
Id: pointer.Get("123"),
MongoDBVersion: pointer.Get("7.0.0"),
StateName: pointer.Get("IDLE"),
Paused: pointer.Get(false),
},
},
}

buf := new(bytes.Buffer)
listOpts := &ListOpts{
DeploymentOpts: options.DeploymentOpts{
PodmanClient: mockPodman,
CredStore: mockCredentialsGetter,
AtlasClusterListStore: mockStore,
Config: mockProfileReader,
},
GlobalOpts: cli.GlobalOpts{
ProjectID: "64f670f0bf789926667dad1a",
},
OutputOpts: cli.OutputOpts{
Template: listTemplate,
OutWriter: buf,
},
}

mockStore.
EXPECT().
ProjectClusters(listOpts.ProjectID,
&store.ListOptions{
PageNum: cli.DefaultPage,
ItemsPerPage: options.MaxItemsPerPage,
},
).
Return(expectedAtlasClusters, nil).
Times(1)

mockCredentialsGetter.
EXPECT().
AuthType().
Return(config.OAuth).
Times(2)

mockPodman.
EXPECT().
Ready(ctx).
Return(nil).
Times(1)

mockPodman.
EXPECT().
ListContainers(ctx, options.MongodHostnamePrefix).
Return(nil, errors.New("this is an error")).
Times(1)

if err := listOpts.Run(ctx); err != nil {
t.Fatalf("Run() unexpected error: %v", err)
}

assert.Equal(t, `NAME TYPE MDB VER STATE
atlasCluster2 ATLAS 7.0.0 IDLE
atlasCluster1 ATLAS 7.0.0 IDLE
`, buf.String())
t.Log(buf.String())
}

func TestList_Run_NoAtlas(t *testing.T) {
ctrl := gomock.NewController(t)
mockStore := mocks.NewMockClusterLister(ctrl)
mockCredentialsGetter := mocks.NewMockCredentialsGetter(ctrl)
mockProfileReader := mocks.NewMockProfileReader(ctrl)
mockPodman := mocks.NewMockClient(ctrl)
ctx := context.Background()

cli.TokenRefreshed = true
t.Cleanup(func() {
cli.TokenRefreshed = false
})

expectedAtlasClusters := &admin.PaginatedAdvancedClusterDescription{
Results: &[]admin.AdvancedClusterDescription{
{
Name: pointer.Get("atlasCluster2"),
Id: pointer.Get("123"),
MongoDBVersion: pointer.Get("7.0.0"),
StateName: pointer.Get("IDLE"),
Paused: pointer.Get(false),
},
{
Name: pointer.Get("atlasCluster1"),
Id: pointer.Get("123"),
MongoDBVersion: pointer.Get("7.0.0"),
StateName: pointer.Get("IDLE"),
Paused: pointer.Get(false),
},
},
}

buf := new(bytes.Buffer)
listOpts := &ListOpts{
DeploymentOpts: options.DeploymentOpts{
PodmanClient: mockPodman,
CredStore: mockCredentialsGetter,
AtlasClusterListStore: mockStore,
Config: mockProfileReader,
},
GlobalOpts: cli.GlobalOpts{
ProjectID: "64f670f0bf789926667dad1a",
},
OutputOpts: cli.OutputOpts{
Template: listTemplate,
OutWriter: buf,
},
}

mockStore.
EXPECT().
ProjectClusters(listOpts.ProjectID,
&store.ListOptions{
PageNum: cli.DefaultPage,
ItemsPerPage: options.MaxItemsPerPage,
},
).
Return(expectedAtlasClusters, nil).
Times(1)

mockCredentialsGetter.
EXPECT().
AuthType().
Return(config.OAuth).
Times(2)

mockPodman.
EXPECT().
Ready(ctx).
Return(nil).
Times(1)

mockPodman.
EXPECT().
ListContainers(ctx, options.MongodHostnamePrefix).
Return(nil, errors.New("new error test")).
Times(1)

if err := listOpts.Run(ctx); err != nil {
t.Fatalf("Run() unexpected error: %v", err)
}

assert.Equal(t, `NAME TYPE MDB VER STATE
atlasCluster2 ATLAS 7.0.0 IDLE
atlasCluster1 ATLAS 7.0.0 IDLE
`, buf.String())
t.Log(buf.String())
}

func TestListBuilder(t *testing.T) {
test.CmdValidator(
t,
Expand Down

0 comments on commit 1dcc389

Please sign in to comment.