diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc index d9a8d0558714f..fe4c8a9280158 100644 --- a/docs/apm/api.asciidoc +++ b/docs/apm/api.asciidoc @@ -11,6 +11,7 @@ Some APM app features are provided via a REST API: * <> * <> * <> +* <> [float] [[apm-api-example]] @@ -72,6 +73,7 @@ curl -X POST \ //// ******************************************************* +******************************************************* //// [role="xpack"] @@ -202,11 +204,9 @@ DELETE /api/apm/settings/agent-configuration ******************************************************* //// - [[apm-list-config]] ==== List configuration - [[apm-list-config-req]] ===== Request @@ -274,7 +274,6 @@ GET /api/apm/settings/agent-configuration ******************************************************* //// - [[apm-search-config]] ==== Search configuration @@ -472,6 +471,7 @@ curl -X POST \ //// ******************************************************* +******************************************************* //// [[kibana-api]] @@ -553,3 +553,239 @@ The API returns the following: // More examples will go here More information on Kibana's API is available in <>. + +//// +******************************************************* +******************************************************* +//// + +[role="xpack"] +[[rum-sourcemap-api]] +=== RUM source map API + +IMPORTANT: This endpoint is only compatible with the +{apm-server-ref}/apm-integration.html[APM integration for Elastic Agent]. +Users with a standalone APM Server should instead use the APM Server +{apm-server-ref}/sourcemap-api.html[source map upload API]. + +A source map allows minified files to be mapped back to original source code -- +allowing you to maintain the speed advantage of minified code, +without losing the ability to quickly and easily debug your application. + +For best results, uploading source maps should become a part of your deployment procedure, +and not something you only do when you see unhelpful errors. +That’s because uploading source maps after errors happen won’t make old errors magically readable -- +errors must occur again for source mapping to occur. + +The following APIs are available: + +* <> +* <> +* <> + +[float] +[[use-sourcemap-api]] +==== How to use APM APIs + +.Expand for required headers, privileges, and usage details +[%collapsible%closed] +====== +include::api.asciidoc[tag=using-the-APIs] +====== + +//// +******************************************************* +//// + +[[rum-sourcemap-post]] +==== Create or update source map + +Create or update a source map for a specific service and version. + +[[rum-sourcemap-post-privs]] +===== Privileges + +The user accessing this endpoint requires `All` Kibana privileges for the {beat_kib_app} feature. +For more information, see <>. + +[[apm-sourcemap-post-req]] +===== Request + +`POST /api/apm/sourcemaps` + +[role="child_attributes"] +[[apm-sourcemap-post-req-body]] +===== Request body + +`service_name`:: +(required, string) The name of the service that the service map should apply to. + +`service_version`:: +(required, string) The version of the service that the service map should apply to. + +`bundle_filepath`:: +(required, string) The absolute path of the final bundle as used in the web application. + +`sourcemap`:: +(required, string or file upload) The source map. It must follow the +https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k[source map revision 3 proposal]. + +[[apm-sourcemap-post-example]] +===== Examples + +The following example uploads a source map for a service named `foo` and a service version of `1.0.0`: + +[source,curl] +-------------------------------------------------- +curl -X POST "http://localhost:5601/api/apm/sourcemaps" \ +-H 'Content-Type: multipart/form-data' \ +-H 'kbn-xsrf: true' \ +-H 'Authorization: ApiKey ${YOUR_API_KEY}' \ +-F 'service_name="foo"' \ +-F 'service_version="1.0.0"' \ +-F 'bundle_filepath="/test/e2e/general-usecase/bundle.js.map"' \ +-F 'sourcemap="{\"version\":3,\"file\":\"static/js/main.chunk.js\",\"sources\":[\"fleet-source-map-client/src/index.css\",\"fleet-source-map-client/src/App.js\",\"webpack:///./src/index.css?bb0a\",\"fleet-source-map-client/src/index.js\",\"fleet-source-map-client/src/reportWebVitals.js\"],\"sourcesContent\":[\"content\"],\"mappings\":\"mapping\",\"sourceRoot\":\"\"}"' <1> +-------------------------------------------------- +<1> Alternatively, upload the source map as a file with `-F 'sourcemap=@path/to/source_map/bundle.js.map'` + +[[apm-sourcemap-post-body]] +===== Response body + +[source,js] +-------------------------------------------------- +{ + "type": "sourcemap", + "identifier": "foo-1.0.0", + "relative_url": "/api/fleet/artifacts/foo-1.0.0/644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "body": "eJyFkL1OwzAUhd/Fc+MbYMuCEBIbHRjKgBgc96R16tiWr1OQqr47NwqJxEK3q/PzWccXxchnZ7E1A1SjuhjVZtF2yOxiEPlO17oWox3D3uPFeSRTjmJQARfCPeiAgGx8NTKsYdAc1T3rwaSJGcds8Sp3c1HnhfywUZ3QhMTFFGepZxqMC9oex3CS9tpk1XyozgOlmoVKuJX1DqEQZ0su7PGtLU+V/3JPKc3cL7TJ2FNDRPov4bFta3MDM4f7W69lpJjLO9qdK8bzVPhcJz3HUCQ4LbO/p5hCSC4cZPByrp/wFqOklbpefwAhzpqI", + "created": "2021-07-09T20:47:44.812Z", + "id": "apm:foo-1.0.0-644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "compressionAlgorithm": "zlib", + "decodedSha256": "644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "decodedSize": 441, + "encodedSha256": "024c72749c3e3dd411b103f7040ae62633558608f480bce4b108cf5b2275bd24", + "encodedSize": 237, + "encryptionAlgorithm": "none", + "packageName": "apm" +} +-------------------------------------------------- + +//// +******************************************************* +//// + +[[rum-sourcemap-get]] +==== Get source maps + +Returns an array of Fleet artifacts, including source map uploads. + +[[rum-sourcemap-get-privs]] +===== Privileges + +The user accessing this endpoint requires `Read` or `All` Kibana privileges for the {beat_kib_app} feature. +For more information, see <>. + +[[apm-sourcemap-get-req]] +===== Request + +`GET /api/apm/sourcemaps` + +[[apm-sourcemap-get-example]] +===== Example + +The following example requests all uploaded source maps: + +[source,curl] +-------------------------------------------------- +curl -X GET "http://localhost:5601/api/apm/sourcemaps" \ +-H 'Content-Type: application/json' \ +-H 'kbn-xsrf: true' \ +-H 'Authorization: ApiKey ${YOUR_API_KEY}' +-------------------------------------------------- + +[[apm-sourcemap-get-body]] +===== Response body + +[source,js] +-------------------------------------------------- +{ + "artifacts": [ + { + "type": "sourcemap", + "identifier": "foo-1.0.0", + "relative_url": "/api/fleet/artifacts/foo-1.0.0/644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "body": { + "serviceName": "foo", + "serviceVersion": "1.0.0", + "bundleFilepath": "/test/e2e/general-usecase/bundle.js.map", + "sourceMap": { + "version": 3, + "file": "static/js/main.chunk.js", + "sources": [ + "fleet-source-map-client/src/index.css", + "fleet-source-map-client/src/App.js", + "webpack:///./src/index.css?bb0a", + "fleet-source-map-client/src/index.js", + "fleet-source-map-client/src/reportWebVitals.js" + ], + "sourcesContent": [ + "content" + ], + "mappings": "mapping", + "sourceRoot": "" + } + }, + "created": "2021-07-09T20:47:44.812Z", + "id": "apm:foo-1.0.0-644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "compressionAlgorithm": "zlib", + "decodedSha256": "644fd5a997d1ddd90ee131ba18e2b3d03931d89dd1fe4599143c0b3264b3e456", + "decodedSize": 441, + "encodedSha256": "024c72749c3e3dd411b103f7040ae62633558608f480bce4b108cf5b2275bd24", + "encodedSize": 237, + "encryptionAlgorithm": "none", + "packageName": "apm" + } + ] +} +-------------------------------------------------- + +//// +******************************************************* +//// + +[[rum-sourcemap-delete]] +==== Delete source map + +Delete a previously uploaded source map. + +[[rum-sourcemap-delete-privs]] +===== Privileges + +The user accessing this endpoint requires `All` Kibana privileges for the {beat_kib_app} feature. +For more information, see <>. + +[[apm-sourcemap-delete-req]] +===== Request + +`DELETE /api/apm/sourcemaps/:id` + +[[apm-sourcemap-delete-example]] +===== Example + +The following example deletes a source map with an id of `apm:foo-1.0.0-644fd5a9`: + +[source,curl] +-------------------------------------------------- +curl -X DELETE "http://localhost:5601/api/apm/sourcemaps/apm:foo-1.0.0-644fd5a9" \ +-H 'Content-Type: application/json' \ +-H 'kbn-xsrf: true' \ +-H 'Authorization: ApiKey ${YOUR_API_KEY}' +-------------------------------------------------- + +[[apm-sourcemap-delete-body]] +===== Response body + +[source,js] +-------------------------------------------------- +{} +-------------------------------------------------- diff --git a/docs/apm/apm-app-users.asciidoc b/docs/apm/apm-app-users.asciidoc index 9b8a9c64ac43b..a8eb619a8eab8 100644 --- a/docs/apm/apm-app-users.asciidoc +++ b/docs/apm/apm-app-users.asciidoc @@ -3,7 +3,6 @@ == APM app users and privileges :beat_default_index_prefix: apm -:beat_kib_app: APM app :annotation_index: observability-annotations ++++ @@ -22,7 +21,7 @@ In general, there are three types of privileges you'll work with: * **Elasticsearch cluster privileges**: Manage the actions a user can perform against your cluster. * **Elasticsearch index privileges**: Control access to the data in specific indices your cluster. -* **Kibana space privileges**: Grant users write or read access to features and apps within Kibana. +* **Kibana feature privileges**: Grant users write or read access to features and apps within Kibana. Select your use-case to get started: @@ -88,18 +87,18 @@ include::./tab-widgets/apm-app-reader/widget.asciidoc[] TIP: Using the {apm-server-ref-v}/apm-integration.html[APM integration for Elastic Agent]? Add the privileges under the **Data streams** tab. -. Assign space privileges to any Kibana space that the user needs access to. +. Assign feature privileges to any Kibana feature that the user needs access to. Here are two examples: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -| `Read` or `All` on the {beat_kib_app} -| Allow the use of the the {beat_kib_app} +| Kibana +| `Read` or `All` on the {beat_kib_app} feature +| Allow the use of the the {beat_kib_app} apps -| Spaces +| Kibana | `Read` or `All` on Dashboards and Discover | Allow the user to view, edit, and create dashboards, as well as browse data. |==== @@ -190,16 +189,16 @@ include::./tab-widgets/central-config-users/widget.asciidoc[] TIP: Using the {apm-server-ref-v}/apm-integration.html[APM integration for Elastic Agent]? Add the privileges under the **Data streams** tab. -. Assign the `central-config-manager` role created in the previous step, and the following Kibana space privileges to -anyone who needs to manage central configurations: +. Assign the `central-config-manager` role created in the previous step, +and the following Kibana feature privileges to anyone who needs to manage central configurations: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -|`All` on {beat_kib_app} -|Allow full use of the {beat_kib_app} +| Kibana +|`All` on the {beat_kib_app} feature +|Allow full use of the {beat_kib_app} apps |==== [[apm-app-central-config-reader]] @@ -217,16 +216,16 @@ include::./tab-widgets/central-config-users/widget.asciidoc[] TIP: Using the {apm-server-ref-v}/apm-integration.html[APM integration for Elastic Agent]? Add the privileges under the **Data streams** tab. -. Assign the `central-config-reader` role created in the previous step, and the following Kibana space privileges to -anyone who needs to read central configurations: +. Assign the `central-config-reader` role created in the previous step, +and the following Kibana feature privileges to anyone who needs to read central configurations: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -|`read` on the {beat_kib_app} -|Allow read access to the {beat_kib_app} +| Kibana +|`read` on the {beat_kib_app} feature +|Allow read access to the {beat_kib_app} apps |==== [[apm-app-central-config-api]] @@ -253,15 +252,15 @@ include::./tab-widgets/code.asciidoc[] Users can list, search, create, update, and delete central configurations via the APM app API. -. Assign the following Kibana space privileges: +. Assign the following Kibana feature privileges: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -|`all` on the {beat_kib_app} -|Allow all access to the {beat_kib_app} +| Kibana +|`all` on the {beat_kib_app} feature +|Allow all access to the {beat_kib_app} apps |==== [[apm-app-api-config-reader]] @@ -269,15 +268,15 @@ Users can list, search, create, update, and delete central configurations via th Sometimes a user only needs to list and search central configurations via the APM app API. -. Assign the following Kibana space privileges: +. Assign the following Kibana feature privileges: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -|`read` on the {beat_kib_app} -|Allow read access to the {beat_kib_app} +| Kibana +|`read` on the {beat_kib_app} feature +|Allow read access to the {beat_kib_app} apps |==== [[apm-app-api-annotation-manager]] @@ -310,15 +309,15 @@ and assign the following privileges: |==== . Assign the `annotation_role` created previously, -and the following Kibana space privileges to any annotation API users: +and the following Kibana feature privileges to any annotation API users: + [options="header"] |==== |Type | Privilege | Purpose -| Spaces -|`all` on the {beat_kib_app} -|Allow all access to the {beat_kib_app} +| Kibana +|`all` on the {beat_kib_app} feature +|Allow all access to the {beat_kib_app} apps |==== //LEARN MORE diff --git a/docs/apm/index.asciidoc b/docs/apm/index.asciidoc index 53ffee5e061d6..f4d35a2d554ba 100644 --- a/docs/apm/index.asciidoc +++ b/docs/apm/index.asciidoc @@ -25,6 +25,8 @@ you can also see contextual information such as the request header, user informa system values, or custom data that you manually attached to the request. -- +:beat_kib_app: APM and User Experience + include::set-up.asciidoc[] include::getting-started.asciidoc[] diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.test.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.test.tsx index 4ceacc40942e2..373b4d78a84cc 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.test.tsx @@ -43,7 +43,8 @@ describe('when using the EndpointHostIsolationStatus component', () => { expect(getByTestId('test').textContent).toBe('Isolated'); }); - it.each([ + // FIXME: un-skip when we bring back the pending isolation statuses + it.skip.each([ ['Isolating', { pendingIsolate: 2 }], ['Releasing', { pendingUnIsolate: 2 }], ['4 actions pending', { isIsolated: true, pendingUnIsolate: 2, pendingIsolate: 2 }], diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.tsx index 7ae7cae89f19e..425172a5cd460 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/endpoint_host_isolation_status.tsx @@ -6,9 +6,9 @@ */ import React, { memo, useMemo } from 'react'; -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiTextColor, EuiToolTip } from '@elastic/eui'; +import { EuiBadge } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { useTestIdGenerator } from '../../../../management/components/hooks/use_test_id_generator'; +// import { useTestIdGenerator } from '../../../../management/components/hooks/use_test_id_generator'; export interface EndpointHostIsolationStatusProps { isIsolated: boolean; @@ -25,94 +25,114 @@ export interface EndpointHostIsolationStatusProps { * (`null` is returned) */ export const EndpointHostIsolationStatus = memo( - ({ isIsolated, pendingIsolate = 0, pendingUnIsolate = 0, 'data-test-subj': dataTestSubj }) => { - const getTestId = useTestIdGenerator(dataTestSubj); + ({ + isIsolated, + /* pendingIsolate = 0, pendingUnIsolate = 0,*/ 'data-test-subj': dataTestSubj, + }) => { + // const getTestId = useTestIdGenerator(dataTestSubj); return useMemo(() => { // If nothing is pending and host is not currently isolated, then render nothing - if (!isIsolated && !pendingIsolate && !pendingUnIsolate) { + if (!isIsolated) { return null; } + // if (!isIsolated && !pendingIsolate && !pendingUnIsolate) { + // return null; + // } - // If nothing is pending, but host is isolated, then show isolation badge - if (!pendingIsolate && !pendingUnIsolate) { - return ( - - - - ); - } - - // If there are multiple types of pending isolation actions, then show count of actions with tooltip that displays breakdown - if (pendingIsolate && pendingUnIsolate) { - return ( - - -
- -
- - - - - {pendingIsolate} - - - - - - {pendingUnIsolate} - - - } - > - - - -
-
- ); - } - - // Show 'pending [un]isolate' depending on what's pending return ( - - {pendingIsolate ? ( - - ) : ( - - )} - + ); - }, [dataTestSubj, getTestId, isIsolated, pendingIsolate, pendingUnIsolate]); + + // If nothing is pending and host is not currently isolated, then render nothing + // if (!isIsolated && !pendingIsolate && !pendingUnIsolate) { + // return null; + // } + // + // // If nothing is pending, but host is isolated, then show isolation badge + // if (!pendingIsolate && !pendingUnIsolate) { + // return ( + // + // + // + // ); + // } + // + // // If there are multiple types of pending isolation actions, then show count of actions with tooltip that displays breakdown + // if (pendingIsolate && pendingUnIsolate) { + // return ( + // + // + //
+ // + //
+ // + // + // + // + // {pendingIsolate} + // + // + // + // + // + // {pendingUnIsolate} + // + // + // } + // > + // + // + // + //
+ //
+ // ); + // } + // + // // Show 'pending [un]isolate' depending on what's pending + // return ( + // + // + // {pendingIsolate ? ( + // + // ) : ( + // + // )} + // + // + // ); + }, [dataTestSubj, isIsolated /* , getTestId , pendingIsolate, pendingUnIsolate*/]); } ); diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/unisolate_form.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/unisolate_form.tsx index 98006524844c4..ac650edca43e4 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/unisolate_form.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/unisolate_form.tsx @@ -11,10 +11,10 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, - EuiSpacer, + EuiForm, + EuiFormRow, EuiText, EuiTextArea, - EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { CANCEL, COMMENT, COMMENT_PLACEHOLDER, CONFIRM, UNISOLATE, ISOLATED } from './translations'; @@ -30,50 +30,49 @@ export const EndpointUnisolateForm = memo( ); return ( - <> - -

- {hostName}, - isolated: {ISOLATED}, - unisolate: {UNISOLATE}, - }} - />{' '} - {messageAppend} -

-
+ + + +

+ {hostName}, + isolated: {ISOLATED}, + unisolate: {UNISOLATE}, + }} + />{' '} + {messageAppend} +

+
+
- + + + - -

{COMMENT}

-
- - - - - - - - {CANCEL} - - - - - {CONFIRM} - - - - + + + + + {CANCEL} + + + + + {CONFIRM} + + + + +
); } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/context_menu_item_nav_by_rotuer.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/context_menu_item_nav_by_rotuer.tsx index ac1b83bdc493b..f4f9a7542415d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/context_menu_item_nav_by_rotuer.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/context_menu_item_nav_by_rotuer.tsx @@ -34,3 +34,5 @@ export const ContextMenuItemNavByRouter = memo( ); } ); + +ContextMenuItemNavByRouter.displayName = 'EuiContextMenuItemNavByRouter'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/endpoint_agent_status.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/endpoint_agent_status.test.tsx index 0b5ff7cc4da0f..be7fef156815b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/endpoint_agent_status.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/endpoint_agent_status.test.tsx @@ -57,7 +57,8 @@ describe('When using the EndpointAgentStatus component', () => { expect(renderResult.getByTestId('rowHostStatus').textContent).toEqual(expectedLabel); }); - describe('and host is isolated or pending isolation', () => { + // FIXME: un-skip test once Islation pending statuses are supported + describe.skip('and host is isolated or pending isolation', () => { beforeEach(async () => { // Ensure pending action api sets pending action for the test endpoint metadata const pendingActionsResponseProvider = httpMocks.responseProvider.pendingActions.getMockImplementation(); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/table_row_actions.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/table_row_actions.tsx index 94303c43cd4da..5a2ad6cf4c60b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/table_row_actions.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/components/table_row_actions.tsx @@ -62,5 +62,3 @@ export const TableRowActions = memo(({ endpointMetadata }) ); }); TableRowActions.displayName = 'EndpointTableRowActions'; - -ContextMenuItemNavByRouter.displayName = 'EuiContextMenuItemNavByRouter'; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx index 6a0e7c381664c..7f447670fd1e1 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx @@ -71,7 +71,8 @@ describe('EndpointOverview Component', () => { expect(findData.at(3).text()).toEqual('HealthyIsolated'); }); - test.each([ + // FIXME: un-skip once pending isolation status are supported again + test.skip.each([ ['isolate', 'Isolating'], ['unisolate', 'Releasing'], ])('it shows pending %s status', (action, expectedLabel) => {