mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Uptime] UI Monitor Management - Add namespace field (#123248)
* Add namespace field to monitor management monitor form * Fix field id, add namespace validation and uptime-level default namespace constant * Namespace format validation and unit tests * Update integration test fixtures with namespace * Update validation to use util provided by fleet package * Reference locations from config enum * Fix namespace data for tests * [Uptime] Move monitor namespace field to advanced options section * Add advanced field rendering test * Add icmp advanced fields tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
110dc8b7cb
commit
d66a7bf255
30 changed files with 427 additions and 156 deletions
|
@ -13,3 +13,4 @@ export * from './settings_defaults';
|
|||
export { QUERY } from './query';
|
||||
export * from './ui';
|
||||
export * from './rest_api';
|
||||
export const DEFAULT_NAMESPACE_STRING = 'default';
|
||||
|
|
|
@ -20,6 +20,7 @@ export enum ConfigKey {
|
|||
METADATA = '__ui',
|
||||
MONITOR_TYPE = 'type',
|
||||
NAME = 'name',
|
||||
NAMESPACE = 'namespace',
|
||||
LOCATIONS = 'locations',
|
||||
PARAMS = 'params',
|
||||
PASSWORD = 'password',
|
||||
|
|
|
@ -50,6 +50,7 @@ export type ZipUrlTLSFields = t.TypeOf<typeof ZipUrlTLSFieldsCodec>;
|
|||
// CommonFields
|
||||
export const CommonFieldsCodec = t.interface({
|
||||
[ConfigKey.NAME]: t.string,
|
||||
[ConfigKey.NAMESPACE]: t.string,
|
||||
[ConfigKey.MONITOR_TYPE]: DataStreamCodec,
|
||||
[ConfigKey.ENABLED]: t.boolean,
|
||||
[ConfigKey.SCHEDULE]: Schedule,
|
||||
|
|
|
@ -8,5 +8,9 @@
|
|||
import { ConfigKey, MonitorFields } from '../runtime_types';
|
||||
|
||||
export type Validator = (config: Partial<MonitorFields>) => boolean;
|
||||
export type NamespaceValidator = (config: Partial<MonitorFields>) => false | string;
|
||||
|
||||
export type Validation = Partial<Record<ConfigKey, Validator>>;
|
||||
export type ConfigValidation = Omit<Record<ConfigKey, Validator>, ConfigKey.NAMESPACE> &
|
||||
Record<ConfigKey.NAMESPACE, NamespaceValidator>;
|
||||
|
||||
export type Validation = Partial<ConfigValidation>;
|
||||
|
|
|
@ -37,16 +37,18 @@ describe('<BrowserAdvancedFields />', () => {
|
|||
defaultValues = defaultConfig,
|
||||
defaultSimpleFields = defaultBrowserSimpleFields,
|
||||
validate = defaultValidation,
|
||||
children,
|
||||
}: {
|
||||
defaultValues?: BrowserAdvancedFieldsType;
|
||||
defaultSimpleFields?: BrowserSimpleFields;
|
||||
validate?: Validation;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<IntlProvider locale="en">
|
||||
<BrowserSimpleFieldsContextProvider defaultValues={defaultSimpleFields}>
|
||||
<BrowserAdvancedFieldsContextProvider defaultValues={defaultValues}>
|
||||
<BrowserAdvancedFields validate={validate} />
|
||||
<BrowserAdvancedFields validate={validate}>{children}</BrowserAdvancedFields>
|
||||
</BrowserAdvancedFieldsContextProvider>
|
||||
</BrowserSimpleFieldsContextProvider>
|
||||
</IntlProvider>
|
||||
|
@ -96,4 +98,12 @@ describe('<BrowserAdvancedFields />', () => {
|
|||
)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders upstream fields', () => {
|
||||
const upstreamFieldsText = 'Monitor Advanced field section';
|
||||
const { getByText } = render(<WrappedComponent>{upstreamFieldsText}</WrappedComponent>);
|
||||
|
||||
const upstream = getByText(upstreamFieldsText) as HTMLInputElement;
|
||||
expect(upstream).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -27,9 +27,10 @@ import { ThrottlingFields } from './throttling_fields';
|
|||
|
||||
interface Props {
|
||||
validate: Validation;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const BrowserAdvancedFields = memo<Props>(({ validate }) => {
|
||||
export const BrowserAdvancedFields = memo<Props>(({ validate, children }) => {
|
||||
const { fields, setFields } = useBrowserAdvancedFieldsContext();
|
||||
const { fields: simpleFields } = useBrowserSimpleFieldsContext();
|
||||
|
||||
|
@ -213,6 +214,7 @@ export const BrowserAdvancedFields = memo<Props>(({ validate }) => {
|
|||
</EuiDescribedFormGroup>
|
||||
|
||||
<ThrottlingFields validate={validate} />
|
||||
{children}
|
||||
</EuiAccordion>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants';
|
||||
import { CommonFields, ConfigKey, ScheduleUnit, DataStream } from '../types';
|
||||
|
||||
export const defaultValues: CommonFields = {
|
||||
|
@ -20,4 +21,5 @@ export const defaultValues: CommonFields = {
|
|||
[ConfigKey.TIMEOUT]: '16',
|
||||
[ConfigKey.NAME]: '',
|
||||
[ConfigKey.LOCATIONS]: [],
|
||||
[ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING,
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ export const commonFormatters: CommonFormatMap = {
|
|||
[ConfigKey.APM_SERVICE_NAME]: null,
|
||||
[ConfigKey.TAGS]: (fields) => arrayToJsonFormatter(fields[ConfigKey.TAGS]),
|
||||
[ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT]),
|
||||
[ConfigKey.NAMESPACE]: null,
|
||||
};
|
||||
|
||||
export const arrayToJsonFormatter = (value: string[] = []) =>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { CommonFields, ConfigKey } from '../types';
|
||||
import { NewPackagePolicyInput } from '../../../../../fleet/common';
|
||||
import { defaultValues as commonDefaultValues } from './default_values';
|
||||
import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants';
|
||||
|
||||
// TO DO: create a standard input format that all fields resolve to
|
||||
export type Normalizer = (fields: NewPackagePolicyInput['vars']) => unknown;
|
||||
|
@ -79,4 +80,6 @@ export const commonNormalizers: CommonNormalizerMap = {
|
|||
[ConfigKey.APM_SERVICE_NAME]: getCommonNormalizer(ConfigKey.APM_SERVICE_NAME),
|
||||
[ConfigKey.TAGS]: getCommonjsonToJavascriptNormalizer(ConfigKey.TAGS),
|
||||
[ConfigKey.TIMEOUT]: getCommonCronToSecondsNormalizer(ConfigKey.TIMEOUT),
|
||||
[ConfigKey.NAMESPACE]: (fields) =>
|
||||
fields?.[ConfigKey.NAMESPACE]?.value ?? DEFAULT_NAMESPACE_STRING,
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import React, { createContext, useContext, useMemo, useState } from 'react';
|
||||
import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants';
|
||||
import { ScheduleUnit, ServiceLocations } from '../../../../common/runtime_types';
|
||||
import { DataStream } from '../types';
|
||||
|
||||
|
@ -15,6 +16,7 @@ interface IPolicyConfigContext {
|
|||
setLocations: React.Dispatch<React.SetStateAction<ServiceLocations>>;
|
||||
setIsTLSEnabled: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setIsZipUrlTLSEnabled: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setNamespace: React.Dispatch<React.SetStateAction<string>>;
|
||||
monitorType: DataStream;
|
||||
defaultMonitorType: DataStream;
|
||||
isTLSEnabled?: boolean;
|
||||
|
@ -28,6 +30,8 @@ interface IPolicyConfigContext {
|
|||
defaultLocations?: ServiceLocations;
|
||||
locations?: ServiceLocations;
|
||||
allowedScheduleUnits?: ScheduleUnit[];
|
||||
defaultNamespace?: string;
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface IPolicyConfigContextProvider {
|
||||
|
@ -37,6 +41,7 @@ export interface IPolicyConfigContextProvider {
|
|||
defaultIsZipUrlTLSEnabled?: boolean;
|
||||
defaultName?: string;
|
||||
defaultLocations?: ServiceLocations;
|
||||
defaultNamespace?: string;
|
||||
isEditable?: boolean;
|
||||
isZipUrlSourceEnabled?: boolean;
|
||||
allowedScheduleUnits?: ScheduleUnit[];
|
||||
|
@ -62,6 +67,9 @@ const defaultContext: IPolicyConfigContext = {
|
|||
'setIsZipUrlTLSEnabled was not initialized, set it when you invoke the context'
|
||||
);
|
||||
},
|
||||
setNamespace: (_namespace: React.SetStateAction<string>) => {
|
||||
throw new Error('setNamespace was not initialized, set it when you invoke the context');
|
||||
},
|
||||
monitorType: initialValue, // mutable
|
||||
defaultMonitorType: initialValue, // immutable,
|
||||
defaultIsTLSEnabled: false,
|
||||
|
@ -71,6 +79,7 @@ const defaultContext: IPolicyConfigContext = {
|
|||
isEditable: false,
|
||||
isZipUrlSourceEnabled: true,
|
||||
allowedScheduleUnits: [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS],
|
||||
defaultNamespace: DEFAULT_NAMESPACE_STRING,
|
||||
};
|
||||
|
||||
export const PolicyConfigContext = createContext(defaultContext);
|
||||
|
@ -82,6 +91,7 @@ export function PolicyConfigContextProvider<ExtraFields = unknown>({
|
|||
defaultIsZipUrlTLSEnabled = false,
|
||||
defaultName = '',
|
||||
defaultLocations = [],
|
||||
defaultNamespace = DEFAULT_NAMESPACE_STRING,
|
||||
isEditable = false,
|
||||
isZipUrlSourceEnabled = true,
|
||||
allowedScheduleUnits = [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS],
|
||||
|
@ -91,6 +101,7 @@ export function PolicyConfigContextProvider<ExtraFields = unknown>({
|
|||
const [locations, setLocations] = useState<ServiceLocations>(defaultLocations);
|
||||
const [isTLSEnabled, setIsTLSEnabled] = useState<boolean>(defaultIsTLSEnabled);
|
||||
const [isZipUrlTLSEnabled, setIsZipUrlTLSEnabled] = useState<boolean>(defaultIsZipUrlTLSEnabled);
|
||||
const [namespace, setNamespace] = useState<string>(defaultNamespace);
|
||||
|
||||
const value = useMemo(() => {
|
||||
return {
|
||||
|
@ -112,6 +123,8 @@ export function PolicyConfigContextProvider<ExtraFields = unknown>({
|
|||
setLocations,
|
||||
isZipUrlSourceEnabled,
|
||||
allowedScheduleUnits,
|
||||
namespace,
|
||||
setNamespace,
|
||||
} as IPolicyConfigContext;
|
||||
}, [
|
||||
monitorType,
|
||||
|
@ -127,6 +140,7 @@ export function PolicyConfigContextProvider<ExtraFields = unknown>({
|
|||
locations,
|
||||
defaultLocations,
|
||||
allowedScheduleUnits,
|
||||
namespace,
|
||||
]);
|
||||
|
||||
return <PolicyConfigContext.Provider value={value} children={children} />;
|
||||
|
|
|
@ -29,11 +29,13 @@ import { TCPAdvancedFields } from './tcp/advanced_fields';
|
|||
import { ICMPSimpleFields } from './icmp/simple_fields';
|
||||
import { BrowserSimpleFields } from './browser/simple_fields';
|
||||
import { BrowserAdvancedFields } from './browser/advanced_fields';
|
||||
import { ICMPAdvancedFields } from './icmp/advanced_fields';
|
||||
|
||||
interface Props {
|
||||
validate: Validation;
|
||||
dataStreams?: DataStream[];
|
||||
children?: React.ReactNode;
|
||||
appendAdvancedFields?: React.ReactNode;
|
||||
}
|
||||
|
||||
const dataStreamToString = [
|
||||
|
@ -51,154 +53,162 @@ const dataStreamToString = [
|
|||
},
|
||||
];
|
||||
|
||||
export const CustomFields = memo<Props>(({ validate, dataStreams = [], children }) => {
|
||||
const { monitorType, setMonitorType, isTLSEnabled, setIsTLSEnabled, isEditable } =
|
||||
usePolicyConfigContext();
|
||||
export const CustomFields = memo<Props>(
|
||||
({ validate, dataStreams = [], children, appendAdvancedFields }) => {
|
||||
const { monitorType, setMonitorType, isTLSEnabled, setIsTLSEnabled, isEditable } =
|
||||
usePolicyConfigContext();
|
||||
|
||||
const isHTTP = monitorType === DataStream.HTTP;
|
||||
const isTCP = monitorType === DataStream.TCP;
|
||||
const isBrowser = monitorType === DataStream.BROWSER;
|
||||
const isHTTP = monitorType === DataStream.HTTP;
|
||||
const isTCP = monitorType === DataStream.TCP;
|
||||
const isBrowser = monitorType === DataStream.BROWSER;
|
||||
const isICMP = monitorType === DataStream.ICMP;
|
||||
|
||||
const dataStreamOptions = useMemo(() => {
|
||||
return dataStreamToString.filter((dataStream) => dataStreams.includes(dataStream.value));
|
||||
}, [dataStreams]);
|
||||
const dataStreamOptions = useMemo(() => {
|
||||
return dataStreamToString.filter((dataStream) => dataStreams.includes(dataStream.value));
|
||||
}, [dataStreams]);
|
||||
|
||||
const renderSimpleFields = (type: DataStream) => {
|
||||
switch (type) {
|
||||
case DataStream.HTTP:
|
||||
return <HTTPSimpleFields validate={validate} />;
|
||||
case DataStream.ICMP:
|
||||
return <ICMPSimpleFields validate={validate} />;
|
||||
case DataStream.TCP:
|
||||
return <TCPSimpleFields validate={validate} />;
|
||||
case DataStream.BROWSER:
|
||||
return <BrowserSimpleFields validate={validate} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const renderSimpleFields = (type: DataStream) => {
|
||||
switch (type) {
|
||||
case DataStream.HTTP:
|
||||
return <HTTPSimpleFields validate={validate} />;
|
||||
case DataStream.ICMP:
|
||||
return <ICMPSimpleFields validate={validate} />;
|
||||
case DataStream.TCP:
|
||||
return <TCPSimpleFields validate={validate} />;
|
||||
case DataStream.BROWSER:
|
||||
return <BrowserSimpleFields validate={validate} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const isWithInUptime = window.location.pathname.includes('/app/uptime');
|
||||
const isWithInUptime = window.location.pathname.includes('/app/uptime');
|
||||
|
||||
return (
|
||||
<EuiForm component="form">
|
||||
<EuiDescribedFormGroup
|
||||
title={
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle"
|
||||
defaultMessage="Monitor settings"
|
||||
/>
|
||||
</h4>
|
||||
}
|
||||
description={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription"
|
||||
defaultMessage="Configure your monitor with the following options."
|
||||
/>
|
||||
}
|
||||
data-test-subj="monitorSettingsSection"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
{children}
|
||||
{!isEditable && (
|
||||
<EuiFormRow
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType"
|
||||
defaultMessage="Monitor Type"
|
||||
/>
|
||||
}
|
||||
isInvalid={
|
||||
!!validate[ConfigKey.MONITOR_TYPE]?.({
|
||||
[ConfigKey.MONITOR_TYPE]: monitorType as DataStream,
|
||||
})
|
||||
}
|
||||
error={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error"
|
||||
defaultMessage="Monitor type is required"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiSelect
|
||||
options={dataStreamOptions}
|
||||
value={monitorType}
|
||||
onChange={(event) => setMonitorType(event.target.value as DataStream)}
|
||||
data-test-subj="syntheticsMonitorTypeField"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
{isBrowser && !isWithInUptime && (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description"
|
||||
defaultMessage='To create a "Browser" monitor, please ensure you are using the elastic-agent-complete Docker container, which contains the dependencies to run these monitors. For more information, please visit our {link}.'
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
target="_blank"
|
||||
href="https://www.elastic.co/guide/en/observability/current/synthetics-quickstart-fleet.html"
|
||||
external
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link"
|
||||
defaultMessage="synthetics documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
}
|
||||
iconType="help"
|
||||
size="s"
|
||||
/>
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
{renderSimpleFields(monitorType)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiDescribedFormGroup>
|
||||
{(isHTTP || isTCP) && (
|
||||
return (
|
||||
<EuiForm component="form">
|
||||
<EuiDescribedFormGroup
|
||||
title={
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label"
|
||||
defaultMessage="TLS settings"
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle"
|
||||
defaultMessage="Monitor settings"
|
||||
/>
|
||||
</h4>
|
||||
}
|
||||
description={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.description"
|
||||
defaultMessage="Configure TLS options, including verification mode, certificate authorities, and client certificates."
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription"
|
||||
defaultMessage="Configure your monitor with the following options."
|
||||
/>
|
||||
}
|
||||
id="uptimeFleetIsTLSEnabled"
|
||||
data-test-subj="monitorSettingsSection"
|
||||
>
|
||||
<EuiSwitch
|
||||
id="uptimeFleetIsTLSEnabled"
|
||||
data-test-subj="syntheticsIsTLSEnabled"
|
||||
checked={!!isTLSEnabled}
|
||||
label={
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
{children}
|
||||
{!isEditable && (
|
||||
<EuiFormRow
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType"
|
||||
defaultMessage="Monitor Type"
|
||||
/>
|
||||
}
|
||||
isInvalid={
|
||||
!!validate[ConfigKey.MONITOR_TYPE]?.({
|
||||
[ConfigKey.MONITOR_TYPE]: monitorType as DataStream,
|
||||
})
|
||||
}
|
||||
error={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error"
|
||||
defaultMessage="Monitor type is required"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiSelect
|
||||
options={dataStreamOptions}
|
||||
value={monitorType}
|
||||
onChange={(event) => setMonitorType(event.target.value as DataStream)}
|
||||
data-test-subj="syntheticsMonitorTypeField"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
{isBrowser && !isWithInUptime && (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description"
|
||||
defaultMessage='To create a "Browser" monitor, please ensure you are using the elastic-agent-complete Docker container, which contains the dependencies to run these monitors. For more information, please visit our {link}.'
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
target="_blank"
|
||||
href="https://www.elastic.co/guide/en/observability/current/synthetics-quickstart-fleet.html"
|
||||
external
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link"
|
||||
defaultMessage="synthetics documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
}
|
||||
iconType="help"
|
||||
size="s"
|
||||
/>
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
{renderSimpleFields(monitorType)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiDescribedFormGroup>
|
||||
{(isHTTP || isTCP) && (
|
||||
<EuiDescribedFormGroup
|
||||
title={
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label"
|
||||
defaultMessage="TLS settings"
|
||||
/>
|
||||
</h4>
|
||||
}
|
||||
description={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label"
|
||||
defaultMessage="Enable TLS configuration"
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.description"
|
||||
defaultMessage="Configure TLS options, including verification mode, certificate authorities, and client certificates."
|
||||
/>
|
||||
}
|
||||
onChange={(event) => setIsTLSEnabled(event.target.checked)}
|
||||
/>
|
||||
<TLSFields />
|
||||
</EuiDescribedFormGroup>
|
||||
)}
|
||||
<EuiSpacer size="m" />
|
||||
{isHTTP && <HTTPAdvancedFields validate={validate} />}
|
||||
{isTCP && <TCPAdvancedFields />}
|
||||
{isBrowser && <BrowserAdvancedFields validate={validate} />}
|
||||
</EuiForm>
|
||||
);
|
||||
});
|
||||
id="uptimeFleetIsTLSEnabled"
|
||||
>
|
||||
<EuiSwitch
|
||||
id="uptimeFleetIsTLSEnabled"
|
||||
data-test-subj="syntheticsIsTLSEnabled"
|
||||
checked={!!isTLSEnabled}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label"
|
||||
defaultMessage="Enable TLS configuration"
|
||||
/>
|
||||
}
|
||||
onChange={(event) => setIsTLSEnabled(event.target.checked)}
|
||||
/>
|
||||
<TLSFields />
|
||||
</EuiDescribedFormGroup>
|
||||
)}
|
||||
<EuiSpacer size="m" />
|
||||
{isHTTP && (
|
||||
<HTTPAdvancedFields validate={validate}>{appendAdvancedFields}</HTTPAdvancedFields>
|
||||
)}
|
||||
{isTCP && <TCPAdvancedFields>{appendAdvancedFields}</TCPAdvancedFields>}
|
||||
{isBrowser && (
|
||||
<BrowserAdvancedFields validate={validate}>{appendAdvancedFields}</BrowserAdvancedFields>
|
||||
)}
|
||||
{isICMP && <ICMPAdvancedFields>{appendAdvancedFields}</ICMPAdvancedFields>}
|
||||
</EuiForm>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -60,6 +60,7 @@ export const usePolicy = (fleetPolicyName: string = '') => {
|
|||
isZipUrlTLSEnabled,
|
||||
name: monitorName, // the monitor name can come from two different places, either from fleet or from uptime
|
||||
locations,
|
||||
namespace,
|
||||
} = usePolicyConfigContext();
|
||||
const { fields: httpSimpleFields } = useHTTPSimpleFieldsContext();
|
||||
const { fields: tcpSimpleFields } = useTCPSimpleFieldsContext();
|
||||
|
@ -91,6 +92,7 @@ export const usePolicy = (fleetPolicyName: string = '') => {
|
|||
},
|
||||
[ConfigKey.NAME]: fleetPolicyName || monitorName,
|
||||
[ConfigKey.LOCATIONS]: locations,
|
||||
[ConfigKey.NAMESPACE]: namespace,
|
||||
} as HTTPFields,
|
||||
[DataStream.TCP]: {
|
||||
...tcpSimpleFields,
|
||||
|
@ -102,11 +104,13 @@ export const usePolicy = (fleetPolicyName: string = '') => {
|
|||
},
|
||||
[ConfigKey.NAME]: fleetPolicyName || monitorName,
|
||||
[ConfigKey.LOCATIONS]: locations,
|
||||
[ConfigKey.NAMESPACE]: namespace,
|
||||
} as TCPFields,
|
||||
[DataStream.ICMP]: {
|
||||
...icmpSimpleFields,
|
||||
[ConfigKey.NAME]: fleetPolicyName || monitorName,
|
||||
[ConfigKey.LOCATIONS]: locations,
|
||||
[ConfigKey.NAMESPACE]: namespace,
|
||||
} as ICMPFields,
|
||||
[DataStream.BROWSER]: {
|
||||
...browserSimpleFields,
|
||||
|
@ -117,6 +121,7 @@ export const usePolicy = (fleetPolicyName: string = '') => {
|
|||
},
|
||||
[ConfigKey.NAME]: fleetPolicyName || monitorName,
|
||||
[ConfigKey.LOCATIONS]: locations,
|
||||
[ConfigKey.NAMESPACE]: namespace,
|
||||
} as BrowserFields,
|
||||
}),
|
||||
[
|
||||
|
@ -132,6 +137,7 @@ export const usePolicy = (fleetPolicyName: string = '') => {
|
|||
fleetPolicyName,
|
||||
monitorName,
|
||||
locations,
|
||||
namespace,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -49,13 +49,15 @@ describe('<HTTPAdvancedFields />', () => {
|
|||
const WrappedComponent = ({
|
||||
defaultValues,
|
||||
validate = defaultValidation,
|
||||
children,
|
||||
}: {
|
||||
defaultValues?: HTTPAdvancedFieldsType;
|
||||
validate?: Validation;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<HTTPAdvancedFieldsContextProvider defaultValues={defaultValues}>
|
||||
<HTTPAdvancedFields validate={validate} />
|
||||
<HTTPAdvancedFields validate={validate}>{children}</HTTPAdvancedFields>
|
||||
</HTTPAdvancedFieldsContextProvider>
|
||||
);
|
||||
};
|
||||
|
@ -126,4 +128,12 @@ describe('<HTTPAdvancedFields />', () => {
|
|||
expect(indexResponseBody.checked).toBe(false);
|
||||
expect(indexResponseHeaders.checked).toBe(false);
|
||||
});
|
||||
|
||||
it('renders upstream fields', () => {
|
||||
const upstreamFieldsText = 'Monitor Advanced field section';
|
||||
const { getByText } = render(<WrappedComponent>{upstreamFieldsText}</WrappedComponent>);
|
||||
|
||||
const upstream = getByText(upstreamFieldsText) as HTMLInputElement;
|
||||
expect(upstream).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,9 +32,10 @@ import { ComboBox } from '../combo_box';
|
|||
|
||||
interface Props {
|
||||
validate: Validation;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const HTTPAdvancedFields = memo<Props>(({ validate }) => {
|
||||
export const HTTPAdvancedFields = memo<Props>(({ validate, children }) => {
|
||||
const { fields, setFields } = useHTTPAdvancedFieldsContext();
|
||||
const handleInputChange = useCallback(
|
||||
({ value, configKey }: { value: unknown; configKey: ConfigKey }) => {
|
||||
|
@ -461,6 +462,7 @@ export const HTTPAdvancedFields = memo<Props>(({ validate }) => {
|
|||
/>
|
||||
</EuiFormRow>
|
||||
</EuiDescribedFormGroup>
|
||||
{children}
|
||||
</EuiAccordion>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { render } from '../../../lib/helper/rtl_helpers';
|
||||
import { ICMPAdvancedFields } from './advanced_fields';
|
||||
|
||||
// ensures fields and labels map appropriately
|
||||
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||
htmlIdGenerator: () => () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
||||
describe('<ICMPAdvancedFields />', () => {
|
||||
const WrappedComponent = ({ children }: { children?: React.ReactNode }) => (
|
||||
<ICMPAdvancedFields>{children}</ICMPAdvancedFields>
|
||||
);
|
||||
|
||||
it('renders upstream fields', () => {
|
||||
const upstreamFieldsText = 'Monitor Advanced field section';
|
||||
const { getByText, getByTestId } = render(
|
||||
<WrappedComponent>{upstreamFieldsText}</WrappedComponent>
|
||||
);
|
||||
|
||||
const upstream = getByText(upstreamFieldsText) as HTMLInputElement;
|
||||
const accordion = getByTestId('syntheticsICMPAdvancedFieldsAccordion') as HTMLInputElement;
|
||||
expect(upstream).toBeInTheDocument();
|
||||
expect(accordion).toBeInTheDocument();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 { EuiAccordion, EuiSpacer } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
export const ICMPAdvancedFields = ({ children }: { children?: React.ReactNode }) => {
|
||||
if (!!children) {
|
||||
return (
|
||||
<EuiAccordion
|
||||
id="uptimeFleetIcmpAdvancedOptions"
|
||||
buttonContent={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.createPackagePolicy.stepConfigure.icmpAdvancedOptions"
|
||||
defaultMessage="Advanced ICMP options"
|
||||
/>
|
||||
}
|
||||
data-test-subj="syntheticsICMPAdvancedFieldsAccordion"
|
||||
>
|
||||
<EuiSpacer size="xl" />
|
||||
{children}
|
||||
</EuiAccordion>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
};
|
|
@ -23,12 +23,14 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
|||
describe('<TCPAdvancedFields />', () => {
|
||||
const WrappedComponent = ({
|
||||
defaultValues = defaultConfig,
|
||||
children,
|
||||
}: {
|
||||
defaultValues?: TCPAdvancedFieldsType;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<TCPAdvancedFieldsContextProvider defaultValues={defaultValues}>
|
||||
<TCPAdvancedFields />
|
||||
<TCPAdvancedFields>{children}</TCPAdvancedFields>
|
||||
</TCPAdvancedFieldsContextProvider>
|
||||
);
|
||||
};
|
||||
|
@ -68,4 +70,12 @@ describe('<TCPAdvancedFields />', () => {
|
|||
|
||||
expect(getByLabelText('Resolve hostnames locally')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders upstream fields', () => {
|
||||
const upstreamFieldsText = 'Monitor Advanced field section';
|
||||
const { getByText } = render(<WrappedComponent>{upstreamFieldsText}</WrappedComponent>);
|
||||
|
||||
const upstream = getByText(upstreamFieldsText) as HTMLInputElement;
|
||||
expect(upstream).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
EuiAccordion,
|
||||
|
@ -22,7 +22,11 @@ import { ConfigKey } from '../types';
|
|||
|
||||
import { OptionalLabel } from '../optional_label';
|
||||
|
||||
export const TCPAdvancedFields = () => {
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const TCPAdvancedFields = memo<Props>(({ children }) => {
|
||||
const { fields, setFields } = useTCPAdvancedFieldsContext();
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
|
@ -176,6 +180,7 @@ export const TCPAdvancedFields = () => {
|
|||
/>
|
||||
</EuiFormRow>
|
||||
</EuiDescribedFormGroup>
|
||||
{children}
|
||||
</EuiAccordion>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@ import { useTrackPageview } from '../../../../observability/public';
|
|||
import { SyntheticsProviders } from '../fleet_package/contexts';
|
||||
import { PolicyConfig } from '../fleet_package/types';
|
||||
import { MonitorConfig } from './monitor_config/monitor_config';
|
||||
import { DEFAULT_NAMESPACE_STRING } from '../../../common/constants';
|
||||
|
||||
interface Props {
|
||||
monitor: MonitorFields;
|
||||
|
@ -74,8 +75,9 @@ export const EditMonitorConfig = ({ monitor }: Props) => {
|
|||
defaultIsTLSEnabled: isTLSEnabled,
|
||||
defaultIsZipUrlTLSEnabled: isZipUrlTLSEnabled,
|
||||
defaultMonitorType: monitorType,
|
||||
defaultName: defaultConfig?.name || '', // TODO - figure out typing concerns for name
|
||||
defaultLocations: defaultConfig.locations,
|
||||
defaultName: defaultConfig?.[ConfigKey.NAME] || '', // TODO - figure out typing concerns for name
|
||||
defaultNamespace: defaultConfig?.[ConfigKey.NAMESPACE] || DEFAULT_NAMESPACE_STRING,
|
||||
defaultLocations: defaultConfig[ConfigKey.LOCATIONS],
|
||||
isEditable: true,
|
||||
isZipUrlSourceEnabled: false,
|
||||
allowedScheduleUnits: [ScheduleUnit.MINUTES],
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 React, { memo } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiFormRow, EuiSpacer, EuiDescribedFormGroup, EuiLink, EuiFieldText } from '@elastic/eui';
|
||||
import type { Validation } from '../../../../common/types/index';
|
||||
import { ConfigKey } from '../../../../common/runtime_types/monitor_management';
|
||||
import { usePolicyConfigContext } from '../../fleet_package/contexts';
|
||||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
interface Props {
|
||||
validate: Validation;
|
||||
}
|
||||
|
||||
export const MonitorManagementAdvancedFields = memo<Props>(({ validate }) => {
|
||||
const { namespace, setNamespace } = usePolicyConfigContext();
|
||||
|
||||
const namespaceErrorMsg = validate[ConfigKey.NAMESPACE]?.({
|
||||
[ConfigKey.NAMESPACE]: namespace,
|
||||
});
|
||||
const isNamespaceInvalid = !!namespaceErrorMsg;
|
||||
const { services } = useKibana();
|
||||
|
||||
return (
|
||||
<EuiDescribedFormGroup
|
||||
title={
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title"
|
||||
defaultMessage="Data stream settings"
|
||||
/>
|
||||
</h4>
|
||||
}
|
||||
description={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description"
|
||||
defaultMessage="Configure additional Data Stream options."
|
||||
/>
|
||||
}
|
||||
data-test-subj="monitorAdvancedFieldsSection"
|
||||
>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFormRow
|
||||
isInvalid={isNamespaceInvalid}
|
||||
error={namespaceErrorMsg}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel"
|
||||
defaultMessage="Namespace"
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel"
|
||||
defaultMessage="Change the default namespace. This setting changes the name of the monitor's data stream. {learnMore}."
|
||||
values={{
|
||||
learnMore: (
|
||||
<EuiLink
|
||||
target="_blank"
|
||||
href={services.docLinks?.links?.fleet?.datastreamsNamingScheme}
|
||||
external
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel"
|
||||
defaultMessage="Learn More"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFieldText
|
||||
defaultValue={namespace}
|
||||
onChange={(event) => setNamespace(event.target.value)}
|
||||
required={true}
|
||||
isInvalid={isNamespaceInvalid}
|
||||
fullWidth={true}
|
||||
name="namespace"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiDescribedFormGroup>
|
||||
);
|
||||
});
|
|
@ -13,6 +13,7 @@ import { usePolicyConfigContext } from '../../fleet_package/contexts';
|
|||
import { CustomFields } from '../../fleet_package/custom_fields';
|
||||
import { validate } from '../validation';
|
||||
import { MonitorNameAndLocation } from './monitor_name_location';
|
||||
import { MonitorManagementAdvancedFields } from './monitor_advanced_fields';
|
||||
|
||||
export const MonitorFields = () => {
|
||||
const { monitorType } = usePolicyConfigContext();
|
||||
|
@ -21,6 +22,7 @@ export const MonitorFields = () => {
|
|||
<CustomFields
|
||||
validate={validate[monitorType]}
|
||||
dataStreams={[DataStream.HTTP, DataStream.TCP, DataStream.ICMP, DataStream.BROWSER]}
|
||||
appendAdvancedFields={<MonitorManagementAdvancedFields validate={validate[monitorType]} />}
|
||||
>
|
||||
<MonitorNameAndLocation validate={validate[monitorType]} />
|
||||
</CustomFields>
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
ScheduleUnit,
|
||||
ServiceLocations,
|
||||
} from '../../../common/runtime_types';
|
||||
import { validate } from './validation';
|
||||
import { validate, validateCommon } from './validation';
|
||||
|
||||
describe('[Monitor Management] validation', () => {
|
||||
const commonPropsValid: Partial<MonitorFields> = {
|
||||
|
@ -27,8 +27,29 @@ describe('[Monitor Management] validation', () => {
|
|||
label: 'EU West',
|
||||
},
|
||||
] as ServiceLocations,
|
||||
[ConfigKey.NAME]: 'test-name',
|
||||
[ConfigKey.NAMESPACE]: 'namespace',
|
||||
};
|
||||
|
||||
describe('Common monitor fields', () => {
|
||||
it('should return false for all valid props', () => {
|
||||
const result = Object.values(validateCommon).map((validator) => {
|
||||
return validator ? validator(commonPropsValid) : true;
|
||||
});
|
||||
|
||||
expect(result.reduce((previous, current) => previous || current)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should invalidate on invalid namespace', () => {
|
||||
const validatorFn = validateCommon[ConfigKey.NAMESPACE];
|
||||
const result = [undefined, null, '', '*/&<>:', 'A', 'a'.repeat(101)].map((testValue) =>
|
||||
validatorFn?.({ [ConfigKey.NAMESPACE]: testValue } as Partial<MonitorFields>)
|
||||
);
|
||||
|
||||
expect(result.reduce((previous, current) => previous && current)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('HTTP', () => {
|
||||
const httpPropsValid: Partial<HTTPFields> = {
|
||||
...commonPropsValid,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { isValidNamespace } from '../../../../fleet/common';
|
||||
import {
|
||||
ConfigKey,
|
||||
DataStream,
|
||||
|
@ -11,13 +12,11 @@ import {
|
|||
MonitorFields,
|
||||
isServiceLocationInvalid,
|
||||
} from '../../../common/runtime_types';
|
||||
import { Validation, Validator } from '../../../common/types';
|
||||
import { Validation } from '../../../common/types';
|
||||
|
||||
export const digitsOnly = /^[0-9]*$/g;
|
||||
export const includesValidPort = /[^\:]+:[0-9]{1,5}$/g;
|
||||
|
||||
type ValidationLibrary = Record<string, Validator>;
|
||||
|
||||
// returns true if invalid
|
||||
function validateHeaders<T>(headers: T): boolean {
|
||||
return Object.keys(headers).some((key) => {
|
||||
|
@ -56,7 +55,7 @@ const validateTimeout = ({
|
|||
};
|
||||
|
||||
// validation functions return true when invalid
|
||||
const validateCommon: ValidationLibrary = {
|
||||
export const validateCommon: Validation = {
|
||||
[ConfigKey.NAME]: ({ [ConfigKey.NAME]: value }) => {
|
||||
return !value || typeof value !== 'string';
|
||||
},
|
||||
|
@ -83,9 +82,13 @@ const validateCommon: ValidationLibrary = {
|
|||
!Array.isArray(locations) || locations.length < 1 || locations.some(isServiceLocationInvalid)
|
||||
);
|
||||
},
|
||||
[ConfigKey.NAMESPACE]: ({ [ConfigKey.NAMESPACE]: value }) => {
|
||||
const { error = '', valid } = isValidNamespace(value ?? '');
|
||||
return valid ? false : error;
|
||||
},
|
||||
};
|
||||
|
||||
const validateHTTP: ValidationLibrary = {
|
||||
const validateHTTP: Validation = {
|
||||
[ConfigKey.RESPONSE_STATUS_CHECK]: ({ [ConfigKey.RESPONSE_STATUS_CHECK]: value }) => {
|
||||
const statusCodes = value as MonitorFields[ConfigKey.RESPONSE_STATUS_CHECK];
|
||||
return statusCodes.length ? statusCodes.some((code) => !`${code}`.match(digitsOnly)) : false;
|
||||
|
@ -105,14 +108,14 @@ const validateHTTP: ValidationLibrary = {
|
|||
...validateCommon,
|
||||
};
|
||||
|
||||
const validateTCP: Record<string, Validator> = {
|
||||
const validateTCP: Validation = {
|
||||
[ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => {
|
||||
return !value || !`${value}`.match(includesValidPort);
|
||||
},
|
||||
...validateCommon,
|
||||
};
|
||||
|
||||
const validateICMP: ValidationLibrary = {
|
||||
const validateICMP: Validation = {
|
||||
[ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => !value,
|
||||
[ConfigKey.WAIT]: ({ [ConfigKey.WAIT]: value }) =>
|
||||
!!value &&
|
||||
|
@ -127,7 +130,7 @@ const validateThrottleValue = (speed: string | undefined, allowZero?: boolean) =
|
|||
return isNaN(throttleValue) || (allowZero ? throttleValue < 0 : throttleValue <= 0);
|
||||
};
|
||||
|
||||
const validateBrowser: ValidationLibrary = {
|
||||
const validateBrowser: Validation = {
|
||||
...validateCommon,
|
||||
[ConfigKey.SOURCE_ZIP_URL]: ({
|
||||
[ConfigKey.SOURCE_ZIP_URL]: zipUrl,
|
||||
|
|
|
@ -24,6 +24,7 @@ export const commonFormatters: CommonFormatMap = {
|
|||
[ConfigKey.APM_SERVICE_NAME]: null,
|
||||
[ConfigKey.TAGS]: (fields) => arrayFormatter(fields[ConfigKey.TAGS]),
|
||||
[ConfigKey.TIMEOUT]: (fields) => secondsToCronFormatter(fields[ConfigKey.TIMEOUT]),
|
||||
[ConfigKey.NAMESPACE]: null,
|
||||
};
|
||||
|
||||
export const arrayFormatter = (value: string[] = []) => (value.length ? value : null);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants';
|
||||
import { DataStream, MonitorFields } from '../../../../common/runtime_types';
|
||||
|
||||
interface DataStreamConfig {
|
||||
|
@ -33,7 +34,7 @@ export function convertToDataStreamFormat(monitor: Record<string, any>): DataStr
|
|||
schedule: monitor.schedule,
|
||||
enabled: monitor.enabled ?? true,
|
||||
data_stream: {
|
||||
namespace: monitor.namespace ?? 'default',
|
||||
namespace: monitor.namespace ?? DEFAULT_NAMESPACE_STRING,
|
||||
},
|
||||
streams: [
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ describe('validateMonitor', () => {
|
|||
url: 'https://test-url.com',
|
||||
},
|
||||
],
|
||||
[ConfigKey.NAMESPACE]: 'testnamespace',
|
||||
};
|
||||
testMetaData = {
|
||||
is_tls_enabled: false,
|
||||
|
@ -425,6 +426,7 @@ function getJsonPayload() {
|
|||
' "TLSv1.2"' +
|
||||
' ],' +
|
||||
' "name": "test-monitor-name",' +
|
||||
' "namespace": "testnamespace",' +
|
||||
' "locations": [{' +
|
||||
' "id": "eu-west-01",' +
|
||||
' "label": "Europe West",' +
|
||||
|
|
|
@ -37,5 +37,6 @@
|
|||
"throttling.latency": "20",
|
||||
"throttling.config": "5d/3u/20l",
|
||||
"locations": [],
|
||||
"name": "Test HTTP Monitor 03"
|
||||
"name": "Test HTTP Monitor 03",
|
||||
"namespace": "testnamespace"
|
||||
}
|
||||
|
|
|
@ -57,5 +57,6 @@
|
|||
"lon": 73.2342343434
|
||||
},
|
||||
"url": "https://example-url.com"
|
||||
}]
|
||||
}],
|
||||
"namespace": "testnamespace"
|
||||
}
|
||||
|
|
|
@ -31,5 +31,6 @@
|
|||
"TLSv1.2",
|
||||
"TLSv1.3"
|
||||
],
|
||||
"name": "Test HTTP Monitor 04"
|
||||
"name": "Test HTTP Monitor 04",
|
||||
"namespace": "testnamespace"
|
||||
}
|
||||
|
|
|
@ -27,5 +27,6 @@
|
|||
"TLSv1.1",
|
||||
"TLSv1.3"
|
||||
],
|
||||
"name": "Test HTTP Monitor 04"
|
||||
"name": "Test HTTP Monitor 04",
|
||||
"namespace": "testnamespace"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue