[Infrastructure UI] Decouple source config HTTP API schema from saved object schema (#158562)

Resolves https://github.com/elastic/kibana/issues/152279

Separates out the type for saved object `infrastructure-ui-source` so
the HTTP API no longer references the same type.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Sandra G 2023-05-30 08:45:07 -04:00 committed by GitHub
parent 6547d33635
commit 13806c8c8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 39 deletions

View file

@ -19,25 +19,6 @@
import { omit } from 'lodash';
import * as rt from 'io-ts';
import moment from 'moment';
import { pipe } from 'fp-ts/lib/pipeable';
import { chain } from 'fp-ts/lib/Either';
export const TimestampFromString = new rt.Type<number, string>(
'TimestampFromString',
(input): input is number => typeof input === 'number',
(input, context) =>
pipe(
rt.string.validate(input, context),
chain((stringInput) => {
const momentValue = moment(stringInput);
return momentValue.isValid()
? rt.success(momentValue.valueOf())
: rt.failure(stringInput, context);
})
),
(output) => new Date(output).toISOString()
);
/**
* Source configuration config file properties.
@ -246,21 +227,3 @@ export const SourceResponseRuntimeType = rt.type({
});
export type SourceResponse = rt.TypeOf<typeof SourceResponseRuntimeType>;
/**
* Saved object type with metadata
*/
export const SourceConfigurationSavedObjectRuntimeType = rt.intersection([
rt.type({
id: rt.string,
attributes: SavedSourceConfigurationRuntimeType,
}),
rt.partial({
version: rt.string,
updated_at: TimestampFromString,
}),
]);
export interface SourceConfigurationSavedObject
extends rt.TypeOf<typeof SourceConfigurationSavedObjectRuntimeType> {}

View file

@ -12,3 +12,4 @@ export {
} from './saved_object_type';
export * from './sources';
export * from '../../../common/source_configuration/source_configuration';
export { SourceConfigurationSavedObjectRT } from './types';

View file

@ -22,8 +22,8 @@ import {
InfraStaticSourceConfiguration,
SourceConfigurationConfigFileProperties,
sourceConfigurationConfigFilePropertiesRT,
SourceConfigurationSavedObjectRuntimeType,
} from '../../../common/source_configuration/source_configuration';
import { SourceConfigurationSavedObjectRT } from '.';
import { InfraConfig } from '../..';
import { defaultSourceConfiguration } from './defaults';
import { AnomalyThresholdRangeError, NotFoundError } from './errors';
@ -258,7 +258,7 @@ export const mergeSourceConfiguration = (
export const convertSavedObjectToSavedSourceConfiguration = (savedObject: SavedObject<unknown>) =>
pipe(
SourceConfigurationSavedObjectRuntimeType.decode(savedObject),
SourceConfigurationSavedObjectRT.decode(savedObject),
map((savedSourceConfiguration) => ({
id: savedSourceConfiguration.id,
version: savedSourceConfiguration.version,

View file

@ -0,0 +1,94 @@
/*
* 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 * as rt from 'io-ts';
import moment from 'moment';
import { pipe } from 'fp-ts/lib/pipeable';
import { chain } from 'fp-ts/lib/Either';
export const TimestampFromString = new rt.Type<number, string>(
'TimestampFromString',
(input): input is number => typeof input === 'number',
(input, context) =>
pipe(
rt.string.validate(input, context),
chain((stringInput) => {
const momentValue = moment(stringInput);
return momentValue.isValid()
? rt.success(momentValue.valueOf())
: rt.failure(stringInput, context);
})
),
(output) => new Date(output).toISOString()
);
export const SourceConfigurationSavedObjectFieldColumnRT = rt.type({
fieldColumn: rt.type({
id: rt.string,
field: rt.string,
}),
});
export const SourceConfigurationSavedObjectMessageColumnRT = rt.type({
messageColumn: rt.type({
id: rt.string,
}),
});
export const SourceConfigurationSavedObjectTimestampColumnRT = rt.type({
timestampColumn: rt.type({
id: rt.string,
}),
});
export const SourceConfigurationSavedObjectColumnRT = rt.union([
SourceConfigurationSavedObjectTimestampColumnRT,
SourceConfigurationSavedObjectMessageColumnRT,
SourceConfigurationSavedObjectFieldColumnRT,
]);
export const logIndexPatternSavedObjectReferenceRT = rt.type({
type: rt.literal('index_pattern'),
indexPatternId: rt.string,
});
export const logIndexNameSavedObjectReferenceRT = rt.type({
type: rt.literal('index_name'),
indexName: rt.string,
});
export const logIndexSavedObjectReferenceRT = rt.union([
logIndexPatternSavedObjectReferenceRT,
logIndexNameSavedObjectReferenceRT,
]);
export const SourceConfigurationSavedObjectAttributesRT = rt.type({
name: rt.string,
description: rt.string,
metricAlias: rt.string,
logIndices: logIndexSavedObjectReferenceRT,
inventoryDefaultView: rt.string,
metricsExplorerDefaultView: rt.string,
fields: rt.record(rt.string, rt.unknown),
logColumns: rt.array(SourceConfigurationSavedObjectColumnRT),
anomalyThreshold: rt.number,
});
export const SavedSourceConfigurationSavedObjectRT = rt.partial(
SourceConfigurationSavedObjectAttributesRT.props
);
export const SourceConfigurationSavedObjectRT = rt.intersection([
rt.type({
id: rt.string,
attributes: SavedSourceConfigurationSavedObjectRT,
}),
rt.partial({
version: rt.string,
updated_at: TimestampFromString,
}),
]);