Skip to content

[SR] Delete and execute SLM policies#41934

Merged
jen-huang merged 7 commits intoelastic:masterfrom
jen-huang:feature/slm-delete
Aug 1, 2019
Merged

[SR] Delete and execute SLM policies#41934
jen-huang merged 7 commits intoelastic:masterfrom
jen-huang:feature/slm-delete

Conversation

@jen-huang
Copy link
Contributor

@jen-huang jen-huang commented Jul 24, 2019

Summary

This PR adds the ability to delete and execute SLM policies from the UI. Executing a policy is referred to as "Run" (i.e. "Run policy") in the UI and this action means that a snapshot will be taken immediately using the configuration specified in the policy. Delete is self explanatory and uses our single/multi-delete pattern used in other apps.

Screenshots

Actions in table and details .

Run and delete actions in table row
image

Bulk delete from selecting multiple rows
image

Run and delete actions in policy details
image

Delete policy(ies) .

Single delete modal
image

Bulk delete modal
image

Run policy

Run policy modal
image

@jen-huang jen-huang added release_note:enhancement v8.0.0 Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more t// Feature:Snapshot and Restore Elasticsearch snapshots and repositories UI v7.4.0 labels Jul 24, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/es-ui


const deleteRepository = () => {
const repositoriesToDelete = [...repositoryNames];
deleteRepositories(repositoriesToDelete).then(({ data: { itemsDeleted, errors }, error }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

while working on policy deletion, I found that for server errors such as 404 or 500, which don't return a data object, early destructuring here causes an undefined object error, so no toast notification is shown. I adjusted this for policy deletion and fixed it for other delete providers in this app such as here.

aria-labelledby="srPolicyDetailsFlyoutTitle"
size="m"
maxWidth={400}
maxWidth={550}
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 bumped up the max width of all flyouts in this app as recent changes in EUI made them too narrow

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@alisonelizabeth alisonelizabeth left a comment

Choose a reason for hiding this comment

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

@jen-huang tested locally and everything LGTM. Left a couple minor comments.

return (
<EuiButtonEmpty
color="danger"
data-test-subj="srPoicyDetailsDeleteActionButton"
Copy link
Contributor

Choose a reason for hiding this comment

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

typo here i think: srPoicyDetailsDeleteActionButton --> srPolicyDetailsDeleteActionButton

}
fill
color="primary"
data-test-subj="srPoicyDetailsExecuteActionButton"
Copy link
Contributor

Choose a reason for hiding this comment

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

srPoicyDetailsExecuteActionButton --> srPolicyDetailsExecuteActionButton

aria-label={i18n.translate(
'xpack.snapshotRestore.policyList.table.actionExecuteAriaLabel',
{
defaultMessage: 'Run policy `{name}`',
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be

`Run policy '{name}'`

aria-label={i18n.translate(
'xpack.snapshotRestore.policyList.table.actionDeleteAriaLabel',
{
defaultMessage: 'Delete policy `{name}`',
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be

`Delete policy '{name}'`

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@jen-huang jen-huang merged commit 6860574 into elastic:master Aug 1, 2019
@jen-huang jen-huang deleted the feature/slm-delete branch August 1, 2019 00:40
jen-huang added a commit that referenced this pull request Aug 1, 2019
* Add single and bulk policy delete

* Add policy execution

* Remove early destructuring of provider request responses

* Address PR feedback

* Adjust policy requests for useRequest changes

* Fix policy reload
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.

Looks awesome! I know this is a bit late, but I had some suggestions for your perusal.

};

const deletePolicy = () => {
const policiesToDelete = [...policyNames];
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we create a copy of policyNames here? Does something bad happen if we delete policyNames directly?

const deletePolicy = () => {
const policiesToDelete = [...policyNames];
deletePolicies(policiesToDelete).then(({ data, error }) => {
const { itemsDeleted, errors } = data || { itemsDeleted: undefined, errors: undefined };
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: we could also assign a default value to the data parameter above, which would be a bit terser. We could also set a default value to itemsDeleted and errors, which would make lines 52 and 72 terser as well.

    deletePolicies(policiesToDelete).then(({ data = {}, error }) => {
      const { itemsDeleted = [], errors = [] } = data;
// ln 52
      if (itemsDeleted.length) {
// ln 72
      if (error || errors.length) {

I just realized that this won't quite work with the current logic for displaying error messages, but I have a suggestion that could make it work in the next comment.

// Surface error notifications
// `error` is generic server error
// `data.errors` are specific errors with removing particular policy(ies)
if (error || (errors && errors.length)) {
Copy link
Contributor

@cjcenizal cjcenizal Aug 1, 2019

Choose a reason for hiding this comment

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

I was having trouble following this logic because it contains two parallel conditional branches. How about something like this to make the two branches easier to discern and compare?

      function createErrorMessageMultiple(count) {
        return i18n.translate('xpack.snapshotRestore.deletePolicy.errorMultipleNotificationTitle', {
          defaultMessage: 'Error deleting {count} policies',
          values: { count },
        });
      }

      function createErrorMessageSingle(name) {
        return i18n.translate('xpack.snapshotRestore.deletePolicy.errorSingleNotificationTitle', {
          defaultMessage: "Error deleting policy '{name}'",
          values: { name },
        });
      }

      // Surface error notifications
      let errorMessage;

      if (errors.length) {
        // `data.errors` are specific errors with removing particular policy(ies)
        errorMessage = errors.length > 1
          ? createErrorMessageMultiple(errors.length)
          : createErrorMessageSingle(errors[0].name);
      } else if (error) {
        // `error` is generic server error
        errorMessage = policiesToDelete.length > 1
          ? createErrorMessageMultiple(policiesToDelete.length)
          : createErrorMessageSingle(policiesToDelete[0])
      }

      if (errorMessage) {
        toastNotifications.addDanger(errorMessage);
      }

const deleteRepository = () => {
const repositoriesToDelete = [...repositoryNames];
deleteRepositories(repositoriesToDelete).then(({ data: { itemsDeleted, errors }, error }) => {
deleteRepositories(repositoriesToDelete).then(({ data, error }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be fixed like this?

// Default `data` to an empty object if it's not provided, which will have
// undefined `itemsDeleted` and `errors` properties.
deleteRepositories(repositoriesToDelete).then(({ data: { itemsDeleted, errors } = {}, error }) => {

onClick={() =>
executePolicyPrompt(policyName, () => {
onPolicyExecuted();
reload();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this needed? It looks like policy_list calls reload itself.


export const deleteHandler: RouterRouteHandler = async (req, callWithRequest) => {
const { names } = req.params;
const policyNames = names.split(',');
Copy link
Contributor

Choose a reason for hiding this comment

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

Dumb question: are commas disallowed in policy names?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature:Snapshot and Restore Elasticsearch snapshots and repositories UI release_note:enhancement Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more t// v7.4.0 v8.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants