Skip to content

Commit

Permalink
feat(cli): also delete replica indices (#127)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Clement Denoix <[email protected]>
  • Loading branch information
kai687 and clemfromspace authored Jul 24, 2023
1 parent a72c409 commit 26ef30e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 20 deletions.
50 changes: 46 additions & 4 deletions pkg/cmd/indices/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ type DeleteOptions struct {

SearchClient func() (*search.Client, error)

Indices []string
DoConfirm bool
Indices []string
DoConfirm bool
IncludeReplicas bool
}

// NewDeleteCmd creates and returns a delete command for indices
Expand All @@ -48,6 +49,9 @@ func NewDeleteCmd(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
# Delete the index named "TEST_PRODUCTS_1"
$ algolia indices delete TEST_PRODUCTS_1
# Delete the index named "TEST_PRODUCTS_1" and its replicas
$ algolia indices delete TEST_PRODUCTS_1 --includeReplicas
# Delete the index named "TEST_PRODUCTS_1", skipping the confirmation prompt
$ algolia indices delete TEST_PRODUCTS_1 -y
Expand All @@ -73,6 +77,7 @@ func NewDeleteCmd(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
}

cmd.Flags().BoolVarP(&confirm, "confirm", "y", false, "skip confirmation prompt")
cmd.Flags().BoolVarP(&opts.IncludeReplicas, "includeReplicas", "r", false, "delete replica indices too")

return cmd
}
Expand All @@ -85,7 +90,11 @@ func runDeleteCmd(opts *DeleteOptions) error {

if opts.DoConfirm {
var confirmed bool
err := prompt.Confirm(fmt.Sprintf("Are you sure you want to delete the indices %q?", strings.Join(opts.Indices, ", ")), &confirmed)
msg := "Are you sure you want to delete the indices %q?"
if opts.IncludeReplicas {
msg = "Are you sure you want to delete the indices %q including their replicas?"
}
err := prompt.Confirm(fmt.Sprintf(msg, strings.Join(opts.Indices, ", ")), &confirmed)
if err != nil {
return fmt.Errorf("failed to prompt: %w", err)
}
Expand All @@ -102,10 +111,43 @@ func runDeleteCmd(opts *DeleteOptions) error {
return fmt.Errorf("index %q does not exist", indexName)
}
indices = append(indices, index)

if opts.IncludeReplicas {
settings, err := index.GetSettings()

if err != nil {
return fmt.Errorf("can't get settings of index %q: %w", indexName, err)
}

replicas := settings.Replicas
for _, replicaName := range replicas.Get() {
replica := client.InitIndex(replicaName)
indices = append(indices, replica)
}
}
}

for _, index := range indices {
if _, err := index.Delete(); err != nil {
var mustWait bool

if opts.IncludeReplicas {
settings, err := index.GetSettings()
if err != nil {
return fmt.Errorf("failed to get settings of index %q: %w", index.GetName(), err)
}
if len(settings.Replicas.Get()) > 0 {
mustWait = true
}
}

res, err := index.Delete()

// Otherwise, the replica indices might not be 'fully detached' yet.
if mustWait {
_ = res.Wait()
}

if err != nil {
opts.IO.StartProgressIndicatorWithLabel(fmt.Sprint("Deleting replica index ", index.GetName()))
err := deleteReplicaIndex(client, index)
opts.IO.StopProgressIndicator()
Expand Down
54 changes: 38 additions & 16 deletions pkg/cmd/indices/delete/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ func TestNewDeleteCmd(t *testing.T) {
name string
tty bool
cli string
isReplica bool
wantsErr bool
wantsOpts DeleteOptions
}{
Expand Down Expand Up @@ -97,12 +96,13 @@ func TestNewDeleteCmd(t *testing.T) {

func Test_runDeleteCmd(t *testing.T) {
tests := []struct {
name string
cli string
indices []string
replica bool
isTTY bool
wantOut string
name string
cli string
indices []string
isReplica bool
hasReplicas bool
isTTY bool
wantOut string
}{
{
name: "no TTY",
Expand All @@ -122,8 +122,8 @@ func Test_runDeleteCmd(t *testing.T) {
name: "no TTY, multiple indices",
cli: "foo bar --confirm",
indices: []string{"foo", "bar"},
isTTY: true,
wantOut: "✓ Deleted indices foo, bar\n",
isTTY: false,
wantOut: "",
},
{
name: "TTY, multiple indices",
Expand All @@ -133,12 +133,20 @@ func Test_runDeleteCmd(t *testing.T) {
wantOut: "✓ Deleted indices foo, bar\n",
},
{
name: "TTY, replica indice",
cli: "foo --confirm",
indices: []string{"foo"},
replica: true,
isTTY: true,
wantOut: "✓ Deleted indices foo\n",
name: "TTY, replica indices",
cli: "foo --confirm",
indices: []string{"foo"},
isReplica: true,
isTTY: true,
wantOut: "✓ Deleted indices foo\n",
},
{
name: "TTY, has replica indices",
cli: "foo --confirm --includeReplicas",
indices: []string{"foo"},
hasReplicas: true,
isTTY: true,
wantOut: "✓ Deleted indices foo\n",
},
}

Expand All @@ -148,7 +156,21 @@ func Test_runDeleteCmd(t *testing.T) {
for _, index := range tt.indices {
// First settings call with `Exists()`
r.Register(httpmock.REST("GET", fmt.Sprintf("1/indexes/%s/settings", index)), httpmock.JSONResponse(search.Settings{}))
if tt.replica {
if tt.hasReplicas {
// Settings calls for the primary index and its replicas
r.Register(httpmock.REST("GET", fmt.Sprintf("1/indexes/%s/settings", index)), httpmock.JSONResponse(search.Settings{
Replicas: opt.Replicas("bar"),
}))
r.Register(httpmock.REST("GET", fmt.Sprintf("1/indexes/%s/settings", index)), httpmock.JSONResponse(search.Settings{
Replicas: opt.Replicas("bar"),
}))
r.Register(httpmock.REST("GET", "1/indexes/bar/settings"), httpmock.JSONResponse(search.Settings{
Primary: opt.Primary("foo"),
}))
// Additional DELETE calls for the replicas
r.Register(httpmock.REST("DELETE", "1/indexes/bar"), httpmock.JSONResponse(search.Settings{}))
}
if tt.isReplica {
// We want the first `Delete()` call to fail
r.Register(httpmock.REST("DELETE", fmt.Sprintf("1/indexes/%s", index)), httpmock.ErrorResponse())
// Second settings call to fetch the primary index name
Expand Down

0 comments on commit 26ef30e

Please sign in to comment.