Skip to content

Commit 97e420a

Browse files
authored
CLOUDP-58960: Backup: list available restore jobs (#44)
1 parent 0f3f0f2 commit 97e420a

9 files changed

+384
-1
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ gen-mocks: ## Generate mocks
5959
mockgen -source=internal/store/organizations.go -destination=internal/mocks/mock_organizations.go -package=mocks
6060
mockgen -source=internal/store/owners.go -destination=internal/mocks/mock_owners.go -package=mocks
6161
mockgen -source=internal/store/continuous_snapshots.go -destination=internal/mocks/mock_continuous_snapshots.go -package=mocks
62+
mockgen -source=internal/store/continuous_jobs.go -destination=internal/mocks/mock_continuous_jobs.go -package=mocks
6263

6364
.PHONY: build
6465
build: ## Generate a binary in ./bin

internal/cli/atlas_backups.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func AtlasBackupsBuilder() *cobra.Command {
2626
}
2727

2828
cmd.AddCommand(AtlasBackupsSnapshotsBuilder())
29+
cmd.AddCommand(AtlasBackupsRestoresBuilder())
2930

3031
return cmd
3132
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2020 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cli
16+
17+
import (
18+
"github.com/spf13/cobra"
19+
)
20+
21+
func AtlasBackupsRestoresBuilder() *cobra.Command {
22+
cmd := &cobra.Command{
23+
Use: "restores",
24+
Short: "Manage restore jobs.",
25+
Aliases: []string{"restore"},
26+
}
27+
28+
cmd.AddCommand(AtlasBackupsRestoresListBuilder())
29+
30+
return cmd
31+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2020 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cli
16+
17+
import (
18+
atlas "github.com/mongodb/go-client-mongodb-atlas/mongodbatlas"
19+
"github.com/mongodb/mongocli/internal/flags"
20+
"github.com/mongodb/mongocli/internal/json"
21+
"github.com/mongodb/mongocli/internal/store"
22+
"github.com/mongodb/mongocli/internal/usage"
23+
"github.com/spf13/cobra"
24+
)
25+
26+
type atlasBackupsRestoresListOpts struct {
27+
*globalOpts
28+
clusterName string
29+
pageNum int
30+
itemsPerPage int
31+
store store.ContinuousJobLister
32+
}
33+
34+
func (opts *atlasBackupsRestoresListOpts) init() error {
35+
if opts.ProjectID() == "" {
36+
return errMissingProjectID
37+
}
38+
39+
var err error
40+
opts.store, err = store.New()
41+
return err
42+
}
43+
44+
func (opts *atlasBackupsRestoresListOpts) Run() error {
45+
listOpts := opts.newListOptions()
46+
result, err := opts.store.ContinuousRestoreJobs(opts.ProjectID(), opts.clusterName, listOpts)
47+
48+
if err != nil {
49+
return err
50+
}
51+
52+
return json.PrettyPrint(result)
53+
}
54+
55+
func (opts *atlasBackupsRestoresListOpts) newListOptions() *atlas.ListOptions {
56+
return &atlas.ListOptions{
57+
PageNum: opts.pageNum,
58+
ItemsPerPage: opts.itemsPerPage,
59+
}
60+
}
61+
62+
// mongocli atlas backup(s) restore(s) job(s) list
63+
func AtlasBackupsRestoresListBuilder() *cobra.Command {
64+
opts := &atlasBackupsRestoresListOpts{
65+
globalOpts: newGlobalOpts(),
66+
}
67+
cmd := &cobra.Command{
68+
Use: "list",
69+
Aliases: []string{"ls"},
70+
Short: "Start a restore job.",
71+
Args: cobra.ExactArgs(1),
72+
PreRunE: func(cmd *cobra.Command, args []string) error {
73+
return opts.init()
74+
},
75+
RunE: func(cmd *cobra.Command, args []string) error {
76+
opts.clusterName = args[0]
77+
78+
return opts.Run()
79+
},
80+
}
81+
82+
cmd.Flags().IntVar(&opts.pageNum, flags.Page, 0, usage.Page)
83+
cmd.Flags().IntVar(&opts.itemsPerPage, flags.Limit, 0, usage.Limit)
84+
85+
cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID)
86+
87+
return cmd
88+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2020 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cli
16+
17+
import (
18+
"testing"
19+
20+
"github.com/golang/mock/gomock"
21+
"github.com/mongodb/mongocli/internal/fixtures"
22+
"github.com/mongodb/mongocli/internal/mocks"
23+
)
24+
25+
func TestAtlasBackupsRestoresListOpts_Run(t *testing.T) {
26+
ctrl := gomock.NewController(t)
27+
mockStore := mocks.NewMockContinuousJobLister(ctrl)
28+
29+
defer ctrl.Finish()
30+
31+
expected := fixtures.ContinuousJobs()
32+
33+
listOpts := &atlasBackupsRestoresListOpts{
34+
globalOpts: newGlobalOpts(),
35+
store: mockStore,
36+
clusterName: "Cluster0",
37+
}
38+
39+
mockStore.
40+
EXPECT().
41+
ContinuousRestoreJobs(listOpts.projectID, "Cluster0", listOpts.newListOptions()).
42+
Return(expected, nil).
43+
Times(1)
44+
45+
err := listOpts.Run()
46+
if err != nil {
47+
t.Fatalf("Run() unexpected error: %v", err)
48+
}
49+
}

internal/cli/atlas_backups_snapshots_list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (opts *atlasBackupsSnapshotsListOpts) newListOptions() *atlas.ListOptions {
5959
}
6060
}
6161

62-
// mongocli atlas cluster(s) list --projectId projectId [--page N] [--limit N]
62+
// mongocli atlas backups snapshots list --projectId projectId [--page N] [--limit N]
6363
func AtlasBackupsSnapshotsListBuilder() *cobra.Command {
6464
opts := &atlasBackupsSnapshotsListOpts{
6565
globalOpts: newGlobalOpts(),

internal/fixtures/continuous_jobs.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package fixtures
2+
3+
import atlas "github.com/mongodb/go-client-mongodb-atlas/mongodbatlas"
4+
5+
func AutomatedContinuousJob() *atlas.ContinuousJob {
6+
return &atlas.ContinuousJob{
7+
BatchID: "",
8+
ClusterID: "",
9+
Created: "",
10+
ClusterName: "",
11+
Delivery: nil,
12+
EncryptionEnabled: false,
13+
GroupID: "",
14+
Hashes: nil,
15+
ID: "",
16+
Links: nil,
17+
MasterKeyUUID: "",
18+
SnapshotID: "",
19+
StatusName: "",
20+
PointInTime: nil,
21+
Timestamp: atlas.SnapshotTimestamp{},
22+
}
23+
}
24+
25+
func ContinuousJobs() *atlas.ContinuousJobs {
26+
pointInTime := false
27+
28+
return &atlas.ContinuousJobs{
29+
Links: []*atlas.Link{
30+
{
31+
Href: "http://mms:9080/backup/restore/v2/pull/5e6a4f56917b225d8c10e708/ODgwODQzZDZmNjk3NGE2ZGExMDM2M2U1YmU1MjgwMGM=/myReplicaSet4-1584012528-5e6a4f56917b225d8c10e708.tar.gz",
32+
Rel: "self",
33+
},
34+
},
35+
Results: []*atlas.ContinuousJob{
36+
{
37+
ClusterID: "5e662732917b220fbd8be844",
38+
Created: "2020-03-12T15:03:50Z",
39+
Delivery: &atlas.Delivery{
40+
Expires: "2020-03-12T17:03:50Z",
41+
ExpirationHours: 2,
42+
MaxDownloads: 1,
43+
MethodName: "HTTP",
44+
StatusName: "READY",
45+
URL: "http://mms:9080/backup/restore/v2/pull/5e6a4f56917b225d8c10e708/ODgwODQzZDZmNjk3NGE2ZGExMDM2M2U1YmU1MjgwMGM=/myReplicaSet4-1584012528-5e6a4f56917b225d8c10e708.tar.gz",
46+
},
47+
EncryptionEnabled: false,
48+
GroupID: "5e66185d917b220fbd8bb4d1",
49+
ID: "5e6a4f56917b225d8c10e708",
50+
Links: []*atlas.Link{
51+
{
52+
Href: "http://mms:9080/api/public/v1.0/groups/5e66185d917b220fbd8bb4d1/clusters/5e662732917b220fbd8be844/restoreJobs/5e6a4f56917b225d8c10e708",
53+
Rel: "self",
54+
},
55+
},
56+
SnapshotID: "5e6a1d3f917b22609860fd74",
57+
StatusName: "FINISHED",
58+
PointInTime: &pointInTime,
59+
Timestamp: atlas.SnapshotTimestamp{
60+
Date: "2020-03-12T11:28:48Z",
61+
Increment: 1,
62+
},
63+
},
64+
},
65+
TotalCount: 1,
66+
}
67+
}

internal/mocks/mock_continuous_jobs.go

Lines changed: 87 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)