Skip to content

Commit afbf5f3

Browse files
authored
cmd: add --all flag to apm resync command (#125)
Implements a new --all flag for APM resync $ ecctl deployment apm resync --all
1 parent 3fe4656 commit afbf5f3

File tree

5 files changed

+122
-7
lines changed

5 files changed

+122
-7
lines changed

cmd/deployment/apm/resync.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,32 @@ import (
2828
)
2929

3030
var resyncApmCmd = &cobra.Command{
31-
Use: "resync <deployment id>",
32-
Short: "Resynchronizes the search index and cache for the selected APM deployment",
33-
PreRunE: cmdutil.MinimumNArgsAndUUID(1),
31+
Use: "resync {<deployment id> | --all}",
32+
Short: "Resynchronizes the search index and cache for the selected APM deployment or all APM deployments",
33+
PreRunE: cmdutil.CheckInputHas1ArgsOr0ArgAndAll,
3434
RunE: func(cmd *cobra.Command, args []string) error {
35+
all, _ := cmd.Flags().GetBool("all")
36+
37+
if all {
38+
fmt.Println("Resynchronizing all APM deployments")
39+
res, err := apm.ResyncAll(apm.ResyncAllParams{
40+
API: ecctl.Get().API,
41+
})
42+
if err != nil {
43+
return err
44+
}
45+
46+
return ecctl.Get().Formatter.Format("", res)
47+
}
48+
3549
fmt.Printf("Resynchronizing APM deployment: %s\n", args[0])
3650
return apm.Resync(apm.ResyncParams{
3751
API: ecctl.Get().API,
3852
ClusterID: args[0],
3953
})
4054
},
4155
}
56+
57+
func init() {
58+
resyncApmCmd.Flags().Bool("all", false, "Resynchronizes the search index for all APM instances")
59+
}

docs/ecctl_deployment_apm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ ecctl deployment apm [flags]
4444
* [ecctl deployment apm list](ecctl_deployment_apm_list.md) - Lists the APM deployments
4545
* [ecctl deployment apm plan](ecctl_deployment_apm_plan.md) - Manages APM plans
4646
* [ecctl deployment apm restart](ecctl_deployment_apm_restart.md) - Restarts an APM deployment
47-
* [ecctl deployment apm resync](ecctl_deployment_apm_resync.md) - Resynchronizes the search index and cache for the selected APM deployment
47+
* [ecctl deployment apm resync](ecctl_deployment_apm_resync.md) - Resynchronizes the search index and cache for the selected APM deployment or all APM deployments
4848
* [ecctl deployment apm show](ecctl_deployment_apm_show.md) - Shows the specified APM deployment
4949
* [ecctl deployment apm stop](ecctl_deployment_apm_stop.md) - Stops an APM deployment
5050
* [ecctl deployment apm upgrade](ecctl_deployment_apm_upgrade.md) - Upgrades an APM deployment to the Elasticsearch deployment version

docs/ecctl_deployment_apm_resync.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
## ecctl deployment apm resync
22

3-
Resynchronizes the search index and cache for the selected APM deployment
3+
Resynchronizes the search index and cache for the selected APM deployment or all APM deployments
44

55
### Synopsis
66

7-
Resynchronizes the search index and cache for the selected APM deployment
7+
Resynchronizes the search index and cache for the selected APM deployment or all APM deployments
88

99
```
10-
ecctl deployment apm resync <deployment id> [flags]
10+
ecctl deployment apm resync {<deployment id> | --all} [flags]
1111
```
1212

1313
### Options
1414

1515
```
16+
--all Resynchronizes the search index for all APM instances
1617
-h, --help help for resync
1718
```
1819

pkg/deployment/apm/resync.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package apm
2020
import (
2121
"github.com/elastic/cloud-sdk-go/pkg/api"
2222
"github.com/elastic/cloud-sdk-go/pkg/client/clusters_apm"
23+
"github.com/elastic/cloud-sdk-go/pkg/models"
2324
multierror "github.com/hashicorp/go-multierror"
2425

2526
"github.com/elastic/ecctl/pkg/deployment/deputil"
@@ -44,6 +45,19 @@ func (params ResyncParams) Validate() error {
4445
return err.ErrorOrNil()
4546
}
4647

48+
// ResyncAllParams is consumed by ResyncAll
49+
type ResyncAllParams struct {
50+
*api.API
51+
}
52+
53+
// Validate ensures the parameters are usable by the consuming function.
54+
func (params ResyncAllParams) Validate() error {
55+
if params.API == nil {
56+
return util.ErrAPIReq
57+
}
58+
return nil
59+
}
60+
4761
// Resync forces indexer to immediately resynchronize the search index
4862
// and cache for a given APM cluster.
4963
func Resync(params ResyncParams) error {
@@ -59,3 +73,20 @@ func Resync(params ResyncParams) error {
5973
),
6074
)
6175
}
76+
77+
// ResyncAll asynchronously resynchronizes the search index for all APM instances.
78+
func ResyncAll(params ResyncAllParams) (*models.ModelVersionIndexSynchronizationResults, error) {
79+
if err := params.Validate(); err != nil {
80+
return nil, err
81+
}
82+
83+
res, err := params.API.V1API.ClustersApm.ResyncApmClusters(
84+
clusters_apm.NewResyncApmClustersParams(),
85+
params.API.AuthWriter,
86+
)
87+
if err != nil {
88+
return nil, api.UnwrapError(err)
89+
}
90+
91+
return res.Payload, nil
92+
}

pkg/deployment/apm/resync_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"github.com/elastic/cloud-sdk-go/pkg/api"
2828
"github.com/elastic/cloud-sdk-go/pkg/api/mock"
29+
"github.com/elastic/cloud-sdk-go/pkg/models"
2930
multierror "github.com/hashicorp/go-multierror"
3031

3132
"github.com/elastic/ecctl/pkg/util"
@@ -102,3 +103,67 @@ func TestResync(t *testing.T) {
102103
})
103104
}
104105
}
106+
107+
func TestResyncAll(t *testing.T) {
108+
type args struct {
109+
params ResyncAllParams
110+
}
111+
tests := []struct {
112+
name string
113+
args args
114+
wantErr error
115+
want *models.ModelVersionIndexSynchronizationResults
116+
}{
117+
{
118+
name: "Fails due to parameter validation (API)",
119+
args: args{params: ResyncAllParams{}},
120+
wantErr: errors.New("api reference is required for command"),
121+
},
122+
{
123+
name: "Fails due to unknown API response",
124+
args: args{params: ResyncAllParams{
125+
API: api.NewMock(mock.Response{Response: http.Response{
126+
StatusCode: http.StatusForbidden,
127+
Body: mock.NewStringBody(`{"error": "some forbidden error"}`),
128+
}}),
129+
}},
130+
wantErr: errors.New(`{"error": "some forbidden error"}`),
131+
},
132+
{
133+
name: "Fails due to API error",
134+
args: args{params: ResyncAllParams{
135+
API: api.NewMock(mock.Response{
136+
Error: errors.New("error with API"),
137+
}),
138+
}},
139+
wantErr: &url.Error{
140+
Op: "Post",
141+
URL: "https://mock-host/mock-path/clusters/apm/_resync?skip_matching_version=true",
142+
Err: errors.New("error with API"),
143+
},
144+
},
145+
{
146+
name: "Succeeds to resynchronize all APM instances without errors",
147+
args: args{params: ResyncAllParams{
148+
API: api.NewMock(mock.Response{Response: http.Response{
149+
StatusCode: http.StatusAccepted,
150+
Body: mock.NewStringBody(`{}`),
151+
}}),
152+
}},
153+
want: &models.ModelVersionIndexSynchronizationResults{},
154+
},
155+
}
156+
157+
for _, tt := range tests {
158+
t.Run(tt.name, func(t *testing.T) {
159+
got, err := ResyncAll(tt.args.params)
160+
if !reflect.DeepEqual(tt.wantErr, err) {
161+
t.Errorf("ResyncAll() error = %v, wantErr %v", err, tt.wantErr)
162+
return
163+
}
164+
if !reflect.DeepEqual(got, tt.want) {
165+
t.Errorf("ResyncAll() = %v, want %v", got, tt.want)
166+
}
167+
})
168+
}
169+
}

0 commit comments

Comments
 (0)