[ML] Serverless compatibility fixes (#163724)

**ML Management page**
- Fixes general page loading issues.
- Ensures only enabled features are shown as tabs
- Ensures only jobs for enabled features can be exported and imported.
- Ensures only enabled features are listed in the saved object sync
output.
- On trained models tab:
  - Only lists DFA models if NLP is disabled.
  - Only lists non-DFA models if DFA is disabled.

**Anomaly Detection**
- Hides node information in anomaly detection jobs list.
- Hides the Exclude frozen data option in the Use full time range
selector in job wizards.

**Data frame analytics**
 - Hides all node and license level information.

**Trained models**
 - Only lists DFA models if NLP is disabled.
 - Only lists non-DFA models if DFA is disabled.
 - Hides all node and license level information.
 - Hides DFA nodes 

**Notifications and memory usage**
- Ensures only enabled features are mentioned. Including selectable
types in the search bar filters.

**Integrations with other plugins**
- Changes registration for integrations into other plugins so they only
happen if the relevant feature is enabled.
   - Client side: UI actions, cases, embeddables, alerts, maps.
   - Server side: Sample data sets, cases

**AIOPS**
- Hides the Exclude frozen data option in the Use full time range
selector on all pages

**Notes for non ML team reviewers**

**response-ops**
I've divided the
[persistable_state.ts](https://github.com/elastic/kibana/pull/163724#diff-e02dc0b6cb5b63965372b1f4a84d2287cba31a15ab525ab7983f02d09f23879f)
test into basic and trial version.
The ML cases attachments should only be registered if anomaly detection
is available in a trial or platinum license. This was a bug which I
noticed when making serverless changes.

 **Observability**
I've made a few minor changes to the nav menu, fixing names of ML
features and adding the missing Change point detection AIOPs page.

**Security solution**
I've made a few minor changes to the nav menu, fixing names of ML
features and adding some missing ML features.
I think the icons being used will need to be revisited before release as
we have [official ML
icons](https://elastic.github.io/eui/#/display/icons#apps) but not for
every page. So we should probably either have new icons created or all
agree on which standard non-ML icons should be used for the ones which
are missing.

**Search**
The NLP feature is currently disabled in main, I believe this was an
attempt to stop ML anomaly detection alert rules from being registered.
I've reenabled NLP and changed the way we're registering the alerts.
They will now only be registered if the anomaly detection feature is
enabled.


Fixes https://github.com/elastic/kibana/issues/163372
This commit is contained in:
James Gowdy 2023-09-13 20:07:55 +01:00 committed by GitHub
parent 1abe8c02c3
commit 09faf897c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
102 changed files with 1587 additions and 937 deletions

View file

@ -7,7 +7,7 @@
import Boom from '@hapi/boom';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { IScopedClusterClient } from '@kbn/core/server';
import type { IScopedClusterClient } from '@kbn/core/server';
import {
getAnalysisType,
INDEX_CREATED_BY,
@ -23,20 +23,21 @@ import { flatten } from 'lodash';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import { modelsProvider } from '../model_management';
import {
ExtendAnalyticsMapArgs,
GetAnalyticsMapArgs,
InitialElementsReturnType,
type ExtendAnalyticsMapArgs,
type GetAnalyticsMapArgs,
type InitialElementsReturnType,
type NextLinkReturnType,
type GetAnalyticsJobIdArg,
type GetAnalyticsModelIdArg,
isCompleteInitialReturnType,
isAnalyticsMapEdgeElement,
isAnalyticsMapNodeElement,
isIndexPatternLinkReturnType,
isJobDataLinkReturnType,
isTransformLinkReturnType,
NextLinkReturnType,
GetAnalyticsJobIdArg,
GetAnalyticsModelIdArg,
} from './types';
import type { MlClient } from '../../lib/ml_client';
import type { MlFeatures } from '../../types';
import { DEFAULT_TRAINED_MODELS_PAGE_SIZE } from '../../routes/trained_models';
export class AnalyticsManager {
@ -44,12 +45,20 @@ export class AnalyticsManager {
private _jobs: estypes.MlDataframeAnalyticsSummary[] = [];
private _transforms?: TransformGetTransformTransformSummary[];
constructor(private _mlClient: MlClient, private _client: IScopedClusterClient) {}
constructor(
private readonly _mlClient: MlClient,
private readonly _client: IScopedClusterClient,
private readonly _enabledFeatures: MlFeatures
) {}
private async initData() {
const [models, jobs] = await Promise.all([
this._mlClient.getTrainedModels({ size: DEFAULT_TRAINED_MODELS_PAGE_SIZE }),
this._mlClient.getDataFrameAnalytics({ size: 1000 }),
this._enabledFeatures.nlp || this._enabledFeatures.dfa
? this._mlClient.getTrainedModels({ size: DEFAULT_TRAINED_MODELS_PAGE_SIZE })
: { trained_model_configs: [] },
this._enabledFeatures.dfa
? this._mlClient.getDataFrameAnalytics({ size: 1000 })
: { data_frame_analytics: [] },
]);
this._trainedModels = models.trained_model_configs;
this._jobs = jobs.data_frame_analytics;

View file

@ -133,10 +133,16 @@ describe('Model service', () => {
}),
} as unknown as jest.Mocked<MlClient>;
const mlFeatures = {
ad: true,
dfa: true,
nlp: true,
};
let service: MemoryUsageService;
beforeEach(() => {
service = new MemoryUsageService(mlClient);
service = new MemoryUsageService(mlClient, mlFeatures);
});
afterEach(() => {});

View file

@ -22,6 +22,7 @@ import type {
NodeDeploymentStatsResponse,
NodesOverviewResponse,
} from '../../../common/types/trained_models';
import type { MlFeatures } from '../../types';
// @ts-expect-error numeral missing value
const AD_EXTRA_MEMORY = numeral('10MB').value();
@ -33,7 +34,7 @@ const NODE_FIELDS = ['attributes', 'name', 'roles'] as const;
export type RequiredNodeFields = Pick<estypes.NodesInfoNodeInfo, typeof NODE_FIELDS[number]>;
export class MemoryUsageService {
constructor(private readonly mlClient: MlClient) {}
constructor(private readonly mlClient: MlClient, private readonly mlFeatures: MlFeatures) {}
public async getMemorySizes(itemType?: MlSavedObjectType, node?: string, showClosedJobs = false) {
let memories: MemoryUsageInfo[] = [];
@ -60,11 +61,19 @@ export class MemoryUsageService {
}
private async getADJobsSizes() {
if (this.mlFeatures.ad === false) {
return [];
}
const jobs = await this.mlClient.getJobStats();
return jobs.jobs.map(this.getADJobMemorySize);
}
private async getTrainedModelsSizes() {
if (this.mlFeatures.nlp === false) {
return [];
}
const [models, stats] = await Promise.all([
this.mlClient.getTrainedModels(),
this.mlClient.getTrainedModelsStats(),
@ -83,6 +92,10 @@ export class MemoryUsageService {
}
private async getDFAJobsSizes() {
if (this.mlFeatures.dfa === false) {
return [];
}
const [jobs, jobsStats] = await Promise.all([
this.mlClient.getDataFrameAnalytics(),
this.mlClient.getDataFrameAnalyticsStats(),