kibana/x-pack/plugins/security_solution/common/utility_types.ts
Frank Hassanabad 8ce6ed42a3
[Security Solutions][Detection Engine] Adds a warning banner when the alerts data has not been migrated yet. (#90258)
## Summary

Adds a warning banner for when the alerting/signals data has not been migrated to the new structure. Although we are planning on supporting some backwards compatibility where the rules don't completely blow up, this support of backwards compatibility is going to be best effort and not have explicit tests and checks against backwards compatibility. Hence the reason we need to alert any users of the system when we can that they should have an administrator visit the detections page to start a migration.

From previous reasons why we don't migrate on startup of Kibana is that there are multiple instances running and it might be a worse situation so we migrate on page visit by an administrator to reduce chances of issues. In the future we might revisit this decision but for now this is what we have moved forward with.

If the user does not have sufficient privileges such as t1 analyst to see if they have should upgrade, no message is shown to those users.

This PR adds the following banner which is non-dismissible to:
* Main detections page
* Manage rules page
* View/Edit rules page
<img width="2259" alt="Screen Shot 2021-02-03 at 4 16 00 PM" src="https://user-images.githubusercontent.com/1151048/106926989-eb2fb300-66ce-11eb-877c-1210357af108.png">

If other dismissible alerts are on the page then you will get a stacked effect until you dismiss those messages. Again, this message cannot be dismissed intentionally to let the user know that they should contact an administrator to update/upgrade the alerting/signal data:
<img width="1526" alt="Screen Shot 2021-02-03 at 5 41 57 PM" src="https://user-images.githubusercontent.com/1151048/106927465-6b561880-66cf-11eb-8c0f-dfdfa624c24b.png">

Other items of note:
* Added ability to remove the button from the callouts
* Consolidated in one area some types
* Removed one part of the callout that has branching logic we never activate. We can re-add that later if we do have a need for it
* e2e Cypress tests added to detect when the banner should be present
* Backfilled unit tests for enzyme for some of the callout code

Manual testing:
Bump this number in your dev env:
https://github.com/elastic/kibana/blob/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_signals_template.ts#L11

Give yourself these permissions (or use one of the scripts for creating these roles):
<img width="1243" alt="Screen Shot 2021-02-05 at 1 49 02 PM" src="https://user-images.githubusercontent.com/1151048/107087773-30301400-67b9-11eb-9ac9-0a67fafd8231.png">

Visit the page.

### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)
- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
- [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
2021-02-16 20:58:52 -07:00

54 lines
2.2 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import * as runtimeTypes from 'io-ts';
import { ReactNode } from 'react';
// This type is for typing EuiDescriptionList
export interface DescriptionList {
title: NonNullable<ReactNode>;
description: NonNullable<ReactNode>;
}
export const unionWithNullType = <T extends runtimeTypes.Mixed>(type: T) =>
runtimeTypes.union([type, runtimeTypes.null]);
export const stringEnum = <T>(enumObj: T, enumName = 'enum') =>
new runtimeTypes.Type<T[keyof T], string>(
enumName,
(u): u is T[keyof T] => Object.values(enumObj).includes(u),
(u, c) =>
Object.values(enumObj).includes(u)
? runtimeTypes.success(u as T[keyof T])
: runtimeTypes.failure(u, c),
(a) => (a as unknown) as string
);
/**
* Unreachable Assertion helper for scenarios like exhaustive switches.
* For references see: https://stackoverflow.com/questions/39419170/how-do-i-check-that-a-switch-block-is-exhaustive-in-typescript
* This "x" should _always_ be a type of "never" and not change to "unknown" or any other type. See above link or the generic
* concept of exhaustive checks in switch blocks.
*
* Optionally you can avoid the use of this by using early returns and TypeScript will clear your type checking without complaints
* but there are situations and times where this function might still be needed.
*
* If you see an error, DO NOT cast "as never" such as:
* assertUnreachable(x as never) // BUG IN YOUR CODE NOW AND IT WILL THROW DURING RUNTIME
* If you see code like that remove it, as that deactivates the intent of this utility.
* If you need to do that, then you should remove assertUnreachable from your code and
* use a default at the end of the switch instead.
* @param x Unreachable field
* @param message Message of error thrown
*/
export const assertUnreachable = (
x: never, // This should always be a type of "never"
message = 'Unknown Field in switch statement'
): never => {
throw new Error(`${message}: ${x}`);
};