Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Uptime] Settings public API #163400

Merged
merged 10 commits into from Oct 23, 2023
11 changes: 11 additions & 0 deletions docs/api/uptime-api.asciidoc
@@ -0,0 +1,11 @@
[[uptime-apis]]
== Uptime APIs

The following APIs are available for Uptime.

* <<get-settings-api, Get settings API>> to get a settings
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved

* <<update-settings-api, Update settings API>> to update the attributes for existing settings

include::uptime/get-settings.asciidoc[leveloffset=+1]
include::uptime/update-settings.asciidoc[leveloffset=+1]
39 changes: 39 additions & 0 deletions docs/api/uptime/get-settings.asciidoc
@@ -0,0 +1,39 @@
[[get-settings-api]]
== Get settings API
++++
<titleabbrev>Get settings</titleabbrev>
++++

Retrieve uptime settings existing settings.

[[get-settings-api-request]]
=== {api-request-title}

`GET <kibana host>:<port>/api/uptime/settings`

`GET <kibana host>:<port>/s/<space_id>/api/uptime/settings`

=== {api-prereq-title}

You must have `read` privileges for the *uptime* feature in *{observability}* section of the
<<kibana-feature-privileges,{kib} feature privileges>>.

The API returns the following:

[source,sh]
--------------------------------------------------
{
"heartbeatIndices": "heartbeat-8*",
"certExpirationThreshold": 30,
"certAgeThreshold": 730,
"defaultConnectors": [
"08990f40-09c5-11ee-97ae-912b222b13d4",
"db25f830-2318-11ee-9391-6b0c030836d6"
],
"defaultEmail": {
"to": [],
"cc": [],
"bcc": []
}
}
--------------------------------------------------
117 changes: 117 additions & 0 deletions docs/api/uptime/update-settings.asciidoc
@@ -0,0 +1,117 @@
[[update-settings-api]]
== Update settings API
++++
<titleabbrev>Update settings</titleabbrev>
++++

Updates uptime settings attributes like heartbeatIndices, certExpirationThreshold, certAgeThreshold, defaultConnectors or defaultEmail

=== {api-request-title}

`PUT <kibana host>:<port>/api/uptime/settings`

`PUT <kibana host>:<port>/s/<space_id>/api/uptime/settings`

=== {api-prereq-title}

You must have `all` privileges for the *uptime* feature in *{observability}* section of the
<<kibana-feature-privileges,{kib} feature privileges>>.

[[settings-api-update-path-params]]
==== Path parameters

`space_id`::
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.

[[api-update-request-body]]
==== Request body

A partial update is supported, provided settings keys will be merged with existing settings.

`heartbeatIndices`::
(Optional, string) index pattern string to be used within uptime app/alerts to query heartbeat data. Defaults to `heartbeat-*`.


`certExpirationThreshold`::
(Optional, number) Number of days before a certificate expires to trigger an alert. Defaults to `30`.

`certAgeThreshold`::
(Optional, number) Number of days after a certificate is created to trigger an alert. Defaults to `730`.

`defaultConnectors`::
(Optional, array) List of connector IDs to be used as default connectors for new alerts. Defaults to `[]`.

`defaultEmail`::
(Optional, object) Default email configuration for new alerts. Defaults to `{"to": [], "cc": [], "bcc": []}`.

[[settings-api-update-example]]
==== Example

[source,sh]
--------------------------------------------------
PUT api/uptime/settings
{
"heartbeatIndices": "heartbeat-8*",
"certExpirationThreshold": 30,
"certAgeThreshold": 730,
"defaultConnectors": [
"08990f40-09c5-11ee-97ae-912b222b13d4",
"db25f830-2318-11ee-9391-6b0c030836d6"
],
"defaultEmail": {
"to": [],
"cc": [],
"bcc": []
}
}
--------------------------------------------------

The API returns the following:

[source,json]
--------------------------------------------------
{
"heartbeatIndices": "heartbeat-8*",
"certExpirationThreshold": 30,
"certAgeThreshold": 730,
"defaultConnectors": [
"08990f40-09c5-11ee-97ae-912b222b13d4",
"db25f830-2318-11ee-9391-6b0c030836d6"
],
"defaultEmail": {
"to": [],
"cc": [],
"bcc": []
}
}
--------------------------------------------------
[[settings-api-partial-update-example]]
==== Partial update example

[source,sh]
--------------------------------------------------
PUT api/uptime/settings
{
"heartbeatIndices": "heartbeat-8*",
}
--------------------------------------------------

The API returns the following:

[source,json]
--------------------------------------------------
{
"heartbeatIndices": "heartbeat-8*",
"certExpirationThreshold": 30,
"certAgeThreshold": 730,
"defaultConnectors": [
"08990f40-09c5-11ee-97ae-912b222b13d4",
"db25f830-2318-11ee-9391-6b0c030836d6"
],
"defaultEmail": {
"to": [],
"cc": [],
"bcc": []
}
}
--------------------------------------------------
1 change: 1 addition & 0 deletions docs/user/api.asciidoc
Expand Up @@ -109,3 +109,4 @@ include::{kib-repo-dir}/api/osquery-manager.asciidoc[]
include::{kib-repo-dir}/api/short-urls.asciidoc[]
include::{kib-repo-dir}/api/task-manager/health.asciidoc[]
include::{kib-repo-dir}/api/upgrade-assistant.asciidoc[]
include::{kib-repo-dir}/api/uptime-api.asciidoc[]
Expand Up @@ -48,5 +48,5 @@ export enum SYNTHETICS_API_URLS {
SYNTHETICS_MONITORS_PROJECT_UPDATE = '/api/synthetics/project/{projectName}/monitors/_bulk_update',
SYNTHETICS_MONITORS_PROJECT_DELETE = '/api/synthetics/project/{projectName}/monitors/_bulk_delete',

DYNAMIC_SETTINGS = `/internal/uptime/dynamic_settings`,
DYNAMIC_SETTINGS = `/api/uptime/settings`,
}
Expand Up @@ -24,7 +24,6 @@ journey('OverviewScrolling', async ({ page, params }) => {
const listOfRequests: string[] = [];
const expected = [
'http://localhost:5620/internal/synthetics/service/enablement',
'http://localhost:5620/internal/uptime/dynamic_settings',
'http://localhost:5620/internal/synthetics/monitor/filters',
'http://localhost:5620/internal/uptime/service/locations',
'http://localhost:5620/internal/synthetics/overview?sortField=status&sortOrder=asc&',
Expand Down
Expand Up @@ -21,20 +21,29 @@ import {
import { SYNTHETICS_API_URLS } from '../../../../../common/constants';
import { LocationMonitor } from '.';

const apiPath = SYNTHETICS_API_URLS.DYNAMIC_SETTINGS;

interface SaveApiRequest {
settings: DynamicSettings;
}

export const getDynamicSettings = async (): Promise<DynamicSettings> => {
return await apiService.get(apiPath, undefined, DynamicSettingsCodec);
return await apiService.get(
SYNTHETICS_API_URLS.DYNAMIC_SETTINGS,
{ version: '2023-10-31' },
DynamicSettingsCodec
);
};

export const setDynamicSettings = async ({
settings,
}: SaveApiRequest): Promise<DynamicSettingsSaveResponse> => {
return await apiService.post(apiPath, settings, DynamicSettingsSaveCodec);
return await apiService.put(
SYNTHETICS_API_URLS.DYNAMIC_SETTINGS,
settings,
DynamicSettingsSaveCodec,
{
version: '2023-10-31',
}
);
};

export const fetchLocationMonitors = async (): Promise<LocationMonitor[]> => {
Expand Down
26 changes: 15 additions & 11 deletions x-pack/plugins/synthetics/public/utils/api_service/api_service.ts
Expand Up @@ -9,7 +9,7 @@ import { isRight } from 'fp-ts/lib/Either';
import { formatErrors } from '@kbn/securitysolution-io-ts-utils';
import { HttpFetchQuery, HttpSetup } from '@kbn/core/public';
import { FETCH_STATUS, AddInspectorRequest } from '@kbn/observability-shared-plugin/public';

type Params = HttpFetchQuery & { version?: string };
class ApiService {
private static instance: ApiService;
private _http!: HttpSetup;
Expand Down Expand Up @@ -59,39 +59,43 @@ class ApiService {
return response;
}

public async get<T>(
apiUrl: string,
params?: HttpFetchQuery,
decodeType?: any,
asResponse = false
) {
public async get<T>(apiUrl: string, params: Params = {}, decodeType?: any, asResponse = false) {
const { version, ...queryParams } = params;
const response = await this._http!.fetch<T>({
path: apiUrl,
query: params,
query: queryParams,
asResponse,
version,
});

this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false });

return this.parseResponse(response, apiUrl, decodeType);
}

public async post<T>(apiUrl: string, data?: any, decodeType?: any, params?: HttpFetchQuery) {
public async post<T>(apiUrl: string, data?: any, decodeType?: any, params: Params = {}) {
const { version, ...queryParams } = params;

const response = await this._http!.post<T>(apiUrl, {
method: 'POST',
body: JSON.stringify(data),
query: params,
query: queryParams,
version,
});

this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false });

return this.parseResponse(response, apiUrl, decodeType);
}

public async put<T>(apiUrl: string, data?: any, decodeType?: any) {
public async put<T>(apiUrl: string, data?: any, decodeType?: any, params: Params = {}) {
const { version, ...queryParams } = params;

const response = await this._http!.put<T>(apiUrl, {
method: 'PUT',
body: JSON.stringify(data),
query: queryParams,
version,
});

return this.parseResponse(response, apiUrl, decodeType);
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/uptime/common/constants/rest_api.ts
Expand Up @@ -6,7 +6,7 @@
*/

export enum API_URLS {
DYNAMIC_SETTINGS = `/internal/uptime/dynamic_settings`,
DYNAMIC_SETTINGS = `/api/uptime/settings`,
INDEX_STATUS = '/internal/uptime/index_status',
MONITOR_LIST = `/internal/uptime/monitor/list`,
MONITOR_LOCATIONS = `/internal/uptime/monitor/locations`,
Expand Down
Expand Up @@ -14,18 +14,22 @@ import {
import { apiService } from './utils';
import { API_URLS } from '../../../../common/constants';

const apiPath = API_URLS.DYNAMIC_SETTINGS;

interface SaveApiRequest {
settings: DynamicSettings;
}

export const getDynamicSettings = async (): Promise<DynamicSettings> => {
return await apiService.get(apiPath, undefined, DynamicSettingsCodec);
return await apiService.get(
API_URLS.DYNAMIC_SETTINGS,
{ version: '2023-10-31' },
DynamicSettingsCodec
);
};

export const setDynamicSettings = async ({
settings,
}: SaveApiRequest): Promise<DynamicSettingsSaveResponse> => {
return await apiService.post(apiPath, settings, DynamicSettingsSaveCodec);
return await apiService.put(API_URLS.DYNAMIC_SETTINGS, settings, DynamicSettingsSaveCodec, {
version: '2023-10-31',
});
};
Expand Up @@ -5,7 +5,11 @@
* 2.0.
*/

import { SavedObjectsErrorHelpers, SavedObjectsServiceSetup } from '@kbn/core/server';
import {
SavedObjectsClientContract,
SavedObjectsErrorHelpers,
SavedObjectsServiceSetup,
} from '@kbn/core/server';

import { DYNAMIC_SETTINGS_DEFAULT_ATTRIBUTES } from '../../../constants/settings';
import { DynamicSettingsAttributes } from '../../../runtime_types/settings';
Expand All @@ -20,7 +24,10 @@ export const registerUptimeSavedObjects = (savedObjectsService: SavedObjectsServ
export interface UMSavedObjectsAdapter {
config: UptimeConfig | null;
getUptimeDynamicSettings: UMSavedObjectsQueryFn<DynamicSettingsAttributes>;
setUptimeDynamicSettings: UMSavedObjectsQueryFn<void, DynamicSettingsAttributes>;
setUptimeDynamicSettings: (
client: SavedObjectsClientContract,
attr: DynamicSettingsAttributes
) => Promise<DynamicSettingsAttributes>;
}

export const savedObjectsAdapter: UMSavedObjectsAdapter = {
Expand All @@ -43,10 +50,15 @@ export const savedObjectsAdapter: UMSavedObjectsAdapter = {
throw getErr;
}
},
setUptimeDynamicSettings: async (client, settings: DynamicSettingsAttributes | undefined) => {
await client.create(umDynamicSettings.name, settings, {
id: settingsObjectId,
overwrite: true,
});
setUptimeDynamicSettings: async (client, settings: DynamicSettingsAttributes) => {
const newObj = await client.create<DynamicSettingsAttributes>(
umDynamicSettings.name,
settings,
{
id: settingsObjectId,
overwrite: true,
}
);
return newObj.attributes;
},
};