Skip to content

Commit

Permalink
[Logs UI] Add missing ML capabilities checks (#72606)
Browse files Browse the repository at this point in the history
This adds several missing Machine Learning capabilities checks to the UI to make sure the user doesn't run into downstream errors resulting from the lack of permissions. It also updates the messages of the permission prompt screens to refer to the new Kibana Machine Learning permissions instead of the old built-in roles.
  • Loading branch information
weltenwort authored Jul 22, 2020
1 parent fe5b4b8 commit ba55ca9
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@

export * from './log_analysis_job_problem_indicator';
export * from './notices_section';
export * from './recreate_job_button';
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import React from 'react';
import { RecreateJobCallout } from './recreate_job_callout';

export const JobConfigurationOutdatedCallout: React.FC<{
hasSetupCapabilities: boolean;
moduleName: string;
onRecreateMlJob: () => void;
}> = ({ moduleName, onRecreateMlJob }) => (
}> = ({ hasSetupCapabilities, moduleName, onRecreateMlJob }) => (
<RecreateJobCallout
hasSetupCapabilities={hasSetupCapabilities}
title={i18n.translate('xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutTitle', {
defaultMessage: 'The {moduleName} ML job configuration is outdated',
values: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import React from 'react';
import { RecreateJobCallout } from './recreate_job_callout';

export const JobDefinitionOutdatedCallout: React.FC<{
hasSetupCapabilities: boolean;
moduleName: string;
onRecreateMlJob: () => void;
}> = ({ moduleName, onRecreateMlJob }) => (
}> = ({ hasSetupCapabilities, moduleName, onRecreateMlJob }) => (
<RecreateJobCallout
hasSetupCapabilities={hasSetupCapabilities}
title={i18n.translate('xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutTitle', {
defaultMessage: 'The {moduleName} ML job definition is outdated',
values: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FirstUseCallout } from '../log_analysis_results';
export const LogAnalysisJobProblemIndicator: React.FC<{
hasOutdatedJobConfigurations: boolean;
hasOutdatedJobDefinitions: boolean;
hasSetupCapabilities: boolean;
hasStoppedJobs: boolean;
isFirstUse: boolean;
moduleName: string;
Expand All @@ -22,6 +23,7 @@ export const LogAnalysisJobProblemIndicator: React.FC<{
}> = ({
hasOutdatedJobConfigurations,
hasOutdatedJobDefinitions,
hasSetupCapabilities,
hasStoppedJobs,
isFirstUse,
moduleName,
Expand All @@ -32,12 +34,14 @@ export const LogAnalysisJobProblemIndicator: React.FC<{
<>
{hasOutdatedJobDefinitions ? (
<JobDefinitionOutdatedCallout
hasSetupCapabilities={hasSetupCapabilities}
moduleName={moduleName}
onRecreateMlJob={onRecreateMlJobForUpdate}
/>
) : null}
{hasOutdatedJobConfigurations ? (
<JobConfigurationOutdatedCallout
hasSetupCapabilities={hasSetupCapabilities}
moduleName={moduleName}
onRecreateMlJob={onRecreateMlJobForReconfiguration}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CategoryQualityWarnings } from './quality_warning_notices';
export const CategoryJobNoticesSection: React.FC<{
hasOutdatedJobConfigurations: boolean;
hasOutdatedJobDefinitions: boolean;
hasSetupCapabilities: boolean;
hasStoppedJobs: boolean;
isFirstUse: boolean;
moduleName: string;
Expand All @@ -21,6 +22,7 @@ export const CategoryJobNoticesSection: React.FC<{
}> = ({
hasOutdatedJobConfigurations,
hasOutdatedJobDefinitions,
hasSetupCapabilities,
hasStoppedJobs,
isFirstUse,
moduleName,
Expand All @@ -32,6 +34,7 @@ export const CategoryJobNoticesSection: React.FC<{
<LogAnalysisJobProblemIndicator
hasOutdatedJobConfigurations={hasOutdatedJobConfigurations}
hasOutdatedJobDefinitions={hasOutdatedJobDefinitions}
hasSetupCapabilities={hasSetupCapabilities}
hasStoppedJobs={hasStoppedJobs}
isFirstUse={isFirstUse}
moduleName={moduleName}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { EuiCallOut } from '@elastic/eui';

import { RecreateJobButton } from './recreate_job_button';
import React from 'react';
import { RecreateJobButton } from '../log_analysis_setup/create_job_button';

export const RecreateJobCallout: React.FC<{
hasSetupCapabilities?: boolean;
onRecreateMlJob: () => void;
title?: React.ReactNode;
}> = ({ children, onRecreateMlJob, title }) => (
}> = ({ children, hasSetupCapabilities, onRecreateMlJob, title }) => (
<EuiCallOut color="warning" iconType="alert" title={title}>
<p>{children}</p>
<RecreateJobButton color="warning" onClick={onRecreateMlJob} />
<RecreateJobButton
color="warning"
hasSetupCapabilities={hasSetupCapabilities}
onClick={onRecreateMlJob}
/>
</EuiCallOut>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 { EuiButton, PropsOf } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { MissingSetupPrivilegesToolTip } from './missing_setup_privileges_tooltip';

export const CreateJobButton: React.FunctionComponent<
{
hasSetupCapabilities?: boolean;
} & PropsOf<typeof EuiButton>
> = ({ hasSetupCapabilities = true, children, ...buttonProps }) => {
const button = (
<EuiButton isDisabled={!hasSetupCapabilities} {...buttonProps}>
{children ?? (
<FormattedMessage
id="xpack.infra.logs.analysis.createJobButtonLabel"
defaultMessage="Create ML jobs"
/>
)}
</EuiButton>
);

return hasSetupCapabilities ? (
button
) : (
<MissingSetupPrivilegesToolTip position="bottom" delay="regular">
{button}
</MissingSetupPrivilegesToolTip>
);
};

export const RecreateJobButton: React.FunctionComponent<PropsOf<typeof CreateJobButton>> = ({
children,
...otherProps
}) => (
<CreateJobButton {...otherProps}>
{children ?? (
<FormattedMessage
id="xpack.infra.logs.analysis.recreateJobButtonLabel"
defaultMessage="Recreate ML job"
/>
)}
</CreateJobButton>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 { i18n } from '@kbn/i18n';

export const missingMlPrivilegesTitle = i18n.translate(
'xpack.infra.logs.analysis.missingMlPrivilegesTitle',
{
defaultMessage: 'Additional Machine Learning privileges required',
}
);

export const missingMlResultsPrivilegesDescription = i18n.translate(
'xpack.infra.logs.analysis.missingMlResultsPrivilegesDescription',
{
defaultMessage:
'This feature makes use of Machine Learning jobs, which require at least the read permission for the Machine Learning app in order to access their status and results.',
}
);

export const missingMlSetupPrivilegesDescription = i18n.translate(
'xpack.infra.logs.analysis.missingMlSetupPrivilegesDescription',
{
defaultMessage:
'This feature makes use of Machine Learning jobs, which require all permissions for the Machine Learning app in order to be set up.',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,19 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiEmptyPrompt, EuiCode } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiEmptyPrompt } from '@elastic/eui';
import React from 'react';

import { euiStyled } from '../../../../../observability/public';
import {
missingMlPrivilegesTitle,
missingMlResultsPrivilegesDescription,
} from './missing_privileges_messages';
import { UserManagementLink } from './user_management_link';

export const MissingResultsPrivilegesPrompt: React.FunctionComponent = () => (
<EmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.infra.logs.analysis.missingMlResultsPrivilegesTitle"
defaultMessage="Additional Machine Learning privileges required"
/>
</h2>
}
body={
<p>
<FormattedMessage
id="xpack.infra.logs.analysis.missingMlResultsPrivilegesBody"
defaultMessage="This feature makes use of Machine Learning jobs, which require at least the {machineLearningUserRole} role in order to access their status and results."
values={{
machineLearningUserRole: <EuiCode>machine_learning_user</EuiCode>,
}}
/>
</p>
}
title={<h2>{missingMlPrivilegesTitle}</h2>}
body={<p>{missingMlResultsPrivilegesDescription}</p>}
actions={<UserManagementLink />}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,19 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiEmptyPrompt, EuiCode } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiEmptyPrompt } from '@elastic/eui';
import React from 'react';

import { euiStyled } from '../../../../../observability/public';
import {
missingMlPrivilegesTitle,
missingMlSetupPrivilegesDescription,
} from './missing_privileges_messages';
import { UserManagementLink } from './user_management_link';

export const MissingSetupPrivilegesPrompt: React.FunctionComponent = () => (
<EmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.infra.logs.analysis.missingMlSetupPrivilegesTitle"
defaultMessage="Additional Machine Learning privileges required"
/>
</h2>
}
body={
<p>
<FormattedMessage
id="xpack.infra.logs.analysis.missingMlSetupPrivilegesBody"
defaultMessage="This feature makes use of Machine Learning jobs, which require the {machineLearningAdminRole} role in order to be set up."
values={{
machineLearningAdminRole: <EuiCode>machine_learning_admin</EuiCode>,
}}
/>
</p>
}
title={<h2>{missingMlPrivilegesTitle}</h2>}
body={<p>{missingMlSetupPrivilegesDescription}</p>}
actions={<UserManagementLink />}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 { EuiToolTip, PropsOf } from '@elastic/eui';
import React from 'react';
import {
missingMlPrivilegesTitle,
missingMlSetupPrivilegesDescription,
} from './missing_privileges_messages';

export const MissingSetupPrivilegesToolTip: React.FC<Omit<
PropsOf<EuiToolTip>,
'content' | 'title'
>> = (props) => (
<EuiToolTip
{...props}
content={missingMlSetupPrivilegesDescription}
title={missingMlPrivilegesTitle}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { useCallback } from 'react';
import { useLogAnalysisCapabilitiesContext } from '../../../../containers/logs/log_analysis';
import {
logEntryCategoriesModule,
useLogEntryCategoriesModuleContext,
Expand All @@ -20,6 +21,7 @@ import type { ModuleId } from './setup_flyout_state';
export const LogAnalysisModuleList: React.FC<{
onViewModuleSetup: (module: ModuleId) => void;
}> = ({ onViewModuleSetup }) => {
const { hasLogAnalysisSetupCapabilities } = useLogAnalysisCapabilitiesContext();
const { setupStatus: logEntryRateSetupStatus } = useLogEntryRateModuleContext();
const { setupStatus: logEntryCategoriesSetupStatus } = useLogEntryCategoriesModuleContext();

Expand All @@ -35,6 +37,7 @@ export const LogAnalysisModuleList: React.FC<{
<EuiFlexGroup>
<EuiFlexItem>
<LogAnalysisModuleListCard
hasSetupCapabilities={hasLogAnalysisSetupCapabilities}
moduleDescription={logEntryRateModule.moduleDescription}
moduleName={logEntryRateModule.moduleName}
moduleStatus={logEntryRateSetupStatus}
Expand All @@ -43,6 +46,7 @@ export const LogAnalysisModuleList: React.FC<{
</EuiFlexItem>
<EuiFlexItem>
<LogAnalysisModuleListCard
hasSetupCapabilities={hasLogAnalysisSetupCapabilities}
moduleDescription={logEntryCategoriesModule.moduleDescription}
moduleName={logEntryCategoriesModule.moduleName}
moduleStatus={logEntryCategoriesSetupStatus}
Expand Down
Loading

0 comments on commit ba55ca9

Please sign in to comment.