mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Synthetics] Fix private location filter usage (#151968)
Co-authored-by: Dominique Clarke <dominique.clarke@elastic.co>
This commit is contained in:
parent
2b9f2ba684
commit
aa5d089ef1
28 changed files with 193 additions and 181 deletions
|
@ -9,7 +9,6 @@ import React from 'react';
|
|||
import { EuiFilterGroup } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { ServiceLocations } from '../../../../../../../common/runtime_types';
|
||||
import { selectServiceLocationsState } from '../../../../state';
|
||||
|
||||
import {
|
||||
|
@ -20,10 +19,6 @@ import {
|
|||
import { useFilters } from './use_filters';
|
||||
import { FilterButton } from './filter_button';
|
||||
|
||||
export const findLocationItem = (query: string, locations: ServiceLocations) => {
|
||||
return locations.find(({ id, label }) => query === id || label === query);
|
||||
};
|
||||
|
||||
export const FilterGroup = ({
|
||||
handleFilterChange,
|
||||
}: {
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
|
||||
import { FilterGroup } from './filter_group';
|
||||
import { SearchField } from '../search_field';
|
||||
import { SyntheticsMonitorFilterChangeHandler } from './filter_fields';
|
||||
|
||||
export function ListFilters({
|
||||
export const ListFilters = memo(function ({
|
||||
handleFilterChange,
|
||||
}: {
|
||||
handleFilterChange: SyntheticsMonitorFilterChangeHandler;
|
||||
|
@ -27,4 +27,4 @@ export function ListFilters({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -40,7 +40,6 @@ describe('useMonitorList', () => {
|
|||
absoluteTotal: state.monitorList.data.absoluteTotal ?? 0,
|
||||
pageState: state.monitorList.pageState,
|
||||
syntheticsMonitors: selectEncryptedSyntheticsSavedMonitors.resultFunc(state.monitorList),
|
||||
overviewStatus: null,
|
||||
handleFilterChange: jest.fn(),
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useDebounce } from 'react-use';
|
||||
import { useOverviewStatus } from './use_overview_status';
|
||||
import {
|
||||
fetchMonitorListAction,
|
||||
quietFetchMonitorListAction,
|
||||
|
@ -27,8 +26,6 @@ export function useMonitorList() {
|
|||
const { pageState, loading, loaded, error, data } = useSelector(selectMonitorListState);
|
||||
const syntheticsMonitors = useSelector(selectEncryptedSyntheticsSavedMonitors);
|
||||
|
||||
const { status: overviewStatus } = useOverviewStatus();
|
||||
|
||||
const { handleFilterChange } = useMonitorFiltersState();
|
||||
const { lastRefresh } = useSyntheticsRefreshContext();
|
||||
|
||||
|
@ -50,17 +47,20 @@ export function useMonitorList() {
|
|||
}, [lastRefresh]);
|
||||
|
||||
// On initial mount, load the page
|
||||
useEffect(() => {
|
||||
if (isInitialMount.current) {
|
||||
if (loaded) {
|
||||
dispatch(quietFetchMonitorListAction(pageState));
|
||||
} else {
|
||||
dispatch(fetchMonitorListAction.get(pageState));
|
||||
useDebounce(
|
||||
() => {
|
||||
if (isInitialMount.current) {
|
||||
if (loaded) {
|
||||
dispatch(quietFetchMonitorListAction(pageState));
|
||||
} else {
|
||||
dispatch(fetchMonitorListAction.get(pageState));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
100,
|
||||
// we don't use pageState here, for pageState, useDebounce will handle it
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dispatch]);
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
|
@ -86,7 +86,6 @@ export function useMonitorList() {
|
|||
loadPage,
|
||||
reloadPage,
|
||||
absoluteTotal: data.absoluteTotal ?? 0,
|
||||
overviewStatus,
|
||||
handleFilterChange,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
selectOverviewStatus,
|
||||
} from '../../../state/overview_status';
|
||||
|
||||
export function useOverviewStatus() {
|
||||
export function useOverviewStatus({ scopeStatusByLocation }: { scopeStatusByLocation: boolean }) {
|
||||
const pageState = useSelector(selectOverviewPageState);
|
||||
|
||||
const { status, error, loaded } = useSelector(selectOverviewStatus);
|
||||
|
@ -24,16 +24,16 @@ export function useOverviewStatus() {
|
|||
|
||||
const dispatch = useDispatch();
|
||||
const reload = useCallback(() => {
|
||||
dispatch(fetchOverviewStatusAction.get(pageState));
|
||||
}, [dispatch, pageState]);
|
||||
dispatch(fetchOverviewStatusAction.get({ pageState, scopeStatusByLocation }));
|
||||
}, [dispatch, pageState, scopeStatusByLocation]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loaded) {
|
||||
dispatch(quietFetchOverviewStatusAction.get(pageState));
|
||||
dispatch(quietFetchOverviewStatusAction.get({ pageState, scopeStatusByLocation }));
|
||||
} else {
|
||||
reload();
|
||||
}
|
||||
}, [dispatch, reload, lastRefresh, pageState, loaded]);
|
||||
}, [dispatch, reload, lastRefresh, pageState, loaded, scopeStatusByLocation]);
|
||||
|
||||
return {
|
||||
status,
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
import React from 'react';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import type { useMonitorList } from '../hooks/use_monitor_list';
|
||||
import { MonitorAsyncError } from './monitor_errors/monitor_async_error';
|
||||
import { ListFilters } from '../common/monitor_filters/list_filters';
|
||||
import { MonitorList } from './monitor_list_table/monitor_list';
|
||||
import { MonitorStats } from './monitor_stats/monitor_stats';
|
||||
import { selectOverviewStatus } from '../../../state/overview_status';
|
||||
|
||||
export const MonitorListContainer = ({
|
||||
isEnabled,
|
||||
|
@ -30,10 +32,11 @@ export const MonitorListContainer = ({
|
|||
absoluteTotal,
|
||||
loadPage,
|
||||
reloadPage,
|
||||
overviewStatus,
|
||||
handleFilterChange,
|
||||
} = monitorListProps;
|
||||
|
||||
const { status: overviewStatus } = useSelector(selectOverviewStatus);
|
||||
|
||||
// TODO: Display inline errors in the management table
|
||||
|
||||
// const { errorSummaries, loading: errorsLoading } = useInlineErrors({
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Redirect } from 'react-router-dom';
|
|||
import { EuiButton, EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui';
|
||||
import { useTrackPageview } from '@kbn/observability-plugin/public';
|
||||
|
||||
import { useOverviewStatus } from './hooks/use_overview_status';
|
||||
import { GETTING_STARTED_ROUTE } from '../../../../../common/constants';
|
||||
|
||||
import { ServiceAllowedWrapper } from '../common/wrappers/service_allowed_wrapper';
|
||||
|
@ -24,7 +25,7 @@ import { useMonitorListBreadcrumbs } from './hooks/use_breadcrumbs';
|
|||
import { useMonitorList } from './hooks/use_monitor_list';
|
||||
import * as labels from './management/labels';
|
||||
|
||||
const MonitorPage: React.FC = () => {
|
||||
const MonitorManagementPage: React.FC = () => {
|
||||
useTrackPageview({ app: 'synthetics', path: 'monitors' });
|
||||
useTrackPageview({ app: 'synthetics', path: 'monitors', delay: 15000 });
|
||||
|
||||
|
@ -37,6 +38,8 @@ const MonitorPage: React.FC = () => {
|
|||
enableSynthetics,
|
||||
} = useEnablement();
|
||||
|
||||
useOverviewStatus({ scopeStatusByLocation: false });
|
||||
|
||||
const monitorListProps = useMonitorList();
|
||||
const { syntheticsMonitors, loading: monitorsLoading, absoluteTotal, loaded } = monitorListProps;
|
||||
|
||||
|
@ -91,6 +94,6 @@ const MonitorPage: React.FC = () => {
|
|||
|
||||
export const MonitorsPageWithServiceAllowed = React.memo(() => (
|
||||
<ServiceAllowedWrapper>
|
||||
<MonitorPage />
|
||||
<MonitorManagementPage />
|
||||
</ServiceAllowedWrapper>
|
||||
));
|
||||
|
|
|
@ -20,7 +20,7 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
|
|||
import { useSelector } from 'react-redux';
|
||||
import { selectOverviewStatus } from '../../../../state/overview_status';
|
||||
import { AlertsLink } from '../../../common/links/view_alerts';
|
||||
import { useRefreshedRange } from '../../../../hooks';
|
||||
import { useRefreshedRange, useGetUrlParams } from '../../../../hooks';
|
||||
import { ClientPluginsStart } from '../../../../../../plugin';
|
||||
|
||||
export const OverviewAlerts = () => {
|
||||
|
@ -33,6 +33,8 @@ export const OverviewAlerts = () => {
|
|||
|
||||
const { status } = useSelector(selectOverviewStatus);
|
||||
|
||||
const { locations } = useGetUrlParams();
|
||||
|
||||
const loading = !status?.allIds || status?.allIds.length === 0;
|
||||
|
||||
return (
|
||||
|
@ -66,6 +68,7 @@ export const OverviewAlerts = () => {
|
|||
status?.enabledMonitorQueryIds.length > 0
|
||||
? status?.enabledMonitorQueryIds
|
||||
: ['false-id'],
|
||||
...(locations?.length ? { 'observer.geo.name': locations } : {}),
|
||||
},
|
||||
filters: [{ field: 'kibana.alert.status', values: ['active', 'recovered'] }],
|
||||
color: theme.eui.euiColorVis1,
|
||||
|
@ -92,6 +95,7 @@ export const OverviewAlerts = () => {
|
|||
status?.enabledMonitorQueryIds.length > 0
|
||||
? status?.enabledMonitorQueryIds
|
||||
: ['false-id'],
|
||||
...(locations?.length ? { 'observer.geo.name': locations } : {}),
|
||||
},
|
||||
dataType: 'alerts',
|
||||
selectedMetricField: RECORDS_FIELD,
|
||||
|
|
|
@ -18,7 +18,7 @@ import { useSelector } from 'react-redux';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { selectOverviewStatus } from '../../../../../state/overview_status';
|
||||
import { OverviewErrorsSparklines } from './overview_errors_sparklines';
|
||||
import { useRefreshedRange } from '../../../../../hooks';
|
||||
import { useRefreshedRange, useGetUrlParams } from '../../../../../hooks';
|
||||
import { OverviewErrorsCount } from './overview_errors_count';
|
||||
|
||||
export function OverviewErrors() {
|
||||
|
@ -28,6 +28,8 @@ export function OverviewErrors() {
|
|||
|
||||
const { from, to } = useRefreshedRange(6, 'hours');
|
||||
|
||||
const params = useGetUrlParams();
|
||||
|
||||
return (
|
||||
<EuiPanel hasShadow={false} hasBorder>
|
||||
<EuiTitle size="xs">
|
||||
|
@ -43,6 +45,7 @@ export function OverviewErrors() {
|
|||
from={from}
|
||||
to={to}
|
||||
monitorIds={status?.enabledMonitorQueryIds ?? []}
|
||||
locations={params.locations}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={true}>
|
||||
|
@ -50,6 +53,7 @@ export function OverviewErrors() {
|
|||
from={from}
|
||||
to={to}
|
||||
monitorIds={status?.enabledMonitorQueryIds ?? []}
|
||||
locations={params.locations}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -16,13 +16,14 @@ interface MonitorErrorsCountProps {
|
|||
to: string;
|
||||
locationLabel?: string;
|
||||
monitorIds: string[];
|
||||
locations?: string[];
|
||||
}
|
||||
|
||||
export const OverviewErrorsCount = ({
|
||||
monitorIds,
|
||||
from,
|
||||
to,
|
||||
locationLabel,
|
||||
locations,
|
||||
}: MonitorErrorsCountProps) => {
|
||||
const { observability } = useKibana<ClientPluginsStart>().services;
|
||||
|
||||
|
@ -41,7 +42,7 @@ export const OverviewErrorsCount = ({
|
|||
time,
|
||||
reportDefinitions: {
|
||||
'monitor.id': monitorIds.length > 0 ? monitorIds : ['false-monitor-id'],
|
||||
...(locationLabel ? { 'observer.geo.name': [locationLabel] } : {}),
|
||||
...(locations?.length ? { 'observer.geo.name': locations } : {}),
|
||||
},
|
||||
dataType: 'synthetics',
|
||||
selectedMetricField: 'monitor_errors',
|
||||
|
|
|
@ -15,8 +15,9 @@ interface Props {
|
|||
from: string;
|
||||
to: string;
|
||||
monitorIds: string[];
|
||||
locations?: string[];
|
||||
}
|
||||
export const OverviewErrorsSparklines = ({ from, to, monitorIds }: Props) => {
|
||||
export const OverviewErrorsSparklines = ({ from, to, monitorIds, locations }: Props) => {
|
||||
const { observability } = useKibana<ClientPluginsStart>().services;
|
||||
|
||||
const { ExploratoryViewEmbeddable } = observability;
|
||||
|
@ -38,6 +39,7 @@ export const OverviewErrorsSparklines = ({ from, to, monitorIds }: Props) => {
|
|||
seriesType: 'area',
|
||||
reportDefinitions: {
|
||||
'monitor.id': monitorIds.length > 0 ? monitorIds : ['false-monitor-id'],
|
||||
...(locations?.length ? { 'observer.geo.name': locations } : {}),
|
||||
},
|
||||
dataType: 'synthetics',
|
||||
selectedMetricField: 'monitor_errors',
|
||||
|
|
|
@ -21,7 +21,7 @@ function title(t?: number) {
|
|||
export function OverviewStatus() {
|
||||
const { statusFilter } = useGetUrlParams();
|
||||
|
||||
const { status, error: statusError } = useOverviewStatus();
|
||||
const { status, error: statusError } = useOverviewStatus({ scopeStatusByLocation: true });
|
||||
const dispatch = useDispatch();
|
||||
const [statusConfig, setStatusConfig] = useState({
|
||||
up: status?.up,
|
||||
|
|
|
@ -100,11 +100,11 @@ export function* upsertMonitorEffect() {
|
|||
if (action.payload.shouldQuietFetchAfterSuccess !== false) {
|
||||
const monitorState = yield select(selectOverviewState);
|
||||
if (hasPageState(monitorState)) {
|
||||
yield put(quietFetchOverviewAction.get(monitorState.pageState));
|
||||
yield put(
|
||||
quietFetchOverviewAction.get(monitorState.pageState as MonitorOverviewPageState)
|
||||
);
|
||||
yield put(
|
||||
quietFetchOverviewStatusAction.get(monitorState.pageState as MonitorOverviewPageState)
|
||||
quietFetchOverviewStatusAction.get({
|
||||
pageState: monitorState.pageState,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ import { createAsyncAction } from '../utils/actions';
|
|||
import { OverviewStatus } from '../../../../../common/runtime_types';
|
||||
|
||||
export const fetchOverviewStatusAction = createAsyncAction<
|
||||
MonitorOverviewPageState,
|
||||
{ pageState: MonitorOverviewPageState; scopeStatusByLocation?: boolean },
|
||||
OverviewStatus
|
||||
>('fetchOverviewStatusAction');
|
||||
|
||||
export const quietFetchOverviewStatusAction = createAsyncAction<
|
||||
MonitorOverviewPageState,
|
||||
{ pageState: MonitorOverviewPageState; scopeStatusByLocation?: boolean },
|
||||
OverviewStatus
|
||||
>('quietFetchOverviewStatusAction');
|
||||
|
||||
|
|
|
@ -11,9 +11,17 @@ import { OverviewStatus, OverviewStatusCodec } from '../../../../../common/runti
|
|||
import { apiService } from '../../../../utils/api_service';
|
||||
import { toStatusOverviewQueryArgs } from '../overview/api';
|
||||
|
||||
export const fetchOverviewStatus = async (
|
||||
pageState: MonitorOverviewPageState
|
||||
): Promise<OverviewStatus> => {
|
||||
export const fetchOverviewStatus = async ({
|
||||
pageState,
|
||||
scopeStatusByLocation,
|
||||
}: {
|
||||
pageState: MonitorOverviewPageState;
|
||||
scopeStatusByLocation?: boolean;
|
||||
}): Promise<OverviewStatus> => {
|
||||
const params = toStatusOverviewQueryArgs(pageState);
|
||||
return apiService.get(SYNTHETICS_API_URLS.OVERVIEW_STATUS, params, OverviewStatusCodec);
|
||||
return apiService.get(
|
||||
SYNTHETICS_API_URLS.OVERVIEW_STATUS,
|
||||
{ ...params, scopeStatusByLocation },
|
||||
OverviewStatusCodec
|
||||
);
|
||||
};
|
||||
|
|
|
@ -67,11 +67,11 @@ export class StatusRuleExecutor {
|
|||
}
|
||||
|
||||
async getAllLocationNames() {
|
||||
const { publicLocations, privateLocations } = await getAllLocations(
|
||||
this.server,
|
||||
this.syntheticsMonitorClient,
|
||||
this.soClient
|
||||
);
|
||||
const { publicLocations, privateLocations } = await getAllLocations({
|
||||
server: this.server,
|
||||
syntheticsMonitorClient: this.syntheticsMonitorClient,
|
||||
savedObjectsClient: this.soClient,
|
||||
});
|
||||
|
||||
publicLocations.forEach((loc) => {
|
||||
this.locationIdNameMap[loc.label] = loc.id;
|
||||
|
|
|
@ -109,15 +109,7 @@ export type UMRouteHandler = ({
|
|||
subject?: Subject<unknown>;
|
||||
}) => IKibanaResponse<any> | Promise<IKibanaResponse<any>>;
|
||||
|
||||
export type SyntheticsRouteHandler = ({
|
||||
uptimeEsClient,
|
||||
context,
|
||||
request,
|
||||
response,
|
||||
server,
|
||||
savedObjectsClient,
|
||||
subject: Subject,
|
||||
}: {
|
||||
export interface RouteContext {
|
||||
uptimeEsClient: UptimeEsClient;
|
||||
context: UptimeRequestHandlerContext;
|
||||
request: SyntheticsRequest;
|
||||
|
@ -126,7 +118,17 @@ export type SyntheticsRouteHandler = ({
|
|||
server: UptimeServerSetup;
|
||||
syntheticsMonitorClient: SyntheticsMonitorClient;
|
||||
subject?: Subject<unknown>;
|
||||
}) => IKibanaResponse<any> | Promise<IKibanaResponse<any>>;
|
||||
}
|
||||
|
||||
export type SyntheticsRouteHandler = ({
|
||||
uptimeEsClient,
|
||||
context,
|
||||
request,
|
||||
response,
|
||||
server,
|
||||
savedObjectsClient,
|
||||
subject: Subject,
|
||||
}: RouteContext) => IKibanaResponse<any> | Promise<IKibanaResponse<any>>;
|
||||
|
||||
export type SyntheticsStreamingRouteHandler = ({
|
||||
uptimeEsClient,
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { SavedObjectsClientContract, SavedObjectsFindResponse } from '@kbn/core/server';
|
||||
import { SyntheticsService } from '../synthetics_service/synthetics_service';
|
||||
import { SavedObjectsFindResponse } from '@kbn/core/server';
|
||||
import { getAllLocations } from '../synthetics_service/get_all_locations';
|
||||
import { EncryptedSyntheticsMonitor, ServiceLocations } from '../../common/runtime_types';
|
||||
import { monitorAttributes } from '../../common/types/saved_objects';
|
||||
import { syntheticsMonitorType } from '../legacy_uptime/lib/saved_objects/synthetics_monitor';
|
||||
import { RouteContext } from '../legacy_uptime/routes';
|
||||
|
||||
export const QuerySchema = schema.object({
|
||||
page: schema.maybe(schema.number()),
|
||||
|
@ -40,6 +41,7 @@ export const OverviewStatusSchema = schema.object({
|
|||
projects: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
|
||||
schedules: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
|
||||
status: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
|
||||
scopeStatusByLocation: schema.maybe(schema.boolean()),
|
||||
});
|
||||
|
||||
export type OverviewStatusQuery = TypeOf<typeof OverviewStatusSchema>;
|
||||
|
@ -54,10 +56,8 @@ export const SEARCH_FIELDS = [
|
|||
'project_id.text',
|
||||
];
|
||||
|
||||
export const getMonitors = (
|
||||
request: MonitorsQuery,
|
||||
syntheticsService: SyntheticsService,
|
||||
savedObjectsClient: SavedObjectsClientContract
|
||||
export const getMonitors = async (
|
||||
context: RouteContext
|
||||
): Promise<SavedObjectsFindResponse<EncryptedSyntheticsMonitor>> => {
|
||||
const {
|
||||
perPage = 50,
|
||||
|
@ -73,19 +73,19 @@ export const getMonitors = (
|
|||
searchAfter,
|
||||
projects,
|
||||
schedules,
|
||||
} = request as MonitorsQuery;
|
||||
} = context.request.query as MonitorsQuery;
|
||||
|
||||
const filterStr = getMonitorFilters({
|
||||
const filterStr = await getMonitorFilters({
|
||||
filter,
|
||||
monitorTypes,
|
||||
tags,
|
||||
locations,
|
||||
serviceLocations: syntheticsService.locations,
|
||||
projects,
|
||||
schedules,
|
||||
context,
|
||||
});
|
||||
|
||||
return savedObjectsClient.find({
|
||||
return context.savedObjectsClient.find({
|
||||
type: syntheticsMonitorType,
|
||||
perPage,
|
||||
page,
|
||||
|
@ -99,15 +99,14 @@ export const getMonitors = (
|
|||
});
|
||||
};
|
||||
|
||||
export const getMonitorFilters = ({
|
||||
export const getMonitorFilters = async ({
|
||||
tags,
|
||||
ports,
|
||||
filter,
|
||||
locations,
|
||||
projects,
|
||||
monitorTypes,
|
||||
schedules,
|
||||
serviceLocations,
|
||||
context,
|
||||
}: {
|
||||
filter?: string;
|
||||
tags?: string | string[];
|
||||
|
@ -115,10 +114,9 @@ export const getMonitorFilters = ({
|
|||
locations?: string | string[];
|
||||
projects?: string | string[];
|
||||
schedules?: string | string[];
|
||||
ports?: string | string[];
|
||||
serviceLocations: ServiceLocations;
|
||||
context: RouteContext;
|
||||
}) => {
|
||||
const locationFilter = parseLocationFilter(serviceLocations, locations);
|
||||
const locationFilter = await parseLocationFilter(context, locations);
|
||||
|
||||
return [
|
||||
filter,
|
||||
|
@ -160,18 +158,20 @@ export const getKqlFilter = ({
|
|||
return `${fieldKey}:"${values}"`;
|
||||
};
|
||||
|
||||
const parseLocationFilter = (serviceLocations: ServiceLocations, locations?: string | string[]) => {
|
||||
if (!locations) {
|
||||
const parseLocationFilter = async (context: RouteContext, locations?: string | string[]) => {
|
||||
if (!locations || locations?.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const { allLocations } = await getAllLocations(context);
|
||||
|
||||
if (Array.isArray(locations)) {
|
||||
return locations
|
||||
.map((loc) => findLocationItem(loc, serviceLocations)?.id ?? '')
|
||||
.map((loc) => findLocationItem(loc, allLocations)?.id ?? '')
|
||||
.filter((val) => !!val);
|
||||
}
|
||||
|
||||
return findLocationItem(locations, serviceLocations)?.id ?? '';
|
||||
return findLocationItem(locations, allLocations)?.id ?? '';
|
||||
};
|
||||
|
||||
export const findLocationItem = (query: string, locations: ServiceLocations) => {
|
||||
|
|
|
@ -45,11 +45,11 @@ export const addSyntheticsProjectMonitorRouteLegacy: SyntheticsStreamingRouteFac
|
|||
const { id: spaceId } = await server.spaces.spacesService.getActiveSpace(request);
|
||||
|
||||
const { keep_stale: keepStale, project: projectId } = request.body || {};
|
||||
const { publicLocations, privateLocations } = await getAllLocations(
|
||||
const { publicLocations, privateLocations } = await getAllLocations({
|
||||
server,
|
||||
syntheticsMonitorClient,
|
||||
savedObjectsClient
|
||||
);
|
||||
savedObjectsClient,
|
||||
});
|
||||
const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient();
|
||||
|
||||
const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({
|
||||
|
|
|
@ -25,13 +25,8 @@ export const deleteSyntheticsMonitorProjectRoute: SyntheticsRestApiRouteFactory
|
|||
projectName: schema.string(),
|
||||
}),
|
||||
},
|
||||
handler: async ({
|
||||
request,
|
||||
response,
|
||||
savedObjectsClient,
|
||||
server,
|
||||
syntheticsMonitorClient,
|
||||
}): Promise<any> => {
|
||||
handler: async (routeContext): Promise<any> => {
|
||||
const { request, response, savedObjectsClient, server, syntheticsMonitorClient } = routeContext;
|
||||
const { projectName } = request.params;
|
||||
const { monitors: monitorsToDelete } = request.body;
|
||||
const decodedProjectName = decodeURI(projectName);
|
||||
|
@ -43,20 +38,20 @@ export const deleteSyntheticsMonitorProjectRoute: SyntheticsRestApiRouteFactory
|
|||
});
|
||||
}
|
||||
|
||||
const { saved_objects: monitors } = await getMonitors(
|
||||
{
|
||||
filter: `${syntheticsMonitorType}.attributes.${
|
||||
ConfigKey.PROJECT_ID
|
||||
}: "${decodedProjectName}" AND ${getKqlFilter({
|
||||
field: 'journey_id',
|
||||
values: monitorsToDelete.map((id: string) => `${id}`),
|
||||
})}`,
|
||||
fields: [],
|
||||
perPage: 500,
|
||||
const deleteFilter = `${syntheticsMonitorType}.attributes.${
|
||||
ConfigKey.PROJECT_ID
|
||||
}: "${decodedProjectName}" AND ${getKqlFilter({
|
||||
field: 'journey_id',
|
||||
values: monitorsToDelete.map((id: string) => `${id}`),
|
||||
})}`;
|
||||
|
||||
const { saved_objects: monitors } = await getMonitors({
|
||||
...routeContext,
|
||||
request: {
|
||||
...request,
|
||||
query: { ...request.query, filter: deleteFilter, fields: [], perPage: 500 },
|
||||
},
|
||||
syntheticsMonitorClient.syntheticsService,
|
||||
savedObjectsClient
|
||||
);
|
||||
});
|
||||
|
||||
const {
|
||||
integrations: { writeIntegrationPolicies },
|
||||
|
|
|
@ -65,7 +65,8 @@ export const getAllSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () =>
|
|||
validate: {
|
||||
query: QuerySchema,
|
||||
},
|
||||
handler: async ({ request, savedObjectsClient, syntheticsMonitorClient }): Promise<any> => {
|
||||
handler: async (routeContext): Promise<any> => {
|
||||
const { request, savedObjectsClient, syntheticsMonitorClient } = routeContext;
|
||||
const totalCountQuery = async () => {
|
||||
if (isMonitorsQueryFiltered(request.query)) {
|
||||
return savedObjectsClient.find({
|
||||
|
@ -77,7 +78,7 @@ export const getAllSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () =>
|
|||
};
|
||||
|
||||
const [queryResult, totalCount] = await Promise.all([
|
||||
getMonitors(request.query, syntheticsMonitorClient.syntheticsService, savedObjectsClient),
|
||||
getMonitors(routeContext),
|
||||
totalCountQuery(),
|
||||
]);
|
||||
|
||||
|
@ -101,7 +102,9 @@ export const getSyntheticsMonitorOverviewRoute: SyntheticsRestApiRouteFactory =
|
|||
validate: {
|
||||
query: QuerySchema,
|
||||
},
|
||||
handler: async ({ request, savedObjectsClient, syntheticsMonitorClient }): Promise<any> => {
|
||||
handler: async (routeContext): Promise<any> => {
|
||||
const { request, savedObjectsClient } = routeContext;
|
||||
|
||||
const {
|
||||
sortField,
|
||||
sortOrder,
|
||||
|
@ -109,9 +112,9 @@ export const getSyntheticsMonitorOverviewRoute: SyntheticsRestApiRouteFactory =
|
|||
locations: queriedLocations,
|
||||
} = request.query as MonitorsQuery;
|
||||
|
||||
const filtersStr = getMonitorFilters({
|
||||
const filtersStr = await getMonitorFilters({
|
||||
...request.query,
|
||||
serviceLocations: syntheticsMonitorClient.syntheticsService.locations,
|
||||
context: routeContext,
|
||||
});
|
||||
|
||||
const allMonitorConfigs = await getAllMonitors({
|
||||
|
|
|
@ -25,31 +25,33 @@ export const getSyntheticsProjectMonitorsRoute: SyntheticsRestApiRouteFactory =
|
|||
}),
|
||||
query: querySchema,
|
||||
},
|
||||
handler: async ({
|
||||
request,
|
||||
response,
|
||||
server: { logger },
|
||||
savedObjectsClient,
|
||||
syntheticsMonitorClient,
|
||||
}): Promise<any> => {
|
||||
handler: async (routeContext): Promise<any> => {
|
||||
const {
|
||||
request,
|
||||
server: { logger },
|
||||
} = routeContext;
|
||||
|
||||
const { projectName } = request.params;
|
||||
const { per_page: perPage = 500, search_after: searchAfter } = request.query;
|
||||
const decodedProjectName = decodeURI(projectName);
|
||||
const decodedSearchAfter = searchAfter ? decodeURI(searchAfter) : undefined;
|
||||
|
||||
try {
|
||||
const { saved_objects: monitors, total } = await getMonitors(
|
||||
{
|
||||
filter: `${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${decodedProjectName}"`,
|
||||
fields: [ConfigKey.JOURNEY_ID, ConfigKey.CONFIG_HASH],
|
||||
perPage,
|
||||
sortField: ConfigKey.JOURNEY_ID,
|
||||
sortOrder: 'asc',
|
||||
searchAfter: decodedSearchAfter ? [...decodedSearchAfter.split(',')] : undefined,
|
||||
const { saved_objects: monitors, total } = await getMonitors({
|
||||
...routeContext,
|
||||
request: {
|
||||
...request,
|
||||
query: {
|
||||
...request.query,
|
||||
filter: `${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${decodedProjectName}"`,
|
||||
fields: [ConfigKey.JOURNEY_ID, ConfigKey.CONFIG_HASH],
|
||||
perPage,
|
||||
sortField: ConfigKey.JOURNEY_ID,
|
||||
sortOrder: 'asc',
|
||||
searchAfter: decodedSearchAfter ? [...decodedSearchAfter.split(',')] : undefined,
|
||||
},
|
||||
},
|
||||
syntheticsMonitorClient.syntheticsService,
|
||||
savedObjectsClient
|
||||
);
|
||||
});
|
||||
const projectMonitors = monitors.map((monitor) => ({
|
||||
journey_id: monitor.attributes[ConfigKey.JOURNEY_ID],
|
||||
hash: monitor.attributes[ConfigKey.CONFIG_HASH] || '',
|
||||
|
|
|
@ -6,20 +6,16 @@
|
|||
*/
|
||||
import { intersection } from 'lodash';
|
||||
import datemath, { Unit } from '@kbn/datemath';
|
||||
import { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import moment from 'moment';
|
||||
import { ConfigKey } from '../../../common/runtime_types';
|
||||
import {
|
||||
getAllMonitors,
|
||||
processMonitors,
|
||||
} from '../../saved_objects/synthetics_monitor/get_all_monitors';
|
||||
import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters';
|
||||
import { queryMonitorStatus } from '../../queries/query_monitor_status';
|
||||
import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
||||
import { UMServerLibs } from '../../legacy_uptime/uptime_server';
|
||||
import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes';
|
||||
import { UptimeEsClient } from '../../legacy_uptime/lib/lib';
|
||||
import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client';
|
||||
import { RouteContext, SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes';
|
||||
import { getMonitorFilters, OverviewStatusSchema, OverviewStatusQuery } from '../common';
|
||||
|
||||
/**
|
||||
|
@ -40,14 +36,10 @@ export function periodToMs(schedule: { number: string; unit: Unit }) {
|
|||
* Subsequently, fetch the status for each monitor per location in the data streams.
|
||||
* @returns The counts of up/down/disabled monitor by location, and a map of each monitor:location status.
|
||||
*/
|
||||
export async function getStatus(
|
||||
server: UptimeServerSetup,
|
||||
uptimeEsClient: UptimeEsClient,
|
||||
soClient: SavedObjectsClientContract,
|
||||
syntheticsMonitorClient: SyntheticsMonitorClient,
|
||||
params: OverviewStatusQuery
|
||||
) {
|
||||
const { query, locations: queryLocations } = params;
|
||||
export async function getStatus(context: RouteContext, params: OverviewStatusQuery) {
|
||||
const { uptimeEsClient, syntheticsMonitorClient, savedObjectsClient, server } = context;
|
||||
|
||||
const { query, locations: queryLocations, scopeStatusByLocation = true } = params;
|
||||
/**
|
||||
* Walk through all monitor saved objects, bucket IDs by disabled/enabled status.
|
||||
*
|
||||
|
@ -55,12 +47,13 @@ export async function getStatus(
|
|||
* latest ping for all enabled monitors.
|
||||
*/
|
||||
|
||||
const filtersStr = getMonitorFilters({
|
||||
const filtersStr = await getMonitorFilters({
|
||||
...params,
|
||||
serviceLocations: syntheticsMonitorClient.syntheticsService.locations,
|
||||
context,
|
||||
});
|
||||
|
||||
const allMonitors = await getAllMonitors({
|
||||
soClient,
|
||||
soClient: savedObjectsClient,
|
||||
search: query ? `${query}*` : undefined,
|
||||
filter: filtersStr,
|
||||
fields: [
|
||||
|
@ -83,14 +76,15 @@ export async function getStatus(
|
|||
disabledMonitorsCount,
|
||||
projectMonitorsCount,
|
||||
monitorQueryIdToConfigIdMap,
|
||||
} = await processMonitors(allMonitors, server, soClient, syntheticsMonitorClient);
|
||||
} = await processMonitors(allMonitors, server, savedObjectsClient, syntheticsMonitorClient);
|
||||
|
||||
// Account for locations filter
|
||||
const queryLocationsArray =
|
||||
queryLocations && !Array.isArray(queryLocations) ? [queryLocations] : queryLocations;
|
||||
const listOfLocationAfterFilter = queryLocationsArray
|
||||
? intersection(listOfLocations, queryLocationsArray)
|
||||
: listOfLocations;
|
||||
const listOfLocationAfterFilter =
|
||||
queryLocationsArray && scopeStatusByLocation
|
||||
? intersection(listOfLocations, queryLocationsArray)
|
||||
: listOfLocations;
|
||||
|
||||
const range = {
|
||||
from: moment().subtract(maxPeriod, 'milliseconds').subtract(20, 'minutes').toISOString(),
|
||||
|
@ -128,20 +122,10 @@ export const createGetCurrentStatusRoute: SyntheticsRestApiRouteFactory = (libs:
|
|||
validate: {
|
||||
query: OverviewStatusSchema,
|
||||
},
|
||||
handler: async ({
|
||||
server,
|
||||
uptimeEsClient,
|
||||
savedObjectsClient,
|
||||
syntheticsMonitorClient,
|
||||
request,
|
||||
}): Promise<any> => {
|
||||
handler: async (routeContext): Promise<any> => {
|
||||
const { request } = routeContext;
|
||||
|
||||
const params = request.query as OverviewStatusQuery;
|
||||
return await getStatus(
|
||||
server,
|
||||
uptimeEsClient,
|
||||
savedObjectsClient,
|
||||
syntheticsMonitorClient,
|
||||
params
|
||||
);
|
||||
return await getStatus(routeContext, params);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -14,14 +14,14 @@ export const getServiceLocationsRoute: SyntheticsRestApiRouteFactory = () => ({
|
|||
path: API_URLS.SERVICE_LOCATIONS,
|
||||
validate: {},
|
||||
handler: async ({ server, savedObjectsClient, syntheticsMonitorClient }): Promise<any> => {
|
||||
const { publicLocations, privateLocations, throttling } = await getAllLocations(
|
||||
const { throttling, allLocations } = await getAllLocations({
|
||||
server,
|
||||
syntheticsMonitorClient,
|
||||
savedObjectsClient
|
||||
);
|
||||
savedObjectsClient,
|
||||
});
|
||||
|
||||
return {
|
||||
locations: [...publicLocations, ...privateLocations],
|
||||
locations: allLocations,
|
||||
throttling,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -87,11 +87,11 @@ export const processMonitors = async (
|
|||
|
||||
const getLocationLabel = async (locationId: string) => {
|
||||
if (!allLocations) {
|
||||
const { publicLocations, privateLocations } = await getAllLocations(
|
||||
const { publicLocations, privateLocations } = await getAllLocations({
|
||||
server,
|
||||
syntheticsMonitorClient,
|
||||
soClient
|
||||
);
|
||||
savedObjectsClient: soClient,
|
||||
});
|
||||
|
||||
allLocations = [...publicLocations, ...privateLocations];
|
||||
}
|
||||
|
|
|
@ -10,20 +10,29 @@ import { getServiceLocations } from './get_service_locations';
|
|||
import { SyntheticsMonitorClient } from './synthetics_monitor/synthetics_monitor_client';
|
||||
import { UptimeServerSetup } from '../legacy_uptime/lib/adapters/framework';
|
||||
|
||||
export async function getAllLocations(
|
||||
server: UptimeServerSetup,
|
||||
syntheticsMonitorClient: SyntheticsMonitorClient,
|
||||
savedObjectsClient: SavedObjectsClientContract
|
||||
) {
|
||||
export async function getAllLocations({
|
||||
syntheticsMonitorClient,
|
||||
savedObjectsClient,
|
||||
server,
|
||||
}: {
|
||||
server: UptimeServerSetup;
|
||||
syntheticsMonitorClient: SyntheticsMonitorClient;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
}) {
|
||||
try {
|
||||
const [privateLocations, { locations: publicLocations, throttling }] = await Promise.all([
|
||||
getPrivateLocations(syntheticsMonitorClient, savedObjectsClient),
|
||||
getServicePublicLocations(server, syntheticsMonitorClient),
|
||||
]);
|
||||
return { publicLocations, privateLocations, throttling };
|
||||
return {
|
||||
publicLocations,
|
||||
privateLocations,
|
||||
throttling,
|
||||
allLocations: [...publicLocations, ...privateLocations],
|
||||
};
|
||||
} catch (e) {
|
||||
server.logger.error(e);
|
||||
return { publicLocations: [], privateLocations: [] };
|
||||
return { publicLocations: [], privateLocations: [], allLocations: [] };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,11 +120,11 @@ export class ProjectMonitorFormatter {
|
|||
}
|
||||
|
||||
init = async () => {
|
||||
const locationsPromise = getAllLocations(
|
||||
this.server,
|
||||
this.syntheticsMonitorClient,
|
||||
this.savedObjectsClient
|
||||
);
|
||||
const locationsPromise = getAllLocations({
|
||||
server: this.server,
|
||||
syntheticsMonitorClient: this.syntheticsMonitorClient,
|
||||
savedObjectsClient: this.savedObjectsClient,
|
||||
});
|
||||
const existingMonitorsPromise = this.getProjectMonitorsForProject();
|
||||
|
||||
const [locations, existingMonitors] = await Promise.all([
|
||||
|
|
|
@ -30,7 +30,6 @@ import { syntheticsMonitorType } from '../../legacy_uptime/lib/saved_objects/syn
|
|||
|
||||
export class SyntheticsMonitorClient {
|
||||
public syntheticsService: SyntheticsService;
|
||||
|
||||
public privateLocationAPI: SyntheticsPrivateLocation;
|
||||
|
||||
constructor(syntheticsService: SyntheticsService, server: UptimeServerSetup) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue