mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.10`: - [chore(slo): general enhancement (#164723)](https://github.com/elastic/kibana/pull/164723) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kevin Delemme","email":"kevin.delemme@elastic.co"},"sourceCommit":{"committedDate":"2023-08-28T18:50:38Z","message":"chore(slo): general enhancement (#164723)","sha":"733869e9e5774c4813126c80e8c00532ba8659ed","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["backport","release_note:skip","Team: Actionable Observability","v8.10.0","v8.11.0"],"number":164723,"url":"https://github.com/elastic/kibana/pull/164723","mergeCommit":{"message":"chore(slo): general enhancement (#164723)","sha":"733869e9e5774c4813126c80e8c00532ba8659ed"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164723","number":164723,"mergeCommit":{"message":"chore(slo): general enhancement (#164723)","sha":"733869e9e5774c4813126c80e8c00532ba8659ed"}}]}] BACKPORT--> Co-authored-by: Kevin Delemme <kevin.delemme@elastic.co>
This commit is contained in:
parent
ee5c73d84d
commit
c47cdbf1ed
13 changed files with 79 additions and 223 deletions
|
@ -188,10 +188,6 @@ const findSloDefinitionsParamsSchema = t.type({
|
|||
*/
|
||||
const findSloDefinitionsResponseSchema = t.array(sloResponseSchema);
|
||||
|
||||
const getSLODiagnosisParamsSchema = t.type({
|
||||
path: t.type({ id: t.string }),
|
||||
});
|
||||
|
||||
const getSLOBurnRatesResponseSchema = t.type({
|
||||
burnRates: t.array(
|
||||
t.type({
|
||||
|
@ -277,7 +273,6 @@ export {
|
|||
findSLOResponseSchema,
|
||||
getPreviewDataParamsSchema,
|
||||
getPreviewDataResponseSchema,
|
||||
getSLODiagnosisParamsSchema,
|
||||
getSLOParamsSchema,
|
||||
getSLOResponseSchema,
|
||||
fetchHistoricalSummaryParamsSchema,
|
||||
|
|
|
@ -135,6 +135,7 @@ export function useFetchActiveAlerts({ sloIdsAndInstanceIds = [] }: Params): Use
|
|||
}
|
||||
},
|
||||
refetchOnWindowFocus: false,
|
||||
enabled: Boolean(sloIdsAndInstanceIds.length),
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -5,32 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
QueryObserverResult,
|
||||
RefetchOptions,
|
||||
RefetchQueryFilters,
|
||||
useQuery,
|
||||
} from '@tanstack/react-query';
|
||||
import type { SecurityHasPrivilegesResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { PublicLicenseJSON } from '@kbn/licensing-plugin/public';
|
||||
import type {
|
||||
SecurityGetUserPrivilegesResponse,
|
||||
TransformGetTransformStatsResponse,
|
||||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useKibana } from '../../utils/kibana_react';
|
||||
import { convertErrorForUseInToast } from './helpers/convert_error_for_use_in_toast';
|
||||
import { sloKeys } from './query_key_factory';
|
||||
|
||||
interface SloGlobalDiagnosisResponse {
|
||||
licenseAndFeatures: PublicLicenseJSON;
|
||||
userPrivileges: SecurityGetUserPrivilegesResponse;
|
||||
sloResources: {
|
||||
[x: string]: 'OK' | 'NOT_OK';
|
||||
};
|
||||
sloSummaryResources: {
|
||||
[x: string]: 'OK' | 'NOT_OK';
|
||||
};
|
||||
sloSummaryTransformsStats: TransformGetTransformStatsResponse;
|
||||
userPrivileges: { write: SecurityHasPrivilegesResponse; read: SecurityHasPrivilegesResponse };
|
||||
}
|
||||
|
||||
export interface UseFetchSloGlobalDiagnoseResponse {
|
||||
|
@ -39,10 +24,7 @@ export interface UseFetchSloGlobalDiagnoseResponse {
|
|||
isRefetching: boolean;
|
||||
isSuccess: boolean;
|
||||
isError: boolean;
|
||||
globalSloDiagnosis: SloGlobalDiagnosisResponse | undefined;
|
||||
refetch: <TPageData>(
|
||||
options?: (RefetchOptions & RefetchQueryFilters<TPageData>) | undefined
|
||||
) => Promise<QueryObserverResult<SloGlobalDiagnosisResponse | undefined, unknown>>;
|
||||
data: SloGlobalDiagnosisResponse | undefined;
|
||||
}
|
||||
|
||||
export function useFetchSloGlobalDiagnosis(): UseFetchSloGlobalDiagnoseResponse {
|
||||
|
@ -51,44 +33,41 @@ export function useFetchSloGlobalDiagnosis(): UseFetchSloGlobalDiagnoseResponse
|
|||
notifications: { toasts },
|
||||
} = useKibana().services;
|
||||
|
||||
const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data, refetch } = useQuery(
|
||||
{
|
||||
queryKey: sloKeys.globalDiagnosis(),
|
||||
queryFn: async ({ signal }) => {
|
||||
try {
|
||||
const response = await http.get<SloGlobalDiagnosisResponse>(
|
||||
'/internal/observability/slos/_diagnosis',
|
||||
{
|
||||
query: {},
|
||||
signal,
|
||||
}
|
||||
);
|
||||
const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({
|
||||
queryKey: sloKeys.globalDiagnosis(),
|
||||
queryFn: async ({ signal }) => {
|
||||
try {
|
||||
const response = await http.get<SloGlobalDiagnosisResponse>(
|
||||
'/internal/observability/slos/_diagnosis',
|
||||
{
|
||||
query: {},
|
||||
signal,
|
||||
}
|
||||
);
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw convertErrorForUseInToast(error);
|
||||
}
|
||||
},
|
||||
keepPreviousData: true,
|
||||
refetchOnWindowFocus: false,
|
||||
retry: false,
|
||||
onError: (error: Error) => {
|
||||
toasts.addError(error, {
|
||||
title: i18n.translate('xpack.observability.slo.globalDiagnosis.errorNotification', {
|
||||
defaultMessage: 'You do not have the right permissions to use this feature.',
|
||||
}),
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw convertErrorForUseInToast(error);
|
||||
}
|
||||
},
|
||||
keepPreviousData: true,
|
||||
refetchOnWindowFocus: false,
|
||||
retry: false,
|
||||
onError: (error: Error) => {
|
||||
toasts.addError(error, {
|
||||
title: i18n.translate('xpack.observability.slo.globalDiagnosis.errorNotification', {
|
||||
defaultMessage: 'You do not have the right permissions to use this feature.',
|
||||
}),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
globalSloDiagnosis: data,
|
||||
data,
|
||||
isLoading,
|
||||
isInitialLoading,
|
||||
isRefetching,
|
||||
isSuccess,
|
||||
isError,
|
||||
refetch,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export function useFetchIndexPatternFields(
|
|||
return [];
|
||||
}
|
||||
try {
|
||||
return await dataViews.getFieldsForWildcard({ pattern: indexPattern });
|
||||
return await dataViews.getFieldsForWildcard({ pattern: indexPattern, allowNoIndex: true });
|
||||
} catch (error) {
|
||||
throw new Error(`Something went wrong. Error: ${error}`);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,7 @@ export function useFetchRulesForSlo({ sloIds = [] }: Params): UseFetchRulesForSl
|
|||
queryFn: async () => {
|
||||
try {
|
||||
const body = JSON.stringify({
|
||||
filter:
|
||||
sloIds?.map((sloId) => `alert.attributes.params.sloId:${sloId}`).join(' or ') ?? '',
|
||||
filter: sloIds.map((sloId) => `alert.attributes.params.sloId:${sloId}`).join(' or '),
|
||||
fields: ['params.sloId', 'name'],
|
||||
per_page: 1000,
|
||||
});
|
||||
|
@ -62,7 +61,7 @@ export function useFetchRulesForSlo({ sloIds = [] }: Params): UseFetchRulesForSl
|
|||
body,
|
||||
});
|
||||
|
||||
const init = sloIds?.reduce((acc, sloId) => ({ ...acc, [sloId]: [] }), {});
|
||||
const init = sloIds.reduce((acc, sloId) => ({ ...acc, [sloId]: [] }), {});
|
||||
|
||||
return response.data.reduce(
|
||||
(acc, rule) => ({
|
||||
|
@ -75,7 +74,7 @@ export function useFetchRulesForSlo({ sloIds = [] }: Params): UseFetchRulesForSl
|
|||
// ignore error for retrieving slos
|
||||
}
|
||||
},
|
||||
enabled: Boolean(sloIds?.length),
|
||||
enabled: Boolean(sloIds.length),
|
||||
refetchOnWindowFocus: false,
|
||||
keepPreviousData: true,
|
||||
}
|
||||
|
|
|
@ -59,7 +59,9 @@ describe('SLOs Welcome Page', () => {
|
|||
useFetchSloListMock.mockReturnValue({ isLoading: false, sloList: emptySloList });
|
||||
useLicenseMock.mockReturnValue({ hasAtLeast: () => false });
|
||||
useGlobalDiagnosisMock.mockReturnValue({
|
||||
isError: false,
|
||||
data: {
|
||||
userPrivileges: { write: { has_all_requested: true }, read: { has_all_requested: true } },
|
||||
},
|
||||
});
|
||||
|
||||
render(<SlosWelcomePage />);
|
||||
|
@ -104,7 +106,12 @@ describe('SLOs Welcome Page', () => {
|
|||
hasReadCapabilities: true,
|
||||
});
|
||||
useGlobalDiagnosisMock.mockReturnValue({
|
||||
isError: true,
|
||||
data: {
|
||||
userPrivileges: {
|
||||
write: { has_all_requested: false },
|
||||
read: { has_all_requested: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<SlosWelcomePage />);
|
||||
|
@ -116,7 +123,12 @@ describe('SLOs Welcome Page', () => {
|
|||
|
||||
it('should display the welcome message with a Create new SLO button which should navigate to the SLO Creation page', async () => {
|
||||
useGlobalDiagnosisMock.mockReturnValue({
|
||||
isError: false,
|
||||
data: {
|
||||
userPrivileges: {
|
||||
write: { has_all_requested: true },
|
||||
read: { has_all_requested: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<SlosWelcomePage />);
|
||||
|
@ -136,7 +148,12 @@ describe('SLOs Welcome Page', () => {
|
|||
beforeEach(() => {
|
||||
useFetchSloListMock.mockReturnValue({ isLoading: false, sloList });
|
||||
useGlobalDiagnosisMock.mockReturnValue({
|
||||
isError: false,
|
||||
data: {
|
||||
userPrivileges: {
|
||||
write: { has_all_requested: true },
|
||||
read: { has_all_requested: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export function SlosWelcomePage() {
|
|||
http: { basePath },
|
||||
} = useKibana().services;
|
||||
const { hasWriteCapabilities } = useCapabilities();
|
||||
const { isError: hasErrorInGlobalDiagnosis } = useFetchSloGlobalDiagnosis();
|
||||
const { data: globalDiagnosis } = useFetchSloGlobalDiagnosis();
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
|
||||
const { hasAtLeast } = useLicense();
|
||||
|
@ -43,12 +43,15 @@ export function SlosWelcomePage() {
|
|||
const { isLoading, sloList } = useFetchSloList();
|
||||
const { total } = sloList || { total: 0 };
|
||||
|
||||
const hasRequiredWritePrivileges = !!globalDiagnosis?.userPrivileges.write.has_all_requested;
|
||||
const hasRequiredReadPrivileges = !!globalDiagnosis?.userPrivileges.read.has_all_requested;
|
||||
|
||||
const handleClickCreateSlo = () => {
|
||||
navigateToUrl(basePath.prepend(paths.observability.sloCreate));
|
||||
};
|
||||
|
||||
const hasSlosAndHasPermissions =
|
||||
total > 0 && hasAtLeast('platinum') === true && !hasErrorInGlobalDiagnosis;
|
||||
total > 0 && hasAtLeast('platinum') === true && hasRequiredReadPrivileges;
|
||||
|
||||
useEffect(() => {
|
||||
if (hasSlosAndHasPermissions) {
|
||||
|
@ -115,7 +118,7 @@ export function SlosWelcomePage() {
|
|||
fill
|
||||
color="primary"
|
||||
onClick={handleClickCreateSlo}
|
||||
disabled={!hasWriteCapabilities || hasErrorInGlobalDiagnosis}
|
||||
disabled={!hasWriteCapabilities || !hasRequiredWritePrivileges}
|
||||
>
|
||||
{i18n.translate('xpack.observability.slo.sloList.welcomePrompt.buttonLabel', {
|
||||
defaultMessage: 'Create SLO',
|
||||
|
|
|
@ -9,7 +9,7 @@ import { lazy } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { ALERT_REASON } from '@kbn/rule-data-utils';
|
||||
|
||||
import { SLO_ID_FIELD } from '../../common/field_names/slo';
|
||||
import { SLO_ID_FIELD, SLO_INSTANCE_ID_FIELD } from '../../common/field_names/slo';
|
||||
import { ConfigSchema } from '../plugin';
|
||||
import { ObservabilityRuleTypeRegistry } from './create_observability_rule_type_registry';
|
||||
import {
|
||||
|
@ -86,7 +86,9 @@ export const registerObservabilityRuleTypes = (
|
|||
format: ({ fields }) => {
|
||||
return {
|
||||
reason: fields[ALERT_REASON] ?? '-',
|
||||
link: `/app/observability/slos/${fields[SLO_ID_FIELD]}`,
|
||||
link: `/app/observability/slos/${fields[SLO_ID_FIELD]}?instanceId=${
|
||||
fields[SLO_INSTANCE_ID_FIELD] ?? '*'
|
||||
}`,
|
||||
};
|
||||
},
|
||||
iconClass: 'bell',
|
||||
|
|
|
@ -11,7 +11,7 @@ export const getSLOSummarySettingsTemplate = (name: string) => ({
|
|||
name,
|
||||
template: {
|
||||
settings: {
|
||||
auto_expand_replicas: '0-all',
|
||||
auto_expand_replicas: '0-1',
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
findSLOParamsSchema,
|
||||
getPreviewDataParamsSchema,
|
||||
getSLOBurnRatesParamsSchema,
|
||||
getSLODiagnosisParamsSchema,
|
||||
getSLOInstancesParamsSchema,
|
||||
getSLOParamsSchema,
|
||||
manageSLOParamsSchema,
|
||||
|
@ -35,7 +34,7 @@ import {
|
|||
import { FetchHistoricalSummary } from '../../services/slo/fetch_historical_summary';
|
||||
import { FindSLODefinitions } from '../../services/slo/find_slo_definitions';
|
||||
import { getBurnRates } from '../../services/slo/get_burn_rates';
|
||||
import { getGlobalDiagnosis, getSloDiagnosis } from '../../services/slo/get_diagnosis';
|
||||
import { getGlobalDiagnosis } from '../../services/slo/get_diagnosis';
|
||||
import { GetPreviewData } from '../../services/slo/get_preview_data';
|
||||
import { GetSLOInstances } from '../../services/slo/get_slo_instances';
|
||||
import { DefaultHistoricalSummaryClient } from '../../services/slo/historical_summary_client';
|
||||
|
@ -310,21 +309,6 @@ const getDiagnosisRoute = createObservabilityServerRoute({
|
|||
},
|
||||
});
|
||||
|
||||
const getSloDiagnosisRoute = createObservabilityServerRoute({
|
||||
endpoint: 'GET /internal/observability/slos/{id}/_diagnosis',
|
||||
options: {
|
||||
tags: [],
|
||||
},
|
||||
params: getSLODiagnosisParamsSchema,
|
||||
handler: async ({ context, params }) => {
|
||||
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
|
||||
const soClient = (await context.core).savedObjects.client;
|
||||
const repository = new KibanaSavedObjectsSLORepository(soClient);
|
||||
|
||||
return getSloDiagnosis(params.path.id, { esClient, repository });
|
||||
},
|
||||
});
|
||||
|
||||
const getSloBurnRates = createObservabilityServerRoute({
|
||||
endpoint: 'POST /internal/observability/slos/{id}/_burn_rates',
|
||||
options: {
|
||||
|
@ -375,7 +359,6 @@ export const sloRouteRepository = {
|
|||
...getSLORoute,
|
||||
...updateSLORoute,
|
||||
...getDiagnosisRoute,
|
||||
...getSloDiagnosisRoute,
|
||||
...getSloBurnRates,
|
||||
...getPreviewData,
|
||||
...getSLOInstancesRoute,
|
||||
|
|
|
@ -57,7 +57,7 @@ export const slo: SavedObjectsType = {
|
|||
},
|
||||
management: {
|
||||
displayName: 'SLO',
|
||||
importableAndExportable: true,
|
||||
importableAndExportable: false,
|
||||
getTitle(sloSavedObject: SavedObject<StoredSLO>) {
|
||||
return `SLO: [${sloSavedObject.attributes.name}]`;
|
||||
},
|
||||
|
|
|
@ -5,147 +5,24 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { errors } from '@elastic/elasticsearch';
|
||||
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server';
|
||||
import {
|
||||
getSLOTransformId,
|
||||
SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME,
|
||||
SLO_COMPONENT_TEMPLATE_SETTINGS_NAME,
|
||||
SLO_INDEX_TEMPLATE_NAME,
|
||||
SLO_INGEST_PIPELINE_NAME,
|
||||
SLO_SUMMARY_COMPONENT_TEMPLATE_MAPPINGS_NAME,
|
||||
SLO_SUMMARY_COMPONENT_TEMPLATE_SETTINGS_NAME,
|
||||
SLO_SUMMARY_INDEX_TEMPLATE_NAME,
|
||||
SLO_SUMMARY_TRANSFORM_NAME_PREFIX,
|
||||
} from '../../assets/constants';
|
||||
import { SLO } from '../../domain/models';
|
||||
import { SLORepository } from './slo_repository';
|
||||
|
||||
const OK = 'OK';
|
||||
const NOT_OK = 'NOT_OK';
|
||||
|
||||
export async function getGlobalDiagnosis(
|
||||
esClient: ElasticsearchClient,
|
||||
licensing: LicensingApiRequestHandlerContext
|
||||
) {
|
||||
const licenseInfo = licensing.license.toJSON();
|
||||
const userPrivileges = await esClient.security.getUserPrivileges();
|
||||
const sloResources = await getSloResourcesDiagnosis(esClient);
|
||||
const sloSummaryResources = await getSloSummaryResourcesDiagnosis(esClient);
|
||||
|
||||
const sloSummaryTransformsStats = await esClient.transform.getTransformStats({
|
||||
transform_id: `${SLO_SUMMARY_TRANSFORM_NAME_PREFIX}*`,
|
||||
allow_no_match: true,
|
||||
const userWritePrivileges = await esClient.security.hasPrivileges({
|
||||
cluster: ['manage_transform'],
|
||||
index: [{ names: '.slo-*', privileges: ['all'] }],
|
||||
});
|
||||
const userReadPrivileges = await esClient.security.hasPrivileges({
|
||||
index: [{ names: '.slo-*', privileges: ['read'] }],
|
||||
});
|
||||
|
||||
return {
|
||||
licenseAndFeatures: licenseInfo,
|
||||
userPrivileges,
|
||||
sloResources,
|
||||
sloSummaryResources,
|
||||
sloSummaryTransformsStats,
|
||||
userPrivileges: { write: userWritePrivileges, read: userReadPrivileges },
|
||||
};
|
||||
}
|
||||
|
||||
export async function getSloDiagnosis(
|
||||
sloId: string,
|
||||
services: { esClient: ElasticsearchClient; repository: SLORepository }
|
||||
) {
|
||||
const { esClient, repository } = services;
|
||||
|
||||
const sloResources = await getSloResourcesDiagnosis(esClient);
|
||||
const sloSummaryResources = await getSloSummaryResourcesDiagnosis(esClient);
|
||||
|
||||
let slo: SLO | undefined;
|
||||
try {
|
||||
slo = await repository.findById(sloId);
|
||||
} catch (err) {
|
||||
// noop
|
||||
}
|
||||
|
||||
const sloTransformStats = await esClient.transform.getTransformStats({
|
||||
transform_id: getSLOTransformId(sloId, slo?.revision ?? 1),
|
||||
allow_no_match: true,
|
||||
});
|
||||
|
||||
const sloSummaryTransformsStats = await esClient.transform.getTransformStats({
|
||||
transform_id: `${SLO_SUMMARY_TRANSFORM_NAME_PREFIX}*`,
|
||||
allow_no_match: true,
|
||||
});
|
||||
|
||||
return {
|
||||
sloResources,
|
||||
sloSummaryResources,
|
||||
slo: slo ?? NOT_OK,
|
||||
sloTransformStats,
|
||||
sloSummaryTransformsStats,
|
||||
};
|
||||
}
|
||||
|
||||
async function getSloResourcesDiagnosis(esClient: ElasticsearchClient) {
|
||||
try {
|
||||
const indexTemplateExists = await esClient.indices.existsIndexTemplate({
|
||||
name: SLO_INDEX_TEMPLATE_NAME,
|
||||
});
|
||||
|
||||
const mappingsTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME,
|
||||
});
|
||||
|
||||
const settingsTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: SLO_COMPONENT_TEMPLATE_SETTINGS_NAME,
|
||||
});
|
||||
|
||||
let ingestPipelineExists = true;
|
||||
try {
|
||||
await esClient.ingest.getPipeline({ id: SLO_INGEST_PIPELINE_NAME });
|
||||
} catch (err) {
|
||||
ingestPipelineExists = false;
|
||||
throw err;
|
||||
}
|
||||
|
||||
return {
|
||||
[SLO_INDEX_TEMPLATE_NAME]: indexTemplateExists ? OK : NOT_OK,
|
||||
[SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME]: mappingsTemplateExists ? OK : NOT_OK,
|
||||
[SLO_COMPONENT_TEMPLATE_SETTINGS_NAME]: settingsTemplateExists ? OK : NOT_OK,
|
||||
[SLO_INGEST_PIPELINE_NAME]: ingestPipelineExists ? OK : NOT_OK,
|
||||
};
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof errors.ResponseError &&
|
||||
(err.statusCode === 403 || err.meta.statusCode === 403)
|
||||
) {
|
||||
throw new Error('Insufficient permissions to access Elasticsearch Cluster', { cause: err });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getSloSummaryResourcesDiagnosis(esClient: ElasticsearchClient) {
|
||||
try {
|
||||
const indexTemplateExists = await esClient.indices.existsIndexTemplate({
|
||||
name: SLO_SUMMARY_INDEX_TEMPLATE_NAME,
|
||||
});
|
||||
|
||||
const mappingsTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: SLO_SUMMARY_COMPONENT_TEMPLATE_MAPPINGS_NAME,
|
||||
});
|
||||
|
||||
const settingsTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: SLO_SUMMARY_COMPONENT_TEMPLATE_SETTINGS_NAME,
|
||||
});
|
||||
|
||||
return {
|
||||
[SLO_SUMMARY_INDEX_TEMPLATE_NAME]: indexTemplateExists ? OK : NOT_OK,
|
||||
[SLO_SUMMARY_COMPONENT_TEMPLATE_MAPPINGS_NAME]: mappingsTemplateExists ? OK : NOT_OK,
|
||||
[SLO_SUMMARY_COMPONENT_TEMPLATE_SETTINGS_NAME]: settingsTemplateExists ? OK : NOT_OK,
|
||||
};
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof errors.ResponseError &&
|
||||
(err.statusCode === 403 || err.meta.statusCode === 403)
|
||||
) {
|
||||
throw new Error('Insufficient permissions to access Elasticsearch Cluster', { cause: err });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ export class DefaultTransformManager implements TransformManager {
|
|||
await retryTransientEsErrors(
|
||||
() =>
|
||||
this.esClient.transform.stopTransform(
|
||||
{ transform_id: transformId, wait_for_completion: true },
|
||||
{ transform_id: transformId, wait_for_completion: true, force: true },
|
||||
{ ignore: [404] }
|
||||
),
|
||||
{ logger: this.logger }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue