From e45cba93e276ba298027895abb5acc230e8b8be9 Mon Sep 17 00:00:00 2001 From: Andrew Wilkins Date: Fri, 4 Jun 2021 13:07:20 +0800 Subject: [PATCH] libbeat/idxmgmt/ilm: fix alias creation When creating the initial index/write alias fails, don't check the status code, just check if the alias exists regardless of the error. This fixes a bug where alias creation fails when the alias exists but points to another index, and the initial index does not exist (e.g. due to ILM deletion.) --- CHANGELOG.next.asciidoc | 1 + libbeat/idxmgmt/ilm/client_handler.go | 17 +++++----- .../ilm/client_handler_integration_test.go | 33 ++++++++++++++++++- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b71219e397da..2a21efcac159 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -238,6 +238,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix 'make setup' instructions for a new beat {pull}24944[24944] - Fix out of date FreeBSD vagrantbox. {pull}25652[25652] - Fix handling of `file_selectors` in aws-s3 input. {pull}25792[25792] +- Fix ILM alias creation when write alias exists and initial index does not exist {pull}26143[26143] *Auditbeat* diff --git a/libbeat/idxmgmt/ilm/client_handler.go b/libbeat/idxmgmt/ilm/client_handler.go index 12b739c99467..d17af457ef46 100644 --- a/libbeat/idxmgmt/ilm/client_handler.go +++ b/libbeat/idxmgmt/ilm/client_handler.go @@ -191,19 +191,18 @@ func (h *ESClientHandler) CreateAlias(alias Alias) error { } // Note: actual aliases are accessible via the index - status, res, err := h.client.Request("PUT", "/"+firstIndex, "", nil, body) - if status == 400 { - // HasAlias fails if there is an index with the same name, that is - // what we want to check here. - _, err := h.HasAlias(alias.Name) - if err != nil { + if _, res, err := h.client.Request("PUT", "/"+firstIndex, "", nil, body); err != nil { + // Creating the index may fail for multiple reasons, e.g. because + // the index exists, or because the write alias exists and points + // to another index. + if ok, err := h.HasAlias(alias.Name); err != nil { + // HasAlias fails if there is an index with the same name. return err + } else if ok { + return errOf(ErrAliasAlreadyExists) } - return errOf(ErrAliasAlreadyExists) - } else if err != nil { return wrapErrf(err, ErrAliasCreateFailed, "failed to create alias: %s", res) } - return nil } diff --git a/libbeat/idxmgmt/ilm/client_handler_integration_test.go b/libbeat/idxmgmt/ilm/client_handler_integration_test.go index 936eb35dcd81..9471da7c9cfb 100644 --- a/libbeat/idxmgmt/ilm/client_handler_integration_test.go +++ b/libbeat/idxmgmt/ilm/client_handler_integration_test.go @@ -136,13 +136,44 @@ func TestESClientHandler_Alias(t *testing.T) { assert.True(t, b) }) - t.Run("second create", func(t *testing.T) { + t.Run("create index exists", func(t *testing.T) { alias := makeAlias("esch-alias-2create") h := newESClientHandler(t) err := h.CreateAlias(alias) assert.NoError(t, err) + // Second time around creating the alias, ErrAliasAlreadyExists is returned: + // the initial index already exists and the write alias points to it. + err = h.CreateAlias(alias) + require.Error(t, err) + assert.Equal(t, ilm.ErrAliasAlreadyExists, ilm.ErrReason(err)) + + b, err := h.HasAlias(alias.Name) + assert.NoError(t, err) + assert.True(t, b) + }) + + t.Run("create alias exists", func(t *testing.T) { + alias := makeAlias("esch-alias-2create") + alias.Pattern = "000001" // no date math, so we get predictable index names + h := newESClientHandler(t) + + err := h.CreateAlias(alias) + assert.NoError(t, err) + + // Rollover, so write alias points at -000002. + es := newRawESClient(t) + _, _, err = es.Request("POST", "/"+alias.Name+"/_rollover", "", nil, nil) + require.NoError(t, err) + + // Delete -000001, simulating ILM delete. + _, _, err = es.Request("DELETE", "/"+alias.Name+"-"+alias.Pattern, "", nil, nil) + require.NoError(t, err) + + // Second time around creating the alias, ErrAliasAlreadyExists is returned: + // initial index does not exist, but the write alias exists and points to + // another index. err = h.CreateAlias(alias) require.Error(t, err) assert.Equal(t, ilm.ErrAliasAlreadyExists, ilm.ErrReason(err))