[Security Solution] Initiate endpoint package upgrade from security app (#77498)

* Working on package update functionality

* Correctly installing package

* Moving upgrade component and working upgrade

* Doing permissions check

* Cleaning up imports

* Adding bulk upgrade api

* Addressing comments

* Removing todo

* Changing body field

* Adding helper for getting the bulk install route

* Adding request spec

* Using bulk install endpoint from ingest

* Moving component to a hook

* Addressing feedback
This commit is contained in:
Jonathan Buttner 2020-09-28 14:18:40 -04:00 committed by GitHub
parent 3c85d3d2af
commit 768ae211b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 0 deletions

View file

@ -21,6 +21,7 @@ import { useInitSourcerer, useSourcererScope } from '../../common/containers/sou
import { useKibana } from '../../common/lib/kibana';
import { DETECTIONS_SUB_PLUGIN_ID } from '../../../common/constants';
import { SourcererScopeName } from '../../common/store/sourcerer/model';
import { useUpgradeEndpointPackage } from '../../common/hooks/endpoint/upgrade';
import { useThrottledResizeObserver } from '../../common/components/utils';
const Main = styled.main.attrs<{ paddingTop: number }>(({ paddingTop }) => ({
@ -58,6 +59,12 @@ const HomePageComponent: React.FC<HomePageProps> = ({ children }) => {
const [showTimeline] = useShowTimeline();
const { browserFields, indexPattern, indicesExist } = useSourcererScope();
// side effect: this will attempt to upgrade the endpoint package if it is not up to date
// this will run when a user navigates to the Security Solution app and when they navigate between
// tabs in the app. This is useful for keeping the endpoint package as up to date as possible until
// a background task solution can be built on the server side. Once a background task solution is available we
// can remove this.
useUpgradeEndpointPackage();
return (
<SecuritySolutionAppWrapper>

View file

@ -0,0 +1,95 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { useEffect } from 'react';
import { HttpFetchOptions, HttpStart } from 'src/core/public';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import {
epmRouteService,
appRoutesService,
CheckPermissionsResponse,
BulkInstallPackagesResponse,
} from '../../../../../ingest_manager/common';
import { StartServices } from '../../../types';
import { useIngestEnabledCheck } from './ingest_enabled';
/**
* Requests that the endpoint package be upgraded to the latest version
*
* @param http an http client for sending the request
* @param options an object containing options for the request
*/
const sendUpgradeEndpointPackage = async (
http: HttpStart,
options: HttpFetchOptions = {}
): Promise<BulkInstallPackagesResponse> => {
return http.post<BulkInstallPackagesResponse>(epmRouteService.getBulkInstallPath(), {
...options,
body: JSON.stringify({
packages: ['endpoint'],
}),
});
};
/**
* Checks with the ingest manager if the current user making these requests has the right permissions
* to install the endpoint package.
*
* @param http an http client for sending the request
* @param options an object containing options for the request
*/
const sendCheckPermissions = async (
http: HttpStart,
options: HttpFetchOptions = {}
): Promise<CheckPermissionsResponse> => {
return http.get<CheckPermissionsResponse>(appRoutesService.getCheckPermissionsPath(), {
...options,
});
};
export const useUpgradeEndpointPackage = () => {
const context = useKibana<StartServices>();
const { allEnabled: ingestEnabled } = useIngestEnabledCheck();
useEffect(() => {
const abortController = new AbortController();
// cancel any ongoing requests
const abortRequests = () => {
abortController.abort();
};
if (ingestEnabled) {
const signal = abortController.signal;
(async () => {
try {
// make sure we're a privileged user before trying to install the package
const { success: hasPermissions } = await sendCheckPermissions(context.services.http, {
signal,
});
// if we're not a privileged user then return and don't try to check the status of the endpoint package
if (!hasPermissions) {
return abortRequests;
}
// ignore the response for now since we aren't notifying the user
await sendUpgradeEndpointPackage(context.services.http, { signal });
} catch (error) {
// Ignore Errors, since this should not hinder the user's ability to use the UI
// ignore the error that occurs from aborting a request
if (!abortController.signal.aborted) {
// eslint-disable-next-line no-console
console.error(error);
}
}
return abortRequests;
})();
}
}, [ingestEnabled, context.services.http]);
};