Skip to content

Commit

Permalink
[8.10] chore(slo): general enhancement (#164723) (#165032)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.10`:
- [chore(slo): general enhancement
(#164723)](#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>
  • Loading branch information
kibanamachine and kdelemme authored Aug 28, 2023
1 parent ee5c73d commit c47cdbf
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 223 deletions.
5 changes: 0 additions & 5 deletions x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -277,7 +273,6 @@ export {
findSLOResponseSchema,
getPreviewDataParamsSchema,
getPreviewDataResponseSchema,
getSLODiagnosisParamsSchema,
getSLOParamsSchema,
getSLOResponseSchema,
fetchHistoricalSummaryParamsSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export function useFetchActiveAlerts({ sloIdsAndInstanceIds = [] }: Params): Use
}
},
refetchOnWindowFocus: false,
enabled: Boolean(sloIdsAndInstanceIds.length),
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand All @@ -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) => ({
Expand All @@ -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,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 />);
Expand Down Expand Up @@ -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 />);
Expand All @@ -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 />);
Expand All @@ -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 },
},
},
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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) {
Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const getSLOSummarySettingsTemplate = (name: string) => ({
name,
template: {
settings: {
auto_expand_replicas: '0-all',
auto_expand_replicas: '0-1',
hidden: true,
},
},
Expand Down
19 changes: 1 addition & 18 deletions x-pack/plugins/observability/server/routes/slo/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
findSLOParamsSchema,
getPreviewDataParamsSchema,
getSLOBurnRatesParamsSchema,
getSLODiagnosisParamsSchema,
getSLOInstancesParamsSchema,
getSLOParamsSchema,
manageSLOParamsSchema,
Expand All @@ -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';
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -375,7 +359,6 @@ export const sloRouteRepository = {
...getSLORoute,
...updateSLORoute,
...getDiagnosisRoute,
...getSloDiagnosisRoute,
...getSloBurnRates,
...getPreviewData,
...getSLOInstancesRoute,
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/observability/server/saved_objects/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const slo: SavedObjectsType = {
},
management: {
displayName: 'SLO',
importableAndExportable: true,
importableAndExportable: false,
getTitle(sloSavedObject: SavedObject<StoredSLO>) {
return `SLO: [${sloSavedObject.attributes.name}]`;
},
Expand Down
Loading

0 comments on commit c47cdbf

Please sign in to comment.