Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Index management] Treat indices beginning with a period as regular indices #112990

Merged

Conversation

sebelga
Copy link
Contributor

@sebelga sebelga commented Sep 23, 2021

In 8.x indices starting with a dot (.) will be considered as normal indices. Only if they are created with the setting { hidden: true } they will be considered hidden.

This PR updates Index management to treat indices beginning with a period as regular indices.

Note on implementation

This PR will be backported to 7.x. Once the backport is done I will add a commit to change the hardcoded version "8.0.0" to "7.16.0" and I will run the test updating the jest snapshots. We will then be able to test in 7.x and make sure there are no regression.

Deleting or closing an index

In 7.x, indices starting with a dot are considered system indices and there is a warning inside the modal that indicates that. In 8.x we won't surface system indices in Index management so we don't show any warning.

In 8.x

Screenshot 2021-09-23 at 16 38 28

In 7.x

Screenshot 2021-09-23 at 16 39 27

Fixes #79527

health: i % 2 === 0 ? 'green' : 'yellow',
status: i % 2 === 0 ? 'open' : 'closed',
let isOpen = true;
const getBaseFakeIndex = () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make this change to make sure alternate indices are open and closed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will be easier to follow if this function accepts isOpen instead of relying on a side effect:

const getBaseFakeIndex = (isOpen) => {
  /* ... */
};

And then the consumer is responsible for the alternation logic:

// Indices will alternate between being open and closed
for (let i = 0; i < 105; i++) {
  indices.push({
    ...getBaseFakeIndex(true),
    name: `testy${i}`,
  });

  indices.push({
    ...getBaseFakeIndex(false),
    name: `.admin${i}`,
    // Add 2 hidden indices in the list in position 3 & 7
    // note: for each loop iteration we add 2 indices
    hidden: i === 1 || i === 3 ? true : false, // ".admin1" and ".admin3" are the only hidden in 8.x
  });
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of the same, but ok if you prefer it like that I will change it 👍

const rendered = mountWithIntl(component);
await runAllPromises();
rendered.update();

snapshot(rendered.find('.euiPagination li').map((item) => item.text()));
const switchControl = rendered.find('.euiSwitch__button');
snapshot(namesText(rendered));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why we were snapshotting the eui pagination list. I changed it to snapshot the list of indices names.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cuff-links Looks like there is some overlap here with the work you're doing in #112010

import SemVer from 'semver/classes/semver';
import { Index } from '../../../common';

const version = '8.0.0';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 7.x this will be 7.16.0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be hardcoded? I think you can read the Kibana version from core via PluginInitializerContext.env.packageInfo.version. See #85969 (comment).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Alison. Would we have to remember to update these strings for each patch release (7.16.1, 8.0.1) and minor (8.1.0)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started trying to inject dynamically the version with PluginInitializerContext.env.packageInfo.version. Then I realised it was going to change way too many files for very little benefit. I then weighted the pros and cons and thought it was much more surgical with less impact in the code base (less risk of regression) to have 2 hardcoded strings.

Would we have to remember to update these strings for each patch release

No we won't, the code only looks for the major version.

import { ExtensionsService } from '../../../services';
import { getFilteredIndices } from '.';
// @ts-ignore
import { defaultTableState } from '../reducers/table_state';
import { setExtensionsService } from './extension_service';

const version = '8.0.0';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 7.x this will be 7.16.0

@sebelga sebelga marked this pull request as ready for review September 23, 2021 15:33
@sebelga sebelga requested a review from a team as a code owner September 23, 2021 15:33
@sebelga sebelga added backport-v7.16.0 release_note:skip Skip the PR/issue when compiling release notes v8.0.0 Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more labels Sep 23, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-stack-management (Team:Stack Management)

@sebelga sebelga requested a review from cjcenizal September 23, 2021 15:34
@cjcenizal
Copy link
Contributor

cjcenizal commented Sep 23, 2021

This PR will be backported to 7.x.

Why backport this to 7.x? After feature freeze the only backports we'll make to 7.16 are bug fixes, which have historically been fairly rare for our team. I don't think it's worth dealing with a complex backport when the likelihood of having to deal with merge conflicts is low.

I'm concerned about the loss of this type of UX when users delete indices which affect Kibana's internals:

Screenshot 2021-09-23 at 16 39 27

We'll still want to warn users away from making potentially destructive mistakes. But how do we identify these internal indices now? Is it enough to assume any hidden index is internal? I think it might be. Can you reach out to the Core folks about this and get their input?

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, Seb! I tested locally and it works great. I do think we should avoid hardcoding version numbers, but I think we can also avoid having to worry about that entirely by not backporting this to 7.x.

health: i % 2 === 0 ? 'green' : 'yellow',
status: i % 2 === 0 ? 'open' : 'closed',
let isOpen = true;
const getBaseFakeIndex = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will be easier to follow if this function accepts isOpen instead of relying on a side effect:

const getBaseFakeIndex = (isOpen) => {
  /* ... */
};

And then the consumer is responsible for the alternation logic:

// Indices will alternate between being open and closed
for (let i = 0; i < 105; i++) {
  indices.push({
    ...getBaseFakeIndex(true),
    name: `testy${i}`,
  });

  indices.push({
    ...getBaseFakeIndex(false),
    name: `.admin${i}`,
    // Add 2 hidden indices in the list in position 3 & 7
    // note: for each loop iteration we add 2 indices
    hidden: i === 1 || i === 3 ? true : false, // ".admin1" and ".admin3" are the only hidden in 8.x
  });
}

@@ -110,6 +119,7 @@ const testAction = (rendered, buttonIndex, rowIndex = 0) => {
// so we "time" our assertion based on how many Redux actions we observe. This is brittle because it
// depends upon how our UI is architected, which will affect how many actions are dispatched.
// Expect this to break when we rearchitect the UI.
// Update: Expect this to be removed when we rearchitect the UI :)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you help me understand what this means? For clarity on my part, my original comment about rearchitecting wasn't a reference to removing Redux. It was a reference more broadly to any change to architecture which could break the the test. It was an attempt to explain the brittleness behind the test.

Copy link
Contributor Author

@sebelga sebelga Sep 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I went one step further. We are testing implementation detail and we don't want that. Once we rearchitect the UI this test will have to go away. Actually it should even go away (and replaced by CIT) before doing any change of architecture to be sure we don't have any regression.

const rendered = mountWithIntl(component);
await runAllPromises();
rendered.update();

snapshot(rendered.find('.euiPagination li').map((item) => item.text()));
const switchControl = rendered.find('.euiSwitch__button');
snapshot(namesText(rendered));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cuff-links Looks like there is some overlap here with the work you're doing in #112010

switchControl.simulate('click');
snapshot(rendered.find('.euiPagination li').map((item) => item.text()));

snapshot(namesText(rendered));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a hard time understanding what to expect from this. Some questions on my mind are:

  • What's the initial state of the toggle? On or off?
  • Are we expecting to see or not to see hidden indices in the first snapshot?
  • And all of the same questions apply again after we click the toggle again: is it off now, or on? Should we see hidden indices or not?

I think we can improve this by creating two separate tests: one to assert that the table shows hidden indices when the toggle is on, and one to assert the opposite. Within each test it would also be helpful to add an assertion about the state of the toggle (on or off). This will make it easier to verify the tests are working as expected based. We could take these even farther by inlining the expected content of the table instead of using a snapshot:

exports[`index table should show hidden indices only when the switch is turned on 1`] = `
Array [
  "testy0",
  ".admin0",
  "testy1",
  "testy2",
  ".admin2",
  "testy3",
  "testy4",
  ".admin4",
  "testy5",
  ".admin5",
]
`;

exports[`index table should show hidden indices only when the switch is turned on 2`] = `
Array [
  "testy0",
  ".admin0",
  "testy1",
  ".admin1",
  "testy2",
  ".admin2",
  "testy3",
  ".admin3",
  "testy4",
  ".admin4",
]
`;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see what can be done but let's not spend too much time on this (now) as time is scarce. I already improved on a previous bad test to snapshot the list of indices instead of the pagination.
We do have a tech debt to write proper CIT test and get rid of this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I agree with you that it is a terrible test, I just try to do with what's in place to avoid breaking other tests and fixing the whole file.

import SemVer from 'semver/classes/semver';
import { Index } from '../../../common';

const version = '8.0.0';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Alison. Would we have to remember to update these strings for each patch release (7.16.1, 8.0.1) and minor (8.1.0)?

@@ -39,14 +40,14 @@ export const getIndexStatusByIndexName = (state, indexName) => {
const { status } = indices[indexName] || {};
return status;
};
export const getIsSystemIndexByName = (indexNames) => {
export const getIsSystemIndexByName = (indexNames, allIndices) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per my comment we might want to consider all hidden indices to be system indices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hear you and at the same time I'd like to understand why we can't have a simple naming convention and stick to it everywhere in the stack. system indices are system, and hidden indices are simply hidden. Why the UI has to diverge from that and mention to the user that one of his hidden index is in fact system index?

@sebelga
Copy link
Contributor Author

sebelga commented Sep 27, 2021

Why backport this to 7.x? After feature freeze the only backports we'll make to 7.16 are bug fixes, which have historically been fairly rare for our team. I don't think it's worth dealing with a complex backport when the likelihood of having to deal with merge conflicts is low.

I don't think we have to look at it like that. I'd like to put in place a system where we don't have to think what differences exist between majors. This PR could have been created 2 releases ago and we we would have wanted to backport to 7.x

I like to keep things very simple. Are we ever going to backport a PR to a 7.16.x branch? Yes. Then let's have both majors aligned and don't ever worry about remembering the difference between them. The code base is the source of truth (that's why I added comments to explain the nuances).
When we will be in 9.x. If we find in the code if (kibanaVersion.major < 8) { ... } we know for sure that we can delete that branch of the condition.

"dealing with a complex backport" might be a bit an overstatement 😊 I would have preferred to be able to inject the kibana version dynamically but as I said in my comment that was going to be way too big of a change for very little gain.

I'm concerned about the loss of this type of UX when users delete indices which affect Kibana's internals

I will rich out to the @elastic/kibana-core but my assumption is that there were going to mark .kibana as a system index which would not be surfaced in the UI. We need to clarify that indeed but if .kibana is not a system index I don't know what is 😊
The issue I am solving has the title "Treat indices beginning with a period as regular indices" so that's the new behaviour starting in 8.x. Let's see what the core team thinks.

@sebelga sebelga requested a review from cjcenizal September 27, 2021 13:06
@sebelga
Copy link
Contributor Author

sebelga commented Sep 27, 2021

@cjcenizal PR is ready for another round of review, thanks! 👍

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM, didn't test locally. Just want to note that my comment regarding warning users against deleting system indices is moot (#112990 (comment)). I had assumed that ES had already implemented functionality to hide system indices, and that Kibana wasn't going to migrate over to define its internal indices as ES system indices, but that turns out not to be the case.

// We **don't** expect them to be in this list as by default we don't show hidden indices
let indicesInTable = namesText(rendered);
expect(indicesInTable).not.toContain('.admin1');
expect(indicesInTable).not.toContain('.admin3');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test makes sense for 8.0, but does it make sense for 7.16? In 7.16 wouldn't we want to assert that all dot-prefixed indices are hidden here, and revealed on lines 282-283?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what the snapshots should give us. But you are right it is not very explicit (that's why I never use snapshots). I added a test to make it explicit (dc292d5)

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
indexManagement 502 508 +6

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
indexManagement 160 163 +3

Any counts in public APIs

Total count of every any typed public API. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats any for more detailed information.

id before after diff
indexManagement 12 9 -3

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
indexManagement 527.0KB 534.3KB +7.2KB
Unknown metric groups

API count

id before after diff
indexManagement 165 168 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@sebelga sebelga merged commit e28f429 into elastic:master Sep 28, 2021
@sebelga sebelga deleted the index-management/system-hidden-indices branch September 28, 2021 14:29
sebelga added a commit to sebelga/kibana that referenced this pull request Sep 28, 2021
…ndices (elastic#112990)

# Conflicts:
#	x-pack/plugins/index_management/__jest__/client_integration/helpers/constants.ts
#	x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx
sebelga added a commit that referenced this pull request Sep 28, 2021
…ndices (#112990) (#113286)

# Conflicts:
#	x-pack/plugins/index_management/__jest__/client_integration/helpers/constants.ts
#	x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:skip Skip the PR/issue when compiling release notes Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Treat indices beginning with a period as regular indices instead of system indices
5 participants