WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export enum SYNTHETICS_API_URLS {
SYNTHETICS_PROJECT_APIKEY = '/internal/synthetics/service/api_key',
SYNTHETICS_HAS_INTEGRATION_MONITORS = '/internal/synthetics/fleet/has_integration_monitors',
PRIVATE_LOCATIONS_CLEANUP = `/internal/synthetics/private_locations/_cleanup`,
SYNC_GLOBAL_PARAMS = `/internal/synthetics/sync_global_params`,
SYNC_GLOBAL_PARAMS_SETTINGS = `/internal/synthetics/sync_global_params/_settings`,

PINGS = '/internal/synthetics/pings',
MONITOR_STATUS_HEATMAP = '/internal/synthetics/ping_heatmap',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ export class Plugin implements PluginType {

this.syncPrivateLocationMonitorsTask = new SyncPrivateLocationMonitorsTask(
this.server,
plugins.taskManager,
this.syntheticsMonitorClient
);
this.syncPrivateLocationMonitorsTask.registerTaskDefinition(plugins.taskManager);

plugins.embeddable.registerTransforms(SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE, {
transformOutInjectsReferences: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import { syncParamsSettingsParamsRoute } from './settings/params/sync_global_params_settings';
import { syncParamsSyntheticsParamsRoute } from './settings/params/sync_global_params';
import { cleanupPrivateLocationRoute } from './settings/private_locations/cleanup_private_locations';
import { getSyntheticsTriggerTaskRun } from './tasks/trigger_task_run';
import { syntheticsInspectStatusRuleRoute } from './rules/inspect_status_rule';
Expand Down Expand Up @@ -107,6 +109,8 @@ export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [
syntheticsInspectTLSRuleRoute,
getSyntheticsTriggerTaskRun,
cleanupPrivateLocationRoute,
syncParamsSyntheticsParamsRoute,
syncParamsSettingsParamsRoute,
];

export const syntheticsAppPublicRestApiRoutes: SyntheticsRestApiRouteFactory[] = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { SyncPrivateLocationMonitorsTask } from '../../../tasks/sync_private_locations_monitors_task';
import { SYNTHETICS_API_URLS } from '../../../../common/constants';
import { getPrivateLocations } from '../../../synthetics_service/get_private_locations';
import type { SyntheticsRestApiRouteFactory } from '../../types';

export const syncParamsSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
method: 'PUT',
path: SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS,
validate: {},
options: {
// 5 minutes
timeout: {
payload: 1000 * 60 * 5,
},
},
writeAccess: true,
handler: async ({ syntheticsMonitorClient, server }): Promise<any> => {
const soClient = server.coreStart.savedObjects.createInternalRepository();

const allPrivateLocations = await getPrivateLocations(soClient);

const syncTask = new SyncPrivateLocationMonitorsTask(server, syntheticsMonitorClient);
if (allPrivateLocations.length > 0) {
await syncTask.syncGlobalParams({
allPrivateLocations,
soClient,
});
}

return { success: true };
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { schema } from '@kbn/config-schema';
import { disableSyncPrivateLocationTask } from '../../../tasks/sync_private_locations_monitors_task';
import { SYNTHETICS_API_URLS } from '../../../../common/constants';
import type { SyntheticsRestApiRouteFactory } from '../../types';

export const syncParamsSettingsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
method: 'PUT',
path: SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS_SETTINGS,
validate: {
body: schema.object({
enable: schema.boolean(),
}),
},
writeAccess: true,
handler: async ({ server, request }): Promise<any> => {
const { enable } = request.body as { enable: boolean };
await disableSyncPrivateLocationTask({ server, disableAutoSync: !enable });
return { success: true };
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import type { TaskManagerSetupContract } from '@kbn/task-manager-plugin/server/plugin';
import type { CustomTaskInstance } from './sync_private_locations_monitors_task';
import {
SyncPrivateLocationMonitorsTask,
Expand Down Expand Up @@ -84,20 +83,20 @@ describe('SyncPrivateLocationMonitorsTask', () => {
jest.clearAllMocks();
task = new SyncPrivateLocationMonitorsTask(
mockServerSetup as any,
mockTaskManager as unknown as TaskManagerSetupContract,
mockSyntheticsMonitorClient as unknown as SyntheticsMonitorClient
);
mockSoClient.createInternalRepository.mockReturnValue(mockSoClient as any);
});

describe('constructor', () => {
it('should register task definitions correctly', () => {
task.registerTaskDefinition(mockTaskManager as any);
expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalledWith({
'Synthetics:Sync-Private-Location-Monitors': expect.objectContaining({
title: 'Synthetics Sync Global Params Task',
description:
'This task is executed so that we can sync private location monitors for example when global params are updated',
timeout: '5m',
timeout: '10m',
maxAttempts: 1,
createTaskRunner: expect.any(Function),
}),
Expand Down Expand Up @@ -150,6 +149,7 @@ describe('SyncPrivateLocationMonitorsTask', () => {
expect(mockSyntheticsMonitorClient.privateLocationAPI.editMonitors).not.toHaveBeenCalled();
expect(result.error).toBeUndefined();
expect(result.state).toEqual({
disableAutoSync: false,
hasAlreadyDoneCleanup: false,
lastStartedAt: expect.anything(),
lastTotalParams: 1,
Expand Down Expand Up @@ -190,6 +190,7 @@ describe('SyncPrivateLocationMonitorsTask', () => {
expect(task.syncGlobalParams).toHaveBeenCalled();
expect(result.error).toBeUndefined();
expect(result.state).toEqual({
disableAutoSync: false,
lastTotalParams: 1,
lastTotalMWs: 1,
maxCleanUpRetries: 2,
Expand Down Expand Up @@ -227,6 +228,7 @@ describe('SyncPrivateLocationMonitorsTask', () => {
);
expect(result.error).toBe(error);
expect(result.state).toEqual({
disableAutoSync: false,
lastStartedAt: expect.anything(),
lastTotalParams: 1,
lastTotalMWs: 1,
Expand Down Expand Up @@ -414,7 +416,6 @@ describe('SyncPrivateLocationMonitorsTask', () => {

await task.syncGlobalParams({
allPrivateLocations: mockAllPrivateLocations as any,
encryptedSavedObjects: mockEncryptedSoClient as any,
soClient: mockSoClient as any,
});

Expand Down Expand Up @@ -445,7 +446,6 @@ describe('SyncPrivateLocationMonitorsTask', () => {
await task.syncGlobalParams({
allPrivateLocations: [],
soClient: mockSoClient as any,
encryptedSavedObjects: mockEncryptedSoClient as any,
});

expect(mockSyntheticsMonitorClient.privateLocationAPI.editMonitors).not.toHaveBeenCalled();
Expand Down Expand Up @@ -506,7 +506,6 @@ describe('SyncPrivateLocationMonitorsTask', () => {
mockSoClient.createPointInTimeFinder = jest.fn().mockReturnValue(mockFinder);
task = new SyncPrivateLocationMonitorsTask(
mockServerSetup as any,
mockTaskManager as unknown as TaskManagerSetupContract,
mockSyntheticsMonitorClient as unknown as SyntheticsMonitorClient
);
});
Expand All @@ -519,10 +518,10 @@ describe('SyncPrivateLocationMonitorsTask', () => {
);
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, {} as any);
expect(mockFleet.packagePolicyService.delete).not.toHaveBeenCalled();
expect(result.performSync).toBe(false);
expect(result.performCleanupSync).toBe(false);
});

it('should delete unexpected policies and set performSync true', async () => {
it('should delete unexpected policies and set performCleanupSync true', async () => {
mockFleet.packagePolicyService.fetchAllItemIds.mockResolvedValue(
(async function* () {
yield ['monitor1-loc1-space1', 'unexpected-policy'];
Expand All @@ -535,30 +534,30 @@ describe('SyncPrivateLocationMonitorsTask', () => {
['unexpected-policy'],
{ force: true, spaceIds: ['*'] }
);
expect(result.performSync).toBe(true);
expect(result.performCleanupSync).toBe(true);
});

it('should set performSync true if expected policies are missing', async () => {
it('should set performCleanupSync true if expected policies are missing', async () => {
mockFleet.packagePolicyService.fetchAllItemIds.mockResolvedValue(
(async function* () {
yield [];
})()
);
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, {} as any);
expect(result.performSync).toBe(true);
expect(result.performCleanupSync).toBe(true);
});

it('should handle errors gracefully and return performSync', async () => {
it('should handle errors gracefully and return performCleanupSync', async () => {
mockFleet.packagePolicyService.fetchAllItemIds.mockRejectedValue(new Error('fail'));
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, {} as any);
expect(mockLogger.error).toHaveBeenCalled();
expect(result).toHaveProperty('performSync');
expect(result).toHaveProperty('performCleanupSync');
});

it('should skip cleanup if hasAlreadyDoneCleanup is true', async () => {
const state = { hasAlreadyDoneCleanup: true, maxCleanUpRetries: 3 };
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, state as any);
expect(result.performSync).toBe(false);
expect(result.performCleanupSync).toBe(false);
expect(mockLogger.debug).toHaveBeenCalledWith(
'[SyncPrivateLocationMonitorsTask] Skipping cleanup of duplicated package policies as it has already been done once'
);
Expand All @@ -567,7 +566,7 @@ describe('SyncPrivateLocationMonitorsTask', () => {
it('should skip cleanup if maxCleanUpRetries is 0 or less', async () => {
const state = { hasAlreadyDoneCleanup: false, maxCleanUpRetries: 0 };
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, state as any);
expect(result.performSync).toBe(false);
expect(result.performCleanupSync).toBe(false);
expect(state.hasAlreadyDoneCleanup).toBe(true);
expect(state.maxCleanUpRetries).toBe(3);
expect(mockLogger.debug).toHaveBeenCalledWith(
Expand All @@ -581,7 +580,7 @@ describe('SyncPrivateLocationMonitorsTask', () => {
const state = { hasAlreadyDoneCleanup: false, maxCleanUpRetries: 2 };
const result = await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, state as any);
expect(state.maxCleanUpRetries).toBe(1);
expect(result).toHaveProperty('performSync');
expect(result).toHaveProperty('performCleanupSync');
// Call again to reach 0
await task.cleanUpDuplicatedPackagePolicies(mockSoClient as any, state as any);
expect(state.hasAlreadyDoneCleanup).toBe(true);
Expand Down
Loading