diff --git a/x-pack/legacy/plugins/infra/index.ts b/x-pack/legacy/plugins/infra/index.ts index 38661f430c4020..eecb49647e883a 100644 --- a/x-pack/legacy/plugins/infra/index.ts +++ b/x-pack/legacy/plugins/infra/index.ts @@ -7,16 +7,6 @@ import { i18n } from '@kbn/i18n'; import JoiNamespace from 'joi'; import { resolve } from 'path'; -import { PluginInitializerContext } from 'src/core/server'; -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import KbnServer from 'src/legacy/server/kbn_server'; -import { getConfigSchema } from './server/kibana.index'; -import { savedObjectMappings } from './server/saved_objects'; -import { plugin, InfraServerPluginDeps } from './server/new_platform_index'; -import { InfraSetup } from '../../../plugins/infra/server'; -import { PluginSetupContract as FeaturesPluginSetup } from '../../../plugins/features/server'; -import { SpacesPluginSetup } from '../../../plugins/spaces/server'; -import { APMPluginContract } from '../../../plugins/apm/server'; const APP_ID = 'infra'; const logsSampleDataLinkLabel = i18n.translate('xpack.infra.sampleDataLinkLabel', { @@ -72,55 +62,16 @@ export function infra(kibana: any) { url: `/app/${APP_ID}#/logs`, }, ], - mappings: savedObjectMappings, + // mappings: savedObjectMappings, }, config(Joi: typeof JoiNamespace) { - return getConfigSchema(Joi); + return Joi.object({ + enabled: Joi.boolean().default(true), + }) + .unknown() + .default(); }, init(legacyServer: any) { - const { newPlatform } = legacyServer as KbnServer; - const { core, plugins } = newPlatform.setup; - - const infraSetup = (plugins.infra as unknown) as InfraSetup; // chef's kiss - - const initContext = ({ - config: infraSetup.__legacy.config, - } as unknown) as PluginInitializerContext; - // NP_TODO: Use real types from the other plugins as they are migrated - const pluginDeps: InfraServerPluginDeps = { - usageCollection: plugins.usageCollection as UsageCollectionSetup, - indexPatterns: { - indexPatternsServiceFactory: legacyServer.indexPatternsServiceFactory, - }, - metrics: legacyServer.plugins.metrics, - spaces: plugins.spaces as SpacesPluginSetup, - features: plugins.features as FeaturesPluginSetup, - // NP_NOTE: [TSVB_GROUP] Huge hack to make TSVB (getVisData()) work with raw requests that - // originate from the New Platform router (and are very different to the old request object). - // Once TSVB has migrated over to NP, and can work with the new raw requests, or ideally just - // the requestContext, this can be removed. - ___legacy: { - tsvb: { - elasticsearch: legacyServer.plugins.elasticsearch, - __internals: legacyServer.newPlatform.__internals, - }, - }, - apm: plugins.apm as APMPluginContract, - }; - - const infraPluginInstance = plugin(initContext); - infraPluginInstance.setup(core, pluginDeps); - - // NP_TODO: EVERYTHING BELOW HERE IS LEGACY - - const libs = infraPluginInstance.getLibs(); - - // NP_NOTE: Left here for now for legacy plugins to consume - legacyServer.expose( - 'defineInternalSourceConfiguration', - libs.sources.defineInternalSourceConfiguration.bind(libs.sources) - ); - // NP_TODO: How do we move this to new platform? legacyServer.addAppLinksToSampleDataset('logs', [ { diff --git a/x-pack/legacy/plugins/infra/server/features.ts b/x-pack/legacy/plugins/infra/server/features.ts deleted file mode 100644 index fc20813c777b69..00000000000000 --- a/x-pack/legacy/plugins/infra/server/features.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export const METRICS_FEATURE = { - id: 'infrastructure', - name: i18n.translate('xpack.infra.featureRegistry.linkInfrastructureTitle', { - defaultMessage: 'Infrastructure', - }), - icon: 'infraApp', - navLinkId: 'infra:home', - app: ['infra', 'kibana'], - catalogue: ['infraops'], - privileges: { - all: { - api: ['infra'], - savedObject: { - all: ['infrastructure-ui-source'], - read: ['index-pattern'], - }, - ui: ['show', 'configureSource', 'save'], - }, - read: { - api: ['infra'], - savedObject: { - all: [], - read: ['infrastructure-ui-source', 'index-pattern'], - }, - ui: ['show'], - }, - }, -}; - -export const LOGS_FEATURE = { - id: 'logs', - name: i18n.translate('xpack.infra.featureRegistry.linkLogsTitle', { - defaultMessage: 'Logs', - }), - icon: 'loggingApp', - navLinkId: 'infra:logs', - app: ['infra', 'kibana'], - catalogue: ['infralogging'], - privileges: { - all: { - api: ['infra'], - savedObject: { - all: ['infrastructure-ui-source'], - read: [], - }, - ui: ['show', 'configureSource', 'save'], - }, - read: { - api: ['infra'], - savedObject: { - all: [], - read: ['infrastructure-ui-source'], - }, - ui: ['show'], - }, - }, -}; diff --git a/x-pack/legacy/plugins/infra/server/graphql/index.ts b/x-pack/legacy/plugins/infra/server/graphql/index.ts deleted file mode 100644 index 82fef41db1a739..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { rootSchema } from '../../common/graphql/root/schema.gql'; -import { sharedSchema } from '../../common/graphql/shared/schema.gql'; -import { logEntriesSchema } from './log_entries/schema.gql'; -import { sourceStatusSchema } from './source_status/schema.gql'; -import { sourcesSchema } from './sources/schema.gql'; - -export const schemas = [ - rootSchema, - sharedSchema, - logEntriesSchema, - sourcesSchema, - sourceStatusSchema, -]; diff --git a/x-pack/legacy/plugins/infra/server/graphql/log_entries/index.ts b/x-pack/legacy/plugins/infra/server/graphql/log_entries/index.ts deleted file mode 100644 index 21134862663ec2..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/log_entries/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { createLogEntriesResolvers } from './resolvers'; diff --git a/x-pack/legacy/plugins/infra/server/graphql/log_entries/resolvers.ts b/x-pack/legacy/plugins/infra/server/graphql/log_entries/resolvers.ts deleted file mode 100644 index a18ffea3cfd282..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/log_entries/resolvers.ts +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { failure } from 'io-ts/lib/PathReporter'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { - InfraLogEntryColumn, - InfraLogEntryFieldColumn, - InfraLogEntryMessageColumn, - InfraLogEntryTimestampColumn, - InfraLogMessageConstantSegment, - InfraLogMessageFieldSegment, - InfraLogMessageSegment, - InfraSourceResolvers, -} from '../../graphql/types'; -import { InfraLogEntriesDomain } from '../../lib/domains/log_entries_domain'; -import { SourceConfigurationRuntimeType } from '../../lib/sources'; -import { parseFilterQuery } from '../../utils/serialized_query'; -import { ChildResolverOf, InfraResolverOf } from '../../utils/typed_resolvers'; -import { QuerySourceResolver } from '../sources/resolvers'; - -export type InfraSourceLogEntriesAroundResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceLogEntriesBetweenResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceLogEntryHighlightsResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceLogItem = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export const createLogEntriesResolvers = (libs: { - logEntries: InfraLogEntriesDomain; -}): { - InfraSource: { - logEntriesAround: InfraSourceLogEntriesAroundResolver; - logEntriesBetween: InfraSourceLogEntriesBetweenResolver; - logEntryHighlights: InfraSourceLogEntryHighlightsResolver; - logItem: InfraSourceLogItem; - }; - InfraLogEntryColumn: { - __resolveType( - logEntryColumn: InfraLogEntryColumn - ): - | 'InfraLogEntryTimestampColumn' - | 'InfraLogEntryMessageColumn' - | 'InfraLogEntryFieldColumn' - | null; - }; - InfraLogMessageSegment: { - __resolveType( - messageSegment: InfraLogMessageSegment - ): 'InfraLogMessageFieldSegment' | 'InfraLogMessageConstantSegment' | null; - }; -} => ({ - InfraSource: { - async logEntriesAround(source, args, { req }) { - const countBefore = args.countBefore || 0; - const countAfter = args.countAfter || 0; - - const { entriesBefore, entriesAfter } = await libs.logEntries.getLogEntriesAround( - req, - source.id, - args.key, - countBefore + 1, - countAfter + 1, - parseFilterQuery(args.filterQuery) - ); - - const hasMoreBefore = entriesBefore.length > countBefore; - const hasMoreAfter = entriesAfter.length > countAfter; - - const entries = [ - ...(hasMoreBefore ? entriesBefore.slice(1) : entriesBefore), - ...(hasMoreAfter ? entriesAfter.slice(0, -1) : entriesAfter), - ]; - - return { - start: entries.length > 0 ? entries[0].key : null, - end: entries.length > 0 ? entries[entries.length - 1].key : null, - hasMoreBefore, - hasMoreAfter, - filterQuery: args.filterQuery, - entries, - }; - }, - async logEntriesBetween(source, args, { req }) { - const entries = await libs.logEntries.getLogEntriesBetween( - req, - source.id, - args.startKey, - args.endKey, - parseFilterQuery(args.filterQuery) - ); - - return { - start: entries.length > 0 ? entries[0].key : null, - end: entries.length > 0 ? entries[entries.length - 1].key : null, - hasMoreBefore: true, - hasMoreAfter: true, - filterQuery: args.filterQuery, - entries, - }; - }, - async logEntryHighlights(source, args, { req }) { - const highlightedLogEntrySets = await libs.logEntries.getLogEntryHighlights( - req, - source.id, - args.startKey, - args.endKey, - args.highlights.filter(highlightInput => !!highlightInput.query), - parseFilterQuery(args.filterQuery) - ); - - return highlightedLogEntrySets.map(entries => ({ - start: entries.length > 0 ? entries[0].key : null, - end: entries.length > 0 ? entries[entries.length - 1].key : null, - hasMoreBefore: true, - hasMoreAfter: true, - filterQuery: args.filterQuery, - entries, - })); - }, - async logItem(source, args, { req }) { - const sourceConfiguration = pipe( - SourceConfigurationRuntimeType.decode(source.configuration), - fold(errors => { - throw new Error(failure(errors).join('\n')); - }, identity) - ); - - return await libs.logEntries.getLogItem(req, args.id, sourceConfiguration); - }, - }, - InfraLogEntryColumn: { - __resolveType(logEntryColumn) { - if (isTimestampColumn(logEntryColumn)) { - return 'InfraLogEntryTimestampColumn'; - } - - if (isMessageColumn(logEntryColumn)) { - return 'InfraLogEntryMessageColumn'; - } - - if (isFieldColumn(logEntryColumn)) { - return 'InfraLogEntryFieldColumn'; - } - - return null; - }, - }, - InfraLogMessageSegment: { - __resolveType(messageSegment) { - if (isConstantSegment(messageSegment)) { - return 'InfraLogMessageConstantSegment'; - } - - if (isFieldSegment(messageSegment)) { - return 'InfraLogMessageFieldSegment'; - } - - return null; - }, - }, -}); - -const isTimestampColumn = (column: InfraLogEntryColumn): column is InfraLogEntryTimestampColumn => - 'timestamp' in column; - -const isMessageColumn = (column: InfraLogEntryColumn): column is InfraLogEntryMessageColumn => - 'message' in column; - -const isFieldColumn = (column: InfraLogEntryColumn): column is InfraLogEntryFieldColumn => - 'field' in column && 'value' in column; - -const isConstantSegment = ( - segment: InfraLogMessageSegment -): segment is InfraLogMessageConstantSegment => 'constant' in segment; - -const isFieldSegment = (segment: InfraLogMessageSegment): segment is InfraLogMessageFieldSegment => - 'field' in segment && 'value' in segment && 'highlights' in segment; diff --git a/x-pack/legacy/plugins/infra/server/graphql/log_entries/schema.gql.ts b/x-pack/legacy/plugins/infra/server/graphql/log_entries/schema.gql.ts deleted file mode 100644 index 4681ce5a49aa97..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/log_entries/schema.gql.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const logEntriesSchema = gql` - "A segment of the log entry message that was derived from a field" - type InfraLogMessageFieldSegment { - "The field the segment was derived from" - field: String! - "The segment's message" - value: String! - "A list of highlighted substrings of the value" - highlights: [String!]! - } - - "A segment of the log entry message that was derived from a string literal" - type InfraLogMessageConstantSegment { - "The segment's message" - constant: String! - } - - "A segment of the log entry message" - union InfraLogMessageSegment = InfraLogMessageFieldSegment | InfraLogMessageConstantSegment - - "A special built-in column that contains the log entry's timestamp" - type InfraLogEntryTimestampColumn { - "The id of the corresponding column configuration" - columnId: ID! - "The timestamp" - timestamp: Float! - } - - "A special built-in column that contains the log entry's constructed message" - type InfraLogEntryMessageColumn { - "The id of the corresponding column configuration" - columnId: ID! - "A list of the formatted log entry segments" - message: [InfraLogMessageSegment!]! - } - - "A column that contains the value of a field of the log entry" - type InfraLogEntryFieldColumn { - "The id of the corresponding column configuration" - columnId: ID! - "The field name of the column" - field: String! - "The value of the field in the log entry" - value: String! - "A list of highlighted substrings of the value" - highlights: [String!]! - } - - "A column of a log entry" - union InfraLogEntryColumn = - InfraLogEntryTimestampColumn - | InfraLogEntryMessageColumn - | InfraLogEntryFieldColumn - - "A log entry" - type InfraLogEntry { - "A unique representation of the log entry's position in the event stream" - key: InfraTimeKey! - "The log entry's id" - gid: String! - "The source id" - source: String! - "The columns used for rendering the log entry" - columns: [InfraLogEntryColumn!]! - } - - "A highlighting definition" - input InfraLogEntryHighlightInput { - "The query to highlight by" - query: String! - "The number of highlighted documents to include beyond the beginning of the interval" - countBefore: Int! - "The number of highlighted documents to include beyond the end of the interval" - countAfter: Int! - } - - "A consecutive sequence of log entries" - type InfraLogEntryInterval { - "The key corresponding to the start of the interval covered by the entries" - start: InfraTimeKey - "The key corresponding to the end of the interval covered by the entries" - end: InfraTimeKey - "Whether there are more log entries available before the start" - hasMoreBefore: Boolean! - "Whether there are more log entries available after the end" - hasMoreAfter: Boolean! - "The query the log entries were filtered by" - filterQuery: String - "The query the log entries were highlighted with" - highlightQuery: String - "A list of the log entries" - entries: [InfraLogEntry!]! - } - - type InfraLogItemField { - "The flattened field name" - field: String! - "The value for the Field as a string" - value: String! - } - - type InfraLogItem { - "The ID of the document" - id: ID! - "The index where the document was found" - index: String! - "Time key for the document - derived from the source configuration timestamp and tiebreaker settings" - key: InfraTimeKey! - "An array of flattened fields and values" - fields: [InfraLogItemField!]! - } - - extend type InfraSource { - "A consecutive span of log entries surrounding a point in time" - logEntriesAround( - "The sort key that corresponds to the point in time" - key: InfraTimeKeyInput! - "The maximum number of preceding to return" - countBefore: Int = 0 - "The maximum number of following to return" - countAfter: Int = 0 - "The query to filter the log entries by" - filterQuery: String - ): InfraLogEntryInterval! - "A consecutive span of log entries within an interval" - logEntriesBetween( - "The sort key that corresponds to the start of the interval" - startKey: InfraTimeKeyInput! - "The sort key that corresponds to the end of the interval" - endKey: InfraTimeKeyInput! - "The query to filter the log entries by" - filterQuery: String - ): InfraLogEntryInterval! - "Sequences of log entries matching sets of highlighting queries within an interval" - logEntryHighlights( - "The sort key that corresponds to the start of the interval" - startKey: InfraTimeKeyInput! - "The sort key that corresponds to the end of the interval" - endKey: InfraTimeKeyInput! - "The query to filter the log entries by" - filterQuery: String - "The highlighting to apply to the log entries" - highlights: [InfraLogEntryHighlightInput!]! - ): [InfraLogEntryInterval!]! - logItem(id: ID!): InfraLogItem! - } -`; diff --git a/x-pack/legacy/plugins/infra/server/graphql/source_status/index.ts b/x-pack/legacy/plugins/infra/server/graphql/source_status/index.ts deleted file mode 100644 index abc91fa3815c8f..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/source_status/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { createSourceStatusResolvers } from './resolvers'; diff --git a/x-pack/legacy/plugins/infra/server/graphql/source_status/resolvers.ts b/x-pack/legacy/plugins/infra/server/graphql/source_status/resolvers.ts deleted file mode 100644 index 848d66058e64c8..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/source_status/resolvers.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraIndexType, InfraSourceStatusResolvers } from '../../graphql/types'; -import { InfraFieldsDomain } from '../../lib/domains/fields_domain'; -import { InfraSourceStatus } from '../../lib/source_status'; -import { ChildResolverOf, InfraResolverOf } from '../../utils/typed_resolvers'; -import { QuerySourceResolver } from '../sources/resolvers'; - -export type InfraSourceStatusMetricAliasExistsResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusMetricIndicesExistResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusMetricIndicesResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusLogAliasExistsResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusLogIndicesExistResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusLogIndicesResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export type InfraSourceStatusIndexFieldsResolver = ChildResolverOf< - InfraResolverOf, - QuerySourceResolver ->; - -export const createSourceStatusResolvers = (libs: { - sourceStatus: InfraSourceStatus; - fields: InfraFieldsDomain; -}): { - InfraSourceStatus: { - metricAliasExists: InfraSourceStatusMetricAliasExistsResolver; - metricIndicesExist: InfraSourceStatusMetricIndicesExistResolver; - metricIndices: InfraSourceStatusMetricIndicesResolver; - logAliasExists: InfraSourceStatusLogAliasExistsResolver; - logIndicesExist: InfraSourceStatusLogIndicesExistResolver; - logIndices: InfraSourceStatusLogIndicesResolver; - indexFields: InfraSourceStatusIndexFieldsResolver; - }; -} => ({ - InfraSourceStatus: { - async metricAliasExists(source, args, { req }) { - return await libs.sourceStatus.hasMetricAlias(req, source.id); - }, - async metricIndicesExist(source, args, { req }) { - return await libs.sourceStatus.hasMetricIndices(req, source.id); - }, - async metricIndices(source, args, { req }) { - return await libs.sourceStatus.getMetricIndexNames(req, source.id); - }, - async logAliasExists(source, args, { req }) { - return await libs.sourceStatus.hasLogAlias(req, source.id); - }, - async logIndicesExist(source, args, { req }) { - return await libs.sourceStatus.hasLogIndices(req, source.id); - }, - async logIndices(source, args, { req }) { - return await libs.sourceStatus.getLogIndexNames(req, source.id); - }, - async indexFields(source, args, { req }) { - const fields = await libs.fields.getFields( - req, - source.id, - args.indexType || InfraIndexType.ANY - ); - return fields; - }, - }, -}); diff --git a/x-pack/legacy/plugins/infra/server/graphql/source_status/schema.gql.ts b/x-pack/legacy/plugins/infra/server/graphql/source_status/schema.gql.ts deleted file mode 100644 index e0482382c6d6a3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/source_status/schema.gql.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const sourceStatusSchema = gql` - "A descriptor of a field in an index" - type InfraIndexField { - "The name of the field" - name: String! - "The type of the field's values as recognized by Kibana" - type: String! - "Whether the field's values can be efficiently searched for" - searchable: Boolean! - "Whether the field's values can be aggregated" - aggregatable: Boolean! - "Whether the field should be displayed based on event.module and a ECS allowed list" - displayable: Boolean! - } - - extend type InfraSourceStatus { - "Whether the configured metric alias exists" - metricAliasExists: Boolean! - "Whether the configured log alias exists" - logAliasExists: Boolean! - "Whether the configured alias or wildcard pattern resolve to any metric indices" - metricIndicesExist: Boolean! - "Whether the configured alias or wildcard pattern resolve to any log indices" - logIndicesExist: Boolean! - "The list of indices in the metric alias" - metricIndices: [String!]! - "The list of indices in the log alias" - logIndices: [String!]! - "The list of fields defined in the index mappings" - indexFields(indexType: InfraIndexType = ANY): [InfraIndexField!]! - } -`; diff --git a/x-pack/legacy/plugins/infra/server/graphql/sources/index.ts b/x-pack/legacy/plugins/infra/server/graphql/sources/index.ts deleted file mode 100644 index ee187d8c31bec3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/sources/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { createSourcesResolvers } from './resolvers'; -export { sourcesSchema } from './schema.gql'; diff --git a/x-pack/legacy/plugins/infra/server/graphql/sources/resolvers.ts b/x-pack/legacy/plugins/infra/server/graphql/sources/resolvers.ts deleted file mode 100644 index 1fe1431392a389..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/sources/resolvers.ts +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UserInputError } from 'apollo-server-errors'; -import { failure } from 'io-ts/lib/PathReporter'; - -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { - InfraSourceLogColumn, - InfraSourceResolvers, - MutationResolvers, - QueryResolvers, - UpdateSourceLogColumnInput, -} from '../../graphql/types'; -import { InfraSourceStatus } from '../../lib/source_status'; -import { - InfraSources, - SavedSourceConfigurationFieldColumnRuntimeType, - SavedSourceConfigurationMessageColumnRuntimeType, - SavedSourceConfigurationTimestampColumnRuntimeType, - SavedSourceConfigurationColumnRuntimeType, -} from '../../lib/sources'; -import { - ChildResolverOf, - InfraResolverOf, - InfraResolverWithFields, - ResultOf, -} from '../../utils/typed_resolvers'; - -export type QuerySourceResolver = InfraResolverWithFields< - QueryResolvers.SourceResolver, - 'id' | 'version' | 'updatedAt' | 'configuration' ->; - -export type QueryAllSourcesResolver = InfraResolverWithFields< - QueryResolvers.AllSourcesResolver, - 'id' | 'version' | 'updatedAt' | 'configuration' ->; - -export type InfraSourceStatusResolver = ChildResolverOf< - InfraResolverOf>>, - QuerySourceResolver ->; - -export type MutationCreateSourceResolver = InfraResolverOf< - MutationResolvers.CreateSourceResolver<{ - source: ResultOf; - }> ->; - -export type MutationDeleteSourceResolver = InfraResolverOf; - -export type MutationUpdateSourceResolver = InfraResolverOf< - MutationResolvers.UpdateSourceResolver<{ - source: ResultOf; - }> ->; - -interface SourcesResolversDeps { - sources: InfraSources; - sourceStatus: InfraSourceStatus; -} - -export const createSourcesResolvers = ( - libs: SourcesResolversDeps -): { - Query: { - source: QuerySourceResolver; - allSources: QueryAllSourcesResolver; - }; - InfraSource: { - status: InfraSourceStatusResolver; - }; - InfraSourceLogColumn: { - __resolveType( - logColumn: InfraSourceLogColumn - ): - | 'InfraSourceTimestampLogColumn' - | 'InfraSourceMessageLogColumn' - | 'InfraSourceFieldLogColumn' - | null; - }; - Mutation: { - createSource: MutationCreateSourceResolver; - deleteSource: MutationDeleteSourceResolver; - updateSource: MutationUpdateSourceResolver; - }; -} => ({ - Query: { - async source(root, args, { req }) { - const requestedSourceConfiguration = await libs.sources.getSourceConfiguration(req, args.id); - - return requestedSourceConfiguration; - }, - async allSources(root, args, { req }) { - const sourceConfigurations = await libs.sources.getAllSourceConfigurations(req); - - return sourceConfigurations; - }, - }, - InfraSource: { - async status(source) { - return source; - }, - }, - InfraSourceLogColumn: { - __resolveType(logColumn) { - if (SavedSourceConfigurationTimestampColumnRuntimeType.is(logColumn)) { - return 'InfraSourceTimestampLogColumn'; - } - - if (SavedSourceConfigurationMessageColumnRuntimeType.is(logColumn)) { - return 'InfraSourceMessageLogColumn'; - } - - if (SavedSourceConfigurationFieldColumnRuntimeType.is(logColumn)) { - return 'InfraSourceFieldLogColumn'; - } - - return null; - }, - }, - Mutation: { - async createSource(root, args, { req }) { - const sourceConfiguration = await libs.sources.createSourceConfiguration( - req, - args.id, - compactObject({ - ...args.sourceProperties, - fields: args.sourceProperties.fields - ? compactObject(args.sourceProperties.fields) - : undefined, - logColumns: decodeLogColumns(args.sourceProperties.logColumns), - }) - ); - - return { - source: sourceConfiguration, - }; - }, - async deleteSource(root, args, { req }) { - await libs.sources.deleteSourceConfiguration(req, args.id); - - return { - id: args.id, - }; - }, - async updateSource(root, args, { req }) { - const updatedSourceConfiguration = await libs.sources.updateSourceConfiguration( - req, - args.id, - compactObject({ - ...args.sourceProperties, - fields: args.sourceProperties.fields - ? compactObject(args.sourceProperties.fields) - : undefined, - logColumns: decodeLogColumns(args.sourceProperties.logColumns), - }) - ); - - return { - source: updatedSourceConfiguration, - }; - }, - }, -}); - -type CompactObject = { [K in keyof T]: NonNullable }; - -const compactObject = (obj: T): CompactObject => - Object.entries(obj).reduce>( - (accumulatedObj, [key, value]) => - typeof value === 'undefined' || value === null - ? accumulatedObj - : { - ...(accumulatedObj as any), - [key]: value, - }, - {} as CompactObject - ); - -const decodeLogColumns = (logColumns?: UpdateSourceLogColumnInput[] | null) => - logColumns - ? logColumns.map(logColumn => - pipe( - SavedSourceConfigurationColumnRuntimeType.decode(logColumn), - fold(errors => { - throw new UserInputError(failure(errors).join('\n')); - }, identity) - ) - ) - : undefined; diff --git a/x-pack/legacy/plugins/infra/server/graphql/sources/schema.gql.ts b/x-pack/legacy/plugins/infra/server/graphql/sources/schema.gql.ts deleted file mode 100644 index a39399cec7c329..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/sources/schema.gql.ts +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const sourcesSchema = gql` - "A source of infrastructure data" - type InfraSource { - "The id of the source" - id: ID! - "The version number the source configuration was last persisted with" - version: String - "The timestamp the source configuration was last persisted at" - updatedAt: Float - "The origin of the source (one of 'fallback', 'internal', 'stored')" - origin: String! - "The raw configuration of the source" - configuration: InfraSourceConfiguration! - "The status of the source" - status: InfraSourceStatus! - } - - "The status of an infrastructure data source" - type InfraSourceStatus - - "A set of configuration options for an infrastructure data source" - type InfraSourceConfiguration { - "The name of the data source" - name: String! - "A description of the data source" - description: String! - "The alias to read metric data from" - metricAlias: String! - "The alias to read log data from" - logAlias: String! - "The field mapping to use for this source" - fields: InfraSourceFields! - "The columns to use for log display" - logColumns: [InfraSourceLogColumn!]! - } - - "A mapping of semantic fields to their document counterparts" - type InfraSourceFields { - "The field to identify a container by" - container: String! - "The fields to identify a host by" - host: String! - "The fields to use as the log message" - message: [String!]! - "The field to identify a pod by" - pod: String! - "The field to use as a tiebreaker for log events that have identical timestamps" - tiebreaker: String! - "The field to use as a timestamp for metrics and logs" - timestamp: String! - } - - "The built-in timestamp log column" - type InfraSourceTimestampLogColumn { - timestampColumn: InfraSourceTimestampLogColumnAttributes! - } - - type InfraSourceTimestampLogColumnAttributes { - "A unique id for the column" - id: ID! - } - - "The built-in message log column" - type InfraSourceMessageLogColumn { - messageColumn: InfraSourceMessageLogColumnAttributes! - } - - type InfraSourceMessageLogColumnAttributes { - "A unique id for the column" - id: ID! - } - - "A log column containing a field value" - type InfraSourceFieldLogColumn { - fieldColumn: InfraSourceFieldLogColumnAttributes! - } - - type InfraSourceFieldLogColumnAttributes { - "A unique id for the column" - id: ID! - "The field name this column refers to" - field: String! - } - - "All known log column types" - union InfraSourceLogColumn = - InfraSourceTimestampLogColumn - | InfraSourceMessageLogColumn - | InfraSourceFieldLogColumn - - extend type Query { - """ - Get an infrastructure data source by id. - - The resolution order for the source configuration attributes is as follows - with the first defined value winning: - - 1. The attributes of the saved object with the given 'id'. - 2. The attributes defined in the static Kibana configuration key - 'xpack.infra.sources.default'. - 3. The hard-coded default values. - - As a consequence, querying a source that doesn't exist doesn't error out, - but returns the configured or hardcoded defaults. - """ - source("The id of the source" id: ID!): InfraSource! - "Get a list of all infrastructure data sources" - allSources: [InfraSource!]! - } - - "The properties to update the source with" - input UpdateSourceInput { - "The name of the data source" - name: String - "A description of the data source" - description: String - "The alias to read metric data from" - metricAlias: String - "The alias to read log data from" - logAlias: String - "The field mapping to use for this source" - fields: UpdateSourceFieldsInput - "The log columns to display for this source" - logColumns: [UpdateSourceLogColumnInput!] - } - - "The mapping of semantic fields of the source to be created" - input UpdateSourceFieldsInput { - "The field to identify a container by" - container: String - "The fields to identify a host by" - host: String - "The field to identify a pod by" - pod: String - "The field to use as a tiebreaker for log events that have identical timestamps" - tiebreaker: String - "The field to use as a timestamp for metrics and logs" - timestamp: String - } - - "One of the log column types to display for this source" - input UpdateSourceLogColumnInput { - "A custom field log column" - fieldColumn: UpdateSourceFieldLogColumnInput - "A built-in message log column" - messageColumn: UpdateSourceMessageLogColumnInput - "A built-in timestamp log column" - timestampColumn: UpdateSourceTimestampLogColumnInput - } - - input UpdateSourceFieldLogColumnInput { - id: ID! - field: String! - } - - input UpdateSourceMessageLogColumnInput { - id: ID! - } - - input UpdateSourceTimestampLogColumnInput { - id: ID! - } - - "The result of a successful source update" - type UpdateSourceResult { - "The source that was updated" - source: InfraSource! - } - - "The result of a source deletion operations" - type DeleteSourceResult { - "The id of the source that was deleted" - id: ID! - } - - extend type Mutation { - "Create a new source of infrastructure data" - createSource( - "The id of the source" - id: ID! - sourceProperties: UpdateSourceInput! - ): UpdateSourceResult! - "Modify an existing source" - updateSource( - "The id of the source" - id: ID! - "The properties to update the source with" - sourceProperties: UpdateSourceInput! - ): UpdateSourceResult! - "Delete a source of infrastructure data" - deleteSource("The id of the source" id: ID!): DeleteSourceResult! - } -`; diff --git a/x-pack/legacy/plugins/infra/server/graphql/types.ts b/x-pack/legacy/plugins/infra/server/graphql/types.ts deleted file mode 100644 index bb27cc4e21b4eb..00000000000000 --- a/x-pack/legacy/plugins/infra/server/graphql/types.ts +++ /dev/null @@ -1,1599 +0,0 @@ -/* tslint:disable */ -import { InfraContext } from '../lib/infra_types'; -import { GraphQLResolveInfo } from 'graphql'; - -export type Resolver = ( - parent: Parent, - args: Args, - context: Context, - info: GraphQLResolveInfo -) => Promise | Result; - -export interface ISubscriptionResolverObject { - subscribe( - parent: P, - args: Args, - context: Context, - info: GraphQLResolveInfo - ): AsyncIterator; - resolve?( - parent: P, - args: Args, - context: Context, - info: GraphQLResolveInfo - ): R | Result | Promise; -} - -export type SubscriptionResolver = - | ((...args: any[]) => ISubscriptionResolverObject) - | ISubscriptionResolverObject; - -// ==================================================== -// START: Typescript template -// ==================================================== - -// ==================================================== -// Types -// ==================================================== - -export interface Query { - /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source that doesn't exist doesn't error out,but returns the configured or hardcoded defaults. */ - source: InfraSource; - /** Get a list of all infrastructure data sources */ - allSources: InfraSource[]; -} -/** A source of infrastructure data */ -export interface InfraSource { - /** The id of the source */ - id: string; - /** The version number the source configuration was last persisted with */ - version?: string | null; - /** The timestamp the source configuration was last persisted at */ - updatedAt?: number | null; - /** The origin of the source (one of 'fallback', 'internal', 'stored') */ - origin: string; - /** The raw configuration of the source */ - configuration: InfraSourceConfiguration; - /** The status of the source */ - status: InfraSourceStatus; - /** A consecutive span of log entries surrounding a point in time */ - logEntriesAround: InfraLogEntryInterval; - /** A consecutive span of log entries within an interval */ - logEntriesBetween: InfraLogEntryInterval; - /** Sequences of log entries matching sets of highlighting queries within an interval */ - logEntryHighlights: InfraLogEntryInterval[]; - - logItem: InfraLogItem; - /** A snapshot of nodes */ - snapshot?: InfraSnapshotResponse | null; - - metrics: InfraMetricData[]; -} -/** A set of configuration options for an infrastructure data source */ -export interface InfraSourceConfiguration { - /** The name of the data source */ - name: string; - /** A description of the data source */ - description: string; - /** The alias to read metric data from */ - metricAlias: string; - /** The alias to read log data from */ - logAlias: string; - /** The field mapping to use for this source */ - fields: InfraSourceFields; - /** The columns to use for log display */ - logColumns: InfraSourceLogColumn[]; -} -/** A mapping of semantic fields to their document counterparts */ -export interface InfraSourceFields { - /** The field to identify a container by */ - container: string; - /** The fields to identify a host by */ - host: string; - /** The fields to use as the log message */ - message: string[]; - /** The field to identify a pod by */ - pod: string; - /** The field to use as a tiebreaker for log events that have identical timestamps */ - tiebreaker: string; - /** The field to use as a timestamp for metrics and logs */ - timestamp: string; -} -/** The built-in timestamp log column */ -export interface InfraSourceTimestampLogColumn { - timestampColumn: InfraSourceTimestampLogColumnAttributes; -} - -export interface InfraSourceTimestampLogColumnAttributes { - /** A unique id for the column */ - id: string; -} -/** The built-in message log column */ -export interface InfraSourceMessageLogColumn { - messageColumn: InfraSourceMessageLogColumnAttributes; -} - -export interface InfraSourceMessageLogColumnAttributes { - /** A unique id for the column */ - id: string; -} -/** A log column containing a field value */ -export interface InfraSourceFieldLogColumn { - fieldColumn: InfraSourceFieldLogColumnAttributes; -} - -export interface InfraSourceFieldLogColumnAttributes { - /** A unique id for the column */ - id: string; - /** The field name this column refers to */ - field: string; -} -/** The status of an infrastructure data source */ -export interface InfraSourceStatus { - /** Whether the configured metric alias exists */ - metricAliasExists: boolean; - /** Whether the configured log alias exists */ - logAliasExists: boolean; - /** Whether the configured alias or wildcard pattern resolve to any metric indices */ - metricIndicesExist: boolean; - /** Whether the configured alias or wildcard pattern resolve to any log indices */ - logIndicesExist: boolean; - /** The list of indices in the metric alias */ - metricIndices: string[]; - /** The list of indices in the log alias */ - logIndices: string[]; - /** The list of fields defined in the index mappings */ - indexFields: InfraIndexField[]; -} -/** A descriptor of a field in an index */ -export interface InfraIndexField { - /** The name of the field */ - name: string; - /** The type of the field's values as recognized by Kibana */ - type: string; - /** Whether the field's values can be efficiently searched for */ - searchable: boolean; - /** Whether the field's values can be aggregated */ - aggregatable: boolean; - /** Whether the field should be displayed based on event.module and a ECS allowed list */ - displayable: boolean; -} -/** A consecutive sequence of log entries */ -export interface InfraLogEntryInterval { - /** The key corresponding to the start of the interval covered by the entries */ - start?: InfraTimeKey | null; - /** The key corresponding to the end of the interval covered by the entries */ - end?: InfraTimeKey | null; - /** Whether there are more log entries available before the start */ - hasMoreBefore: boolean; - /** Whether there are more log entries available after the end */ - hasMoreAfter: boolean; - /** The query the log entries were filtered by */ - filterQuery?: string | null; - /** The query the log entries were highlighted with */ - highlightQuery?: string | null; - /** A list of the log entries */ - entries: InfraLogEntry[]; -} -/** A representation of the log entry's position in the event stream */ -export interface InfraTimeKey { - /** The timestamp of the event that the log entry corresponds to */ - time: number; - /** The tiebreaker that disambiguates events with the same timestamp */ - tiebreaker: number; -} -/** A log entry */ -export interface InfraLogEntry { - /** A unique representation of the log entry's position in the event stream */ - key: InfraTimeKey; - /** The log entry's id */ - gid: string; - /** The source id */ - source: string; - /** The columns used for rendering the log entry */ - columns: InfraLogEntryColumn[]; -} -/** A special built-in column that contains the log entry's timestamp */ -export interface InfraLogEntryTimestampColumn { - /** The id of the corresponding column configuration */ - columnId: string; - /** The timestamp */ - timestamp: number; -} -/** A special built-in column that contains the log entry's constructed message */ -export interface InfraLogEntryMessageColumn { - /** The id of the corresponding column configuration */ - columnId: string; - /** A list of the formatted log entry segments */ - message: InfraLogMessageSegment[]; -} -/** A segment of the log entry message that was derived from a field */ -export interface InfraLogMessageFieldSegment { - /** The field the segment was derived from */ - field: string; - /** The segment's message */ - value: string; - /** A list of highlighted substrings of the value */ - highlights: string[]; -} -/** A segment of the log entry message that was derived from a string literal */ -export interface InfraLogMessageConstantSegment { - /** The segment's message */ - constant: string; -} -/** A column that contains the value of a field of the log entry */ -export interface InfraLogEntryFieldColumn { - /** The id of the corresponding column configuration */ - columnId: string; - /** The field name of the column */ - field: string; - /** The value of the field in the log entry */ - value: string; - /** A list of highlighted substrings of the value */ - highlights: string[]; -} - -export interface InfraLogItem { - /** The ID of the document */ - id: string; - /** The index where the document was found */ - index: string; - /** Time key for the document - derived from the source configuration timestamp and tiebreaker settings */ - key: InfraTimeKey; - /** An array of flattened fields and values */ - fields: InfraLogItemField[]; -} - -export interface InfraLogItemField { - /** The flattened field name */ - field: string; - /** The value for the Field as a string */ - value: string; -} - -export interface InfraSnapshotResponse { - /** Nodes of type host, container or pod grouped by 0, 1 or 2 terms */ - nodes: InfraSnapshotNode[]; -} - -export interface InfraSnapshotNode { - path: InfraSnapshotNodePath[]; - - metric: InfraSnapshotNodeMetric; -} - -export interface InfraSnapshotNodePath { - value: string; - - label: string; - - ip?: string | null; -} - -export interface InfraSnapshotNodeMetric { - name: InfraSnapshotMetricType; - - value?: number | null; - - avg?: number | null; - - max?: number | null; -} - -export interface InfraMetricData { - id?: InfraMetric | null; - - series: InfraDataSeries[]; -} - -export interface InfraDataSeries { - id: string; - - label: string; - - data: InfraDataPoint[]; -} - -export interface InfraDataPoint { - timestamp: number; - - value?: number | null; -} - -export interface Mutation { - /** Create a new source of infrastructure data */ - createSource: UpdateSourceResult; - /** Modify an existing source */ - updateSource: UpdateSourceResult; - /** Delete a source of infrastructure data */ - deleteSource: DeleteSourceResult; -} -/** The result of a successful source update */ -export interface UpdateSourceResult { - /** The source that was updated */ - source: InfraSource; -} -/** The result of a source deletion operations */ -export interface DeleteSourceResult { - /** The id of the source that was deleted */ - id: string; -} - -// ==================================================== -// InputTypes -// ==================================================== - -export interface InfraTimeKeyInput { - time: number; - - tiebreaker: number; -} -/** A highlighting definition */ -export interface InfraLogEntryHighlightInput { - /** The query to highlight by */ - query: string; - /** The number of highlighted documents to include beyond the beginning of the interval */ - countBefore: number; - /** The number of highlighted documents to include beyond the end of the interval */ - countAfter: number; -} - -export interface InfraTimerangeInput { - /** The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan. */ - interval: string; - /** The end of the timerange */ - to: number; - /** The beginning of the timerange */ - from: number; -} - -export interface InfraSnapshotGroupbyInput { - /** The label to use in the results for the group by for the terms group by */ - label?: string | null; - /** The field to group by from a terms aggregation, this is ignored by the filter type */ - field?: string | null; -} - -export interface InfraSnapshotMetricInput { - /** The type of metric */ - type: InfraSnapshotMetricType; -} - -export interface InfraNodeIdsInput { - nodeId: string; - - cloudId?: string | null; -} -/** The properties to update the source with */ -export interface UpdateSourceInput { - /** The name of the data source */ - name?: string | null; - /** A description of the data source */ - description?: string | null; - /** The alias to read metric data from */ - metricAlias?: string | null; - /** The alias to read log data from */ - logAlias?: string | null; - /** The field mapping to use for this source */ - fields?: UpdateSourceFieldsInput | null; - /** The log columns to display for this source */ - logColumns?: UpdateSourceLogColumnInput[] | null; -} -/** The mapping of semantic fields of the source to be created */ -export interface UpdateSourceFieldsInput { - /** The field to identify a container by */ - container?: string | null; - /** The fields to identify a host by */ - host?: string | null; - /** The field to identify a pod by */ - pod?: string | null; - /** The field to use as a tiebreaker for log events that have identical timestamps */ - tiebreaker?: string | null; - /** The field to use as a timestamp for metrics and logs */ - timestamp?: string | null; -} -/** One of the log column types to display for this source */ -export interface UpdateSourceLogColumnInput { - /** A custom field log column */ - fieldColumn?: UpdateSourceFieldLogColumnInput | null; - /** A built-in message log column */ - messageColumn?: UpdateSourceMessageLogColumnInput | null; - /** A built-in timestamp log column */ - timestampColumn?: UpdateSourceTimestampLogColumnInput | null; -} - -export interface UpdateSourceFieldLogColumnInput { - id: string; - - field: string; -} - -export interface UpdateSourceMessageLogColumnInput { - id: string; -} - -export interface UpdateSourceTimestampLogColumnInput { - id: string; -} - -// ==================================================== -// Arguments -// ==================================================== - -export interface SourceQueryArgs { - /** The id of the source */ - id: string; -} -export interface LogEntriesAroundInfraSourceArgs { - /** The sort key that corresponds to the point in time */ - key: InfraTimeKeyInput; - /** The maximum number of preceding to return */ - countBefore?: number | null; - /** The maximum number of following to return */ - countAfter?: number | null; - /** The query to filter the log entries by */ - filterQuery?: string | null; -} -export interface LogEntriesBetweenInfraSourceArgs { - /** The sort key that corresponds to the start of the interval */ - startKey: InfraTimeKeyInput; - /** The sort key that corresponds to the end of the interval */ - endKey: InfraTimeKeyInput; - /** The query to filter the log entries by */ - filterQuery?: string | null; -} -export interface LogEntryHighlightsInfraSourceArgs { - /** The sort key that corresponds to the start of the interval */ - startKey: InfraTimeKeyInput; - /** The sort key that corresponds to the end of the interval */ - endKey: InfraTimeKeyInput; - /** The query to filter the log entries by */ - filterQuery?: string | null; - /** The highlighting to apply to the log entries */ - highlights: InfraLogEntryHighlightInput[]; -} -export interface LogItemInfraSourceArgs { - id: string; -} -export interface SnapshotInfraSourceArgs { - timerange: InfraTimerangeInput; - - filterQuery?: string | null; -} -export interface MetricsInfraSourceArgs { - nodeIds: InfraNodeIdsInput; - - nodeType: InfraNodeType; - - timerange: InfraTimerangeInput; - - metrics: InfraMetric[]; -} -export interface IndexFieldsInfraSourceStatusArgs { - indexType?: InfraIndexType | null; -} -export interface NodesInfraSnapshotResponseArgs { - type: InfraNodeType; - - groupBy: InfraSnapshotGroupbyInput[]; - - metric: InfraSnapshotMetricInput; -} -export interface CreateSourceMutationArgs { - /** The id of the source */ - id: string; - - sourceProperties: UpdateSourceInput; -} -export interface UpdateSourceMutationArgs { - /** The id of the source */ - id: string; - /** The properties to update the source with */ - sourceProperties: UpdateSourceInput; -} -export interface DeleteSourceMutationArgs { - /** The id of the source */ - id: string; -} - -// ==================================================== -// Enums -// ==================================================== - -export enum InfraIndexType { - ANY = 'ANY', - LOGS = 'LOGS', - METRICS = 'METRICS', -} - -export enum InfraNodeType { - pod = 'pod', - container = 'container', - host = 'host', - awsEC2 = 'awsEC2', - awsS3 = 'awsS3', - awsRDS = 'awsRDS', - awsSQS = 'awsSQS' -} - -export enum InfraSnapshotMetricType { - count = 'count', - cpu = 'cpu', - load = 'load', - memory = 'memory', - tx = 'tx', - rx = 'rx', - logRate = 'logRate', - diskIOReadBytes = 'diskIOReadBytes', - diskIOWriteBytes = 'diskIOWriteBytes', - s3TotalRequests = 's3TotalRequests', - s3NumberOfObjects = 's3NumberOfObjects', - s3BucketSize = 's3BucketSize', - s3DownloadBytes = 's3DownloadBytes', - s3UploadBytes = 's3UploadBytes', - rdsConnections = 'rdsConnections', - rdsQueriesExecuted = 'rdsQueriesExecuted', - rdsActiveTransactions = 'rdsActiveTransactions', - rdsLatency = 'rdsLatency', - sqsMessagesVisible = 'sqsMessagesVisible', - sqsMessagesDelayed = 'sqsMessagesDelayed', - sqsMessagesSent = 'sqsMessagesSent', - sqsMessagesEmpty = 'sqsMessagesEmpty', - sqsOldestMessage = 'sqsOldestMessage', -} - -export enum InfraMetric { - hostSystemOverview = 'hostSystemOverview', - hostCpuUsage = 'hostCpuUsage', - hostFilesystem = 'hostFilesystem', - hostK8sOverview = 'hostK8sOverview', - hostK8sCpuCap = 'hostK8sCpuCap', - hostK8sDiskCap = 'hostK8sDiskCap', - hostK8sMemoryCap = 'hostK8sMemoryCap', - hostK8sPodCap = 'hostK8sPodCap', - hostLoad = 'hostLoad', - hostMemoryUsage = 'hostMemoryUsage', - hostNetworkTraffic = 'hostNetworkTraffic', - hostDockerOverview = 'hostDockerOverview', - hostDockerInfo = 'hostDockerInfo', - hostDockerTop5ByCpu = 'hostDockerTop5ByCpu', - hostDockerTop5ByMemory = 'hostDockerTop5ByMemory', - podOverview = 'podOverview', - podCpuUsage = 'podCpuUsage', - podMemoryUsage = 'podMemoryUsage', - podLogUsage = 'podLogUsage', - podNetworkTraffic = 'podNetworkTraffic', - containerOverview = 'containerOverview', - containerCpuKernel = 'containerCpuKernel', - containerCpuUsage = 'containerCpuUsage', - containerDiskIOOps = 'containerDiskIOOps', - containerDiskIOBytes = 'containerDiskIOBytes', - containerMemory = 'containerMemory', - containerNetworkTraffic = 'containerNetworkTraffic', - nginxHits = 'nginxHits', - nginxRequestRate = 'nginxRequestRate', - nginxActiveConnections = 'nginxActiveConnections', - nginxRequestsPerConnection = 'nginxRequestsPerConnection', - awsOverview = 'awsOverview', - awsCpuUtilization = 'awsCpuUtilization', - awsNetworkBytes = 'awsNetworkBytes', - awsNetworkPackets = 'awsNetworkPackets', - awsDiskioBytes = 'awsDiskioBytes', - awsDiskioOps = 'awsDiskioOps', - awsEC2CpuUtilization = 'awsEC2CpuUtilization', - awsEC2DiskIOBytes = 'awsEC2DiskIOBytes', - awsEC2NetworkTraffic = 'awsEC2NetworkTraffic', - awsS3TotalRequests = 'awsS3TotalRequests', - awsS3NumberOfObjects = 'awsS3NumberOfObjects', - awsS3BucketSize = 'awsS3BucketSize', - awsS3DownloadBytes = 'awsS3DownloadBytes', - awsS3UploadBytes = 'awsS3UploadBytes', - awsRDSCpuTotal = 'awsRDSCpuTotal', - awsRDSConnections = 'awsRDSConnections', - awsRDSQueriesExecuted = 'awsRDSQueriesExecuted', - awsRDSActiveTransactions = 'awsRDSActiveTransactions', - awsRDSLatency = 'awsRDSLatency', - awsSQSMessagesVisible = 'awsSQSMessagesVisible', - awsSQSMessagesDelayed = 'awsSQSMessagesDelayed', - awsSQSMessagesSent = 'awsSQSMessagesSent', - awsSQSMessagesEmpty = 'awsSQSMessagesEmpty', - awsSQSOldestMessage = 'awsSQSOldestMessage', - custom = 'custom', -} - -// ==================================================== -// Unions -// ==================================================== - -/** All known log column types */ -export type InfraSourceLogColumn = - | InfraSourceTimestampLogColumn - | InfraSourceMessageLogColumn - | InfraSourceFieldLogColumn; - -/** A column of a log entry */ -export type InfraLogEntryColumn = - | InfraLogEntryTimestampColumn - | InfraLogEntryMessageColumn - | InfraLogEntryFieldColumn; - -/** A segment of the log entry message */ -export type InfraLogMessageSegment = InfraLogMessageFieldSegment | InfraLogMessageConstantSegment; - -// ==================================================== -// END: Typescript template -// ==================================================== - -// ==================================================== -// Resolvers -// ==================================================== - -export namespace QueryResolvers { - export interface Resolvers { - /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source that doesn't exist doesn't error out,but returns the configured or hardcoded defaults. */ - source?: SourceResolver; - /** Get a list of all infrastructure data sources */ - allSources?: AllSourcesResolver; - } - - export type SourceResolver = Resolver< - R, - Parent, - Context, - SourceArgs - >; - export interface SourceArgs { - /** The id of the source */ - id: string; - } - - export type AllSourcesResolver< - R = InfraSource[], - Parent = never, - Context = InfraContext - > = Resolver; -} -/** A source of infrastructure data */ -export namespace InfraSourceResolvers { - export interface Resolvers { - /** The id of the source */ - id?: IdResolver; - /** The version number the source configuration was last persisted with */ - version?: VersionResolver; - /** The timestamp the source configuration was last persisted at */ - updatedAt?: UpdatedAtResolver; - /** The origin of the source (one of 'fallback', 'internal', 'stored') */ - origin?: OriginResolver; - /** The raw configuration of the source */ - configuration?: ConfigurationResolver; - /** The status of the source */ - status?: StatusResolver; - /** A consecutive span of log entries surrounding a point in time */ - logEntriesAround?: LogEntriesAroundResolver; - /** A consecutive span of log entries within an interval */ - logEntriesBetween?: LogEntriesBetweenResolver; - /** Sequences of log entries matching sets of highlighting queries within an interval */ - logEntryHighlights?: LogEntryHighlightsResolver; - - logItem?: LogItemResolver; - /** A snapshot of nodes */ - snapshot?: SnapshotResolver; - - metrics?: MetricsResolver; - } - - export type IdResolver = Resolver< - R, - Parent, - Context - >; - export type VersionResolver< - R = string | null, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export type UpdatedAtResolver< - R = number | null, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export type OriginResolver = Resolver< - R, - Parent, - Context - >; - export type ConfigurationResolver< - R = InfraSourceConfiguration, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export type StatusResolver< - R = InfraSourceStatus, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export type LogEntriesAroundResolver< - R = InfraLogEntryInterval, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface LogEntriesAroundArgs { - /** The sort key that corresponds to the point in time */ - key: InfraTimeKeyInput; - /** The maximum number of preceding to return */ - countBefore?: number | null; - /** The maximum number of following to return */ - countAfter?: number | null; - /** The query to filter the log entries by */ - filterQuery?: string | null; - } - - export type LogEntriesBetweenResolver< - R = InfraLogEntryInterval, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface LogEntriesBetweenArgs { - /** The sort key that corresponds to the start of the interval */ - startKey: InfraTimeKeyInput; - /** The sort key that corresponds to the end of the interval */ - endKey: InfraTimeKeyInput; - /** The query to filter the log entries by */ - filterQuery?: string | null; - } - - export type LogEntryHighlightsResolver< - R = InfraLogEntryInterval[], - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface LogEntryHighlightsArgs { - /** The sort key that corresponds to the start of the interval */ - startKey: InfraTimeKeyInput; - /** The sort key that corresponds to the end of the interval */ - endKey: InfraTimeKeyInput; - /** The query to filter the log entries by */ - filterQuery?: string | null; - /** The highlighting to apply to the log entries */ - highlights: InfraLogEntryHighlightInput[]; - } - - export type LogItemResolver< - R = InfraLogItem, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface LogItemArgs { - id: string; - } - - export type SnapshotResolver< - R = InfraSnapshotResponse | null, - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface SnapshotArgs { - timerange: InfraTimerangeInput; - - filterQuery?: string | null; - } - - export type MetricsResolver< - R = InfraMetricData[], - Parent = InfraSource, - Context = InfraContext - > = Resolver; - export interface MetricsArgs { - nodeIds: InfraNodeIdsInput; - - nodeType: InfraNodeType; - - timerange: InfraTimerangeInput; - - metrics: InfraMetric[]; - } -} -/** A set of configuration options for an infrastructure data source */ -export namespace InfraSourceConfigurationResolvers { - export interface Resolvers { - /** The name of the data source */ - name?: NameResolver; - /** A description of the data source */ - description?: DescriptionResolver; - /** The alias to read metric data from */ - metricAlias?: MetricAliasResolver; - /** The alias to read log data from */ - logAlias?: LogAliasResolver; - /** The field mapping to use for this source */ - fields?: FieldsResolver; - /** The columns to use for log display */ - logColumns?: LogColumnsResolver; - } - - export type NameResolver< - R = string, - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; - export type DescriptionResolver< - R = string, - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; - export type MetricAliasResolver< - R = string, - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; - export type LogAliasResolver< - R = string, - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; - export type FieldsResolver< - R = InfraSourceFields, - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; - export type LogColumnsResolver< - R = InfraSourceLogColumn[], - Parent = InfraSourceConfiguration, - Context = InfraContext - > = Resolver; -} -/** A mapping of semantic fields to their document counterparts */ -export namespace InfraSourceFieldsResolvers { - export interface Resolvers { - /** The field to identify a container by */ - container?: ContainerResolver; - /** The fields to identify a host by */ - host?: HostResolver; - /** The fields to use as the log message */ - message?: MessageResolver; - /** The field to identify a pod by */ - pod?: PodResolver; - /** The field to use as a tiebreaker for log events that have identical timestamps */ - tiebreaker?: TiebreakerResolver; - /** The field to use as a timestamp for metrics and logs */ - timestamp?: TimestampResolver; - } - - export type ContainerResolver< - R = string, - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; - export type HostResolver< - R = string, - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; - export type MessageResolver< - R = string[], - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; - export type PodResolver< - R = string, - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; - export type TiebreakerResolver< - R = string, - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; - export type TimestampResolver< - R = string, - Parent = InfraSourceFields, - Context = InfraContext - > = Resolver; -} -/** The built-in timestamp log column */ -export namespace InfraSourceTimestampLogColumnResolvers { - export interface Resolvers { - timestampColumn?: TimestampColumnResolver< - InfraSourceTimestampLogColumnAttributes, - TypeParent, - Context - >; - } - - export type TimestampColumnResolver< - R = InfraSourceTimestampLogColumnAttributes, - Parent = InfraSourceTimestampLogColumn, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSourceTimestampLogColumnAttributesResolvers { - export interface Resolvers< - Context = InfraContext, - TypeParent = InfraSourceTimestampLogColumnAttributes - > { - /** A unique id for the column */ - id?: IdResolver; - } - - export type IdResolver< - R = string, - Parent = InfraSourceTimestampLogColumnAttributes, - Context = InfraContext - > = Resolver; -} -/** The built-in message log column */ -export namespace InfraSourceMessageLogColumnResolvers { - export interface Resolvers { - messageColumn?: MessageColumnResolver< - InfraSourceMessageLogColumnAttributes, - TypeParent, - Context - >; - } - - export type MessageColumnResolver< - R = InfraSourceMessageLogColumnAttributes, - Parent = InfraSourceMessageLogColumn, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSourceMessageLogColumnAttributesResolvers { - export interface Resolvers< - Context = InfraContext, - TypeParent = InfraSourceMessageLogColumnAttributes - > { - /** A unique id for the column */ - id?: IdResolver; - } - - export type IdResolver< - R = string, - Parent = InfraSourceMessageLogColumnAttributes, - Context = InfraContext - > = Resolver; -} -/** A log column containing a field value */ -export namespace InfraSourceFieldLogColumnResolvers { - export interface Resolvers { - fieldColumn?: FieldColumnResolver; - } - - export type FieldColumnResolver< - R = InfraSourceFieldLogColumnAttributes, - Parent = InfraSourceFieldLogColumn, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSourceFieldLogColumnAttributesResolvers { - export interface Resolvers< - Context = InfraContext, - TypeParent = InfraSourceFieldLogColumnAttributes - > { - /** A unique id for the column */ - id?: IdResolver; - /** The field name this column refers to */ - field?: FieldResolver; - } - - export type IdResolver< - R = string, - Parent = InfraSourceFieldLogColumnAttributes, - Context = InfraContext - > = Resolver; - export type FieldResolver< - R = string, - Parent = InfraSourceFieldLogColumnAttributes, - Context = InfraContext - > = Resolver; -} -/** The status of an infrastructure data source */ -export namespace InfraSourceStatusResolvers { - export interface Resolvers { - /** Whether the configured metric alias exists */ - metricAliasExists?: MetricAliasExistsResolver; - /** Whether the configured log alias exists */ - logAliasExists?: LogAliasExistsResolver; - /** Whether the configured alias or wildcard pattern resolve to any metric indices */ - metricIndicesExist?: MetricIndicesExistResolver; - /** Whether the configured alias or wildcard pattern resolve to any log indices */ - logIndicesExist?: LogIndicesExistResolver; - /** The list of indices in the metric alias */ - metricIndices?: MetricIndicesResolver; - /** The list of indices in the log alias */ - logIndices?: LogIndicesResolver; - /** The list of fields defined in the index mappings */ - indexFields?: IndexFieldsResolver; - } - - export type MetricAliasExistsResolver< - R = boolean, - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type LogAliasExistsResolver< - R = boolean, - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type MetricIndicesExistResolver< - R = boolean, - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type LogIndicesExistResolver< - R = boolean, - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type MetricIndicesResolver< - R = string[], - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type LogIndicesResolver< - R = string[], - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export type IndexFieldsResolver< - R = InfraIndexField[], - Parent = InfraSourceStatus, - Context = InfraContext - > = Resolver; - export interface IndexFieldsArgs { - indexType?: InfraIndexType | null; - } -} -/** A descriptor of a field in an index */ -export namespace InfraIndexFieldResolvers { - export interface Resolvers { - /** The name of the field */ - name?: NameResolver; - /** The type of the field's values as recognized by Kibana */ - type?: TypeResolver; - /** Whether the field's values can be efficiently searched for */ - searchable?: SearchableResolver; - /** Whether the field's values can be aggregated */ - aggregatable?: AggregatableResolver; - /** Whether the field should be displayed based on event.module and a ECS allowed list */ - displayable?: DisplayableResolver; - } - - export type NameResolver = Resolver< - R, - Parent, - Context - >; - export type TypeResolver = Resolver< - R, - Parent, - Context - >; - export type SearchableResolver< - R = boolean, - Parent = InfraIndexField, - Context = InfraContext - > = Resolver; - export type AggregatableResolver< - R = boolean, - Parent = InfraIndexField, - Context = InfraContext - > = Resolver; - export type DisplayableResolver< - R = boolean, - Parent = InfraIndexField, - Context = InfraContext - > = Resolver; -} -/** A consecutive sequence of log entries */ -export namespace InfraLogEntryIntervalResolvers { - export interface Resolvers { - /** The key corresponding to the start of the interval covered by the entries */ - start?: StartResolver; - /** The key corresponding to the end of the interval covered by the entries */ - end?: EndResolver; - /** Whether there are more log entries available before the start */ - hasMoreBefore?: HasMoreBeforeResolver; - /** Whether there are more log entries available after the end */ - hasMoreAfter?: HasMoreAfterResolver; - /** The query the log entries were filtered by */ - filterQuery?: FilterQueryResolver; - /** The query the log entries were highlighted with */ - highlightQuery?: HighlightQueryResolver; - /** A list of the log entries */ - entries?: EntriesResolver; - } - - export type StartResolver< - R = InfraTimeKey | null, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type EndResolver< - R = InfraTimeKey | null, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type HasMoreBeforeResolver< - R = boolean, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type HasMoreAfterResolver< - R = boolean, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type FilterQueryResolver< - R = string | null, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type HighlightQueryResolver< - R = string | null, - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; - export type EntriesResolver< - R = InfraLogEntry[], - Parent = InfraLogEntryInterval, - Context = InfraContext - > = Resolver; -} -/** A representation of the log entry's position in the event stream */ -export namespace InfraTimeKeyResolvers { - export interface Resolvers { - /** The timestamp of the event that the log entry corresponds to */ - time?: TimeResolver; - /** The tiebreaker that disambiguates events with the same timestamp */ - tiebreaker?: TiebreakerResolver; - } - - export type TimeResolver = Resolver< - R, - Parent, - Context - >; - export type TiebreakerResolver< - R = number, - Parent = InfraTimeKey, - Context = InfraContext - > = Resolver; -} -/** A log entry */ -export namespace InfraLogEntryResolvers { - export interface Resolvers { - /** A unique representation of the log entry's position in the event stream */ - key?: KeyResolver; - /** The log entry's id */ - gid?: GidResolver; - /** The source id */ - source?: SourceResolver; - /** The columns used for rendering the log entry */ - columns?: ColumnsResolver; - } - - export type KeyResolver< - R = InfraTimeKey, - Parent = InfraLogEntry, - Context = InfraContext - > = Resolver; - export type GidResolver = Resolver< - R, - Parent, - Context - >; - export type SourceResolver = Resolver< - R, - Parent, - Context - >; - export type ColumnsResolver< - R = InfraLogEntryColumn[], - Parent = InfraLogEntry, - Context = InfraContext - > = Resolver; -} -/** A special built-in column that contains the log entry's timestamp */ -export namespace InfraLogEntryTimestampColumnResolvers { - export interface Resolvers { - /** The id of the corresponding column configuration */ - columnId?: ColumnIdResolver; - /** The timestamp */ - timestamp?: TimestampResolver; - } - - export type ColumnIdResolver< - R = string, - Parent = InfraLogEntryTimestampColumn, - Context = InfraContext - > = Resolver; - export type TimestampResolver< - R = number, - Parent = InfraLogEntryTimestampColumn, - Context = InfraContext - > = Resolver; -} -/** A special built-in column that contains the log entry's constructed message */ -export namespace InfraLogEntryMessageColumnResolvers { - export interface Resolvers { - /** The id of the corresponding column configuration */ - columnId?: ColumnIdResolver; - /** A list of the formatted log entry segments */ - message?: MessageResolver; - } - - export type ColumnIdResolver< - R = string, - Parent = InfraLogEntryMessageColumn, - Context = InfraContext - > = Resolver; - export type MessageResolver< - R = InfraLogMessageSegment[], - Parent = InfraLogEntryMessageColumn, - Context = InfraContext - > = Resolver; -} -/** A segment of the log entry message that was derived from a field */ -export namespace InfraLogMessageFieldSegmentResolvers { - export interface Resolvers { - /** The field the segment was derived from */ - field?: FieldResolver; - /** The segment's message */ - value?: ValueResolver; - /** A list of highlighted substrings of the value */ - highlights?: HighlightsResolver; - } - - export type FieldResolver< - R = string, - Parent = InfraLogMessageFieldSegment, - Context = InfraContext - > = Resolver; - export type ValueResolver< - R = string, - Parent = InfraLogMessageFieldSegment, - Context = InfraContext - > = Resolver; - export type HighlightsResolver< - R = string[], - Parent = InfraLogMessageFieldSegment, - Context = InfraContext - > = Resolver; -} -/** A segment of the log entry message that was derived from a string literal */ -export namespace InfraLogMessageConstantSegmentResolvers { - export interface Resolvers { - /** The segment's message */ - constant?: ConstantResolver; - } - - export type ConstantResolver< - R = string, - Parent = InfraLogMessageConstantSegment, - Context = InfraContext - > = Resolver; -} -/** A column that contains the value of a field of the log entry */ -export namespace InfraLogEntryFieldColumnResolvers { - export interface Resolvers { - /** The id of the corresponding column configuration */ - columnId?: ColumnIdResolver; - /** The field name of the column */ - field?: FieldResolver; - /** The value of the field in the log entry */ - value?: ValueResolver; - /** A list of highlighted substrings of the value */ - highlights?: HighlightsResolver; - } - - export type ColumnIdResolver< - R = string, - Parent = InfraLogEntryFieldColumn, - Context = InfraContext - > = Resolver; - export type FieldResolver< - R = string, - Parent = InfraLogEntryFieldColumn, - Context = InfraContext - > = Resolver; - export type ValueResolver< - R = string, - Parent = InfraLogEntryFieldColumn, - Context = InfraContext - > = Resolver; - export type HighlightsResolver< - R = string[], - Parent = InfraLogEntryFieldColumn, - Context = InfraContext - > = Resolver; -} - -export namespace InfraLogItemResolvers { - export interface Resolvers { - /** The ID of the document */ - id?: IdResolver; - /** The index where the document was found */ - index?: IndexResolver; - /** Time key for the document - derived from the source configuration timestamp and tiebreaker settings */ - key?: KeyResolver; - /** An array of flattened fields and values */ - fields?: FieldsResolver; - } - - export type IdResolver = Resolver< - R, - Parent, - Context - >; - export type IndexResolver = Resolver< - R, - Parent, - Context - >; - export type KeyResolver< - R = InfraTimeKey, - Parent = InfraLogItem, - Context = InfraContext - > = Resolver; - export type FieldsResolver< - R = InfraLogItemField[], - Parent = InfraLogItem, - Context = InfraContext - > = Resolver; -} - -export namespace InfraLogItemFieldResolvers { - export interface Resolvers { - /** The flattened field name */ - field?: FieldResolver; - /** The value for the Field as a string */ - value?: ValueResolver; - } - - export type FieldResolver< - R = string, - Parent = InfraLogItemField, - Context = InfraContext - > = Resolver; - export type ValueResolver< - R = string, - Parent = InfraLogItemField, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSnapshotResponseResolvers { - export interface Resolvers { - /** Nodes of type host, container or pod grouped by 0, 1 or 2 terms */ - nodes?: NodesResolver; - } - - export type NodesResolver< - R = InfraSnapshotNode[], - Parent = InfraSnapshotResponse, - Context = InfraContext - > = Resolver; - export interface NodesArgs { - type: InfraNodeType; - - groupBy: InfraSnapshotGroupbyInput[]; - - metric: InfraSnapshotMetricInput; - } -} - -export namespace InfraSnapshotNodeResolvers { - export interface Resolvers { - path?: PathResolver; - - metric?: MetricResolver; - } - - export type PathResolver< - R = InfraSnapshotNodePath[], - Parent = InfraSnapshotNode, - Context = InfraContext - > = Resolver; - export type MetricResolver< - R = InfraSnapshotNodeMetric, - Parent = InfraSnapshotNode, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSnapshotNodePathResolvers { - export interface Resolvers { - value?: ValueResolver; - - label?: LabelResolver; - - ip?: IpResolver; - } - - export type ValueResolver< - R = string, - Parent = InfraSnapshotNodePath, - Context = InfraContext - > = Resolver; - export type LabelResolver< - R = string, - Parent = InfraSnapshotNodePath, - Context = InfraContext - > = Resolver; - export type IpResolver< - R = string | null, - Parent = InfraSnapshotNodePath, - Context = InfraContext - > = Resolver; -} - -export namespace InfraSnapshotNodeMetricResolvers { - export interface Resolvers { - name?: NameResolver; - - value?: ValueResolver; - - avg?: AvgResolver; - - max?: MaxResolver; - } - - export type NameResolver< - R = InfraSnapshotMetricType, - Parent = InfraSnapshotNodeMetric, - Context = InfraContext - > = Resolver; - export type ValueResolver< - R = number | null, - Parent = InfraSnapshotNodeMetric, - Context = InfraContext - > = Resolver; - export type AvgResolver< - R = number | null, - Parent = InfraSnapshotNodeMetric, - Context = InfraContext - > = Resolver; - export type MaxResolver< - R = number | null, - Parent = InfraSnapshotNodeMetric, - Context = InfraContext - > = Resolver; -} - -export namespace InfraMetricDataResolvers { - export interface Resolvers { - id?: IdResolver; - - series?: SeriesResolver; - } - - export type IdResolver< - R = InfraMetric | null, - Parent = InfraMetricData, - Context = InfraContext - > = Resolver; - export type SeriesResolver< - R = InfraDataSeries[], - Parent = InfraMetricData, - Context = InfraContext - > = Resolver; -} - -export namespace InfraDataSeriesResolvers { - export interface Resolvers { - id?: IdResolver; - - label?: LabelResolver; - - data?: DataResolver; - } - - export type IdResolver = Resolver< - R, - Parent, - Context - >; - export type LabelResolver< - R = string, - Parent = InfraDataSeries, - Context = InfraContext - > = Resolver; - export type DataResolver< - R = InfraDataPoint[], - Parent = InfraDataSeries, - Context = InfraContext - > = Resolver; -} - -export namespace InfraDataPointResolvers { - export interface Resolvers { - timestamp?: TimestampResolver; - - value?: ValueResolver; - } - - export type TimestampResolver< - R = number, - Parent = InfraDataPoint, - Context = InfraContext - > = Resolver; - export type ValueResolver< - R = number | null, - Parent = InfraDataPoint, - Context = InfraContext - > = Resolver; -} - -export namespace MutationResolvers { - export interface Resolvers { - /** Create a new source of infrastructure data */ - createSource?: CreateSourceResolver; - /** Modify an existing source */ - updateSource?: UpdateSourceResolver; - /** Delete a source of infrastructure data */ - deleteSource?: DeleteSourceResolver; - } - - export type CreateSourceResolver< - R = UpdateSourceResult, - Parent = never, - Context = InfraContext - > = Resolver; - export interface CreateSourceArgs { - /** The id of the source */ - id: string; - - sourceProperties: UpdateSourceInput; - } - - export type UpdateSourceResolver< - R = UpdateSourceResult, - Parent = never, - Context = InfraContext - > = Resolver; - export interface UpdateSourceArgs { - /** The id of the source */ - id: string; - /** The properties to update the source with */ - sourceProperties: UpdateSourceInput; - } - - export type DeleteSourceResolver< - R = DeleteSourceResult, - Parent = never, - Context = InfraContext - > = Resolver; - export interface DeleteSourceArgs { - /** The id of the source */ - id: string; - } -} -/** The result of a successful source update */ -export namespace UpdateSourceResultResolvers { - export interface Resolvers { - /** The source that was updated */ - source?: SourceResolver; - } - - export type SourceResolver< - R = InfraSource, - Parent = UpdateSourceResult, - Context = InfraContext - > = Resolver; -} -/** The result of a source deletion operations */ -export namespace DeleteSourceResultResolvers { - export interface Resolvers { - /** The id of the source that was deleted */ - id?: IdResolver; - } - - export type IdResolver< - R = string, - Parent = DeleteSourceResult, - Context = InfraContext - > = Resolver; -} diff --git a/x-pack/legacy/plugins/infra/server/infra_server.ts b/x-pack/legacy/plugins/infra/server/infra_server.ts deleted file mode 100644 index f5a4bf8e8e054d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/infra_server.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { IResolvers, makeExecutableSchema } from 'graphql-tools'; -import { initIpToHostName } from './routes/ip_to_hostname'; -import { schemas } from './graphql'; -import { createLogEntriesResolvers } from './graphql/log_entries'; -import { createSourceStatusResolvers } from './graphql/source_status'; -import { createSourcesResolvers } from './graphql/sources'; -import { InfraBackendLibs } from './lib/infra_types'; -import { - initGetLogEntryRateRoute, - initValidateLogAnalysisIndicesRoute, -} from './routes/log_analysis'; -import { initMetricExplorerRoute } from './routes/metrics_explorer'; -import { initMetadataRoute } from './routes/metadata'; -import { initSnapshotRoute } from './routes/snapshot'; -import { initNodeDetailsRoute } from './routes/node_details'; -import { - initLogEntriesSummaryRoute, - initLogEntriesSummaryHighlightsRoute, -} from './routes/log_entries'; -import { initInventoryMetaRoute } from './routes/inventory_metadata'; - -export const initInfraServer = (libs: InfraBackendLibs) => { - const schema = makeExecutableSchema({ - resolvers: [ - createLogEntriesResolvers(libs) as IResolvers, - createSourcesResolvers(libs) as IResolvers, - createSourceStatusResolvers(libs) as IResolvers, - ], - typeDefs: schemas, - }); - - libs.framework.registerGraphQLEndpoint('/graphql', schema); - - initIpToHostName(libs); - initGetLogEntryRateRoute(libs); - initSnapshotRoute(libs); - initNodeDetailsRoute(libs); - initValidateLogAnalysisIndicesRoute(libs); - initLogEntriesSummaryRoute(libs); - initLogEntriesSummaryHighlightsRoute(libs); - initMetricExplorerRoute(libs); - initMetadataRoute(libs); - initInventoryMetaRoute(libs); -}; diff --git a/x-pack/legacy/plugins/infra/server/kibana.index.ts b/x-pack/legacy/plugins/infra/server/kibana.index.ts deleted file mode 100644 index b4301b3edf3678..00000000000000 --- a/x-pack/legacy/plugins/infra/server/kibana.index.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server } from 'hapi'; -import JoiNamespace from 'joi'; - -export interface KbnServer extends Server { - usage: any; -} - -// NP_TODO: this is only used in the root index file AFAICT, can remove after migrating to NP -export const getConfigSchema = (Joi: typeof JoiNamespace) => { - const InfraDefaultSourceConfigSchema = Joi.object({ - metricAlias: Joi.string(), - logAlias: Joi.string(), - fields: Joi.object({ - container: Joi.string(), - host: Joi.string(), - message: Joi.array() - .items(Joi.string()) - .single(), - pod: Joi.string(), - tiebreaker: Joi.string(), - timestamp: Joi.string(), - }), - }); - - // NP_TODO: make sure this is all represented in the NP config schema - const InfraRootConfigSchema = Joi.object({ - enabled: Joi.boolean().default(true), - query: Joi.object({ - partitionSize: Joi.number(), - partitionFactor: Joi.number(), - }).default(), - sources: Joi.object() - .keys({ - default: InfraDefaultSourceConfigSchema, - }) - .default(), - }).default(); - - return InfraRootConfigSchema; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/adapter_types.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/fields/adapter_types.ts deleted file mode 100644 index 3aaa23b3780966..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/adapter_types.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; - -export interface FieldsAdapter { - getIndexFields( - requestContext: RequestHandlerContext, - indices: string, - timefield: string - ): Promise; -} - -export interface IndexFieldDescriptor { - name: string; - type: string; - searchable: boolean; - aggregatable: boolean; - displayable: boolean; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts deleted file mode 100644 index 834c991d5c6a41..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { startsWith, uniq, first } from 'lodash'; -import { RequestHandlerContext } from 'src/core/server'; -import { InfraDatabaseSearchResponse } from '../framework'; -import { KibanaFramework } from '../framework/kibana_framework_adapter'; -import { FieldsAdapter, IndexFieldDescriptor } from './adapter_types'; -import { getAllowedListForPrefix } from '../../../../common/ecs_allowed_list'; -import { getAllCompositeData } from '../../../utils/get_all_composite_data'; -import { createAfterKeyHandler } from '../../../utils/create_afterkey_handler'; - -interface Bucket { - key: { dataset: string }; - doc_count: number; -} - -interface DataSetResponse { - datasets: { - buckets: Bucket[]; - after_key: { - dataset: string; - }; - }; -} - -export class FrameworkFieldsAdapter implements FieldsAdapter { - private framework: KibanaFramework; - - constructor(framework: KibanaFramework) { - this.framework = framework; - } - - public async getIndexFields( - requestContext: RequestHandlerContext, - indices: string, - timefield: string - ): Promise { - const indexPatternsService = this.framework.getIndexPatternsService(requestContext); - const response = await indexPatternsService.getFieldsForWildcard({ - pattern: indices, - }); - const { dataSets, modules } = await this.getDataSetsAndModules( - requestContext, - indices, - timefield - ); - const allowedList = modules.reduce( - (acc, name) => uniq([...acc, ...getAllowedListForPrefix(name)]), - [] as string[] - ); - const dataSetsWithAllowedList = [...allowedList, ...dataSets]; - return response.map(field => ({ - ...field, - displayable: dataSetsWithAllowedList.some(name => startsWith(field.name, name)), - })); - } - - private async getDataSetsAndModules( - requestContext: RequestHandlerContext, - indices: string, - timefield: string - ): Promise<{ dataSets: string[]; modules: string[] }> { - const params = { - index: indices, - allowNoIndices: true, - ignoreUnavailable: true, - body: { - size: 0, - query: { - bool: { - filter: [ - { - range: { - [timefield]: { - gte: 'now-24h', - lte: 'now', - }, - }, - }, - ], - }, - }, - aggs: { - datasets: { - composite: { - sources: [ - { - dataset: { - terms: { - field: 'event.dataset', - }, - }, - }, - ], - }, - }, - }, - }, - }; - - const bucketSelector = (response: InfraDatabaseSearchResponse<{}, DataSetResponse>) => - (response.aggregations && response.aggregations.datasets.buckets) || []; - const handleAfterKey = createAfterKeyHandler( - 'body.aggs.datasets.composite.after', - input => input?.aggregations?.datasets?.after_key - ); - - const buckets = await getAllCompositeData( - this.framework, - requestContext, - params, - bucketSelector, - handleAfterKey - ); - const dataSets = buckets.map(bucket => bucket.key.dataset); - const modules = dataSets.reduce((acc, dataset) => { - const module = first(dataset.split(/\./)); - return module ? uniq([...acc, module]) : acc; - }, [] as string[]); - return { modules, dataSets }; - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/index.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/fields/index.ts deleted file mode 100644 index 4e09b5d0e9e2df..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './adapter_types'; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/framework/adapter_types.ts deleted file mode 100644 index 28d5f75c3fdaf8..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { SearchResponse, GenericParams } from 'elasticsearch'; -import { Lifecycle } from 'hapi'; -import { ObjectType } from '@kbn/config-schema'; -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { RouteMethod, RouteConfig } from '../../../../../../../../src/core/server'; -import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../../plugins/features/server'; -import { SpacesPluginSetup } from '../../../../../../../plugins/spaces/server'; -import { APMPluginContract } from '../../../../../../../plugins/apm/server'; - -// NP_TODO: Compose real types from plugins we depend on, no "any" -export interface InfraServerPluginDeps { - spaces: SpacesPluginSetup; - usageCollection: UsageCollectionSetup; - metrics: { - getVisData: any; - }; - indexPatterns: { - indexPatternsServiceFactory: any; - }; - features: FeaturesPluginSetup; - apm: APMPluginContract; - ___legacy: any; -} - -export interface CallWithRequestParams extends GenericParams { - max_concurrent_shard_requests?: number; - name?: string; - index?: string | string[]; - ignore_unavailable?: boolean; - allow_no_indices?: boolean; - size?: number; - terminate_after?: number; - fields?: string | string[]; -} - -export type InfraResponse = Lifecycle.ReturnValue; - -export interface InfraFrameworkPluginOptions { - register: any; - options: any; -} - -export interface InfraDatabaseResponse { - took: number; - timeout: boolean; -} - -export interface InfraDatabaseSearchResponse - extends InfraDatabaseResponse { - _shards: { - total: number; - successful: number; - skipped: number; - failed: number; - }; - aggregations?: Aggregations; - hits: { - total: { - value: number; - relation: string; - }; - hits: Hit[]; - }; -} - -export interface InfraDatabaseMultiResponse extends InfraDatabaseResponse { - responses: Array>; -} - -export interface InfraDatabaseFieldCapsResponse extends InfraDatabaseResponse { - indices: string[]; - fields: InfraFieldsResponse; -} - -export interface InfraDatabaseGetIndicesAliasResponse { - [indexName: string]: { - aliases: { - [aliasName: string]: any; - }; - }; -} - -export interface InfraDatabaseGetIndicesResponse { - [indexName: string]: { - aliases: { - [aliasName: string]: any; - }; - mappings: { - _meta: object; - dynamic_templates: any[]; - date_detection: boolean; - properties: { - [fieldName: string]: any; - }; - }; - settings: { index: object }; - }; -} - -export type SearchHit = SearchResponse['hits']['hits'][0]; - -export interface SortedSearchHit extends SearchHit { - sort: any[]; - _source: { - [field: string]: any; - }; -} - -export type InfraDateRangeAggregationBucket = { - from?: number; - to?: number; - doc_count: number; - key: string; -} & NestedAggregation; - -export interface InfraDateRangeAggregationResponse { - buckets: Array>; -} - -export interface InfraTopHitsAggregationResponse { - hits: { - hits: []; - }; -} - -export interface InfraMetadataAggregationBucket { - key: string; -} - -export interface InfraMetadataAggregationResponse { - buckets: InfraMetadataAggregationBucket[]; -} - -export interface InfraFieldsResponse { - [name: string]: InfraFieldDef; -} - -export interface InfraFieldDetails { - searchable: boolean; - aggregatable: boolean; - type: string; -} - -export interface InfraFieldDef { - [type: string]: InfraFieldDetails; -} - -export interface InfraTSVBResponse { - [key: string]: InfraTSVBPanel; -} - -export interface InfraTSVBPanel { - id: string; - series: InfraTSVBSeries[]; -} - -export interface InfraTSVBSeries { - id: string; - label: string; - data: InfraTSVBDataPoint[]; -} - -export type InfraTSVBDataPoint = [number, number]; - -export type InfraRouteConfig< - params extends ObjectType, - query extends ObjectType, - body extends ObjectType, - method extends RouteMethod -> = { - method: RouteMethod; -} & RouteConfig; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/index.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/framework/index.ts deleted file mode 100644 index 4e09b5d0e9e2df..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './adapter_types'; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts deleted file mode 100644 index b0cdb8389cb290..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/* eslint-disable @typescript-eslint/array-type */ - -import { GenericParams } from 'elasticsearch'; -import { GraphQLSchema } from 'graphql'; -import { Legacy } from 'kibana'; -import { runHttpQuery } from 'apollo-server-core'; -import { schema, TypeOf, ObjectType } from '@kbn/config-schema'; -import { - InfraRouteConfig, - InfraTSVBResponse, - InfraServerPluginDeps, - CallWithRequestParams, - InfraDatabaseSearchResponse, - InfraDatabaseMultiResponse, - InfraDatabaseFieldCapsResponse, - InfraDatabaseGetIndicesResponse, - InfraDatabaseGetIndicesAliasResponse, -} from './adapter_types'; -import { TSVBMetricModel } from '../../../../common/inventory_models/types'; -import { - CoreSetup, - IRouter, - KibanaRequest, - RequestHandlerContext, - KibanaResponseFactory, - RouteMethod, -} from '../../../../../../../../src/core/server'; -import { RequestHandler } from '../../../../../../../../src/core/server'; -import { InfraConfig } from '../../../../../../../plugins/infra/server'; - -export class KibanaFramework { - public router: IRouter; - private core: CoreSetup; - public plugins: InfraServerPluginDeps; - - constructor(core: CoreSetup, config: InfraConfig, plugins: InfraServerPluginDeps) { - this.router = core.http.createRouter(); - this.core = core; - this.plugins = plugins; - } - - public registerRoute< - params extends ObjectType = any, - query extends ObjectType = any, - body extends ObjectType = any, - method extends RouteMethod = any - >( - config: InfraRouteConfig, - handler: RequestHandler - ) { - const defaultOptions = { - tags: ['access:infra'], - }; - const routeConfig = { - path: config.path, - validate: config.validate, - // Currently we have no use of custom options beyond tags, this can be extended - // beyond defaultOptions if it's needed. - options: defaultOptions, - }; - switch (config.method) { - case 'get': - this.router.get(routeConfig, handler); - break; - case 'post': - this.router.post(routeConfig, handler); - break; - case 'delete': - this.router.delete(routeConfig, handler); - break; - case 'put': - this.router.put(routeConfig, handler); - break; - } - } - - public registerGraphQLEndpoint(routePath: string, gqlSchema: GraphQLSchema) { - // These endpoints are validated by GraphQL at runtime and with GraphQL generated types - const body = schema.object({}, { allowUnknowns: true }); - type Body = TypeOf; - - const routeOptions = { - path: `/api/infra${routePath}`, - validate: { - body, - }, - options: { - tags: ['access:infra'], - }, - }; - async function handler( - context: RequestHandlerContext, - request: KibanaRequest, - response: KibanaResponseFactory - ) { - try { - const query = - request.route.method === 'post' - ? (request.body as Record) - : (request.query as Record); - - const gqlResponse = await runHttpQuery([context, request], { - method: request.route.method.toUpperCase(), - options: (req: RequestHandlerContext, rawReq: KibanaRequest) => ({ - context: { req, rawReq }, - schema: gqlSchema, - }), - query, - }); - - return response.ok({ - body: gqlResponse, - headers: { - 'content-type': 'application/json', - }, - }); - } catch (error) { - const errorBody = { - message: error.message, - }; - - if ('HttpQueryError' !== error.name) { - return response.internalError({ - body: errorBody, - }); - } - - if (error.isGraphQLError === true) { - return response.customError({ - statusCode: error.statusCode, - body: errorBody, - headers: { - 'Content-Type': 'application/json', - }, - }); - } - - const { headers = [], statusCode = 500 } = error; - return response.customError({ - statusCode, - headers, - body: errorBody, - }); - } - } - this.router.post(routeOptions, handler); - this.router.get(routeOptions, handler); - } - - callWithRequest( - requestContext: RequestHandlerContext, - endpoint: 'search', - options?: CallWithRequestParams - ): Promise>; - callWithRequest( - requestContext: RequestHandlerContext, - endpoint: 'msearch', - options?: CallWithRequestParams - ): Promise>; - callWithRequest( - requestContext: RequestHandlerContext, - endpoint: 'fieldCaps', - options?: CallWithRequestParams - ): Promise; - callWithRequest( - requestContext: RequestHandlerContext, - endpoint: 'indices.existsAlias', - options?: CallWithRequestParams - ): Promise; - callWithRequest( - requestContext: RequestHandlerContext, - method: 'indices.getAlias', - options?: object - ): Promise; - callWithRequest( - requestContext: RequestHandlerContext, - method: 'indices.get' | 'ml.getBuckets', - options?: object - ): Promise; - callWithRequest( - requestContext: RequestHandlerContext, - endpoint: string, - options?: CallWithRequestParams - ): Promise; - - public async callWithRequest( - requestContext: RequestHandlerContext, - endpoint: string, - params: CallWithRequestParams - ) { - const { elasticsearch, uiSettings } = requestContext.core; - - const includeFrozen = await uiSettings.client.get('search:includeFrozen'); - if (endpoint === 'msearch') { - const maxConcurrentShardRequests = await uiSettings.client.get( - 'courier:maxConcurrentShardRequests' - ); - if (maxConcurrentShardRequests > 0) { - params = { ...params, max_concurrent_shard_requests: maxConcurrentShardRequests }; - } - } - - const frozenIndicesParams = ['search', 'msearch'].includes(endpoint) - ? { - ignore_throttled: !includeFrozen, - } - : {}; - - return elasticsearch.dataClient.callAsCurrentUser(endpoint, { - ...params, - ...frozenIndicesParams, - }); - } - - public getIndexPatternsService( - requestContext: RequestHandlerContext - ): Legacy.IndexPatternsService { - return this.plugins.indexPatterns.indexPatternsServiceFactory({ - callCluster: async (method: string, args: [GenericParams], ...rest: any[]) => { - const fieldCaps = await this.callWithRequest(requestContext, method, { - ...args, - allowNoIndices: true, - } as GenericParams); - return fieldCaps; - }, - }); - } - - public getSpaceId(request: KibanaRequest): string { - const spacesPlugin = this.plugins.spaces; - - if ( - spacesPlugin && - spacesPlugin.spacesService && - typeof spacesPlugin.spacesService.getSpaceId === 'function' - ) { - return spacesPlugin.spacesService.getSpaceId(request); - } else { - return 'default'; - } - } - - // NP_TODO: [TSVB_GROUP] This method needs fixing when the metrics plugin has migrated to the New Platform - public async makeTSVBRequest( - request: KibanaRequest, - model: TSVBMetricModel, - timerange: { min: number; max: number }, - filters: any[], - requestContext: RequestHandlerContext - ): Promise { - const { getVisData } = this.plugins.metrics; - if (typeof getVisData !== 'function') { - throw new Error('TSVB is not available'); - } - const url = this.core.http.basePath.prepend('/api/metrics/vis/data'); - // For the following request we need a copy of the instnace of the internal request - // but modified for our TSVB request. This will ensure all the instance methods - // are available along with our overriden values - const requestCopy = Object.assign({}, request, { - url, - method: 'POST', - payload: { - timerange, - panels: [model], - filters, - }, - // NP_NOTE: [TSVB_GROUP] Huge hack to make TSVB (getVisData()) work with raw requests that - // originate from the New Platform router (and are very different to the old request object). - // Once TSVB has migrated over to NP, and can work with the new raw requests, or ideally just - // the requestContext, this can be removed. - server: { - plugins: { - elasticsearch: this.plugins.___legacy.tsvb.elasticsearch, - }, - newPlatform: { - __internals: this.plugins.___legacy.tsvb.__internals, - }, - }, - getUiSettingsService: () => requestContext.core.uiSettings.client, - getSavedObjectsClient: () => requestContext.core.savedObjects.client, - }); - return getVisData(requestCopy); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/adapter_types.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/adapter_types.ts deleted file mode 100644 index 41bc2aa2588073..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/adapter_types.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/index.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/index.ts deleted file mode 100644 index 41bc2aa2588073..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts deleted file mode 100644 index ec45171baa7b0a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/* eslint-disable @typescript-eslint/no-empty-interface */ - -import { timeMilliseconds } from 'd3-time'; -import * as runtimeTypes from 'io-ts'; -import first from 'lodash/fp/first'; -import get from 'lodash/fp/get'; -import has from 'lodash/fp/has'; -import zip from 'lodash/fp/zip'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { map, fold } from 'fp-ts/lib/Either'; -import { identity, constant } from 'fp-ts/lib/function'; -import { RequestHandlerContext } from 'src/core/server'; -import { compareTimeKeys, isTimeKey, TimeKey } from '../../../../common/time'; -import { JsonObject } from '../../../../common/typed_json'; -import { - LogEntriesAdapter, - LogEntryDocument, - LogEntryQuery, - LogSummaryBucket, -} from '../../domains/log_entries_domain'; -import { InfraSourceConfiguration } from '../../sources'; -import { SortedSearchHit } from '../framework'; -import { KibanaFramework } from '../framework/kibana_framework_adapter'; - -const DAY_MILLIS = 24 * 60 * 60 * 1000; -const LOOKUP_OFFSETS = [0, 1, 7, 30, 365, 10000, Infinity].map(days => days * DAY_MILLIS); -const TIMESTAMP_FORMAT = 'epoch_millis'; - -interface LogItemHit { - _index: string; - _id: string; - _source: JsonObject; - sort: [number, number]; -} - -export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { - constructor(private readonly framework: KibanaFramework) {} - - public async getAdjacentLogEntryDocuments( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - fields: string[], - start: TimeKey, - direction: 'asc' | 'desc', - maxCount: number, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise { - if (maxCount <= 0) { - return []; - } - - const intervals = getLookupIntervals(start.time, direction); - - let documents: LogEntryDocument[] = []; - for (const [intervalStart, intervalEnd] of intervals) { - if (documents.length >= maxCount) { - break; - } - - const documentsInInterval = await this.getLogEntryDocumentsBetween( - requestContext, - sourceConfiguration, - fields, - intervalStart, - intervalEnd, - documents.length > 0 ? documents[documents.length - 1].key : start, - maxCount - documents.length, - filterQuery, - highlightQuery - ); - - documents = [...documents, ...documentsInInterval]; - } - - return direction === 'asc' ? documents : documents.reverse(); - } - - public async getContainedLogEntryDocuments( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - fields: string[], - start: TimeKey, - end: TimeKey, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise { - const documents = await this.getLogEntryDocumentsBetween( - requestContext, - sourceConfiguration, - fields, - start.time, - end.time, - start, - 10000, - filterQuery, - highlightQuery - ); - - return documents.filter(document => compareTimeKeys(document.key, end) < 0); - } - - public async getContainedLogSummaryBuckets( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - start: number, - end: number, - bucketSize: number, - filterQuery?: LogEntryQuery - ): Promise { - const bucketIntervalStarts = timeMilliseconds(new Date(start), new Date(end), bucketSize); - - const query = { - allowNoIndices: true, - index: sourceConfiguration.logAlias, - ignoreUnavailable: true, - body: { - aggregations: { - count_by_date: { - date_range: { - field: sourceConfiguration.fields.timestamp, - format: TIMESTAMP_FORMAT, - ranges: bucketIntervalStarts.map(bucketIntervalStart => ({ - from: bucketIntervalStart.getTime(), - to: bucketIntervalStart.getTime() + bucketSize, - })), - }, - aggregations: { - top_hits_by_key: { - top_hits: { - size: 1, - sort: [ - { [sourceConfiguration.fields.timestamp]: 'asc' }, - { [sourceConfiguration.fields.tiebreaker]: 'asc' }, - ], - _source: false, - }, - }, - }, - }, - }, - query: { - bool: { - filter: [ - ...createQueryFilterClauses(filterQuery), - { - range: { - [sourceConfiguration.fields.timestamp]: { - gte: start, - lte: end, - format: TIMESTAMP_FORMAT, - }, - }, - }, - ], - }, - }, - size: 0, - track_total_hits: false, - }, - }; - - const response = await this.framework.callWithRequest(requestContext, 'search', query); - - return pipe( - LogSummaryResponseRuntimeType.decode(response), - map(logSummaryResponse => - logSummaryResponse.aggregations.count_by_date.buckets.map( - convertDateRangeBucketToSummaryBucket - ) - ), - fold(constant([]), identity) - ); - } - - public async getLogItem( - requestContext: RequestHandlerContext, - id: string, - sourceConfiguration: InfraSourceConfiguration - ) { - const search = (searchOptions: object) => - this.framework.callWithRequest(requestContext, 'search', searchOptions); - - const params = { - index: sourceConfiguration.logAlias, - terminate_after: 1, - body: { - size: 1, - sort: [ - { [sourceConfiguration.fields.timestamp]: 'desc' }, - { [sourceConfiguration.fields.tiebreaker]: 'desc' }, - ], - query: { - ids: { - values: [id], - }, - }, - }, - }; - - const response = await search(params); - const document = first(response.hits.hits); - if (!document) { - throw new Error('Document not found'); - } - return document; - } - - private async getLogEntryDocumentsBetween( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - fields: string[], - start: number, - end: number, - after: TimeKey | null, - maxCount: number, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise { - if (maxCount <= 0) { - return []; - } - - const sortDirection: 'asc' | 'desc' = start <= end ? 'asc' : 'desc'; - - const startRange = { - [sortDirection === 'asc' ? 'gte' : 'lte']: start, - }; - const endRange = - end === Infinity - ? {} - : { - [sortDirection === 'asc' ? 'lte' : 'gte']: end, - }; - - const highlightClause = highlightQuery - ? { - highlight: { - boundary_scanner: 'word', - fields: fields.reduce( - (highlightFieldConfigs, fieldName) => ({ - ...highlightFieldConfigs, - [fieldName]: {}, - }), - {} - ), - fragment_size: 1, - number_of_fragments: 100, - post_tags: [''], - pre_tags: [''], - highlight_query: highlightQuery, - }, - } - : {}; - - const searchAfterClause = isTimeKey(after) - ? { - search_after: [after.time, after.tiebreaker], - } - : {}; - - const query = { - allowNoIndices: true, - index: sourceConfiguration.logAlias, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: [ - ...createQueryFilterClauses(filterQuery), - { - range: { - [sourceConfiguration.fields.timestamp]: { - ...startRange, - ...endRange, - format: TIMESTAMP_FORMAT, - }, - }, - }, - ], - }, - }, - ...highlightClause, - ...searchAfterClause, - _source: fields, - size: maxCount, - sort: [ - { [sourceConfiguration.fields.timestamp]: sortDirection }, - { [sourceConfiguration.fields.tiebreaker]: sortDirection }, - ], - track_total_hits: false, - }, - }; - - const response = await this.framework.callWithRequest( - requestContext, - 'search', - query - ); - const hits = response.hits.hits; - const documents = hits.map(convertHitToLogEntryDocument(fields)); - - return documents; - } -} - -function getLookupIntervals(start: number, direction: 'asc' | 'desc'): Array<[number, number]> { - const offsetSign = direction === 'asc' ? 1 : -1; - const translatedOffsets = LOOKUP_OFFSETS.map(offset => start + offset * offsetSign); - const intervals = zip(translatedOffsets.slice(0, -1), translatedOffsets.slice(1)) as Array< - [number, number] - >; - return intervals; -} - -const convertHitToLogEntryDocument = (fields: string[]) => ( - hit: SortedSearchHit -): LogEntryDocument => ({ - gid: hit._id, - fields: fields.reduce( - (flattenedFields, fieldName) => - has(fieldName, hit._source) - ? { - ...flattenedFields, - [fieldName]: get(fieldName, hit._source), - } - : flattenedFields, - {} as { [fieldName: string]: string | number | boolean | null } - ), - highlights: hit.highlight || {}, - key: { - time: hit.sort[0], - tiebreaker: hit.sort[1], - }, -}); - -const convertDateRangeBucketToSummaryBucket = ( - bucket: LogSummaryDateRangeBucket -): LogSummaryBucket => ({ - entriesCount: bucket.doc_count, - start: bucket.from || 0, - end: bucket.to || 0, - topEntryKeys: bucket.top_hits_by_key.hits.hits.map(hit => ({ - tiebreaker: hit.sort[1], - time: hit.sort[0], - })), -}); - -const createQueryFilterClauses = (filterQuery: LogEntryQuery | undefined) => - filterQuery ? [filterQuery] : []; - -const LogSummaryDateRangeBucketRuntimeType = runtimeTypes.intersection([ - runtimeTypes.type({ - doc_count: runtimeTypes.number, - key: runtimeTypes.string, - top_hits_by_key: runtimeTypes.type({ - hits: runtimeTypes.type({ - hits: runtimeTypes.array( - runtimeTypes.type({ - sort: runtimeTypes.tuple([runtimeTypes.number, runtimeTypes.number]), - }) - ), - }), - }), - }), - runtimeTypes.partial({ - from: runtimeTypes.number, - to: runtimeTypes.number, - }), -]); - -export interface LogSummaryDateRangeBucket - extends runtimeTypes.TypeOf {} - -const LogSummaryResponseRuntimeType = runtimeTypes.type({ - aggregations: runtimeTypes.type({ - count_by_date: runtimeTypes.type({ - buckets: runtimeTypes.array(LogSummaryDateRangeBucketRuntimeType), - }), - }), -}); - -export interface LogSummaryResponse - extends runtimeTypes.TypeOf {} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/adapter_types.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/adapter_types.ts deleted file mode 100644 index 844eaf76049277..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/adapter_types.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext, KibanaRequest } from 'src/core/server'; -import { - InfraMetric, - InfraMetricData, - InfraNodeType, - InfraTimerangeInput, -} from '../../../graphql/types'; -import { InfraSourceConfiguration } from '../../sources'; - -export interface InfraMetricsRequestOptions { - nodeIds: { - nodeId: string; - cloudId?: string | null; - }; - nodeType: InfraNodeType; - sourceConfiguration: InfraSourceConfiguration; - timerange: InfraTimerangeInput; - metrics: InfraMetric[]; -} - -export interface InfraMetricsAdapter { - getMetrics( - requestContext: RequestHandlerContext, - options: InfraMetricsRequestOptions, - request: KibanaRequest - ): Promise; -} - -export enum InfraMetricModelQueryType { - lucene = 'lucene', - kuery = 'kuery', -} - -export enum InfraMetricModelMetricType { - avg = 'avg', - max = 'max', - min = 'min', - calculation = 'calculation', - cardinality = 'cardinality', - series_agg = 'series_agg', // eslint-disable-line @typescript-eslint/camelcase - positive_only = 'positive_only', // eslint-disable-line @typescript-eslint/camelcase - derivative = 'derivative', - count = 'count', - sum = 'sum', - cumulative_sum = 'cumulative_sum', // eslint-disable-line @typescript-eslint/camelcase -} - -export interface InfraMetricModel { - id: InfraMetric; - requires: string[]; - index_pattern: string | string[]; - interval: string; - time_field: string; - type: string; - series: InfraMetricModelSeries[]; - filter?: string; - map_field_to?: string; - id_type?: 'cloud' | 'node'; -} - -export interface InfraMetricModelSeries { - id: string; - metrics: InfraMetricModelMetric[]; - split_mode: string; - terms_field?: string; - terms_size?: number; - terms_order_by?: string; - filter?: { query: string; language: InfraMetricModelQueryType }; -} - -export interface InfraMetricModelBasicMetric { - id: string; - field?: string | null; - type: InfraMetricModelMetricType; -} - -export interface InfraMetricModelSeriesAgg { - id: string; - function: string; - type: InfraMetricModelMetricType.series_agg; // eslint-disable-line @typescript-eslint/camelcase -} - -export interface InfraMetricModelDerivative { - id: string; - field: string; - unit: string; - type: InfraMetricModelMetricType; -} - -export interface InfraMetricModelBucketScriptVariable { - field: string; - id: string; - name: string; -} - -export interface InfraMetricModelCount { - id: string; - type: InfraMetricModelMetricType.count; -} - -export interface InfraMetricModelBucketScript { - id: string; - script: string; - type: InfraMetricModelMetricType.calculation; - variables: InfraMetricModelBucketScriptVariable[]; -} - -export type InfraMetricModelMetric = - | InfraMetricModelCount - | InfraMetricModelBasicMetric - | InfraMetricModelBucketScript - | InfraMetricModelDerivative - | InfraMetricModelSeriesAgg; - -export type InfraMetricModelCreator = ( - timeField: string, - indexPattern: string | string[], - interval: string -) => InfraMetricModel; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/index.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/index.ts deleted file mode 100644 index 4e09b5d0e9e2df..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './adapter_types'; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts deleted file mode 100644 index c1b567576c2149..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; -import { flatten, get } from 'lodash'; -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { InfraMetric, InfraMetricData } from '../../../graphql/types'; -import { KibanaFramework } from '../framework/kibana_framework_adapter'; -import { InfraMetricsAdapter, InfraMetricsRequestOptions } from './adapter_types'; -import { checkValidNode } from './lib/check_valid_node'; -import { metrics, findInventoryFields } from '../../../../common/inventory_models'; -import { TSVBMetricModelCreator } from '../../../../common/inventory_models/types'; -import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; - -export class KibanaMetricsAdapter implements InfraMetricsAdapter { - private framework: KibanaFramework; - - constructor(framework: KibanaFramework) { - this.framework = framework; - } - - public async getMetrics( - requestContext: RequestHandlerContext, - options: InfraMetricsRequestOptions, - rawRequest: KibanaRequest - ): Promise { - const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`; - const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - const nodeField = fields.id; - - const search = (searchOptions: object) => - this.framework.callWithRequest<{}, Aggregation>(requestContext, 'search', searchOptions); - - const validNode = await checkValidNode(search, indexPattern, nodeField, options.nodeIds.nodeId); - if (!validNode) { - throw new Error( - i18n.translate('xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage', { - defaultMessage: '{nodeId} does not exist.', - values: { - nodeId: options.nodeIds.nodeId, - }, - }) - ); - } - - const requests = options.metrics.map(metricId => - this.makeTSVBRequest(metricId, options, rawRequest, nodeField, requestContext) - ); - - return Promise.all(requests) - .then(results => { - return results.map(result => { - const metricIds = Object.keys(result).filter( - k => !['type', 'uiRestrictions'].includes(k) - ); - - return metricIds.map((id: string) => { - const infraMetricId: InfraMetric = (InfraMetric as any)[id]; - if (!infraMetricId) { - throw new Error( - i18n.translate('xpack.infra.kibanaMetrics.invalidInfraMetricErrorMessage', { - defaultMessage: '{id} is not a valid InfraMetric', - values: { - id, - }, - }) - ); - } - const panel = result[infraMetricId]; - return { - id: infraMetricId, - series: panel.series.map(series => { - return { - id: series.id, - label: series.label, - data: series.data.map(point => ({ timestamp: point[0], value: point[1] })), - }; - }), - }; - }); - }); - }) - .then(result => flatten(result)); - } - - async makeTSVBRequest( - metricId: InfraMetric, - options: InfraMetricsRequestOptions, - req: KibanaRequest, - nodeField: string, - requestContext: RequestHandlerContext - ) { - const createTSVBModel = get(metrics, ['tsvb', metricId]) as TSVBMetricModelCreator | undefined; - if (!createTSVBModel) { - throw new Error( - i18n.translate('xpack.infra.metrics.missingTSVBModelError', { - defaultMessage: 'The TSVB model for {metricId} does not exist for {nodeType}', - values: { - metricId, - nodeType: options.nodeType, - }, - }) - ); - } - - const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`; - const timerange = { - min: options.timerange.from, - max: options.timerange.to, - }; - - const model = createTSVBModel( - options.sourceConfiguration.fields.timestamp, - indexPattern, - options.timerange.interval - ); - const calculatedInterval = await calculateMetricInterval( - this.framework, - requestContext, - { - indexPattern: `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`, - timestampField: options.sourceConfiguration.fields.timestamp, - timerange: options.timerange, - }, - model.requires - ); - - if (calculatedInterval) { - model.interval = `>=${calculatedInterval}s`; - } - - if (model.id_type === 'cloud' && !options.nodeIds.cloudId) { - throw new Error( - i18n.translate('xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage', { - defaultMessage: - 'Model for {metricId} requires a cloudId, but none was given for {nodeId}.', - values: { - metricId, - nodeId: options.nodeIds.nodeId, - }, - }) - ); - } - const id = - model.id_type === 'cloud' ? (options.nodeIds.cloudId as string) : options.nodeIds.nodeId; - const filters = model.map_field_to - ? [{ match: { [model.map_field_to]: id } }] - : [{ match: { [nodeField]: id } }]; - - return this.framework.makeTSVBRequest(req, model, timerange, filters, requestContext); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/check_valid_node.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/check_valid_node.ts deleted file mode 100644 index bca509334b6924..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/check_valid_node.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraDatabaseSearchResponse } from '../../framework'; - -export const checkValidNode = async ( - search: (options: object) => Promise>, - indexPattern: string | string[], - field: string, - id: string -): Promise => { - const params = { - allowNoIndices: true, - ignoreUnavailable: true, - index: indexPattern, - terminateAfter: 1, - body: { - size: 0, - query: { - match: { - [field]: id, - }, - }, - }, - }; - - const result = await search(params); - return result && result.hits && result.hits.total && result.hits.total.value > 0; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/errors.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/errors.ts deleted file mode 100644 index 750858f3ce1fa6..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/lib/errors.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ApolloError } from 'apollo-server-errors'; -import { InfraMetricsErrorCodes } from '../../../../../common/errors'; - -export class InvalidNodeError extends ApolloError { - constructor(message: string) { - super(message, InfraMetricsErrorCodes.invalid_node); - Object.defineProperty(this, 'name', { value: 'InvalidNodeError' }); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts deleted file mode 100644 index 635f6ff9762c5d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { InfraSourceStatusAdapter } from '../../source_status'; -import { InfraDatabaseGetIndicesResponse } from '../framework'; -import { KibanaFramework } from '../framework/kibana_framework_adapter'; - -export class InfraElasticsearchSourceStatusAdapter implements InfraSourceStatusAdapter { - constructor(private readonly framework: KibanaFramework) {} - - public async getIndexNames(requestContext: RequestHandlerContext, aliasName: string) { - const indexMaps = await Promise.all([ - this.framework - .callWithRequest(requestContext, 'indices.getAlias', { - name: aliasName, - filterPath: '*.settings.index.uuid', // to keep the response size as small as possible - }) - .catch(withDefaultIfNotFound({})), - this.framework - .callWithRequest(requestContext, 'indices.get', { - index: aliasName, - filterPath: '*.settings.index.uuid', // to keep the response size as small as possible - }) - .catch(withDefaultIfNotFound({})), - ]); - - return indexMaps.reduce( - (indexNames, indexMap) => [...indexNames, ...Object.keys(indexMap)], - [] as string[] - ); - } - - public async hasAlias(requestContext: RequestHandlerContext, aliasName: string) { - return await this.framework.callWithRequest(requestContext, 'indices.existsAlias', { - name: aliasName, - }); - } - - public async hasIndices(requestContext: RequestHandlerContext, indexNames: string) { - return await this.framework - .callWithRequest(requestContext, 'search', { - ignore_unavailable: true, - allow_no_indices: true, - index: indexNames, - size: 0, - terminate_after: 1, - }) - .then( - response => response._shards.total > 0, - err => { - if (err.status === 404) { - return false; - } - throw err; - } - ); - } -} - -const withDefaultIfNotFound = (defaultValue: DefaultValue) => ( - error: any -): DefaultValue => { - if (error && error.status === 404) { - return defaultValue; - } - throw error; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/index.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/index.ts deleted file mode 100644 index f5adfe190f8055..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/source_status/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { InfraElasticsearchSourceStatusAdapter } from './elasticsearch_source_status_adapter'; diff --git a/x-pack/legacy/plugins/infra/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/infra/server/lib/compose/kibana.ts deleted file mode 100644 index 305841aa52d36c..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/compose/kibana.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { FrameworkFieldsAdapter } from '../adapters/fields/framework_fields_adapter'; -import { KibanaFramework } from '../adapters/framework/kibana_framework_adapter'; -import { InfraKibanaLogEntriesAdapter } from '../adapters/log_entries/kibana_log_entries_adapter'; -import { KibanaMetricsAdapter } from '../adapters/metrics/kibana_metrics_adapter'; -import { InfraElasticsearchSourceStatusAdapter } from '../adapters/source_status'; -import { InfraFieldsDomain } from '../domains/fields_domain'; -import { InfraLogEntriesDomain } from '../domains/log_entries_domain'; -import { InfraMetricsDomain } from '../domains/metrics_domain'; -import { InfraBackendLibs, InfraDomainLibs } from '../infra_types'; -import { InfraLogAnalysis } from '../log_analysis'; -import { InfraSnapshot } from '../snapshot'; -import { InfraSourceStatus } from '../source_status'; -import { InfraSources } from '../sources'; -import { InfraConfig } from '../../../../../../plugins/infra/server'; -import { CoreSetup } from '../../../../../../../src/core/server'; -import { InfraServerPluginDeps } from '../adapters/framework/adapter_types'; - -export function compose(core: CoreSetup, config: InfraConfig, plugins: InfraServerPluginDeps) { - const framework = new KibanaFramework(core, config, plugins); - const sources = new InfraSources({ - config, - }); - const sourceStatus = new InfraSourceStatus(new InfraElasticsearchSourceStatusAdapter(framework), { - sources, - }); - const snapshot = new InfraSnapshot({ sources, framework }); - const logAnalysis = new InfraLogAnalysis({ framework }); - - // TODO: separate these out individually and do away with "domains" as a temporary group - const domainLibs: InfraDomainLibs = { - fields: new InfraFieldsDomain(new FrameworkFieldsAdapter(framework), { - sources, - }), - logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { - sources, - }), - metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), - }; - - const libs: InfraBackendLibs = { - configuration: config, // NP_TODO: Do we ever use this anywhere? - framework, - logAnalysis, - snapshot, - sources, - sourceStatus, - ...domainLibs, - }; - - return libs; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/constants.ts b/x-pack/legacy/plugins/infra/server/lib/constants.ts deleted file mode 100644 index 0765256c4160c3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const CLOUD_METRICS_MODULES = ['aws']; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/fields_domain.ts b/x-pack/legacy/plugins/infra/server/lib/domains/fields_domain.ts deleted file mode 100644 index a00c76216da4c1..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/fields_domain.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { InfraIndexField, InfraIndexType } from '../../graphql/types'; -import { FieldsAdapter } from '../adapters/fields'; -import { InfraSources } from '../sources'; - -export class InfraFieldsDomain { - constructor( - private readonly adapter: FieldsAdapter, - private readonly libs: { sources: InfraSources } - ) {} - - public async getFields( - requestContext: RequestHandlerContext, - sourceId: string, - indexType: InfraIndexType - ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const includeMetricIndices = [InfraIndexType.ANY, InfraIndexType.METRICS].includes(indexType); - const includeLogIndices = [InfraIndexType.ANY, InfraIndexType.LOGS].includes(indexType); - - const fields = await this.adapter.getIndexFields( - requestContext, - `${includeMetricIndices ? configuration.metricAlias : ''},${ - includeLogIndices ? configuration.logAlias : '' - }`, - configuration.fields.timestamp - ); - - return fields; - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts deleted file mode 100644 index 367ae6a0cae89d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('Apache2 Access', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'apache.access', - 'event.module': 'apache', - 'fileset.name': 'access', - 'http.request.method': 'GET', - 'http.request.referrer': '-', - 'http.response.body.bytes': 499, - 'http.response.status_code': 404, - 'http.version': '1.1', - 'input.type': 'log', - 'log.offset': 73, - 'service.type': 'apache', - 'source.address': '192.168.33.1', - 'source.ip': '192.168.33.1', - 'url.original': '/hello', - 'user.name': '-', - 'user_agent.device': 'Other', - 'user_agent.major': '50', - 'user_agent.minor': '0', - 'user_agent.name': 'Firefox', - 'user_agent.original': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0', - 'user_agent.os.full_name': 'Mac OS X 10.12', - 'user_agent.os.major': '10', - 'user_agent.os.minor': '12', - 'user_agent.os.name': 'Mac OS X', - }; - const highlights = { - 'http.request.method': ['GET'], - }; - - expect(format(flattenedDocument, highlights)).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.module", - "highlights": Array [], - "value": "apache", - }, - Object { - "constant": "][access] ", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "192.168.33.1", - }, - Object { - "constant": " ", - }, - Object { - "field": "user.name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "http.request.method", - "highlights": Array [ - "GET", - ], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "url.original", - "highlights": Array [], - "value": "/hello", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "http.version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "http.response.status_code", - "highlights": Array [], - "value": "404", - }, - Object { - "constant": " ", - }, - Object { - "field": "http.response.body.bytes", - "highlights": Array [], - "value": "499", - }, -] -`); - }); - - test('Apache2 Error', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:08.000Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'apache.error', - 'event.module': 'apache', - 'fileset.name': 'error', - 'input.type': 'log', - 'log.level': 'error', - 'log.offset': 0, - message: 'File does not exist: /var/www/favicon.ico', - 'service.type': 'apache', - 'source.address': '192.168.33.1', - 'source.ip': '192.168.33.1', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[apache][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "error", - }, - Object { - "constant": "] ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "File does not exist: /var/www/favicon.ico", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('Apache2 Access', () => { - const flattenedDocument = { - 'apache2.access': true, - 'apache2.access.remote_ip': '192.168.1.42', - 'apache2.access.user_name': 'admin', - 'apache2.access.method': 'GET', - 'apache2.access.url': '/faqs', - 'apache2.access.http_version': '1.1', - 'apache2.access.response_code': '200', - 'apache2.access.body_sent.bytes': 1024, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[apache][access] ", - }, - Object { - "field": "apache2.access.remote_ip", - "highlights": Array [], - "value": "192.168.1.42", - }, - Object { - "constant": " ", - }, - Object { - "field": "apache2.access.user_name", - "highlights": Array [], - "value": "admin", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "apache2.access.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "apache2.access.url", - "highlights": Array [], - "value": "/faqs", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "apache2.access.http_version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "apache2.access.response_code", - "highlights": Array [], - "value": "200", - }, - Object { - "constant": " ", - }, - Object { - "field": "apache2.access.body_sent.bytes", - "highlights": Array [], - "value": "1024", - }, -] -`); - }); - - test('Apache2 Error', () => { - const flattenedDocument = { - 'apache2.error.message': - 'AH00489: Apache/2.4.18 (Ubuntu) configured -- resuming normal operations', - 'apache2.error.level': 'notice', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[apache][", - }, - Object { - "field": "apache2.error.level", - "highlights": Array [], - "value": "notice", - }, - Object { - "constant": "] ", - }, - Object { - "field": "apache2.error.message", - "highlights": Array [], - "value": "AH00489: Apache/2.4.18 (Ubuntu) configured -- resuming normal operations", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts deleted file mode 100644 index fe7ebffe91329b..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatApache2Rules = [ - { - // pre-ECS - when: { - exists: ['apache2.access'], - }, - format: [ - { - constant: '[apache][access] ', - }, - { - field: 'apache2.access.remote_ip', - }, - { - constant: ' ', - }, - { - field: 'apache2.access.user_name', - }, - { - constant: ' "', - }, - { - field: 'apache2.access.method', - }, - { - constant: ' ', - }, - { - field: 'apache2.access.url', - }, - { - constant: ' HTTP/', - }, - { - field: 'apache2.access.http_version', - }, - { - constant: '" ', - }, - { - field: 'apache2.access.response_code', - }, - { - constant: ' ', - }, - { - field: 'apache2.access.body_sent.bytes', - }, - ], - }, - { - // ECS - when: { - values: { - 'event.dataset': 'apache.error', - }, - }, - format: [ - { - constant: '[apache][', - }, - { - field: 'log.level', - }, - { - constant: '] ', - }, - { - field: 'message', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['apache2.error.message'], - }, - format: [ - { - constant: '[apache][', - }, - { - field: 'apache2.error.level', - }, - { - constant: '] ', - }, - { - field: 'apache2.error.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts deleted file mode 100644 index aa490c595d9fd9..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatAuditdRules } from './filebeat_auditd'; - -const { format } = compileFormattingRules(filebeatAuditdRules); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('auditd log with outcome', () => { - const flattenedDocument = { - '@timestamp': '2016-12-07T02:17:21.515Z', - 'auditd.log': { - addr: '96.241.146.97', - cipher: 'chacha20-poly1305@openssh.com', - direction: 'from-server', - ksize: '512', - laddr: '10.142.0.2', - lport: '22', - pfs: 'curve25519-sha256@libssh.org', - rport: '63927', - sequence: 406, - ses: '4294967295', - spid: '1299', - subj: 'system_u:system_r:sshd_t:s0-s0:c0.c1023', - }, - 'ecs.version': '1.0.0-beta2', - 'event.action': 'crypto_session', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'event.outcome': 'success', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 783, - message: 'op=start', - process: { executable: '/usr/sbin/sshd', pid: 1298 }, - 'service.type': 'auditd', - user: { 'audit.id': '4294967295', id: '0', 'saved.id': '74' }, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[AuditD][", - }, - Object { - "field": "event.action", - "highlights": Array [], - "value": "crypto_session", - }, - Object { - "constant": "]", - }, - Object { - "constant": " ", - }, - Object { - "field": "event.outcome", - "highlights": Array [], - "value": "success", - }, - Object { - "constant": " ", - }, - Object { - "constant": "user", - }, - Object { - "constant": "=", - }, - Object { - "field": "user", - "highlights": Array [], - "value": "{\\"audit.id\\":\\"4294967295\\",\\"id\\":\\"0\\",\\"saved.id\\":\\"74\\"}", - }, - Object { - "constant": " ", - }, - Object { - "constant": "process", - }, - Object { - "constant": "=", - }, - Object { - "field": "process", - "highlights": Array [], - "value": "{\\"executable\\":\\"/usr/sbin/sshd\\",\\"pid\\":1298}", - }, - Object { - "constant": " ", - }, - Object { - "field": "auditd.log", - "highlights": Array [], - "value": "{\\"addr\\":\\"96.241.146.97\\",\\"cipher\\":\\"chacha20-poly1305@openssh.com\\",\\"direction\\":\\"from-server\\",\\"ksize\\":\\"512\\",\\"laddr\\":\\"10.142.0.2\\",\\"lport\\":\\"22\\",\\"pfs\\":\\"curve25519-sha256@libssh.org\\",\\"rport\\":\\"63927\\",\\"sequence\\":406,\\"ses\\":\\"4294967295\\",\\"spid\\":\\"1299\\",\\"subj\\":\\"system_u:system_r:sshd_t:s0-s0:c0.c1023\\"}", - }, - Object { - "constant": " ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "op=start", - }, -] -`); - }); - - test('auditd log without outcome', () => { - const flattenedDocument = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log': { - a0: '9', - a1: '7f564b2672a0', - a2: 'b8', - a3: '0', - exit: '184', - items: '0', - sequence: 18877199, - ses: '4294967295', - success: 'yes', - syscall: '44', - tty: '(none)', - }, - 'ecs.version': '1.0.0-beta2', - 'event.action': 'syscall', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'host.architecture': 'x86_64', - 'input.type': 'log', - 'log.offset': 174, - process: { - executable: '/usr/libexec/strongswan/charon (deleted)', - name: 'charon', - pid: 1281, - ppid: 1240, - }, - 'service.type': 'auditd', - user: { - 'audit.id': '4294967295', - 'effective.group.id': '0', - 'effective.id': '0', - 'filesystem.group.id': '0', - 'filesystem.id': '0', - 'group.id': '0', - id: '0', - 'saved.group.id': '0', - 'saved.id': '0', - }, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[AuditD][", - }, - Object { - "field": "event.action", - "highlights": Array [], - "value": "syscall", - }, - Object { - "constant": "]", - }, - Object { - "constant": " ", - }, - Object { - "constant": "user", - }, - Object { - "constant": "=", - }, - Object { - "field": "user", - "highlights": Array [], - "value": "{\\"audit.id\\":\\"4294967295\\",\\"effective.group.id\\":\\"0\\",\\"effective.id\\":\\"0\\",\\"filesystem.group.id\\":\\"0\\",\\"filesystem.id\\":\\"0\\",\\"group.id\\":\\"0\\",\\"id\\":\\"0\\",\\"saved.group.id\\":\\"0\\",\\"saved.id\\":\\"0\\"}", - }, - Object { - "constant": " ", - }, - Object { - "constant": "process", - }, - Object { - "constant": "=", - }, - Object { - "field": "process", - "highlights": Array [], - "value": "{\\"executable\\":\\"/usr/libexec/strongswan/charon (deleted)\\",\\"name\\":\\"charon\\",\\"pid\\":1281,\\"ppid\\":1240}", - }, - Object { - "constant": " ", - }, - Object { - "field": "auditd.log", - "highlights": Array [], - "value": "{\\"a0\\":\\"9\\",\\"a1\\":\\"7f564b2672a0\\",\\"a2\\":\\"b8\\",\\"a3\\":\\"0\\",\\"exit\\":\\"184\\",\\"items\\":\\"0\\",\\"sequence\\":18877199,\\"ses\\":\\"4294967295\\",\\"success\\":\\"yes\\",\\"syscall\\":\\"44\\",\\"tty\\":\\"(none)\\"}", - }, - Object { - "constant": " ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "undefined", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('auditd IPSEC rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.dst': '192.168.0.0', - 'auditd.log.dst_prefixlen': '16', - 'auditd.log.op': 'SPD-delete', - 'auditd.log.record_type': 'MAC_IPSEC_EVENT', - 'auditd.log.res': '1', - 'auditd.log.sequence': 18877201, - 'auditd.log.ses': '4294967295', - 'auditd.log.src': '192.168.2.0', - 'auditd.log.src_prefixlen': '24', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 0, - }; - const message = format(event, {}); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'MAC_IPSEC_EVENT' }, - { constant: '] src:' }, - { field: 'auditd.log.src', highlights: [], value: '192.168.2.0' }, - { constant: ' dst:' }, - { field: 'auditd.log.dst', highlights: [], value: '192.168.0.0' }, - { constant: ' op:' }, - { field: 'auditd.log.op', highlights: [], value: 'SPD-delete' }, - ]); - }); - - test('AuditD SYSCALL rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.a0': '9', - 'auditd.log.a1': '7f564b2672a0', - 'auditd.log.a2': 'b8', - 'auditd.log.a3': '0', - 'auditd.log.arch': 'x86_64', - 'auditd.log.auid': '4294967295', - 'auditd.log.comm': 'charon', - 'auditd.log.egid': '0', - 'auditd.log.euid': '0', - 'auditd.log.exe': '/usr/libexec/strongswan/charon (deleted)', - 'auditd.log.exit': '184', - 'auditd.log.fsgid': '0', - 'auditd.log.fsuid': '0', - 'auditd.log.gid': '0', - 'auditd.log.items': '0', - 'auditd.log.pid': '1281', - 'auditd.log.ppid': '1240', - 'auditd.log.record_type': 'SYSCALL', - 'auditd.log.sequence': 18877199, - 'auditd.log.ses': '4294967295', - 'auditd.log.sgid': '0', - 'auditd.log.success': 'yes', - 'auditd.log.suid': '0', - 'auditd.log.syscall': '44', - 'auditd.log.tty': '(none)', - 'auditd.log.uid': '0', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event, {}); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'SYSCALL' }, - { constant: '] exe:' }, - { - field: 'auditd.log.exe', - highlights: [], - value: '/usr/libexec/strongswan/charon (deleted)', - }, - { constant: ' gid:' }, - { field: 'auditd.log.gid', highlights: [], value: '0' }, - { constant: ' uid:' }, - { field: 'auditd.log.uid', highlights: [], value: '0' }, - { constant: ' tty:' }, - { field: 'auditd.log.tty', highlights: [], value: '(none)' }, - { constant: ' pid:' }, - { field: 'auditd.log.pid', highlights: [], value: '1281' }, - { constant: ' ppid:' }, - { field: 'auditd.log.ppid', highlights: [], value: '1240' }, - ]); - }); - - test('AuditD events with msg rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.record_type': 'EXAMPLE', - 'auditd.log.msg': 'some kind of message', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event, {}); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, - { constant: '] ' }, - { - field: 'auditd.log.msg', - highlights: [], - value: 'some kind of message', - }, - ]); - }); - - test('AuditD catchall rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.record_type': 'EXAMPLE', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event, {}); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, - { constant: '] Event without message.' }, - ]); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts deleted file mode 100644 index d2557cf1599ce4..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { labelField } from './helpers'; - -const commonActionField = [{ constant: '[AuditD][' }, { field: 'event.action' }, { constant: ']' }]; -const commonOutcomeField = [{ constant: ' ' }, { field: 'event.outcome' }]; - -export const filebeatAuditdRules = [ - { - // ECS format with outcome - when: { - exists: ['ecs.version', 'event.action', 'event.outcome', 'auditd.log'], - }, - format: [ - ...commonActionField, - ...commonOutcomeField, - ...labelField('user', 'user'), - ...labelField('process', 'process'), - { constant: ' ' }, - { field: 'auditd.log' }, - { constant: ' ' }, - { field: 'message' }, - ], - }, - { - // ECS format without outcome - when: { - exists: ['ecs.version', 'event.action', 'auditd.log'], - }, - format: [ - ...commonActionField, - ...labelField('user', 'user'), - ...labelField('process', 'process'), - { constant: ' ' }, - { field: 'auditd.log' }, - { constant: ' ' }, - { field: 'message' }, - ], - }, - { - // pre-ECS IPSEC_EVENT Rule - when: { - exists: ['auditd.log.record_type', 'auditd.log.src', 'auditd.log.dst', 'auditd.log.op'], - values: { - 'auditd.log.record_type': 'MAC_IPSEC_EVENT', - }, - }, - format: [ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type' }, - { constant: '] src:' }, - { field: 'auditd.log.src' }, - { constant: ' dst:' }, - { field: 'auditd.log.dst' }, - { constant: ' op:' }, - { field: 'auditd.log.op' }, - ], - }, - { - // pre-ECS SYSCALL Rule - when: { - exists: [ - 'auditd.log.record_type', - 'auditd.log.exe', - 'auditd.log.gid', - 'auditd.log.uid', - 'auditd.log.tty', - 'auditd.log.pid', - 'auditd.log.ppid', - ], - values: { - 'auditd.log.record_type': 'SYSCALL', - }, - }, - format: [ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type' }, - { constant: '] exe:' }, - { field: 'auditd.log.exe' }, - { constant: ' gid:' }, - { field: 'auditd.log.gid' }, - { constant: ' uid:' }, - { field: 'auditd.log.uid' }, - { constant: ' tty:' }, - { field: 'auditd.log.tty' }, - { constant: ' pid:' }, - { field: 'auditd.log.pid' }, - { constant: ' ppid:' }, - { field: 'auditd.log.ppid' }, - ], - }, - { - // pre-ECS Events with `msg` Rule - when: { - exists: ['auditd.log.record_type', 'auditd.log.msg'], - }, - format: [ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type' }, - { constant: '] ' }, - { field: 'auditd.log.msg' }, - ], - }, - { - // pre-ECS Events with `msg` Rule - when: { - exists: ['auditd.log.record_type'], - }, - format: [ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type' }, - { constant: '] Event without message.' }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts deleted file mode 100644 index 752b61684887e3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts +++ /dev/null @@ -1,791 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatHaproxyRules } from './filebeat_haproxy'; - -const { format } = compileFormattingRules(filebeatHaproxyRules); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('haproxy default log', () => { - const flattenedDocument = { - 'destination.ip': '1.2.3.4', - 'destination.port': 5000, - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'haproxy.log', - 'event.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.frontend_name': 'main', - 'haproxy.mode': 'HTTP', - 'haproxy.source': '1.2.3.4', - 'input.type': 'log', - 'log.offset': 0, - 'process.name': 'haproxy', - 'process.pid': 24551, - 'service.type': 'haproxy', - 'source.address': '1.2.3.4', - 'source.geo.continent_name': 'North America', - 'source.geo.country_iso_code': 'US', - 'source.geo.location.lat': 37.751, - 'source.geo.location.lon': -97.822, - 'source.ip': '1.2.3.4', - 'source.port': 40780, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy] ", - }, - Object { - "field": "source.address", - "highlights": Array [], - "value": "1.2.3.4", - }, - Object { - "constant": ":", - }, - Object { - "field": "source.port", - "highlights": Array [], - "value": "40780", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "main", - }, -] -`); - }); - - test('haproxy tcp log', () => { - const flattenedDocument = { - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'haproxy.log', - 'event.duration': 1000000, - 'event.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.backend_name': 'app', - 'haproxy.backend_queue': 0, - 'haproxy.bytes_read': 212, - 'haproxy.connection_wait_time_ms': -1, - 'haproxy.connections.active': 1, - 'haproxy.connections.backend': 0, - 'haproxy.connections.frontend': 1, - 'haproxy.connections.retries': 0, - 'haproxy.connections.server': 0, - 'haproxy.frontend_name': 'main', - 'haproxy.server_name': '', - 'haproxy.server_queue': 0, - 'haproxy.source': '127.0.0.1', - 'haproxy.termination_state': 'SC', - 'haproxy.total_waiting_time_ms': -1, - 'input.type': 'log', - 'log.offset': 0, - 'process.name': 'haproxy', - 'process.pid': 25457, - 'service.type': 'haproxy', - 'source.address': '127.0.0.1', - 'source.ip': '127.0.0.1', - 'source.port': 40962, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy][tcp] ", - }, - Object { - "field": "source.address", - "highlights": Array [], - "value": "127.0.0.1", - }, - Object { - "constant": ":", - }, - Object { - "field": "source.port", - "highlights": Array [], - "value": "40962", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "main", - }, - Object { - "constant": " -> ", - }, - Object { - "field": "haproxy.backend_name", - "highlights": Array [], - "value": "app", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.server_name", - "highlights": Array [], - "value": "", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.connections.active", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.frontend", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.backend", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.server", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.retries", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.server_queue", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.backend_queue", - "highlights": Array [], - "value": "0", - }, -] -`); - }); - - test('haproxy http log', () => { - const flattenedDocument = { - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'haproxy.log', - 'event.duration': 2000000, - 'event.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.backend_name': 'docs_microservice', - 'haproxy.backend_queue': 0, - 'haproxy.bytes_read': 168, - 'haproxy.connection_wait_time_ms': 1, - 'haproxy.connections.active': 6, - 'haproxy.connections.backend': 0, - 'haproxy.connections.frontend': 6, - 'haproxy.connections.retries': 0, - 'haproxy.connections.server': 0, - 'haproxy.frontend_name': 'incoming~', - 'haproxy.http.request.captured_cookie': '-', - 'haproxy.http.request.captured_headers': ['docs.example.internal'], - 'haproxy.http.request.raw_request_line': - 'GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1', - 'haproxy.http.request.time_wait_ms': 0, - 'haproxy.http.request.time_wait_without_data_ms': 0, - 'haproxy.http.response.captured_cookie': '-', - 'haproxy.http.response.captured_headers': [], - 'haproxy.server_name': 'docs', - 'haproxy.server_queue': 0, - 'haproxy.termination_state': '----', - 'haproxy.total_waiting_time_ms': 0, - 'http.response.bytes': 168, - 'http.response.status_code': 304, - 'input.type': 'log', - 'log.offset': 0, - 'process.name': 'haproxy', - 'process.pid': 32450, - 'service.type': 'haproxy', - 'source.address': '1.2.3.4', - 'source.geo.continent_name': 'North America', - 'source.geo.country_iso_code': 'US', - 'source.geo.location.lat': 37.751, - 'source.geo.location.lon': -97.822, - 'source.ip': '1.2.3.4', - 'source.port': 38862, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy][http] ", - }, - Object { - "field": "source.address", - "highlights": Array [], - "value": "1.2.3.4", - }, - Object { - "constant": ":", - }, - Object { - "field": "source.port", - "highlights": Array [], - "value": "38862", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "incoming~", - }, - Object { - "constant": " -> ", - }, - Object { - "field": "haproxy.backend_name", - "highlights": Array [], - "value": "docs_microservice", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.server_name", - "highlights": Array [], - "value": "docs", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "haproxy.http.request.raw_request_line", - "highlights": Array [], - "value": "GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "http.response.status_code", - "highlights": Array [], - "value": "304", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.http.request.time_wait_ms", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "event.duration", - "highlights": Array [], - "value": "2000000", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connection_wait_time_ms", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.http.request.time_wait_without_data_ms", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "event.duration", - "highlights": Array [], - "value": "2000000", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.connections.active", - "highlights": Array [], - "value": "6", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.frontend", - "highlights": Array [], - "value": "6", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.backend", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.server", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.retries", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.server_queue", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.backend_queue", - "highlights": Array [], - "value": "0", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('haproxy default log', () => { - const flattenedDocument = { - 'event.dataset': 'haproxy.log', - 'fileset.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.client.ip': '1.2.3.4', - 'haproxy.client.port': '40780', - 'haproxy.destination.ip': '1.2.3.4', - 'haproxy.destination.port': '5000', - 'haproxy.frontend_name': 'main', - 'haproxy.geoip.continent_name': 'North America', - 'haproxy.geoip.country_iso_code': 'US', - 'haproxy.geoip.location.lat': 37.751, - 'haproxy.geoip.location.lon': -97.822, - 'haproxy.mode': 'HTTP', - 'haproxy.pid': '24551', - 'haproxy.process_name': 'haproxy', - 'haproxy.source': '1.2.3.4', - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy] ", - }, - Object { - "field": "haproxy.client.ip", - "highlights": Array [], - "value": "1.2.3.4", - }, - Object { - "constant": ":", - }, - Object { - "field": "haproxy.client.port", - "highlights": Array [], - "value": "40780", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "main", - }, -] -`); - }); - - test('haproxy tcp log', () => { - const flattenedDocument = { - 'event.dataset': 'haproxy.log', - 'fileset.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.backend_name': 'app', - 'haproxy.backend_queue': 0, - 'haproxy.bytes_read': 212, - 'haproxy.client.ip': '127.0.0.1', - 'haproxy.client.port': 40962, - 'haproxy.connection_wait_time_ms': -1, - 'haproxy.connections.active': 1, - 'haproxy.connections.backend': 0, - 'haproxy.connections.frontend': 1, - 'haproxy.connections.retries': 0, - 'haproxy.connections.server': 0, - 'haproxy.frontend_name': 'main', - 'haproxy.pid': 25457, - 'haproxy.process_name': 'haproxy', - 'haproxy.server_name': '', - 'haproxy.server_queue': 0, - 'haproxy.source': '127.0.0.1', - 'haproxy.tcp.processing_time_ms': 0, - 'haproxy.termination_state': 'SC', - 'haproxy.total_waiting_time_ms': -1, - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy][tcp] ", - }, - Object { - "field": "haproxy.client.ip", - "highlights": Array [], - "value": "127.0.0.1", - }, - Object { - "constant": ":", - }, - Object { - "field": "haproxy.client.port", - "highlights": Array [], - "value": "40962", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "main", - }, - Object { - "constant": " -> ", - }, - Object { - "field": "haproxy.backend_name", - "highlights": Array [], - "value": "app", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.server_name", - "highlights": Array [], - "value": "", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.connections.active", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.frontend", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.backend", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.server", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.retries", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.server_queue", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.backend_queue", - "highlights": Array [], - "value": "0", - }, -] -`); - }); - - test('haproxy http log', () => { - const flattenedDocument = { - 'event.dataset': 'haproxy.log', - 'fileset.module': 'haproxy', - 'fileset.name': 'log', - 'haproxy.backend_name': 'docs_microservice', - 'haproxy.backend_queue': 0, - 'haproxy.bytes_read': 168, - 'haproxy.client.ip': '1.2.3.4', - 'haproxy.client.port': 38862, - 'haproxy.connection_wait_time_ms': 1, - 'haproxy.connections.active': 6, - 'haproxy.connections.backend': 0, - 'haproxy.connections.frontend': 6, - 'haproxy.connections.retries': 0, - 'haproxy.connections.server': 0, - 'haproxy.frontend_name': 'incoming~', - 'haproxy.geoip.continent_name': 'North America', - 'haproxy.geoip.country_iso_code': 'US', - 'haproxy.geoip.location.lat': 37.751, - 'haproxy.geoip.location.lon': -97.822, - 'haproxy.http.request.captured_cookie': '-', - 'haproxy.http.request.raw_request_line': - 'GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1', - 'haproxy.http.request.time_active_ms': 2, - 'haproxy.http.request.time_wait_ms': 0, - 'haproxy.http.request.time_wait_without_data_ms': 0, - 'haproxy.http.response.captured_cookie': '-', - 'haproxy.http.response.status_code': 304, - 'haproxy.pid': 32450, - 'haproxy.process_name': 'haproxy', - 'haproxy.server_name': 'docs', - 'haproxy.server_queue': 0, - 'haproxy.termination_state': '----', - 'haproxy.total_waiting_time_ms': 0, - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[HAProxy][http] ", - }, - Object { - "field": "haproxy.client.ip", - "highlights": Array [], - "value": "1.2.3.4", - }, - Object { - "constant": ":", - }, - Object { - "field": "haproxy.client.port", - "highlights": Array [], - "value": "38862", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.frontend_name", - "highlights": Array [], - "value": "incoming~", - }, - Object { - "constant": " -> ", - }, - Object { - "field": "haproxy.backend_name", - "highlights": Array [], - "value": "docs_microservice", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.server_name", - "highlights": Array [], - "value": "docs", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "haproxy.http.request.raw_request_line", - "highlights": Array [], - "value": "GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "haproxy.http.response.status_code", - "highlights": Array [], - "value": "304", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.http.request.time_wait_ms", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.total_waiting_time_ms", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connection_wait_time_ms", - "highlights": Array [], - "value": "1", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.http.request.time_wait_without_data_ms", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.http.request.time_active_ms", - "highlights": Array [], - "value": "2", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.connections.active", - "highlights": Array [], - "value": "6", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.frontend", - "highlights": Array [], - "value": "6", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.backend", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.server", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.connections.retries", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": " ", - }, - Object { - "field": "haproxy.server_queue", - "highlights": Array [], - "value": "0", - }, - Object { - "constant": "/", - }, - Object { - "field": "haproxy.backend_queue", - "highlights": Array [], - "value": "0", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts deleted file mode 100644 index 97836b0a8186fe..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -const ecsFrontendFields = [ - { - field: 'source.address', - }, - { - constant: ':', - }, - { - field: 'source.port', - }, - { - constant: ' ', - }, - { - field: 'haproxy.frontend_name', - }, -]; - -const preEcsFrontendFields = [ - { - field: 'haproxy.client.ip', - }, - { - constant: ':', - }, - { - field: 'haproxy.client.port', - }, - { - constant: ' ', - }, - { - field: 'haproxy.frontend_name', - }, -]; - -const commonBackendFields = [ - { - constant: ' -> ', - }, - { - field: 'haproxy.backend_name', - }, - { - constant: '/', - }, - { - field: 'haproxy.server_name', - }, -]; - -const commonConnectionStatsFields = [ - { - field: 'haproxy.connections.active', - }, - { - constant: '/', - }, - { - field: 'haproxy.connections.frontend', - }, - { - constant: '/', - }, - { - field: 'haproxy.connections.backend', - }, - { - constant: '/', - }, - { - field: 'haproxy.connections.server', - }, - { - constant: '/', - }, - { - field: 'haproxy.connections.retries', - }, -]; - -const commonQueueStatsFields = [ - { - field: 'haproxy.server_queue', - }, - { - constant: '/', - }, - { - field: 'haproxy.backend_queue', - }, -]; - -export const filebeatHaproxyRules = [ - { - // ECS - when: { - exists: ['ecs.version', 'haproxy.http.request.raw_request_line'], - }, - format: [ - { - constant: '[HAProxy][http] ', - }, - ...ecsFrontendFields, - ...commonBackendFields, - { - constant: ' "', - }, - { - field: 'haproxy.http.request.raw_request_line', - }, - { - constant: '" ', - }, - { - field: 'http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'haproxy.http.request.time_wait_ms', - }, - { - constant: '/', - }, - { - field: 'event.duration', - }, - { - constant: '/', - }, - { - field: 'haproxy.connection_wait_time_ms', - }, - { - constant: '/', - }, - { - field: 'haproxy.http.request.time_wait_without_data_ms', - }, - { - constant: '/', - }, - { - field: 'event.duration', - }, - { - constant: ' ', - }, - ...commonConnectionStatsFields, - { - constant: ' ', - }, - ...commonQueueStatsFields, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'haproxy.connections.active'], - }, - format: [ - { - constant: '[HAProxy][tcp] ', - }, - ...ecsFrontendFields, - ...commonBackendFields, - { - constant: ' ', - }, - ...commonConnectionStatsFields, - { - constant: ' ', - }, - ...commonQueueStatsFields, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'haproxy.error_message'], - }, - format: [ - { - constant: '[HAProxy] ', - }, - ...ecsFrontendFields, - { - constant: ' ', - }, - { - field: 'haproxy.error_message', - }, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'haproxy.frontend_name'], - }, - format: [ - { - constant: '[HAProxy] ', - }, - ...ecsFrontendFields, - ], - }, - { - // pre-ECS - when: { - exists: ['haproxy.http.request.raw_request_line'], - }, - format: [ - { - constant: '[HAProxy][http] ', - }, - ...preEcsFrontendFields, - ...commonBackendFields, - { - constant: ' "', - }, - { - field: 'haproxy.http.request.raw_request_line', - }, - { - constant: '" ', - }, - { - field: 'haproxy.http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'haproxy.http.request.time_wait_ms', - }, - { - constant: '/', - }, - { - field: 'haproxy.total_waiting_time_ms', - }, - { - constant: '/', - }, - { - field: 'haproxy.connection_wait_time_ms', - }, - { - constant: '/', - }, - { - field: 'haproxy.http.request.time_wait_without_data_ms', - }, - { - constant: '/', - }, - { - field: 'haproxy.http.request.time_active_ms', - }, - { - constant: ' ', - }, - ...commonConnectionStatsFields, - { - constant: ' ', - }, - ...commonQueueStatsFields, - ], - }, - { - // pre-ECS - when: { - exists: ['haproxy.connections.active'], - }, - format: [ - { - constant: '[HAProxy][tcp] ', - }, - ...preEcsFrontendFields, - ...commonBackendFields, - { - constant: ' ', - }, - ...commonConnectionStatsFields, - { - constant: ' ', - }, - ...commonQueueStatsFields, - ], - }, - { - // pre-ECS - when: { - exists: ['haproxy.error_message'], - }, - format: [ - { - constant: '[HAProxy] ', - }, - ...preEcsFrontendFields, - { - constant: ' ', - }, - { - field: 'haproxy.error_message', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['haproxy.frontend_name'], - }, - format: [ - { - constant: '[HAProxy] ', - }, - ...preEcsFrontendFields, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.test.ts deleted file mode 100644 index 120137f15b883b..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.test.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatIcingaRules } from './filebeat_icinga'; - -const { format } = compileFormattingRules(filebeatIcingaRules); - -describe('Filebeat Rules', () => { - describe('in pre-ECS format', () => { - test('icinga debug log', () => { - const flattenedDocument = { - '@timestamp': '2017-04-04T11:43:09.000Z', - 'event.dataset': 'icinga.debug', - 'fileset.module': 'icinga', - 'fileset.name': 'debug', - 'icinga.debug.facility': 'GraphiteWriter', - 'icinga.debug.message': - "Add to metric list:'icinga2.demo.services.procs.procs.perfdata.procs.warn 250 1491306189'.", - 'icinga.debug.severity': 'debug', - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Icinga][", - }, - Object { - "field": "icinga.debug.facility", - "highlights": Array [], - "value": "GraphiteWriter", - }, - Object { - "constant": "][", - }, - Object { - "field": "icinga.debug.severity", - "highlights": Array [], - "value": "debug", - }, - Object { - "constant": "] ", - }, - Object { - "field": "icinga.debug.message", - "highlights": Array [], - "value": "Add to metric list:'icinga2.demo.services.procs.procs.perfdata.procs.warn 250 1491306189'.", - }, -] -`); - }); - - test('icinga main log', () => { - const flattenedDocument = { - '@timestamp': '2017-04-04T09:16:34.000Z', - 'event.dataset': 'icinga.main', - 'fileset.module': 'icinga', - 'fileset.name': 'main', - 'icinga.main.facility': 'Notification', - 'icinga.main.message': - "Sending 'Recovery' notification 'demo!load!mail-icingaadmin for user 'on-call'", - 'icinga.main.severity': 'information', - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Icinga][", - }, - Object { - "field": "icinga.main.facility", - "highlights": Array [], - "value": "Notification", - }, - Object { - "constant": "][", - }, - Object { - "field": "icinga.main.severity", - "highlights": Array [], - "value": "information", - }, - Object { - "constant": "] ", - }, - Object { - "field": "icinga.main.message", - "highlights": Array [], - "value": "Sending 'Recovery' notification 'demo!load!mail-icingaadmin for user 'on-call'", - }, -] -`); - }); - - test('icinga startup log', () => { - const flattenedDocument = { - 'event.dataset': 'icinga.startup', - 'fileset.module': 'icinga', - 'fileset.name': 'startup', - 'icinga.startup.facility': 'cli', - 'icinga.startup.message': 'Icinga application loader (version: r2.6.3-1)', - 'icinga.startup.severity': 'information', - 'input.type': 'log', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Icinga][", - }, - Object { - "field": "icinga.startup.facility", - "highlights": Array [], - "value": "cli", - }, - Object { - "constant": "][", - }, - Object { - "field": "icinga.startup.severity", - "highlights": Array [], - "value": "information", - }, - Object { - "constant": "] ", - }, - Object { - "field": "icinga.startup.message", - "highlights": Array [], - "value": "Icinga application loader (version: r2.6.3-1)", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.ts deleted file mode 100644 index c04a746e6bf41c..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_icinga.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatIcingaRules = [ - { - // pre-ECS - when: { - exists: ['icinga.main.message'], - }, - format: [ - { - constant: '[Icinga][', - }, - { - field: 'icinga.main.facility', - }, - { - constant: '][', - }, - { - field: 'icinga.main.severity', - }, - { - constant: '] ', - }, - { - field: 'icinga.main.message', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['icinga.debug.message'], - }, - format: [ - { - constant: '[Icinga][', - }, - { - field: 'icinga.debug.facility', - }, - { - constant: '][', - }, - { - field: 'icinga.debug.severity', - }, - { - constant: '] ', - }, - { - field: 'icinga.debug.message', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['icinga.startup.message'], - }, - format: [ - { - constant: '[Icinga][', - }, - { - field: 'icinga.startup.facility', - }, - { - constant: '][', - }, - { - field: 'icinga.startup.severity', - }, - { - constant: '] ', - }, - { - field: 'icinga.startup.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts deleted file mode 100644 index 72449c03b63a62..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('iis access log', () => { - const flattenedDocument = { - '@timestamp': '2018-01-01T10:11:12.000Z', - 'destination.address': '127.0.0.1', - 'destination.domain': 'example.com', - 'destination.ip': '127.0.0.1', - 'destination.port': 80, - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'iis.access', - 'event.duration': 789000000, - 'event.module': 'iis', - 'fileset.name': 'access', - 'http.request.body.bytes': 456, - 'http.request.method': 'GET', - 'http.request.referrer': '-', - 'http.response.body.bytes': 123, - 'http.response.status_code': 200, - 'http.version': '1.1', - 'iis.access.cookie': '-', - 'iis.access.server_name': 'MACHINE-NAME', - 'iis.access.site_name': 'W3SVC1', - 'iis.access.sub_status': 0, - 'iis.access.win32_status': 0, - 'input.type': 'log', - 'log.offset': 1204, - 'service.type': 'iis', - 'source.address': '85.181.35.98', - 'source.geo.city_name': 'Berlin', - 'source.geo.continent_name': 'Europe', - 'source.geo.country_iso_code': 'DE', - 'source.geo.location.lat': 52.4908, - 'source.geo.location.lon': 13.3275, - 'source.geo.region_iso_code': 'DE-BE', - 'source.geo.region_name': 'Land Berlin', - 'source.ip': '85.181.35.98', - 'url.path': '/', - 'url.query': 'q=100', - 'user.name': '-', - 'user_agent.device.name': 'Other', - 'user_agent.name': 'Chrome', - 'user_agent.original': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36', - 'user_agent.os.full': 'Mac OS X 10.14.0', - 'user_agent.os.name': 'Mac OS X', - 'user_agent.os.version': '10.14.0', - 'user_agent.version': '70.0.3538', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.module", - "highlights": Array [], - "value": "iis", - }, - Object { - "constant": "][access] ", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "85.181.35.98", - }, - Object { - "constant": " ", - }, - Object { - "field": "user.name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "http.request.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "url.path", - "highlights": Array [], - "value": "/", - }, - Object { - "constant": "?", - }, - Object { - "field": "url.query", - "highlights": Array [], - "value": "q=100", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "http.version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "http.response.status_code", - "highlights": Array [], - "value": "200", - }, - Object { - "constant": " ", - }, - Object { - "field": "http.response.body.bytes", - "highlights": Array [], - "value": "123", - }, -] -`); - }); - - test('iis 7.5 access log', () => { - const flattenedDocument = { - '@timestamp': '2018-08-28T18:24:25.000Z', - 'destination.address': '10.100.220.70', - 'destination.ip': '10.100.220.70', - 'destination.port': 80, - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'iis.access', - 'event.duration': 792000000, - 'event.module': 'iis', - 'fileset.name': 'access', - 'http.request.method': 'GET', - 'http.response.status_code': 404, - 'iis.access.sub_status': 4, - 'iis.access.win32_status': 2, - 'input.type': 'log', - 'log.offset': 244, - 'service.type': 'iis', - 'source.address': '10.100.118.31', - 'source.ip': '10.100.118.31', - 'url.path': '/', - 'url.query': 'q=100', - 'user.name': '-', - 'user_agent.device.name': 'Other', - 'user_agent.name': 'IE', - 'user_agent.original': - 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR[ 2.0.50727](tel: 2050727); .NET CLR 3.0.30729)', - 'user_agent.os.name': 'Windows 8.1', - 'user_agent.version': '7.0', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.module", - "highlights": Array [], - "value": "iis", - }, - Object { - "constant": "][access] ", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "10.100.118.31", - }, - Object { - "constant": " ", - }, - Object { - "field": "user.name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "http.request.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "url.path", - "highlights": Array [], - "value": "/", - }, - Object { - "constant": "?", - }, - Object { - "field": "url.query", - "highlights": Array [], - "value": "q=100", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "http.version", - "highlights": Array [], - "value": "undefined", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "http.response.status_code", - "highlights": Array [], - "value": "404", - }, - Object { - "constant": " ", - }, - Object { - "field": "http.response.body.bytes", - "highlights": Array [], - "value": "undefined", - }, -] -`); - }); - - test('iis error log', () => { - const flattenedDocument = { - '@timestamp': '2018-01-01T08:09:10.000Z', - 'destination.address': '172.31.77.6', - 'destination.ip': '172.31.77.6', - 'destination.port': 80, - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'iis.error', - 'event.module': 'iis', - 'fileset.name': 'error', - 'http.request.method': 'GET', - 'http.response.status_code': 503, - 'http.version': '1.1', - 'iis.error.queue_name': '-', - 'iis.error.reason_phrase': 'ConnLimit', - 'input.type': 'log', - 'log.offset': 186, - 'service.type': 'iis', - 'source.address': '172.31.77.6', - 'source.ip': '172.31.77.6', - 'source.port': 2094, - 'url.original': '/qos/1kbfile.txt', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[iis][error] ", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "172.31.77.6", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.error.reason_phrase", - "highlights": Array [], - "value": "ConnLimit", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('iis access log', () => { - const flattenedDocument = { - '@timestamp': '2018-01-01T08:09:10.000Z', - 'event.dataset': 'iis.access', - 'fileset.module': 'iis', - 'fileset.name': 'access', - 'iis.access.geoip.city_name': 'Berlin', - 'iis.access.geoip.continent_name': 'Europe', - 'iis.access.geoip.country_iso_code': 'DE', - 'iis.access.geoip.location.lat': 52.4908, - 'iis.access.geoip.location.lon': 13.3275, - 'iis.access.geoip.region_iso_code': 'DE-BE', - 'iis.access.geoip.region_name': 'Land Berlin', - 'iis.access.method': 'GET', - 'iis.access.port': '80', - 'iis.access.query_string': 'q=100', - 'iis.access.referrer': '-', - 'iis.access.remote_ip': '85.181.35.98', - 'iis.access.request_time_ms': '123', - 'iis.access.response_code': '200', - 'iis.access.server_ip': '127.0.0.1', - 'iis.access.sub_status': '0', - 'iis.access.url': '/', - 'iis.access.user_agent.device': 'Other', - 'iis.access.user_agent.major': '57', - 'iis.access.user_agent.minor': '0', - 'iis.access.user_agent.name': 'Firefox', - 'iis.access.user_agent.original': - 'Mozilla/5.0+(Windows+NT+6.1;+Win64;+x64;+rv:57.0)+Gecko/20100101+Firefox/57.0', - 'iis.access.user_agent.os': 'Windows', - 'iis.access.user_agent.os_name': 'Windows', - 'iis.access.user_name': '-', - 'iis.access.win32_status': '0', - 'input.type': 'log', - offset: 257, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[iis][access] ", - }, - Object { - "field": "iis.access.remote_ip", - "highlights": Array [], - "value": "85.181.35.98", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.user_name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "iis.access.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.url", - "highlights": Array [], - "value": "/", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "iis.access.http_version", - "highlights": Array [], - "value": "undefined", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "iis.access.response_code", - "highlights": Array [], - "value": "200", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.body_sent.bytes", - "highlights": Array [], - "value": "undefined", - }, -] -`); - }); - - test('iis 7.5 access log', () => { - const flattenedDocument = { - '@timestamp': '2018-08-28T18:24:25.000Z', - 'event.dataset': 'iis.access', - 'fileset.module': 'iis', - 'fileset.name': 'access', - 'iis.access.method': 'GET', - 'iis.access.port': '80', - 'iis.access.query_string': '-', - 'iis.access.remote_ip': '10.100.118.31', - 'iis.access.request_time_ms': '792', - 'iis.access.response_code': '404', - 'iis.access.server_ip': '10.100.220.70', - 'iis.access.sub_status': '4', - 'iis.access.url': '/', - 'iis.access.user_agent.device': 'Other', - 'iis.access.user_agent.name': 'Other', - 'iis.access.user_agent.original': - 'Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.3;+WOW64;+Trident/7.0;+.NET4.0E;+.NET4.0C;+.NET+CLR+3.5.30729;+.NET+CLR[+2.0.50727](tel:+2050727);+.NET+CLR+3.0.30729)', - 'iis.access.user_agent.os': 'Windows', - 'iis.access.user_agent.os_name': 'Windows', - 'iis.access.user_name': '-', - 'iis.access.win32_status': '2', - 'input.type': 'log', - offset: 244, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[iis][access] ", - }, - Object { - "field": "iis.access.remote_ip", - "highlights": Array [], - "value": "10.100.118.31", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.user_name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "iis.access.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.url", - "highlights": Array [], - "value": "/", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "iis.access.http_version", - "highlights": Array [], - "value": "undefined", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "iis.access.response_code", - "highlights": Array [], - "value": "404", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.access.body_sent.bytes", - "highlights": Array [], - "value": "undefined", - }, -] -`); - }); - - test('iis error log', () => { - const flattenedDocument = { - '@timestamp': '2018-01-01T08:09:10.000Z', - 'event.dataset': 'iis.error', - 'fileset.module': 'iis', - 'fileset.name': 'error', - 'iis.error.http_version': '1.1', - 'iis.error.method': 'GET', - 'iis.error.queue_name': '-', - 'iis.error.reason_phrase': 'ConnLimit', - 'iis.error.remote_ip': '172.31.77.6', - 'iis.error.remote_port': '2094', - 'iis.error.response_code': '503', - 'iis.error.server_ip': '172.31.77.6', - 'iis.error.server_port': '80', - 'iis.error.url': '/qos/1kbfile.txt', - 'input.type': 'log', - offset: 186, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[iis][error] ", - }, - Object { - "field": "iis.error.remote_ip", - "highlights": Array [], - "value": "172.31.77.6", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "iis.error.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.error.url", - "highlights": Array [], - "value": "/qos/1kbfile.txt", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "iis.error.http_version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "iis.error.response_code", - "highlights": Array [], - "value": "503", - }, - Object { - "constant": " ", - }, - Object { - "field": "iis.error.reason_phrase", - "highlights": Array [], - "value": "ConnLimit", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts deleted file mode 100644 index ea3485440bb749..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatIisRules = [ - { - // pre-ECS - when: { - exists: ['iis.access.method'], - }, - format: [ - { - constant: '[iis][access] ', - }, - { - field: 'iis.access.remote_ip', - }, - { - constant: ' ', - }, - { - field: 'iis.access.user_name', - }, - { - constant: ' "', - }, - { - field: 'iis.access.method', - }, - { - constant: ' ', - }, - { - field: 'iis.access.url', - }, - { - constant: ' HTTP/', - }, - { - field: 'iis.access.http_version', - }, - { - constant: '" ', - }, - { - field: 'iis.access.response_code', - }, - { - constant: ' ', - }, - { - field: 'iis.access.body_sent.bytes', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['iis.error.url'], - }, - format: [ - { - constant: '[iis][error] ', - }, - { - field: 'iis.error.remote_ip', - }, - { - constant: ' "', - }, - { - field: 'iis.error.method', - }, - { - constant: ' ', - }, - { - field: 'iis.error.url', - }, - { - constant: ' HTTP/', - }, - { - field: 'iis.error.http_version', - }, - { - constant: '" ', - }, - { - field: 'iis.error.response_code', - }, - { - constant: ' ', - }, - { - field: 'iis.error.reason_phrase', - }, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'iis.error.reason_phrase'], - }, - format: [ - { - constant: '[iis][error] ', - }, - { - field: 'source.ip', - }, - { - constant: ' ', - }, - { - field: 'iis.error.reason_phrase', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['iis.error.reason_phrase'], - }, - format: [ - { - constant: '[iis][error] ', - }, - { - field: 'iis.error.remote_ip', - }, - { - constant: ' ', - }, - { - field: 'iis.error.reason_phrase', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts deleted file mode 100644 index 19cb5f6e311185..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('kafka log', () => { - const flattenedDocument = { - '@timestamp': '2017-08-04T10:48:21.063Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'kafka.log', - 'event.module': 'kafka', - 'fileset.name': 'log', - 'input.type': 'log', - 'kafka.log.class': 'kafka.controller.KafkaController', - 'kafka.log.component': 'Controller 0', - 'log.level': 'INFO', - 'log.offset': 131, - message: '0 successfully elected as the controller', - 'service.type': 'kafka', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.dataset", - "highlights": Array [], - "value": "kafka.log", - }, - Object { - "constant": "][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "INFO", - }, - Object { - "constant": "] ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "0 successfully elected as the controller", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts deleted file mode 100644 index edc534d9c345fb..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('logstash log', () => { - const flattenedDocument = { - '@timestamp': '2017-10-23T14:20:12.046Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'logstash.log', - 'event.module': 'logstash', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.level': 'INFO', - 'log.offset': 0, - 'logstash.log.module': 'logstash.modules.scaffold', - message: - 'Initializing module {:module_name=>"fb_apache", :directory=>"/usr/share/logstash/modules/fb_apache/configuration"}', - 'service.type': 'logstash', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.dataset", - "highlights": Array [], - "value": "logstash.log", - }, - Object { - "constant": "][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "INFO", - }, - Object { - "constant": "] ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "Initializing module {:module_name=>\\"fb_apache\\", :directory=>\\"/usr/share/logstash/modules/fb_apache/configuration\\"}", - }, -] -`); - }); - - test('logstash slowlog', () => { - const flattenedDocument = { - '@timestamp': '2017-10-30T09:57:58.243Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'logstash.slowlog', - 'event.duration': 3027675106, - 'event.module': 'logstash', - 'fileset.name': 'slowlog', - 'input.type': 'log', - 'log.level': 'WARN', - 'log.offset': 0, - 'logstash.slowlog': { - event: - '"{\\"@version\\":\\"1\\",\\"@timestamp\\":\\"2017-10-30T13:57:55.130Z\\",\\"host\\":\\"sashimi\\",\\"sequence\\":0,\\"message\\":\\"Hello world!\\"}"', - module: 'slowlog.logstash.filters.sleep', - plugin_name: 'sleep', - plugin_params: - '{"time"=>3, "id"=>"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c"}', - plugin_type: 'filters', - took_in_millis: 3027, - }, - 'service.type': 'logstash', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Logstash][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "WARN", - }, - Object { - "constant": "] ", - }, - Object { - "field": "logstash.slowlog", - "highlights": Array [], - "value": "{\\"event\\":\\"\\\\\\"{\\\\\\\\\\\\\\"@version\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"1\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"@timestamp\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"2017-10-30T13:57:55.130Z\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"host\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"sashimi\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"sequence\\\\\\\\\\\\\\":0,\\\\\\\\\\\\\\"message\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"Hello world!\\\\\\\\\\\\\\"}\\\\\\"\\",\\"module\\":\\"slowlog.logstash.filters.sleep\\",\\"plugin_name\\":\\"sleep\\",\\"plugin_params\\":\\"{\\\\\\"time\\\\\\"=>3, \\\\\\"id\\\\\\"=>\\\\\\"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c\\\\\\"}\\",\\"plugin_type\\":\\"filters\\",\\"took_in_millis\\":3027}", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('logstash log', () => { - const flattenedDocument = { - '@timestamp': '2017-10-23T14:20:12.046Z', - 'event.dataset': 'logstash.log', - 'fileset.module': 'logstash', - 'fileset.name': 'log', - 'input.type': 'log', - 'logstash.log.level': 'INFO', - 'logstash.log.message': - 'Initializing module {:module_name=>"fb_apache", :directory=>"/usr/share/logstash/modules/fb_apache/configuration"}', - 'logstash.log.module': 'logstash.modules.scaffold', - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Logstash][", - }, - Object { - "field": "logstash.log.level", - "highlights": Array [], - "value": "INFO", - }, - Object { - "constant": "] ", - }, - Object { - "field": "logstash.log.module", - "highlights": Array [], - "value": "logstash.modules.scaffold", - }, - Object { - "constant": " - ", - }, - Object { - "field": "logstash.log.message", - "highlights": Array [], - "value": "Initializing module {:module_name=>\\"fb_apache\\", :directory=>\\"/usr/share/logstash/modules/fb_apache/configuration\\"}", - }, -] -`); - }); - - test('logstash slowlog', () => { - const flattenedDocument = { - '@timestamp': '2017-10-30T09:57:58.243Z', - 'event.dataset': 'logstash.slowlog', - 'fileset.module': 'logstash', - 'fileset.name': 'slowlog', - 'input.type': 'log', - 'logstash.slowlog.event': - '"{\\"@version\\":\\"1\\",\\"@timestamp\\":\\"2017-10-30T13:57:55.130Z\\",\\"host\\":\\"sashimi\\",\\"sequence\\":0,\\"message\\":\\"Hello world!\\"}"', - 'logstash.slowlog.level': 'WARN', - 'logstash.slowlog.message': - 'event processing time {:plugin_params=>{"time"=>3, "id"=>"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c"}, :took_in_nanos=>3027675106, :took_in_millis=>3027, :event=>"{\\"@version\\":\\"1\\",\\"@timestamp\\":\\"2017-10-30T13:57:55.130Z\\",\\"host\\":\\"sashimi\\",\\"sequence\\":0,\\"message\\":\\"Hello world!\\"}"}', - 'logstash.slowlog.module': 'slowlog.logstash.filters.sleep', - 'logstash.slowlog.plugin_name': 'sleep', - 'logstash.slowlog.plugin_params': - '{"time"=>3, "id"=>"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c"}', - 'logstash.slowlog.plugin_type': 'filters', - 'logstash.slowlog.took_in_millis': 3027, - 'logstash.slowlog.took_in_nanos': 3027675106, - offset: 0, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Logstash][", - }, - Object { - "field": "logstash.slowlog.level", - "highlights": Array [], - "value": "WARN", - }, - Object { - "constant": "] ", - }, - Object { - "field": "logstash.slowlog.module", - "highlights": Array [], - "value": "slowlog.logstash.filters.sleep", - }, - Object { - "constant": " - ", - }, - Object { - "field": "logstash.slowlog.message", - "highlights": Array [], - "value": "event processing time {:plugin_params=>{\\"time\\"=>3, \\"id\\"=>\\"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c\\"}, :took_in_nanos=>3027675106, :took_in_millis=>3027, :event=>\\"{\\\\\\"@version\\\\\\":\\\\\\"1\\\\\\",\\\\\\"@timestamp\\\\\\":\\\\\\"2017-10-30T13:57:55.130Z\\\\\\",\\\\\\"host\\\\\\":\\\\\\"sashimi\\\\\\",\\\\\\"sequence\\\\\\":0,\\\\\\"message\\\\\\":\\\\\\"Hello world!\\\\\\"}\\"}", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts deleted file mode 100644 index 39b2058ca7cdb3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatLogstashRules = [ - { - // pre-ECS - when: { - exists: ['logstash.log.message'], - }, - format: [ - { - constant: '[Logstash][', - }, - { - field: 'logstash.log.level', - }, - { - constant: '] ', - }, - { - field: 'logstash.log.module', - }, - { - constant: ' - ', - }, - { - field: 'logstash.log.message', - }, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'logstash.slowlog'], - }, - format: [ - { - constant: '[Logstash][', - }, - { - field: 'log.level', - }, - { - constant: '] ', - }, - { - field: 'logstash.slowlog', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['logstash.slowlog.message'], - }, - format: [ - { - constant: '[Logstash][', - }, - { - field: 'logstash.slowlog.level', - }, - { - constant: '] ', - }, - { - field: 'logstash.slowlog.module', - }, - { - constant: ' - ', - }, - { - field: 'logstash.slowlog.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.test.ts deleted file mode 100644 index 3df7ebec241cc3..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatMongodbRules } from './filebeat_mongodb'; - -const { format } = compileFormattingRules(filebeatMongodbRules); - -describe('Filebeat Rules', () => { - describe('in pre-ECS format', () => { - test('mongodb log', () => { - const flattenedDocument = { - '@timestamp': '2018-02-05T12:44:56.677Z', - 'event.dataset': 'mongodb.log', - 'fileset.module': 'mongodb', - 'fileset.name': 'log', - 'input.type': 'log', - 'mongodb.log.component': 'STORAGE', - 'mongodb.log.context': 'initandlisten', - 'mongodb.log.message': - 'wiredtiger_open config: create,cache_size=8G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),', - 'mongodb.log.severity': 'I', - offset: 281, - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[MongoDB][", - }, - Object { - "field": "mongodb.log.component", - "highlights": Array [], - "value": "STORAGE", - }, - Object { - "constant": "] ", - }, - Object { - "field": "mongodb.log.message", - "highlights": Array [], - "value": "wiredtiger_open config: create,cache_size=8G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.ts deleted file mode 100644 index 06a4964875898a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mongodb.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatMongodbRules = [ - { - // pre-ECS - when: { - exists: ['mongodb.log.message'], - }, - format: [ - { - constant: '[MongoDB][', - }, - { - field: 'mongodb.log.component', - }, - { - constant: '] ', - }, - { - field: 'mongodb.log.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts deleted file mode 100644 index 0329d53f92d082..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('mysql error log', () => { - const flattenedDocument = { - '@timestamp': '2016-12-09T12:08:33.335Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'mysql.error', - 'event.module': 'mysql', - 'fileset.name': 'error', - 'input.type': 'log', - 'log.level': 'Warning', - 'log.offset': 92, - message: - 'TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).', - 'mysql.thread_id': 0, - 'service.type': 'mysql', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.dataset", - "highlights": Array [], - "value": "mysql.error", - }, - Object { - "constant": "][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "Warning", - }, - Object { - "constant": "] ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).", - }, -] -`); - }); - - test('mysql slowlog', () => { - const flattenedDocument = { - '@timestamp': '2018-08-07T08:27:47.000Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'mysql.slowlog', - 'event.duration': 4071491000, - 'event.module': 'mysql', - 'fileset.name': 'slowlog', - 'input.type': 'log', - 'log.flags': ['multiline'], - 'log.offset': 526, - 'mysql.slowlog.current_user': 'appuser', - 'mysql.slowlog.lock_time.sec': 0.000212, - 'mysql.slowlog.query': - 'SELECT mcu.mcu_guid, mcu.cus_guid, mcu.mcu_url, mcu.mcu_crawlelements, mcu.mcu_order, GROUP_CONCAT(mca.mca_guid SEPARATOR ";") as mca_guid\n FROM kat_mailcustomerurl mcu, kat_customer cus, kat_mailcampaign mca\n WHERE cus.cus_guid = mcu.cus_guid\n AND cus.pro_code = \'CYB\'\n AND cus.cus_offline = 0\n AND mca.cus_guid = cus.cus_guid\n AND (mcu.mcu_date IS NULL OR mcu.mcu_date < CURDATE())\n AND mcu.mcu_crawlelements IS NOT NULL\n GROUP BY mcu.mcu_guid\n ORDER BY mcu.mcu_order ASC\n LIMIT 1000;', - 'mysql.slowlog.rows_examined': 1489615, - 'mysql.slowlog.rows_sent': 1000, - 'mysql.thread_id': 10997316, - 'service.type': 'mysql', - 'source.domain': 'apphost', - 'source.ip': '1.1.1.1', - 'user.name': 'appuser', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[MySQL][slowlog] ", - }, - Object { - "field": "user.name", - "highlights": Array [], - "value": "appuser", - }, - Object { - "constant": "@", - }, - Object { - "field": "source.domain", - "highlights": Array [], - "value": "apphost", - }, - Object { - "constant": " [", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "1.1.1.1", - }, - Object { - "constant": "] ", - }, - Object { - "constant": " - ", - }, - Object { - "field": "event.duration", - "highlights": Array [], - "value": "4071491000", - }, - Object { - "constant": " ns - ", - }, - Object { - "field": "mysql.slowlog.query", - "highlights": Array [], - "value": "SELECT mcu.mcu_guid, mcu.cus_guid, mcu.mcu_url, mcu.mcu_crawlelements, mcu.mcu_order, GROUP_CONCAT(mca.mca_guid SEPARATOR \\";\\") as mca_guid - FROM kat_mailcustomerurl mcu, kat_customer cus, kat_mailcampaign mca - WHERE cus.cus_guid = mcu.cus_guid - AND cus.pro_code = 'CYB' - AND cus.cus_offline = 0 - AND mca.cus_guid = cus.cus_guid - AND (mcu.mcu_date IS NULL OR mcu.mcu_date < CURDATE()) - AND mcu.mcu_crawlelements IS NOT NULL - GROUP BY mcu.mcu_guid - ORDER BY mcu.mcu_order ASC - LIMIT 1000;", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('mysql error log', () => { - const errorDoc = { - 'mysql.error.message': - "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", - }; - const message = format(errorDoc, {}); - expect(message).toEqual([ - { - constant: '[MySQL][error] ', - }, - { - field: 'mysql.error.message', - highlights: [], - value: "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", - }, - ]); - }); - - test('mysql slow log', () => { - const errorDoc = { - 'mysql.slowlog.query': 'select * from hosts', - 'mysql.slowlog.query_time.sec': 5, - 'mysql.slowlog.user': 'admin', - 'mysql.slowlog.ip': '192.168.1.42', - 'mysql.slowlog.host': 'webserver-01', - }; - const message = format(errorDoc, {}); - expect(message).toEqual([ - { - constant: '[MySQL][slowlog] ', - }, - { - field: 'mysql.slowlog.user', - highlights: [], - value: 'admin', - }, - { - constant: '@', - }, - { - field: 'mysql.slowlog.host', - highlights: [], - value: 'webserver-01', - }, - { - constant: ' [', - }, - { - field: 'mysql.slowlog.ip', - highlights: [], - value: '192.168.1.42', - }, - { - constant: '] ', - }, - { - constant: ' - ', - }, - { - field: 'mysql.slowlog.query_time.sec', - highlights: [], - value: '5', - }, - { - constant: ' s - ', - }, - { - field: 'mysql.slowlog.query', - highlights: [], - value: 'select * from hosts', - }, - ]); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts deleted file mode 100644 index e90977f9bf8fa7..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatMySQLRules = [ - { - // pre-ECS - when: { - exists: ['mysql.error.message'], - }, - format: [ - { - constant: '[MySQL][error] ', - }, - { - field: 'mysql.error.message', - }, - ], - }, - { - // ECS - when: { - exists: ['ecs.version', 'mysql.slowlog.query'], - }, - format: [ - { - constant: '[MySQL][slowlog] ', - }, - { - field: 'user.name', - }, - { - constant: '@', - }, - { - field: 'source.domain', - }, - { - constant: ' [', - }, - { - field: 'source.ip', - }, - { - constant: '] ', - }, - { - constant: ' - ', - }, - { - field: 'event.duration', - }, - { - constant: ' ns - ', - }, - { - field: 'mysql.slowlog.query', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['mysql.slowlog.user', 'mysql.slowlog.query_time.sec', 'mysql.slowlog.query'], - }, - format: [ - { - constant: '[MySQL][slowlog] ', - }, - { - field: 'mysql.slowlog.user', - }, - { - constant: '@', - }, - { - field: 'mysql.slowlog.host', - }, - { - constant: ' [', - }, - { - field: 'mysql.slowlog.ip', - }, - { - constant: '] ', - }, - { - constant: ' - ', - }, - { - field: 'mysql.slowlog.query_time.sec', - }, - { - constant: ' s - ', - }, - { - field: 'mysql.slowlog.query', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts deleted file mode 100644 index 0bc8ae1e907b84..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules(getBuiltinRules([])); - -describe('Filebeat Rules', () => { - describe('in ECS format', () => { - test('Nginx Access', () => { - const flattenedDocument = { - '@timestamp': '2017-05-29T19:02:48.000Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'nginx.access', - 'event.module': 'nginx', - 'fileset.name': 'access', - 'http.request.method': 'GET', - 'http.request.referrer': '-', - 'http.response.body.bytes': 612, - 'http.response.status_code': 404, - 'http.version': '1.1', - 'input.type': 'log', - 'log.offset': 183, - 'service.type': 'nginx', - 'source.ip': '172.17.0.1', - 'url.original': '/stringpatch', - 'user.name': '-', - 'user_agent.device': 'Other', - 'user_agent.major': '15', - 'user_agent.minor': '0', - 'user_agent.name': 'Firefox Alpha', - 'user_agent.original': - 'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2', - 'user_agent.os.full_name': 'Windows 7', - 'user_agent.os.name': 'Windows 7', - 'user_agent.patch': 'a2', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.module", - "highlights": Array [], - "value": "nginx", - }, - Object { - "constant": "][access] ", - }, - Object { - "field": "source.ip", - "highlights": Array [], - "value": "172.17.0.1", - }, - Object { - "constant": " ", - }, - Object { - "field": "user.name", - "highlights": Array [], - "value": "-", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "http.request.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "url.original", - "highlights": Array [], - "value": "/stringpatch", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "http.version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "http.response.status_code", - "highlights": Array [], - "value": "404", - }, - Object { - "constant": " ", - }, - Object { - "field": "http.response.body.bytes", - "highlights": Array [], - "value": "612", - }, -] -`); - }); - - test('Nginx Error', () => { - const flattenedDocument = { - '@timestamp': '2016-10-25T14:49:34.000Z', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'nginx.error', - 'event.module': 'nginx', - 'fileset.name': 'error', - 'input.type': 'log', - 'log.level': 'error', - 'log.offset': 0, - message: - 'open() "/usr/local/Cellar/nginx/1.10.2_1/html/favicon.ico" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"', - 'nginx.error.connection_id': 1, - 'process.pid': 54053, - 'process.thread.id': 0, - 'service.type': 'nginx', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[nginx]", - }, - Object { - "constant": "[", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "error", - }, - Object { - "constant": "] ", - }, - Object { - "field": "message", - "highlights": Array [], - "value": "open() \\"/usr/local/Cellar/nginx/1.10.2_1/html/favicon.ico\\" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: \\"GET /favicon.ico HTTP/1.1\\", host: \\"localhost:8080\\", referrer: \\"http://localhost:8080/\\"", - }, -] -`); - }); - }); - - describe('in pre-ECS format', () => { - test('Nginx Access', () => { - const flattenedDocument = { - 'nginx.access': true, - 'nginx.access.remote_ip': '192.168.1.42', - 'nginx.access.user_name': 'admin', - 'nginx.access.method': 'GET', - 'nginx.access.url': '/faq', - 'nginx.access.http_version': '1.1', - 'nginx.access.body_sent.bytes': 1024, - 'nginx.access.response_code': 200, - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[nginx][access] ", - }, - Object { - "field": "nginx.access.remote_ip", - "highlights": Array [], - "value": "192.168.1.42", - }, - Object { - "constant": " ", - }, - Object { - "field": "nginx.access.user_name", - "highlights": Array [], - "value": "admin", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "nginx.access.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "nginx.access.url", - "highlights": Array [], - "value": "/faq", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "nginx.access.http_version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "nginx.access.response_code", - "highlights": Array [], - "value": "200", - }, - Object { - "constant": " ", - }, - Object { - "field": "nginx.access.body_sent.bytes", - "highlights": Array [], - "value": "1024", - }, -] -`); - }); - - test('Nginx Error', () => { - const flattenedDocument = { - 'nginx.error.message': - 'connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /php-status?json= HTTP/1.1", upstream: "fastcgi://[::1]:9000", host: "localhost"', - 'nginx.error.level': 'error', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[nginx]", - }, - Object { - "constant": "[", - }, - Object { - "field": "nginx.error.level", - "highlights": Array [], - "value": "error", - }, - Object { - "constant": "] ", - }, - Object { - "field": "nginx.error.message", - "highlights": Array [], - "value": "connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: \\"GET /php-status?json= HTTP/1.1\\", upstream: \\"fastcgi://[::1]:9000\\", host: \\"localhost\\"", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts deleted file mode 100644 index 0fd70dc25bb88e..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatNginxRules = [ - { - // pre-ECS - when: { - exists: ['nginx.access.method'], - }, - format: [ - { - constant: '[nginx][access] ', - }, - { - field: 'nginx.access.remote_ip', - }, - { - constant: ' ', - }, - { - field: 'nginx.access.user_name', - }, - { - constant: ' "', - }, - { - field: 'nginx.access.method', - }, - { - constant: ' ', - }, - { - field: 'nginx.access.url', - }, - { - constant: ' HTTP/', - }, - { - field: 'nginx.access.http_version', - }, - { - constant: '" ', - }, - { - field: 'nginx.access.response_code', - }, - { - constant: ' ', - }, - { - field: 'nginx.access.body_sent.bytes', - }, - ], - }, - { - // ECS - when: { - values: { - 'event.dataset': 'nginx.error', - }, - }, - format: [ - { - constant: '[nginx]', - }, - { - constant: '[', - }, - { - field: 'log.level', - }, - { - constant: '] ', - }, - { - field: 'message', - }, - ], - }, - { - // pre-ECS - when: { - exists: ['nginx.error.message'], - }, - format: [ - { - constant: '[nginx]', - }, - { - constant: '[', - }, - { - field: 'nginx.error.level', - }, - { - constant: '] ', - }, - { - field: 'nginx.error.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.test.ts deleted file mode 100644 index 8dc70053e20227..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatOsqueryRules } from './filebeat_osquery'; - -const { format } = compileFormattingRules(filebeatOsqueryRules); - -describe('Filebeat Rules', () => { - describe('in pre-ECS format', () => { - test('osquery result log', () => { - const flattenedDocument = { - '@timestamp': '2017-12-28T14:40:08.000Z', - 'event.dataset': 'osquery.result', - 'fileset.module': 'osquery', - 'fileset.name': 'result', - 'input.type': 'log', - offset: 0, - 'osquery.result.action': 'removed', - 'osquery.result.calendar_time': 'Thu Dec 28 14:40:08 2017 UTC', - 'osquery.result.columns': { - blocks: '122061322', - blocks_available: '75966945', - blocks_free: '121274885', - blocks_size: '4096', - device: '/dev/disk1s4', - device_alias: '/dev/disk1s4', - flags: '345018372', - inodes: '9223372036854775807', - inodes_free: '9223372036854775804', - path: '/private/var/vm', - type: 'apfs', - }, - 'osquery.result.counter': '1', - 'osquery.result.decorations.host_uuid': '4AB2906D-5516-5794-AF54-86D1D7F533F3', - 'osquery.result.decorations.username': 'tsg', - 'osquery.result.epoch': '0', - 'osquery.result.host_identifier': '192-168-0-4.rdsnet.ro', - 'osquery.result.name': 'pack_it-compliance_mounts', - 'osquery.result.unix_time': '1514472008', - 'prospector.type': 'log', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[Osquery][", - }, - Object { - "field": "osquery.result.action", - "highlights": Array [], - "value": "removed", - }, - Object { - "constant": "] ", - }, - Object { - "field": "osquery.result.host_identifier", - "highlights": Array [], - "value": "192-168-0-4.rdsnet.ro", - }, - Object { - "constant": " ", - }, - Object { - "field": "osquery.result.columns", - "highlights": Array [], - "value": "{\\"blocks\\":\\"122061322\\",\\"blocks_available\\":\\"75966945\\",\\"blocks_free\\":\\"121274885\\",\\"blocks_size\\":\\"4096\\",\\"device\\":\\"/dev/disk1s4\\",\\"device_alias\\":\\"/dev/disk1s4\\",\\"flags\\":\\"345018372\\",\\"inodes\\":\\"9223372036854775807\\",\\"inodes_free\\":\\"9223372036854775804\\",\\"path\\":\\"/private/var/vm\\",\\"type\\":\\"apfs\\"}", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.ts deleted file mode 100644 index b3a6ee8c5cb470..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_osquery.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatOsqueryRules = [ - { - // pre-ECS - when: { - exists: ['osquery.result.name'], - }, - format: [ - { - constant: '[Osquery][', - }, - { - field: 'osquery.result.action', - }, - { - constant: '] ', - }, - { - field: 'osquery.result.host_identifier', - }, - { - constant: ' ', - }, - { - field: 'osquery.result.columns', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_redis.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_redis.ts deleted file mode 100644 index 788c65f92c4b49..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_redis.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatRedisRules = [ - { - when: { - exists: ['redis.log.message'], - }, - format: [ - { - constant: '[Redis]', - }, - { - constant: '[', - }, - { - field: 'redis.log.level', - }, - { - constant: '] ', - }, - { - field: 'redis.log.message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_system.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_system.ts deleted file mode 100644 index cb695abcccdc84..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_system.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatSystemRules = [ - { - when: { - exists: ['system.syslog.message'], - }, - format: [ - { - constant: '[System][syslog] ', - }, - { - field: 'system.syslog.program', - }, - { - constant: ' - ', - }, - { - field: 'system.syslog.message', - }, - ], - }, - { - when: { - exists: ['system.auth.message'], - }, - format: [ - { - constant: '[System][auth] ', - }, - { - field: 'system.auth.program', - }, - { - constant: ' - ', - }, - { - field: 'system.auth.message', - }, - ], - }, - { - when: { - exists: ['system.auth.ssh.event'], - }, - format: [ - { - constant: '[System][auth][ssh]', - }, - { - constant: ' ', - }, - { - field: 'system.auth.ssh.event', - }, - { - constant: ' user ', - }, - { - field: 'system.auth.user', - }, - { - constant: ' from ', - }, - { - field: 'system.auth.ssh.ip', - }, - ], - }, - { - when: { - exists: ['system.auth.ssh.dropped_ip'], - }, - format: [ - { - constant: '[System][auth][ssh]', - }, - { - constant: ' Dropped connection from ', - }, - { - field: 'system.auth.ssh.dropped_ip', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts deleted file mode 100644 index b19124558fdd0a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { compileFormattingRules } from '../message'; -import { filebeatTraefikRules } from './filebeat_traefik'; - -const { format } = compileFormattingRules(filebeatTraefikRules); - -describe('Filebeat Rules', () => { - describe('in pre-ECS format', () => { - test('traefik access log', () => { - const flattenedDocument = { - '@timestamp': '2017-10-02T20:22:08.000Z', - 'event.dataset': 'traefik.access', - 'fileset.module': 'traefik', - 'fileset.name': 'access', - 'input.type': 'log', - offset: 280, - 'prospector.type': 'log', - 'traefik.access.backend_url': 'http://172.19.0.3:5601', - 'traefik.access.body_sent.bytes': 0, - 'traefik.access.duration': 3, - 'traefik.access.frontend_name': 'Host-host1', - 'traefik.access.geoip.city_name': 'Berlin', - 'traefik.access.geoip.continent_name': 'Europe', - 'traefik.access.geoip.country_iso_code': 'DE', - 'traefik.access.geoip.location.lat': 52.4908, - 'traefik.access.geoip.location.lon': 13.3275, - 'traefik.access.geoip.region_iso_code': 'DE-BE', - 'traefik.access.geoip.region_name': 'Land Berlin', - 'traefik.access.http_version': '1.1', - 'traefik.access.method': 'GET', - 'traefik.access.referrer': 'http://example.com/login', - 'traefik.access.remote_ip': '85.181.35.98', - 'traefik.access.request_count': 271, - 'traefik.access.response_code': '304', - 'traefik.access.url': '/ui/favicons/favicon.ico', - 'traefik.access.user_agent.device': 'Other', - 'traefik.access.user_agent.major': '61', - 'traefik.access.user_agent.minor': '0', - 'traefik.access.user_agent.name': 'Chrome', - 'traefik.access.user_agent.original': - 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36', - 'traefik.access.user_agent.os': 'Linux', - 'traefik.access.user_agent.os_name': 'Linux', - 'traefik.access.user_agent.patch': '3163', - 'traefik.access.user_identifier': '-', - 'traefik.access.user_name': '-', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[traefik][access] ", - }, - Object { - "field": "traefik.access.remote_ip", - "highlights": Array [], - "value": "85.181.35.98", - }, - Object { - "constant": " ", - }, - Object { - "field": "traefik.access.frontend_name", - "highlights": Array [], - "value": "Host-host1", - }, - Object { - "constant": " -> ", - }, - Object { - "field": "traefik.access.backend_url", - "highlights": Array [], - "value": "http://172.19.0.3:5601", - }, - Object { - "constant": " \\"", - }, - Object { - "field": "traefik.access.method", - "highlights": Array [], - "value": "GET", - }, - Object { - "constant": " ", - }, - Object { - "field": "traefik.access.url", - "highlights": Array [], - "value": "/ui/favicons/favicon.ico", - }, - Object { - "constant": " HTTP/", - }, - Object { - "field": "traefik.access.http_version", - "highlights": Array [], - "value": "1.1", - }, - Object { - "constant": "\\" ", - }, - Object { - "field": "traefik.access.response_code", - "highlights": Array [], - "value": "304", - }, - Object { - "constant": " ", - }, - Object { - "field": "traefik.access.body_sent.bytes", - "highlights": Array [], - "value": "0", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts deleted file mode 100644 index e62c688b9c22fe..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filebeatTraefikRules = [ - { - // pre-ECS - when: { - exists: ['traefik.access.method'], - }, - format: [ - { - constant: '[traefik][access] ', - }, - { - field: 'traefik.access.remote_ip', - }, - { - constant: ' ', - }, - { - field: 'traefik.access.frontend_name', - }, - { - constant: ' -> ', - }, - { - field: 'traefik.access.backend_url', - }, - { - constant: ' "', - }, - { - field: 'traefik.access.method', - }, - { - constant: ' ', - }, - { - field: 'traefik.access.url', - }, - { - constant: ' HTTP/', - }, - { - field: 'traefik.access.http_version', - }, - { - constant: '" ', - }, - { - field: 'traefik.access.response_code', - }, - { - constant: ' ', - }, - { - field: 'traefik.access.body_sent.bytes', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.test.ts deleted file mode 100644 index d168273626cfa0..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.test.ts +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getBuiltinRules } from '.'; -import { compileFormattingRules } from '../message'; - -const { format } = compileFormattingRules( - getBuiltinRules(['first_generic_message', 'second_generic_message']) -); - -describe('Generic Rules', () => { - describe('configurable message rules', () => { - test('includes the event.dataset and log.level if present', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - 'event.dataset': 'generic.test', - 'log.level': 'TEST_LEVEL', - first_generic_message: 'TEST_MESSAGE', - }; - const highlights = { - first_generic_message: ['TEST'], - }; - - expect(format(flattenedDocument, highlights)).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.dataset", - "highlights": Array [], - "value": "generic.test", - }, - Object { - "constant": "][", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "TEST_LEVEL", - }, - Object { - "constant": "] ", - }, - Object { - "field": "first_generic_message", - "highlights": Array [ - "TEST", - ], - "value": "TEST_MESSAGE", - }, -] -`); - }); - - test('includes the log.level if present', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - 'log.level': 'TEST_LEVEL', - first_generic_message: 'TEST_MESSAGE', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "log.level", - "highlights": Array [], - "value": "TEST_LEVEL", - }, - Object { - "constant": "] ", - }, - Object { - "field": "first_generic_message", - "highlights": Array [], - "value": "TEST_MESSAGE", - }, -] -`); - }); - - test('includes the message', () => { - const firstFlattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - first_generic_message: 'FIRST_TEST_MESSAGE', - }; - - expect(format(firstFlattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "field": "first_generic_message", - "highlights": Array [], - "value": "FIRST_TEST_MESSAGE", - }, -] -`); - - const secondFlattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - second_generic_message: 'SECOND_TEST_MESSAGE', - }; - - expect(format(secondFlattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "field": "second_generic_message", - "highlights": Array [], - "value": "SECOND_TEST_MESSAGE", - }, -] -`); - }); - }); - - describe('log.original fallback', () => { - test('includes the event.dataset if present', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - 'event.dataset': 'generic.test', - 'log.original': 'TEST_MESSAGE', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "constant": "[", - }, - Object { - "field": "event.dataset", - "highlights": Array [], - "value": "generic.test", - }, - Object { - "constant": "] ", - }, - Object { - "field": "log.original", - "highlights": Array [], - "value": "TEST_MESSAGE", - }, -] -`); - }); - - test('includes the original message', () => { - const flattenedDocument = { - '@timestamp': '2016-12-26T16:22:13.000Z', - 'log.original': 'TEST_MESSAGE', - }; - - expect(format(flattenedDocument, {})).toMatchInlineSnapshot(` -Array [ - Object { - "field": "log.original", - "highlights": Array [], - "value": "TEST_MESSAGE", - }, -] -`); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts deleted file mode 100644 index 941cfc72afce6a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { LogMessageFormattingRule } from '../rule_types'; - -const BUILTIN_GENERIC_MESSAGE_FIELDS = ['message', '@message']; - -export const getGenericRules = (genericMessageFields: string[]) => [ - ...Array.from(new Set([...genericMessageFields, ...BUILTIN_GENERIC_MESSAGE_FIELDS])).reduce< - LogMessageFormattingRule[] - >((genericRules, fieldName) => [...genericRules, ...createGenericRulesForField(fieldName)], []), - { - when: { - exists: ['event.dataset', 'log.original'], - }, - format: [ - { - constant: '[', - }, - { - field: 'event.dataset', - }, - { - constant: '] ', - }, - { - field: 'log.original', - }, - ], - }, - { - when: { - exists: ['log.original'], - }, - format: [ - { - field: 'log.original', - }, - ], - }, -]; - -const createGenericRulesForField = (fieldName: string) => [ - { - when: { - exists: ['event.dataset', 'log.level', fieldName], - }, - format: [ - { - constant: '[', - }, - { - field: 'event.dataset', - }, - { - constant: '][', - }, - { - field: 'log.level', - }, - { - constant: '] ', - }, - { - field: fieldName, - }, - ], - }, - { - when: { - exists: ['log.level', fieldName], - }, - format: [ - { - constant: '[', - }, - { - field: 'log.level', - }, - { - constant: '] ', - }, - { - field: fieldName, - }, - ], - }, - { - when: { - exists: [fieldName], - }, - format: [ - { - field: fieldName, - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts deleted file mode 100644 index 50f38ad0515b27..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -const commonPrefixFields = [ - { constant: '[' }, - { field: 'event.module' }, - { constant: '][access] ' }, -]; - -export const genericWebserverRules = [ - { - // ECS with parsed url - when: { - exists: ['ecs.version', 'http.response.status_code', 'url.path'], - }, - format: [ - ...commonPrefixFields, - { - field: 'source.ip', - }, - { - constant: ' ', - }, - { - field: 'user.name', - }, - { - constant: ' "', - }, - { - field: 'http.request.method', - }, - { - constant: ' ', - }, - { - field: 'url.path', - }, - { - constant: '?', - }, - { - field: 'url.query', - }, - { - constant: ' HTTP/', - }, - { - field: 'http.version', - }, - { - constant: '" ', - }, - { - field: 'http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'http.response.body.bytes', - }, - ], - }, - { - // ECS with original url - when: { - exists: ['ecs.version', 'http.response.status_code'], - }, - format: [ - ...commonPrefixFields, - { - field: 'source.ip', - }, - { - constant: ' ', - }, - { - field: 'user.name', - }, - { - constant: ' "', - }, - { - field: 'http.request.method', - }, - { - constant: ' ', - }, - { - field: 'url.original', - }, - { - constant: ' HTTP/', - }, - { - field: 'http.version', - }, - { - constant: '" ', - }, - { - field: 'http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'http.response.body.bytes', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts deleted file mode 100644 index 9a6fa30e17e89d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const labelField = (label: string, field: string) => [ - { constant: ' ' }, - { constant: label }, - { constant: '=' }, - { field }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts deleted file mode 100644 index 3f4d7eb901212a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { filebeatApache2Rules } from './filebeat_apache2'; -import { filebeatAuditdRules } from './filebeat_auditd'; -import { filebeatHaproxyRules } from './filebeat_haproxy'; -import { filebeatIcingaRules } from './filebeat_icinga'; -import { filebeatIisRules } from './filebeat_iis'; -import { filebeatLogstashRules } from './filebeat_logstash'; -import { filebeatMongodbRules } from './filebeat_mongodb'; -import { filebeatMySQLRules } from './filebeat_mysql'; -import { filebeatNginxRules } from './filebeat_nginx'; -import { filebeatOsqueryRules } from './filebeat_osquery'; -import { filebeatRedisRules } from './filebeat_redis'; -import { filebeatSystemRules } from './filebeat_system'; -import { filebeatTraefikRules } from './filebeat_traefik'; - -import { getGenericRules } from './generic'; -import { genericWebserverRules } from './generic_webserver'; - -export const getBuiltinRules = (genericMessageFields: string[]) => [ - ...filebeatApache2Rules, - ...filebeatNginxRules, - ...filebeatRedisRules, - ...filebeatSystemRules, - ...filebeatMySQLRules, - ...filebeatAuditdRules, - ...filebeatHaproxyRules, - ...filebeatIcingaRules, - ...filebeatIisRules, - ...filebeatLogstashRules, - ...filebeatMongodbRules, - ...filebeatOsqueryRules, - ...filebeatTraefikRules, - ...genericWebserverRules, - ...getGenericRules(genericMessageFields), - { - when: { - exists: ['log.path'], - }, - format: [ - { - constant: 'failed to format message from ', - }, - { - field: 'log.path', - }, - ], - }, - { - when: { - exists: [], - }, - format: [ - { - constant: 'failed to find message', - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts deleted file mode 100644 index 98d1e2cd89b013..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { convertDocumentSourceToLogItemFields } from './convert_document_source_to_log_item_fields'; - -describe('convertDocumentSourceToLogItemFields', () => { - test('should convert document', () => { - const doc = { - agent: { - hostname: 'demo-stack-client-01', - id: '7adef8b6-2ab7-45cd-a0d5-b3baad735f1b', - type: 'filebeat', - ephemeral_id: 'a0c8164b-3564-4e32-b0bf-f4db5a7ae566', - version: '7.0.0', - }, - tags: ['prod', 'web'], - metadata: [ - { key: 'env', value: 'prod' }, - { key: 'stack', value: 'web' }, - ], - host: { - hostname: 'packer-virtualbox-iso-1546820004', - name: 'demo-stack-client-01', - }, - }; - - const fields = convertDocumentSourceToLogItemFields(doc); - expect(fields).toEqual([ - { - field: 'agent.hostname', - value: 'demo-stack-client-01', - }, - { - field: 'agent.id', - value: '7adef8b6-2ab7-45cd-a0d5-b3baad735f1b', - }, - { - field: 'agent.type', - value: 'filebeat', - }, - { - field: 'agent.ephemeral_id', - value: 'a0c8164b-3564-4e32-b0bf-f4db5a7ae566', - }, - { - field: 'agent.version', - value: '7.0.0', - }, - { - field: 'tags', - value: '["prod","web"]', - }, - { - field: 'metadata', - value: '[{"key":"env","value":"prod"},{"key":"stack","value":"web"}]', - }, - { - field: 'host.hostname', - value: 'packer-virtualbox-iso-1546820004', - }, - { - field: 'host.name', - value: 'demo-stack-client-01', - }, - ]); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts deleted file mode 100644 index 37d7a5bd7465cc..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import stringify from 'json-stable-stringify'; -import { isArray, isPlainObject } from 'lodash'; - -import { JsonObject } from '../../../../common/typed_json'; -import { InfraLogItemField } from '../../../graphql/types'; - -const isJsonObject = (subject: any): subject is JsonObject => { - return isPlainObject(subject); -}; - -const serializeValue = (value: any): string => { - if (isArray(value) || isPlainObject(value)) { - return stringify(value); - } - return `${value}`; -}; - -export const convertDocumentSourceToLogItemFields = ( - source: JsonObject, - path: string[] = [], - fields: InfraLogItemField[] = [] -): InfraLogItemField[] => { - return Object.keys(source).reduce((acc, key) => { - const value = source[key]; - const nextPath = [...path, key]; - if (isJsonObject(value)) { - return convertDocumentSourceToLogItemFields(value, nextPath, acc); - } - const field = { field: nextPath.join('.'), value: serializeValue(value) }; - return [...acc, field]; - }, fields); -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/index.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/index.ts deleted file mode 100644 index 2cb8140febdcd9..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './log_entries_domain'; diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts deleted file mode 100644 index e3f9d8cef04301..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import stringify from 'json-stable-stringify'; -import { sortBy } from 'lodash'; - -import { RequestHandlerContext } from 'src/core/server'; -import { TimeKey } from '../../../../common/time'; -import { JsonObject } from '../../../../common/typed_json'; -import { - LogEntriesSummaryBucket, - LogEntriesSummaryHighlightsBucket, -} from '../../../../common/http_api'; -import { InfraLogEntry, InfraLogItem, InfraLogMessageSegment } from '../../../graphql/types'; -import { - InfraSourceConfiguration, - InfraSources, - SavedSourceConfigurationFieldColumnRuntimeType, - SavedSourceConfigurationMessageColumnRuntimeType, - SavedSourceConfigurationTimestampColumnRuntimeType, -} from '../../sources'; -import { getBuiltinRules } from './builtin_rules'; -import { convertDocumentSourceToLogItemFields } from './convert_document_source_to_log_item_fields'; -import { - CompiledLogMessageFormattingRule, - Fields, - Highlights, - compileFormattingRules, -} from './message'; - -export class InfraLogEntriesDomain { - constructor( - private readonly adapter: LogEntriesAdapter, - private readonly libs: { sources: InfraSources } - ) {} - - public async getLogEntriesAround( - requestContext: RequestHandlerContext, - sourceId: string, - key: TimeKey, - maxCountBefore: number, - maxCountAfter: number, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise<{ entriesBefore: InfraLogEntry[]; entriesAfter: InfraLogEntry[] }> { - if (maxCountBefore <= 0 && maxCountAfter <= 0) { - return { - entriesBefore: [], - entriesAfter: [], - }; - } - - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const messageFormattingRules = compileFormattingRules( - getBuiltinRules(configuration.fields.message) - ); - const requiredFields = getRequiredFields(configuration, messageFormattingRules); - - const documentsBefore = await this.adapter.getAdjacentLogEntryDocuments( - requestContext, - configuration, - requiredFields, - key, - 'desc', - Math.max(maxCountBefore, 1), - filterQuery, - highlightQuery - ); - const lastKeyBefore = - documentsBefore.length > 0 - ? documentsBefore[documentsBefore.length - 1].key - : { - time: key.time - 1, - tiebreaker: 0, - }; - - const documentsAfter = await this.adapter.getAdjacentLogEntryDocuments( - requestContext, - configuration, - requiredFields, - lastKeyBefore, - 'asc', - maxCountAfter, - filterQuery, - highlightQuery - ); - - return { - entriesBefore: (maxCountBefore > 0 ? documentsBefore : []).map( - convertLogDocumentToEntry(sourceId, configuration.logColumns, messageFormattingRules.format) - ), - entriesAfter: documentsAfter.map( - convertLogDocumentToEntry(sourceId, configuration.logColumns, messageFormattingRules.format) - ), - }; - } - - public async getLogEntriesBetween( - requestContext: RequestHandlerContext, - sourceId: string, - startKey: TimeKey, - endKey: TimeKey, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const messageFormattingRules = compileFormattingRules( - getBuiltinRules(configuration.fields.message) - ); - const requiredFields = getRequiredFields(configuration, messageFormattingRules); - const documents = await this.adapter.getContainedLogEntryDocuments( - requestContext, - configuration, - requiredFields, - startKey, - endKey, - filterQuery, - highlightQuery - ); - const entries = documents.map( - convertLogDocumentToEntry(sourceId, configuration.logColumns, messageFormattingRules.format) - ); - return entries; - } - - public async getLogEntryHighlights( - requestContext: RequestHandlerContext, - sourceId: string, - startKey: TimeKey, - endKey: TimeKey, - highlights: Array<{ - query: string; - countBefore: number; - countAfter: number; - }>, - filterQuery?: LogEntryQuery - ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const messageFormattingRules = compileFormattingRules( - getBuiltinRules(configuration.fields.message) - ); - const requiredFields = getRequiredFields(configuration, messageFormattingRules); - - const documentSets = await Promise.all( - highlights.map(async highlight => { - const highlightQuery = createHighlightQueryDsl(highlight.query, requiredFields); - const query = filterQuery - ? { - bool: { - filter: [filterQuery, highlightQuery], - }, - } - : highlightQuery; - const [documentsBefore, documents, documentsAfter] = await Promise.all([ - this.adapter.getAdjacentLogEntryDocuments( - requestContext, - configuration, - requiredFields, - startKey, - 'desc', - highlight.countBefore, - query, - highlightQuery - ), - this.adapter.getContainedLogEntryDocuments( - requestContext, - configuration, - requiredFields, - startKey, - endKey, - query, - highlightQuery - ), - this.adapter.getAdjacentLogEntryDocuments( - requestContext, - configuration, - requiredFields, - endKey, - 'asc', - highlight.countAfter, - query, - highlightQuery - ), - ]); - const entries = [...documentsBefore, ...documents, ...documentsAfter].map( - convertLogDocumentToEntry( - sourceId, - configuration.logColumns, - messageFormattingRules.format - ) - ); - - return entries; - }) - ); - - return documentSets; - } - - public async getLogSummaryBucketsBetween( - requestContext: RequestHandlerContext, - sourceId: string, - start: number, - end: number, - bucketSize: number, - filterQuery?: LogEntryQuery - ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const dateRangeBuckets = await this.adapter.getContainedLogSummaryBuckets( - requestContext, - configuration, - start, - end, - bucketSize, - filterQuery - ); - return dateRangeBuckets; - } - - public async getLogSummaryHighlightBucketsBetween( - requestContext: RequestHandlerContext, - sourceId: string, - start: number, - end: number, - bucketSize: number, - highlightQueries: string[], - filterQuery?: LogEntryQuery - ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const messageFormattingRules = compileFormattingRules( - getBuiltinRules(configuration.fields.message) - ); - const requiredFields = getRequiredFields(configuration, messageFormattingRules); - - const summaries = await Promise.all( - highlightQueries.map(async highlightQueryPhrase => { - const highlightQuery = createHighlightQueryDsl(highlightQueryPhrase, requiredFields); - const query = filterQuery - ? { - bool: { - must: [filterQuery, highlightQuery], - }, - } - : highlightQuery; - const summaryBuckets = await this.adapter.getContainedLogSummaryBuckets( - requestContext, - configuration, - start, - end, - bucketSize, - query - ); - const summaryHighlightBuckets = summaryBuckets - .filter(logSummaryBucketHasEntries) - .map(convertLogSummaryBucketToSummaryHighlightBucket); - return summaryHighlightBuckets; - }) - ); - - return summaries; - } - - public async getLogItem( - requestContext: RequestHandlerContext, - id: string, - sourceConfiguration: InfraSourceConfiguration - ): Promise { - const document = await this.adapter.getLogItem(requestContext, id, sourceConfiguration); - const defaultFields = [ - { field: '_index', value: document._index }, - { field: '_id', value: document._id }, - ]; - - return { - id: document._id, - index: document._index, - key: { - time: document.sort[0], - tiebreaker: document.sort[1], - }, - fields: sortBy( - [...defaultFields, ...convertDocumentSourceToLogItemFields(document._source)], - 'field' - ), - }; - } -} - -interface LogItemHit { - _index: string; - _id: string; - _source: JsonObject; - sort: [number, number]; -} - -export interface LogEntriesAdapter { - getAdjacentLogEntryDocuments( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - fields: string[], - start: TimeKey, - direction: 'asc' | 'desc', - maxCount: number, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise; - - getContainedLogEntryDocuments( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - fields: string[], - start: TimeKey, - end: TimeKey, - filterQuery?: LogEntryQuery, - highlightQuery?: LogEntryQuery - ): Promise; - - getContainedLogSummaryBuckets( - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - start: number, - end: number, - bucketSize: number, - filterQuery?: LogEntryQuery - ): Promise; - - getLogItem( - requestContext: RequestHandlerContext, - id: string, - source: InfraSourceConfiguration - ): Promise; -} - -export type LogEntryQuery = JsonObject; - -export interface LogEntryDocument { - fields: Fields; - gid: string; - highlights: Highlights; - key: TimeKey; -} - -export interface LogSummaryBucket { - entriesCount: number; - start: number; - end: number; - topEntryKeys: TimeKey[]; -} - -const convertLogDocumentToEntry = ( - sourceId: string, - logColumns: InfraSourceConfiguration['logColumns'], - formatLogMessage: (fields: Fields, highlights: Highlights) => InfraLogMessageSegment[] -) => (document: LogEntryDocument): InfraLogEntry => ({ - key: document.key, - gid: document.gid, - source: sourceId, - columns: logColumns.map(logColumn => { - if (SavedSourceConfigurationTimestampColumnRuntimeType.is(logColumn)) { - return { - columnId: logColumn.timestampColumn.id, - timestamp: document.key.time, - }; - } else if (SavedSourceConfigurationMessageColumnRuntimeType.is(logColumn)) { - return { - columnId: logColumn.messageColumn.id, - message: formatLogMessage(document.fields, document.highlights), - }; - } else { - return { - columnId: logColumn.fieldColumn.id, - field: logColumn.fieldColumn.field, - highlights: document.highlights[logColumn.fieldColumn.field] || [], - value: stringify(document.fields[logColumn.fieldColumn.field] || null), - }; - } - }), -}); - -const logSummaryBucketHasEntries = (bucket: LogSummaryBucket) => - bucket.entriesCount > 0 && bucket.topEntryKeys.length > 0; - -const convertLogSummaryBucketToSummaryHighlightBucket = ( - bucket: LogSummaryBucket -): LogEntriesSummaryHighlightsBucket => ({ - entriesCount: bucket.entriesCount, - start: bucket.start, - end: bucket.end, - representativeKey: bucket.topEntryKeys[0], -}); - -const getRequiredFields = ( - configuration: InfraSourceConfiguration, - messageFormattingRules: CompiledLogMessageFormattingRule -): string[] => { - const fieldsFromCustomColumns = configuration.logColumns.reduce( - (accumulatedFields, logColumn) => { - if (SavedSourceConfigurationFieldColumnRuntimeType.is(logColumn)) { - return [...accumulatedFields, logColumn.fieldColumn.field]; - } - return accumulatedFields; - }, - [] - ); - const fieldsFromFormattingRules = messageFormattingRules.requiredFields; - - return Array.from(new Set([...fieldsFromCustomColumns, ...fieldsFromFormattingRules])); -}; - -const createHighlightQueryDsl = (phrase: string, fields: string[]) => ({ - multi_match: { - fields, - lenient: true, - query: phrase, - type: 'phrase', - }, -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/message.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/message.ts deleted file mode 100644 index 58cffc75849797..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/message.ts +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import stringify from 'json-stable-stringify'; - -import { InfraLogMessageSegment } from '../../../graphql/types'; -import { - LogMessageFormattingCondition, - LogMessageFormattingInstruction, - LogMessageFormattingRule, -} from './rule_types'; - -export function compileFormattingRules( - rules: LogMessageFormattingRule[] -): CompiledLogMessageFormattingRule { - const compiledRules = rules.map(compileRule); - - return { - requiredFields: Array.from( - new Set( - compiledRules.reduce( - (combinedRequiredFields, { requiredFields }) => [ - ...combinedRequiredFields, - ...requiredFields, - ], - [] as string[] - ) - ) - ), - format(fields, highlights): InfraLogMessageSegment[] { - for (const compiledRule of compiledRules) { - if (compiledRule.fulfillsCondition(fields)) { - return compiledRule.format(fields, highlights); - } - } - - return []; - }, - fulfillsCondition() { - return true; - }, - }; -} - -const compileRule = (rule: LogMessageFormattingRule): CompiledLogMessageFormattingRule => { - const { conditionFields, fulfillsCondition } = compileCondition(rule.when); - const { formattingFields, format } = compileFormattingInstructions(rule.format); - - return { - requiredFields: [...conditionFields, ...formattingFields], - fulfillsCondition, - format, - }; -}; - -const compileCondition = ( - condition: LogMessageFormattingCondition -): CompiledLogMessageFormattingCondition => - [compileExistsCondition, compileFieldValueCondition].reduce( - (compiledCondition, compile) => compile(condition) || compiledCondition, - catchAllCondition - ); - -const catchAllCondition: CompiledLogMessageFormattingCondition = { - conditionFields: [] as string[], - fulfillsCondition: () => false, -}; - -const compileExistsCondition = (condition: LogMessageFormattingCondition) => - 'exists' in condition - ? { - conditionFields: condition.exists, - fulfillsCondition: (fields: Fields) => - condition.exists.every(fieldName => fieldName in fields), - } - : null; - -const compileFieldValueCondition = (condition: LogMessageFormattingCondition) => - 'values' in condition - ? { - conditionFields: Object.keys(condition.values), - fulfillsCondition: (fields: Fields) => - Object.entries(condition.values).every( - ([fieldName, expectedValue]) => fields[fieldName] === expectedValue - ), - } - : null; - -const compileFormattingInstructions = ( - formattingInstructions: LogMessageFormattingInstruction[] -): CompiledLogMessageFormattingInstruction => - formattingInstructions.reduce( - (combinedFormattingInstructions, formattingInstruction) => { - const compiledFormattingInstruction = compileFormattingInstruction(formattingInstruction); - - return { - formattingFields: [ - ...combinedFormattingInstructions.formattingFields, - ...compiledFormattingInstruction.formattingFields, - ], - format: (fields: Fields, highlights: Highlights) => [ - ...combinedFormattingInstructions.format(fields, highlights), - ...compiledFormattingInstruction.format(fields, highlights), - ], - }; - }, - { - formattingFields: [], - format: () => [], - } as CompiledLogMessageFormattingInstruction - ); - -const compileFormattingInstruction = ( - formattingInstruction: LogMessageFormattingInstruction -): CompiledLogMessageFormattingInstruction => - [compileFieldReferenceFormattingInstruction, compileConstantFormattingInstruction].reduce( - (compiledFormattingInstruction, compile) => - compile(formattingInstruction) || compiledFormattingInstruction, - catchAllFormattingInstruction - ); - -const catchAllFormattingInstruction: CompiledLogMessageFormattingInstruction = { - formattingFields: [], - format: () => [ - { - constant: 'invalid format', - }, - ], -}; - -const compileFieldReferenceFormattingInstruction = ( - formattingInstruction: LogMessageFormattingInstruction -): CompiledLogMessageFormattingInstruction | null => - 'field' in formattingInstruction - ? { - formattingFields: [formattingInstruction.field], - format: (fields, highlights) => { - const value = fields[formattingInstruction.field]; - const highlightedValues = highlights[formattingInstruction.field]; - return [ - { - field: formattingInstruction.field, - value: typeof value === 'object' ? stringify(value) : `${value}`, - highlights: highlightedValues || [], - }, - ]; - }, - } - : null; - -const compileConstantFormattingInstruction = ( - formattingInstruction: LogMessageFormattingInstruction -): CompiledLogMessageFormattingInstruction | null => - 'constant' in formattingInstruction - ? { - formattingFields: [] as string[], - format: () => [ - { - constant: formattingInstruction.constant, - }, - ], - } - : null; - -export interface Fields { - [fieldName: string]: string | number | object | boolean | null; -} - -export interface Highlights { - [fieldName: string]: string[]; -} - -export interface CompiledLogMessageFormattingRule { - requiredFields: string[]; - fulfillsCondition(fields: Fields): boolean; - format(fields: Fields, highlights: Highlights): InfraLogMessageSegment[]; -} - -export interface CompiledLogMessageFormattingCondition { - conditionFields: string[]; - fulfillsCondition(fields: Fields): boolean; -} - -export interface CompiledLogMessageFormattingInstruction { - formattingFields: string[]; - format(fields: Fields, highlights: Highlights): InfraLogMessageSegment[]; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/rule_types.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/rule_types.ts deleted file mode 100644 index 6107fc362f8e34..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/rule_types.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export interface LogMessageFormattingRule { - when: LogMessageFormattingCondition; - format: LogMessageFormattingInstruction[]; -} - -export type LogMessageFormattingCondition = - | LogMessageFormattingExistsCondition - | LogMessageFormattingFieldValueCondition; - -export interface LogMessageFormattingExistsCondition { - exists: string[]; -} - -export interface LogMessageFormattingFieldValueCondition { - values: { - [fieldName: string]: string | number | boolean | null; - }; -} - -export type LogMessageFormattingInstruction = - | LogMessageFormattingFieldReference - | LogMessageFormattingConstant; - -export interface LogMessageFormattingFieldReference { - field: string; -} - -export interface LogMessageFormattingConstant { - constant: string; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/metrics_domain.ts b/x-pack/legacy/plugins/infra/server/lib/domains/metrics_domain.ts deleted file mode 100644 index e53e45afae5c48..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/domains/metrics_domain.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { InfraMetricData } from '../../graphql/types'; -import { InfraMetricsAdapter, InfraMetricsRequestOptions } from '../adapters/metrics/adapter_types'; - -export class InfraMetricsDomain { - private adapter: InfraMetricsAdapter; - - constructor(adapter: InfraMetricsAdapter) { - this.adapter = adapter; - } - - public async getMetrics( - requestContext: RequestHandlerContext, - options: InfraMetricsRequestOptions, - rawRequest: KibanaRequest - ): Promise { - return await this.adapter.getMetrics(requestContext, options, rawRequest); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/infra_types.ts b/x-pack/legacy/plugins/infra/server/lib/infra_types.ts deleted file mode 100644 index 46d32885600dfd..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/infra_types.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraSourceConfiguration } from '../../public/graphql/types'; -import { InfraFieldsDomain } from './domains/fields_domain'; -import { InfraLogEntriesDomain } from './domains/log_entries_domain'; -import { InfraMetricsDomain } from './domains/metrics_domain'; -import { InfraLogAnalysis } from './log_analysis/log_analysis'; -import { InfraSnapshot } from './snapshot'; -import { InfraSources } from './sources'; -import { InfraSourceStatus } from './source_status'; -import { InfraConfig } from '../../../../../plugins/infra/server'; -import { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; - -// NP_TODO: We shouldn't need this context anymore but I am -// not sure how the graphql stuff uses it, so we can't remove it yet -export interface InfraContext { - req: any; - rawReq?: any; -} - -export interface InfraDomainLibs { - fields: InfraFieldsDomain; - logEntries: InfraLogEntriesDomain; - metrics: InfraMetricsDomain; -} - -export interface InfraBackendLibs extends InfraDomainLibs { - configuration: InfraConfig; - framework: KibanaFramework; - logAnalysis: InfraLogAnalysis; - snapshot: InfraSnapshot; - sources: InfraSources; - sourceStatus: InfraSourceStatus; -} - -export interface InfraConfiguration { - enabled: boolean; - query: { - partitionSize: number; - partitionFactor: number; - }; - sources: { - default: InfraSourceConfiguration; - }; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/errors.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/errors.ts deleted file mode 100644 index dc5c87c61fdcee..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/errors.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export class NoLogRateResultsIndexError extends Error { - constructor(message?: string) { - super(message); - Object.setPrototypeOf(this, new.target.prototype); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/index.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/index.ts deleted file mode 100644 index 0b58c71c1db7bf..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './errors'; -export * from './log_analysis'; diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts deleted file mode 100644 index fac49a7980f264..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { pipe } from 'fp-ts/lib/pipeable'; -import { map, fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { getJobId } from '../../../common/log_analysis'; -import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { KibanaFramework } from '../adapters/framework/kibana_framework_adapter'; -import { NoLogRateResultsIndexError } from './errors'; -import { - logRateModelPlotResponseRT, - createLogEntryRateQuery, - LogRateModelPlotBucket, - CompositeTimestampPartitionKey, -} from './queries'; -import { RequestHandlerContext, KibanaRequest } from '../../../../../../../src/core/server'; - -const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000; - -export class InfraLogAnalysis { - constructor( - private readonly libs: { - framework: KibanaFramework; - } - ) {} - - public getJobIds(request: KibanaRequest, sourceId: string) { - return { - logEntryRate: getJobId(this.libs.framework.getSpaceId(request), sourceId, 'log-entry-rate'), - }; - } - - public async getLogEntryRateBuckets( - requestContext: RequestHandlerContext, - sourceId: string, - startTime: number, - endTime: number, - bucketDuration: number, - request: KibanaRequest - ) { - const logRateJobId = this.getJobIds(request, sourceId).logEntryRate; - let mlModelPlotBuckets: LogRateModelPlotBucket[] = []; - let afterLatestBatchKey: CompositeTimestampPartitionKey | undefined; - - while (true) { - const mlModelPlotResponse = await this.libs.framework.callWithRequest( - requestContext, - 'search', - createLogEntryRateQuery( - logRateJobId, - startTime, - endTime, - bucketDuration, - COMPOSITE_AGGREGATION_BATCH_SIZE, - afterLatestBatchKey - ) - ); - - if (mlModelPlotResponse._shards.total === 0) { - throw new NoLogRateResultsIndexError( - `Failed to find ml result index for job ${logRateJobId}.` - ); - } - - const { after_key: afterKey, buckets: latestBatchBuckets } = pipe( - logRateModelPlotResponseRT.decode(mlModelPlotResponse), - map(response => response.aggregations.timestamp_partition_buckets), - fold(throwErrors(createPlainError), identity) - ); - - mlModelPlotBuckets = [...mlModelPlotBuckets, ...latestBatchBuckets]; - afterLatestBatchKey = afterKey; - - if (latestBatchBuckets.length < COMPOSITE_AGGREGATION_BATCH_SIZE) { - break; - } - } - - return mlModelPlotBuckets.reduce< - Array<{ - partitions: Array<{ - analysisBucketCount: number; - anomalies: Array<{ - actualLogEntryRate: number; - anomalyScore: number; - duration: number; - startTime: number; - typicalLogEntryRate: number; - }>; - averageActualLogEntryRate: number; - maximumAnomalyScore: number; - numberOfLogEntries: number; - partitionId: string; - }>; - startTime: number; - }> - >((histogramBuckets, timestampPartitionBucket) => { - const previousHistogramBucket = histogramBuckets[histogramBuckets.length - 1]; - const partition = { - analysisBucketCount: timestampPartitionBucket.filter_model_plot.doc_count, - anomalies: timestampPartitionBucket.filter_records.top_hits_record.hits.hits.map( - ({ _source: record }) => ({ - actualLogEntryRate: record.actual[0], - anomalyScore: record.record_score, - duration: record.bucket_span * 1000, - startTime: record.timestamp, - typicalLogEntryRate: record.typical[0], - }) - ), - averageActualLogEntryRate: - timestampPartitionBucket.filter_model_plot.average_actual.value || 0, - maximumAnomalyScore: - timestampPartitionBucket.filter_records.maximum_record_score.value || 0, - numberOfLogEntries: timestampPartitionBucket.filter_model_plot.sum_actual.value || 0, - partitionId: timestampPartitionBucket.key.partition, - }; - if ( - previousHistogramBucket && - previousHistogramBucket.startTime === timestampPartitionBucket.key.timestamp - ) { - return [ - ...histogramBuckets.slice(0, -1), - { - ...previousHistogramBucket, - partitions: [...previousHistogramBucket.partitions, partition], - }, - ]; - } else { - return [ - ...histogramBuckets, - { - partitions: [partition], - startTime: timestampPartitionBucket.key.timestamp, - }, - ]; - } - }, []); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/index.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/index.ts deleted file mode 100644 index 17494212777198..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './log_entry_rate'; diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts deleted file mode 100644 index 2dd0880cbf8cb7..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import * as rt from 'io-ts'; - -const ML_ANOMALY_INDEX_PREFIX = '.ml-anomalies-'; - -export const createLogEntryRateQuery = ( - logRateJobId: string, - startTime: number, - endTime: number, - bucketDuration: number, - size: number, - afterKey?: CompositeTimestampPartitionKey -) => ({ - allowNoIndices: true, - body: { - query: { - bool: { - filter: [ - { - range: { - timestamp: { - gte: startTime, - lt: endTime, - }, - }, - }, - { - terms: { - result_type: ['model_plot', 'record'], - }, - }, - { - term: { - detector_index: { - value: 0, - }, - }, - }, - ], - }, - }, - aggs: { - timestamp_partition_buckets: { - composite: { - after: afterKey, - size, - sources: [ - { - timestamp: { - date_histogram: { - field: 'timestamp', - fixed_interval: `${bucketDuration}ms`, - order: 'asc', - }, - }, - }, - { - partition: { - terms: { - field: 'partition_field_value', - order: 'asc', - }, - }, - }, - ], - }, - aggs: { - filter_model_plot: { - filter: { - term: { - result_type: 'model_plot', - }, - }, - aggs: { - average_actual: { - avg: { - field: 'actual', - }, - }, - sum_actual: { - sum: { - field: 'actual', - }, - }, - }, - }, - filter_records: { - filter: { - term: { - result_type: 'record', - }, - }, - aggs: { - maximum_record_score: { - max: { - field: 'record_score', - }, - }, - top_hits_record: { - top_hits: { - _source: Object.keys(logRateMlRecordRT.props), - size: 100, - sort: [ - { - timestamp: 'asc', - }, - ], - }, - }, - }, - }, - }, - }, - }, - }, - ignoreUnavailable: true, - index: `${ML_ANOMALY_INDEX_PREFIX}${logRateJobId}`, - size: 0, - trackScores: false, - trackTotalHits: false, -}); - -const logRateMlRecordRT = rt.type({ - actual: rt.array(rt.number), - bucket_span: rt.number, - record_score: rt.number, - timestamp: rt.number, - typical: rt.array(rt.number), -}); - -const metricAggregationRT = rt.type({ - value: rt.union([rt.number, rt.null]), -}); - -const compositeTimestampPartitionKeyRT = rt.type({ - partition: rt.string, - timestamp: rt.number, -}); - -export type CompositeTimestampPartitionKey = rt.TypeOf; - -export const logRateModelPlotBucketRT = rt.type({ - key: compositeTimestampPartitionKeyRT, - filter_records: rt.type({ - doc_count: rt.number, - maximum_record_score: metricAggregationRT, - top_hits_record: rt.type({ - hits: rt.type({ - hits: rt.array( - rt.type({ - _source: logRateMlRecordRT, - }) - ), - }), - }), - }), - filter_model_plot: rt.type({ - doc_count: rt.number, - average_actual: metricAggregationRT, - sum_actual: metricAggregationRT, - }), -}); - -export type LogRateModelPlotBucket = rt.TypeOf; - -export const logRateModelPlotResponseRT = rt.type({ - aggregations: rt.type({ - timestamp_partition_buckets: rt.intersection([ - rt.type({ - buckets: rt.array(logRateModelPlotBucketRT), - }), - rt.partial({ - after_key: compositeTimestampPartitionKeyRT, - }), - ]), - }), -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/constants.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/constants.ts deleted file mode 100644 index 0420878dbcf508..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// TODO: Make SNAPSHOT_COMPOSITE_REQUEST_SIZE configurable from kibana.yml - -export const SNAPSHOT_COMPOSITE_REQUEST_SIZE = 75; diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts deleted file mode 100644 index 6c27e54a78bee4..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { uniq } from 'lodash'; -import { RequestHandlerContext } from 'kibana/server'; -import { InfraSnapshotRequestOptions } from './types'; -import { InfraTimerangeInput } from '../../../public/graphql/types'; -import { getMetricsAggregations } from './query_helpers'; -import { calculateMetricInterval } from '../../utils/calculate_metric_interval'; -import { SnapshotModel, SnapshotModelMetricAggRT } from '../../../common/inventory_models/types'; -import { KibanaFramework } from '../adapters/framework/kibana_framework_adapter'; - -export const createTimeRangeWithInterval = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - options: InfraSnapshotRequestOptions -): Promise => { - const aggregations = getMetricsAggregations(options); - const modules = aggregationsToModules(aggregations); - const interval = - (await calculateMetricInterval( - framework, - requestContext, - { - indexPattern: options.sourceConfiguration.metricAlias, - timestampField: options.sourceConfiguration.fields.timestamp, - timerange: { from: options.timerange.from, to: options.timerange.to }, - }, - modules, - options.nodeType - )) || 60000; - return { - interval: `${interval}s`, - from: options.timerange.to - interval * 5000, // We need at least 5 buckets worth of data - to: options.timerange.to, - }; -}; - -const aggregationsToModules = (aggregations: SnapshotModel): string[] => { - return uniq( - Object.values(aggregations) - .reduce((modules, agg) => { - if (SnapshotModelMetricAggRT.is(agg)) { - return modules.concat(Object.values(agg).map(a => a?.field)); - } - return modules; - }, [] as Array) - .filter(v => v) - .map(field => - field! - .split(/\./) - .slice(0, 2) - .join('.') - ) - ) as string[]; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/index.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/index.ts deleted file mode 100644 index 8db54da803648e..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './snapshot'; diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/query_helpers.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/query_helpers.ts deleted file mode 100644 index 44d32c7b915a8c..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/query_helpers.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; -import { findInventoryModel, findInventoryFields } from '../../../common/inventory_models/index'; -import { InfraSnapshotRequestOptions } from './types'; -import { getIntervalInSeconds } from '../../utils/get_interval_in_seconds'; -import { SnapshotModelRT, SnapshotModel } from '../../../common/inventory_models/types'; - -interface GroupBySource { - [id: string]: { - terms: { - field: string | null | undefined; - missing_bucket?: boolean; - }; - }; -} - -export const getFieldByNodeType = (options: InfraSnapshotRequestOptions) => { - const inventoryFields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - return inventoryFields.id; -}; - -export const getGroupedNodesSources = (options: InfraSnapshotRequestOptions) => { - const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - const sources: GroupBySource[] = options.groupBy.map(gb => { - return { [`${gb.field}`]: { terms: { field: gb.field } } }; - }); - sources.push({ - id: { - terms: { field: fields.id }, - }, - }); - sources.push({ - name: { terms: { field: fields.name, missing_bucket: true } }, - }); - return sources; -}; - -export const getMetricsSources = (options: InfraSnapshotRequestOptions) => { - const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - return [{ id: { terms: { field: fields.id } } }]; -}; - -export const getMetricsAggregations = (options: InfraSnapshotRequestOptions): SnapshotModel => { - const inventoryModel = findInventoryModel(options.nodeType); - const aggregation = inventoryModel.metrics.snapshot?.[options.metric.type]; - if (!SnapshotModelRT.is(aggregation)) { - throw new Error( - i18n.translate('xpack.infra.snapshot.missingSnapshotMetricError', { - defaultMessage: 'The aggregation for {metric} for {nodeType} is not available.', - values: { - nodeType: options.nodeType, - metric: options.metric.type, - }, - }) - ); - } - return aggregation; -}; - -export const getDateHistogramOffset = (options: InfraSnapshotRequestOptions): string => { - const { from, interval } = options.timerange; - const fromInSeconds = Math.floor(from / 1000); - const bucketSizeInSeconds = getIntervalInSeconds(interval); - - // negative offset to align buckets with full intervals (e.g. minutes) - const offset = (fromInSeconds % bucketSizeInSeconds) - bucketSizeInSeconds; - return `${offset}s`; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.test.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.test.ts deleted file mode 100644 index 28146624a8a894..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { isIPv4, getIPFromBucket, InfraSnapshotNodeGroupByBucket } from './response_helpers'; -import { InfraNodeType } from '../../graphql/types'; - -describe('InfraOps ResponseHelpers', () => { - describe('isIPv4', () => { - it('should return true for IPv4', () => { - expect(isIPv4('192.168.2.4')).toBe(true); - }); - it('should return false for anything else', () => { - expect(isIPv4('0:0:0:0:0:0:0:1')).toBe(false); - }); - }); - - describe('getIPFromBucket', () => { - it('should return IPv4 address', () => { - const bucket: InfraSnapshotNodeGroupByBucket = { - key: { - id: 'example-01', - name: 'example-01', - }, - ip: { - hits: { - total: { value: 1 }, - hits: [ - { - _index: 'metricbeat-2019-01-01', - _type: '_doc', - _id: '29392939', - _score: null, - sort: [], - _source: { - host: { - ip: ['2001:db8:85a3::8a2e:370:7334', '192.168.1.4'], - }, - }, - }, - ], - }, - }, - }; - expect(getIPFromBucket(InfraNodeType.host, bucket)).toBe('192.168.1.4'); - }); - it('should NOT return ipv6 address', () => { - const bucket: InfraSnapshotNodeGroupByBucket = { - key: { - id: 'example-01', - name: 'example-01', - }, - ip: { - hits: { - total: { value: 1 }, - hits: [ - { - _index: 'metricbeat-2019-01-01', - _type: '_doc', - _id: '29392939', - _score: null, - sort: [], - _source: { - host: { - ip: ['2001:db8:85a3::8a2e:370:7334'], - }, - }, - }, - ], - }, - }, - }; - expect(getIPFromBucket(InfraNodeType.host, bucket)).toBe(null); - }); - }); -}); diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.ts deleted file mode 100644 index d22f41ff152f76..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/response_helpers.ts +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { isNumber, last, max, sum, get } from 'lodash'; -import moment from 'moment'; - -import { - InfraSnapshotMetricType, - InfraSnapshotNodePath, - InfraSnapshotNodeMetric, - InfraNodeType, -} from '../../graphql/types'; -import { getIntervalInSeconds } from '../../utils/get_interval_in_seconds'; -import { InfraSnapshotRequestOptions } from './types'; -import { findInventoryModel } from '../../../common/inventory_models'; - -export interface InfraSnapshotNodeMetricsBucket { - key: { id: string }; - histogram: { - buckets: InfraSnapshotMetricsBucket[]; - }; -} - -// Jumping through TypeScript hoops here: -// We need an interface that has the known members 'key' and 'doc_count' and also -// an unknown number of members with unknown names but known format, containing the -// metrics. -// This union type is the only way I found to express this that TypeScript accepts. -export interface InfraSnapshotBucketWithKey { - key: string | number; - doc_count: number; -} - -export interface InfraSnapshotBucketWithValues { - [name: string]: { value: number; normalized_value?: number }; -} - -export type InfraSnapshotMetricsBucket = InfraSnapshotBucketWithKey & InfraSnapshotBucketWithValues; - -interface InfraSnapshotIpHit { - _index: string; - _type: string; - _id: string; - _score: number | null; - _source: { - host: { - ip: string[] | string; - }; - }; - sort: number[]; -} - -export interface InfraSnapshotNodeGroupByBucket { - key: { - id: string; - name: string; - [groupByField: string]: string; - }; - ip: { - hits: { - total: { value: number }; - hits: InfraSnapshotIpHit[]; - }; - }; -} - -export const isIPv4 = (subject: string) => /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/.test(subject); - -export const getIPFromBucket = ( - nodeType: InfraNodeType, - bucket: InfraSnapshotNodeGroupByBucket -): string | null => { - const inventoryModel = findInventoryModel(nodeType); - if (!inventoryModel.fields.ip) { - return null; - } - const ip = get(bucket, `ip.hits.hits[0]._source.${inventoryModel.fields.ip}`, null) as - | string[] - | null; - if (Array.isArray(ip)) { - return ip.find(isIPv4) || null; - } else if (typeof ip === 'string') { - return ip; - } - - return null; -}; - -export const getNodePath = ( - groupBucket: InfraSnapshotNodeGroupByBucket, - options: InfraSnapshotRequestOptions -): InfraSnapshotNodePath[] => { - const node = groupBucket.key; - const path = options.groupBy.map(gb => { - return { value: node[`${gb.field}`], label: node[`${gb.field}`] } as InfraSnapshotNodePath; - }); - const ip = getIPFromBucket(options.nodeType, groupBucket); - path.push({ value: node.id, label: node.name || node.id, ip }); - return path; -}; - -interface NodeMetricsForLookup { - [nodeId: string]: InfraSnapshotMetricsBucket[]; -} - -export const getNodeMetricsForLookup = ( - metrics: InfraSnapshotNodeMetricsBucket[] -): NodeMetricsForLookup => { - return metrics.reduce((acc: NodeMetricsForLookup, metric) => { - acc[`${metric.key.id}`] = metric.histogram.buckets; - return acc; - }, {}); -}; - -// In the returned object, -// value contains the value from the last bucket spanning a full interval -// max and avg are calculated from all buckets returned for the timerange -export const getNodeMetrics = ( - nodeBuckets: InfraSnapshotMetricsBucket[], - options: InfraSnapshotRequestOptions -): InfraSnapshotNodeMetric => { - if (!nodeBuckets) { - return { - name: options.metric.type, - value: null, - max: null, - avg: null, - }; - } - const lastBucket = findLastFullBucket(nodeBuckets, options); - const result = { - name: options.metric.type, - value: getMetricValueFromBucket(options.metric.type, lastBucket), - max: calculateMax(nodeBuckets, options.metric.type), - avg: calculateAvg(nodeBuckets, options.metric.type), - }; - return result; -}; - -const findLastFullBucket = ( - buckets: InfraSnapshotMetricsBucket[], - options: InfraSnapshotRequestOptions -) => { - const to = moment.utc(options.timerange.to); - const bucketSize = getIntervalInSeconds(options.timerange.interval); - return buckets.reduce((current, item) => { - const itemKey = isNumber(item.key) ? item.key : parseInt(item.key, 10); - const date = moment.utc(itemKey + bucketSize * 1000); - if (!date.isAfter(to) && item.doc_count > 0) { - return item; - } - return current; - }, last(buckets)); -}; - -const getMetricValueFromBucket = ( - type: InfraSnapshotMetricType, - bucket: InfraSnapshotMetricsBucket -) => { - const metric = bucket[type]; - return (metric && (metric.normalized_value || metric.value)) || 0; -}; - -function calculateMax(buckets: InfraSnapshotMetricsBucket[], type: InfraSnapshotMetricType) { - return max(buckets.map(bucket => getMetricValueFromBucket(type, bucket))) || 0; -} - -function calculateAvg(buckets: InfraSnapshotMetricsBucket[], type: InfraSnapshotMetricType) { - return sum(buckets.map(bucket => getMetricValueFromBucket(type, bucket))) / buckets.length || 0; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/snapshot.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/snapshot.ts deleted file mode 100644 index d5e10ecdce486e..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/snapshot.ts +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { InfraSnapshotNode } from '../../graphql/types'; -import { InfraDatabaseSearchResponse } from '../adapters/framework'; -import { KibanaFramework } from '../adapters/framework/kibana_framework_adapter'; -import { InfraSources } from '../sources'; - -import { JsonObject } from '../../../common/typed_json'; -import { SNAPSHOT_COMPOSITE_REQUEST_SIZE } from './constants'; -import { - getGroupedNodesSources, - getMetricsAggregations, - getMetricsSources, - getDateHistogramOffset, -} from './query_helpers'; -import { - getNodeMetrics, - getNodeMetricsForLookup, - getNodePath, - InfraSnapshotNodeGroupByBucket, - InfraSnapshotNodeMetricsBucket, -} from './response_helpers'; -import { getAllCompositeData } from '../../utils/get_all_composite_data'; -import { createAfterKeyHandler } from '../../utils/create_afterkey_handler'; -import { findInventoryModel } from '../../../common/inventory_models'; -import { InfraSnapshotRequestOptions } from './types'; -import { createTimeRangeWithInterval } from './create_timerange_with_interval'; - -export class InfraSnapshot { - constructor(private readonly libs: { sources: InfraSources; framework: KibanaFramework }) {} - - public async getNodes( - requestContext: RequestHandlerContext, - options: InfraSnapshotRequestOptions - ): Promise<{ nodes: InfraSnapshotNode[]; interval: string }> { - // Both requestGroupedNodes and requestNodeMetrics may send several requests to elasticsearch - // in order to page through the results of their respective composite aggregations. - // Both chains of requests are supposed to run in parallel, and their results be merged - // when they have both been completed. - const timeRangeWithIntervalApplied = await createTimeRangeWithInterval( - this.libs.framework, - requestContext, - options - ); - const optionsWithTimerange = { ...options, timerange: timeRangeWithIntervalApplied }; - const groupedNodesPromise = requestGroupedNodes( - requestContext, - optionsWithTimerange, - this.libs.framework - ); - const nodeMetricsPromise = requestNodeMetrics( - requestContext, - optionsWithTimerange, - this.libs.framework - ); - - const groupedNodeBuckets = await groupedNodesPromise; - const nodeMetricBuckets = await nodeMetricsPromise; - return { - nodes: mergeNodeBuckets(groupedNodeBuckets, nodeMetricBuckets, options), - interval: timeRangeWithIntervalApplied.interval, - }; - } -} - -const bucketSelector = ( - response: InfraDatabaseSearchResponse<{}, InfraSnapshotAggregationResponse> -) => (response.aggregations && response.aggregations.nodes.buckets) || []; - -const handleAfterKey = createAfterKeyHandler( - 'body.aggregations.nodes.composite.after', - input => input?.aggregations?.nodes?.after_key -); - -const requestGroupedNodes = async ( - requestContext: RequestHandlerContext, - options: InfraSnapshotRequestOptions, - framework: KibanaFramework -): Promise => { - const inventoryModel = findInventoryModel(options.nodeType); - const query = { - allowNoIndices: true, - index: `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: [ - ...createQueryFilterClauses(options.filterQuery), - { - range: { - [options.sourceConfiguration.fields.timestamp]: { - gte: options.timerange.from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ], - }, - }, - size: 0, - aggregations: { - nodes: { - composite: { - size: SNAPSHOT_COMPOSITE_REQUEST_SIZE, - sources: getGroupedNodesSources(options), - }, - aggs: { - ip: { - top_hits: { - sort: [{ [options.sourceConfiguration.fields.timestamp]: { order: 'desc' } }], - _source: { - includes: inventoryModel.fields.ip ? [inventoryModel.fields.ip] : [], - }, - size: 1, - }, - }, - }, - }, - }, - }, - }; - - return await getAllCompositeData< - InfraSnapshotAggregationResponse, - InfraSnapshotNodeGroupByBucket - >(framework, requestContext, query, bucketSelector, handleAfterKey); -}; - -const requestNodeMetrics = async ( - requestContext: RequestHandlerContext, - options: InfraSnapshotRequestOptions, - framework: KibanaFramework -): Promise => { - const index = - options.metric.type === 'logRate' - ? `${options.sourceConfiguration.logAlias}` - : `${options.sourceConfiguration.metricAlias}`; - - const query = { - allowNoIndices: true, - index, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: [ - { - range: { - [options.sourceConfiguration.fields.timestamp]: { - gte: options.timerange.from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ], - }, - }, - size: 0, - aggregations: { - nodes: { - composite: { - size: SNAPSHOT_COMPOSITE_REQUEST_SIZE, - sources: getMetricsSources(options), - }, - aggregations: { - histogram: { - date_histogram: { - field: options.sourceConfiguration.fields.timestamp, - interval: options.timerange.interval || '1m', - offset: getDateHistogramOffset(options), - extended_bounds: { - min: options.timerange.from, - max: options.timerange.to, - }, - }, - aggregations: getMetricsAggregations(options), - }, - }, - }, - }, - }, - }; - return await getAllCompositeData< - InfraSnapshotAggregationResponse, - InfraSnapshotNodeMetricsBucket - >(framework, requestContext, query, bucketSelector, handleAfterKey); -}; - -// buckets can be InfraSnapshotNodeGroupByBucket[] or InfraSnapshotNodeMetricsBucket[] -// but typing this in a way that makes TypeScript happy is unreadable (if possible at all) -interface InfraSnapshotAggregationResponse { - nodes: { - buckets: any[]; - after_key: { [id: string]: string }; - }; -} - -const mergeNodeBuckets = ( - nodeGroupByBuckets: InfraSnapshotNodeGroupByBucket[], - nodeMetricsBuckets: InfraSnapshotNodeMetricsBucket[], - options: InfraSnapshotRequestOptions -): InfraSnapshotNode[] => { - const nodeMetricsForLookup = getNodeMetricsForLookup(nodeMetricsBuckets); - - return nodeGroupByBuckets.map(node => { - return { - path: getNodePath(node, options), - metric: getNodeMetrics(nodeMetricsForLookup[node.key.id], options), - }; - }); -}; - -const createQueryFilterClauses = (filterQuery: JsonObject | undefined) => - filterQuery ? [filterQuery] : []; diff --git a/x-pack/legacy/plugins/infra/server/lib/snapshot/types.ts b/x-pack/legacy/plugins/infra/server/lib/snapshot/types.ts deleted file mode 100644 index 778f5045894a90..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/snapshot/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { JsonObject } from '../../../common/typed_json'; -import { - InfraNodeType, - InfraSourceConfiguration, - InfraTimerangeInput, - InfraSnapshotGroupbyInput, - InfraSnapshotMetricInput, -} from '../../../public/graphql/types'; - -export interface InfraSnapshotRequestOptions { - nodeType: InfraNodeType; - sourceConfiguration: InfraSourceConfiguration; - timerange: InfraTimerangeInput; - groupBy: InfraSnapshotGroupbyInput[]; - metric: InfraSnapshotMetricInput; - filterQuery: JsonObject | undefined; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/source_status.ts b/x-pack/legacy/plugins/infra/server/lib/source_status.ts deleted file mode 100644 index 1f0845b6b223f6..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/source_status.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { InfraSources } from './sources'; - -export class InfraSourceStatus { - constructor( - private readonly adapter: InfraSourceStatusAdapter, - private readonly libs: { sources: InfraSources } - ) {} - - public async getLogIndexNames( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const indexNames = await this.adapter.getIndexNames( - requestContext, - sourceConfiguration.configuration.logAlias - ); - return indexNames; - } - public async getMetricIndexNames( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const indexNames = await this.adapter.getIndexNames( - requestContext, - sourceConfiguration.configuration.metricAlias - ); - return indexNames; - } - public async hasLogAlias( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const hasAlias = await this.adapter.hasAlias( - requestContext, - sourceConfiguration.configuration.logAlias - ); - return hasAlias; - } - public async hasMetricAlias( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const hasAlias = await this.adapter.hasAlias( - requestContext, - sourceConfiguration.configuration.metricAlias - ); - return hasAlias; - } - public async hasLogIndices( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const hasIndices = await this.adapter.hasIndices( - requestContext, - sourceConfiguration.configuration.logAlias - ); - return hasIndices; - } - public async hasMetricIndices( - requestContext: RequestHandlerContext, - sourceId: string - ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const hasIndices = await this.adapter.hasIndices( - requestContext, - sourceConfiguration.configuration.metricAlias - ); - return hasIndices; - } -} - -export interface InfraSourceStatusAdapter { - getIndexNames(requestContext: RequestHandlerContext, aliasName: string): Promise; - hasAlias(requestContext: RequestHandlerContext, aliasName: string): Promise; - hasIndices(requestContext: RequestHandlerContext, indexNames: string): Promise; -} diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/defaults.ts b/x-pack/legacy/plugins/infra/server/lib/sources/defaults.ts deleted file mode 100644 index b9ead0d169ee60..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/defaults.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraSourceConfiguration } from './types'; - -export const defaultSourceConfiguration: InfraSourceConfiguration = { - name: 'Default', - description: '', - metricAlias: 'metricbeat-*', - logAlias: 'filebeat-*,kibana_sample_data_logs*', - fields: { - container: 'container.id', - host: 'host.name', - message: ['message', '@message'], - pod: 'kubernetes.pod.uid', - tiebreaker: '_doc', - timestamp: '@timestamp', - }, - logColumns: [ - { - timestampColumn: { - id: '5e7f964a-be8a-40d8-88d2-fbcfbdca0e2f', - }, - }, - { - fieldColumn: { - id: ' eb9777a8-fcd3-420e-ba7d-172fff6da7a2', - field: 'event.dataset', - }, - }, - { - messageColumn: { - id: 'b645d6da-824b-4723-9a2a-e8cece1645c0', - }, - }, - ], -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/errors.ts b/x-pack/legacy/plugins/infra/server/lib/sources/errors.ts deleted file mode 100644 index 9f835f21443c6a..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/errors.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export class NotFoundError extends Error { - constructor(message?: string) { - super(message); - Object.setPrototypeOf(this, new.target.prototype); - } -} diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/index.ts b/x-pack/legacy/plugins/infra/server/lib/sources/index.ts deleted file mode 100644 index 6837f953ea18ae..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './defaults'; -export * from './saved_object_mappings'; -export * from './sources'; -export * from './types'; diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/saved_object_mappings.ts b/x-pack/legacy/plugins/infra/server/lib/sources/saved_object_mappings.ts deleted file mode 100644 index 973a790eeedafd..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/saved_object_mappings.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ElasticsearchMappingOf } from '../../utils/typed_elasticsearch_mappings'; -import { InfraSavedSourceConfiguration } from './types'; - -export const infraSourceConfigurationSavedObjectType = 'infrastructure-ui-source'; - -export const infraSourceConfigurationSavedObjectMappings: { - [infraSourceConfigurationSavedObjectType]: ElasticsearchMappingOf; -} = { - [infraSourceConfigurationSavedObjectType]: { - properties: { - name: { - type: 'text', - }, - description: { - type: 'text', - }, - metricAlias: { - type: 'keyword', - }, - logAlias: { - type: 'keyword', - }, - fields: { - properties: { - container: { - type: 'keyword', - }, - host: { - type: 'keyword', - }, - pod: { - type: 'keyword', - }, - tiebreaker: { - type: 'keyword', - }, - timestamp: { - type: 'keyword', - }, - }, - }, - logColumns: { - type: 'nested', - properties: { - timestampColumn: { - properties: { - id: { - type: 'keyword', - }, - }, - }, - messageColumn: { - properties: { - id: { - type: 'keyword', - }, - }, - }, - fieldColumn: { - properties: { - id: { - type: 'keyword', - }, - field: { - type: 'keyword', - }, - }, - }, - }, - }, - }, - }, -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/sources.test.ts b/x-pack/legacy/plugins/infra/server/lib/sources/sources.test.ts deleted file mode 100644 index 4a83ca730ff83f..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/sources.test.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { InfraSources } from './sources'; - -describe('the InfraSources lib', () => { - describe('getSourceConfiguration method', () => { - test('returns a source configuration if it exists', async () => { - const sourcesLib = new InfraSources({ - config: createMockStaticConfiguration({}), - }); - - const request: any = createRequestContext({ - id: 'TEST_ID', - version: 'foo', - updated_at: '2000-01-01T00:00:00.000Z', - attributes: { - metricAlias: 'METRIC_ALIAS', - logAlias: 'LOG_ALIAS', - fields: { - container: 'CONTAINER', - host: 'HOST', - pod: 'POD', - tiebreaker: 'TIEBREAKER', - timestamp: 'TIMESTAMP', - }, - }, - }); - - expect(await sourcesLib.getSourceConfiguration(request, 'TEST_ID')).toMatchObject({ - id: 'TEST_ID', - version: 'foo', - updatedAt: 946684800000, - configuration: { - metricAlias: 'METRIC_ALIAS', - logAlias: 'LOG_ALIAS', - fields: { - container: 'CONTAINER', - host: 'HOST', - pod: 'POD', - tiebreaker: 'TIEBREAKER', - timestamp: 'TIMESTAMP', - }, - }, - }); - }); - - test('adds missing attributes from the static configuration to a source configuration', async () => { - const sourcesLib = new InfraSources({ - config: createMockStaticConfiguration({ - default: { - metricAlias: 'METRIC_ALIAS', - logAlias: 'LOG_ALIAS', - fields: { - host: 'HOST', - pod: 'POD', - tiebreaker: 'TIEBREAKER', - timestamp: 'TIMESTAMP', - }, - }, - }), - }); - - const request: any = createRequestContext({ - id: 'TEST_ID', - version: 'foo', - updated_at: '2000-01-01T00:00:00.000Z', - attributes: { - fields: { - container: 'CONTAINER', - }, - }, - }); - - expect(await sourcesLib.getSourceConfiguration(request, 'TEST_ID')).toMatchObject({ - id: 'TEST_ID', - version: 'foo', - updatedAt: 946684800000, - configuration: { - metricAlias: 'METRIC_ALIAS', - logAlias: 'LOG_ALIAS', - fields: { - container: 'CONTAINER', - host: 'HOST', - pod: 'POD', - tiebreaker: 'TIEBREAKER', - timestamp: 'TIMESTAMP', - }, - }, - }); - }); - - test('adds missing attributes from the default configuration to a source configuration', async () => { - const sourcesLib = new InfraSources({ - config: createMockStaticConfiguration({}), - }); - - const request: any = createRequestContext({ - id: 'TEST_ID', - version: 'foo', - updated_at: '2000-01-01T00:00:00.000Z', - attributes: {}, - }); - - expect(await sourcesLib.getSourceConfiguration(request, 'TEST_ID')).toMatchObject({ - id: 'TEST_ID', - version: 'foo', - updatedAt: 946684800000, - configuration: { - metricAlias: expect.any(String), - logAlias: expect.any(String), - fields: { - container: expect.any(String), - host: expect.any(String), - pod: expect.any(String), - tiebreaker: expect.any(String), - timestamp: expect.any(String), - }, - }, - }); - }); - }); -}); - -const createMockStaticConfiguration = (sources: any) => ({ - enabled: true, - query: { - partitionSize: 1, - partitionFactor: 1, - }, - sources, -}); - -const createRequestContext = (savedObject?: any) => { - return { - core: { - savedObjects: { - client: { - async get() { - return savedObject; - }, - errors: { - isNotFoundError() { - return typeof savedObject === 'undefined'; - }, - }, - }, - }, - }, - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/sources.ts b/x-pack/legacy/plugins/infra/server/lib/sources/sources.ts deleted file mode 100644 index 2b38d81e4a8d50..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/sources.ts +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import * as runtimeTypes from 'io-ts'; -import { failure } from 'io-ts/lib/PathReporter'; -import { identity, constant } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { map, fold } from 'fp-ts/lib/Either'; -import { RequestHandlerContext } from 'src/core/server'; -import { defaultSourceConfiguration } from './defaults'; -import { NotFoundError } from './errors'; -import { infraSourceConfigurationSavedObjectType } from './saved_object_mappings'; -import { - InfraSavedSourceConfiguration, - InfraSourceConfiguration, - InfraStaticSourceConfiguration, - pickSavedSourceConfiguration, - SourceConfigurationSavedObjectRuntimeType, - StaticSourceConfigurationRuntimeType, -} from './types'; -import { InfraConfig } from '../../../../../../plugins/infra/server'; - -interface Libs { - config: InfraConfig; -} - -export class InfraSources { - private internalSourceConfigurations: Map = new Map(); - private readonly libs: Libs; - - constructor(libs: Libs) { - this.libs = libs; - } - - public async getSourceConfiguration(requestContext: RequestHandlerContext, sourceId: string) { - const staticDefaultSourceConfiguration = await this.getStaticDefaultSourceConfiguration(); - - const savedSourceConfiguration = await this.getInternalSourceConfiguration(sourceId) - .then(internalSourceConfiguration => ({ - id: sourceId, - version: undefined, - updatedAt: undefined, - origin: 'internal' as 'internal', - configuration: mergeSourceConfiguration( - staticDefaultSourceConfiguration, - internalSourceConfiguration - ), - })) - .catch(err => - err instanceof NotFoundError - ? this.getSavedSourceConfiguration(requestContext, sourceId).then(result => ({ - ...result, - configuration: mergeSourceConfiguration( - staticDefaultSourceConfiguration, - result.configuration - ), - })) - : Promise.reject(err) - ) - .catch(err => - requestContext.core.savedObjects.client.errors.isNotFoundError(err) - ? Promise.resolve({ - id: sourceId, - version: undefined, - updatedAt: undefined, - origin: 'fallback' as 'fallback', - configuration: staticDefaultSourceConfiguration, - }) - : Promise.reject(err) - ); - - return savedSourceConfiguration; - } - - public async getAllSourceConfigurations(requestContext: RequestHandlerContext) { - const staticDefaultSourceConfiguration = await this.getStaticDefaultSourceConfiguration(); - - const savedSourceConfigurations = await this.getAllSavedSourceConfigurations(requestContext); - - return savedSourceConfigurations.map(savedSourceConfiguration => ({ - ...savedSourceConfiguration, - configuration: mergeSourceConfiguration( - staticDefaultSourceConfiguration, - savedSourceConfiguration.configuration - ), - })); - } - - public async createSourceConfiguration( - requestContext: RequestHandlerContext, - sourceId: string, - source: InfraSavedSourceConfiguration - ) { - const staticDefaultSourceConfiguration = await this.getStaticDefaultSourceConfiguration(); - - const newSourceConfiguration = mergeSourceConfiguration( - staticDefaultSourceConfiguration, - source - ); - - const createdSourceConfiguration = convertSavedObjectToSavedSourceConfiguration( - await requestContext.core.savedObjects.client.create( - infraSourceConfigurationSavedObjectType, - pickSavedSourceConfiguration(newSourceConfiguration) as any, - { id: sourceId } - ) - ); - - return { - ...createdSourceConfiguration, - configuration: mergeSourceConfiguration( - staticDefaultSourceConfiguration, - createdSourceConfiguration.configuration - ), - }; - } - - public async deleteSourceConfiguration(requestContext: RequestHandlerContext, sourceId: string) { - await requestContext.core.savedObjects.client.delete( - infraSourceConfigurationSavedObjectType, - sourceId - ); - } - - public async updateSourceConfiguration( - requestContext: RequestHandlerContext, - sourceId: string, - sourceProperties: InfraSavedSourceConfiguration - ) { - const staticDefaultSourceConfiguration = await this.getStaticDefaultSourceConfiguration(); - - const { configuration, version } = await this.getSourceConfiguration(requestContext, sourceId); - - const updatedSourceConfigurationAttributes = mergeSourceConfiguration( - configuration, - sourceProperties - ); - - const updatedSourceConfiguration = convertSavedObjectToSavedSourceConfiguration( - await requestContext.core.savedObjects.client.update( - infraSourceConfigurationSavedObjectType, - sourceId, - pickSavedSourceConfiguration(updatedSourceConfigurationAttributes) as any, - { - version, - } - ) - ); - - return { - ...updatedSourceConfiguration, - configuration: mergeSourceConfiguration( - staticDefaultSourceConfiguration, - updatedSourceConfiguration.configuration - ), - }; - } - - public async defineInternalSourceConfiguration( - sourceId: string, - sourceProperties: InfraStaticSourceConfiguration - ) { - this.internalSourceConfigurations.set(sourceId, sourceProperties); - } - - public async getInternalSourceConfiguration(sourceId: string) { - const internalSourceConfiguration = this.internalSourceConfigurations.get(sourceId); - - if (!internalSourceConfiguration) { - throw new NotFoundError( - `Failed to load internal source configuration: no configuration "${sourceId}" found.` - ); - } - - return internalSourceConfiguration; - } - - private async getStaticDefaultSourceConfiguration() { - const staticSourceConfiguration = pipe( - runtimeTypes - .type({ - sources: runtimeTypes.type({ - default: StaticSourceConfigurationRuntimeType, - }), - }) - .decode(this.libs.config), - map(({ sources: { default: defaultConfiguration } }) => defaultConfiguration), - fold(constant({}), identity) - ); - - return mergeSourceConfiguration(defaultSourceConfiguration, staticSourceConfiguration); - } - - private async getSavedSourceConfiguration( - requestContext: RequestHandlerContext, - sourceId: string - ) { - const savedObject = await requestContext.core.savedObjects.client.get( - infraSourceConfigurationSavedObjectType, - sourceId - ); - - return convertSavedObjectToSavedSourceConfiguration(savedObject); - } - - private async getAllSavedSourceConfigurations(requestContext: RequestHandlerContext) { - const savedObjects = await requestContext.core.savedObjects.client.find({ - type: infraSourceConfigurationSavedObjectType, - }); - - return savedObjects.saved_objects.map(convertSavedObjectToSavedSourceConfiguration); - } -} - -const mergeSourceConfiguration = ( - first: InfraSourceConfiguration, - ...others: InfraStaticSourceConfiguration[] -) => - others.reduce( - (previousSourceConfiguration, currentSourceConfiguration) => ({ - ...previousSourceConfiguration, - ...currentSourceConfiguration, - fields: { - ...previousSourceConfiguration.fields, - ...currentSourceConfiguration.fields, - }, - }), - first - ); - -const convertSavedObjectToSavedSourceConfiguration = (savedObject: unknown) => - pipe( - SourceConfigurationSavedObjectRuntimeType.decode(savedObject), - map(savedSourceConfiguration => ({ - id: savedSourceConfiguration.id, - version: savedSourceConfiguration.version, - updatedAt: savedSourceConfiguration.updated_at, - origin: 'stored' as 'stored', - configuration: savedSourceConfiguration.attributes, - })), - fold(errors => { - throw new Error(failure(errors).join('\n')); - }, identity) - ); diff --git a/x-pack/legacy/plugins/infra/server/lib/sources/types.ts b/x-pack/legacy/plugins/infra/server/lib/sources/types.ts deleted file mode 100644 index 1f850635cf35a2..00000000000000 --- a/x-pack/legacy/plugins/infra/server/lib/sources/types.ts +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/* eslint-disable @typescript-eslint/no-empty-interface */ - -import * as runtimeTypes 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 runtimeTypes.Type( - 'TimestampFromString', - (input): input is number => typeof input === 'number', - (input, context) => - pipe( - runtimeTypes.string.validate(input, context), - chain(stringInput => { - const momentValue = moment(stringInput); - return momentValue.isValid() - ? runtimeTypes.success(momentValue.valueOf()) - : runtimeTypes.failure(stringInput, context); - }) - ), - output => new Date(output).toISOString() -); - -/** - * Stored source configuration as read from and written to saved objects - */ - -const SavedSourceConfigurationFieldsRuntimeType = runtimeTypes.partial({ - container: runtimeTypes.string, - host: runtimeTypes.string, - pod: runtimeTypes.string, - tiebreaker: runtimeTypes.string, - timestamp: runtimeTypes.string, -}); - -export const SavedSourceConfigurationTimestampColumnRuntimeType = runtimeTypes.type({ - timestampColumn: runtimeTypes.type({ - id: runtimeTypes.string, - }), -}); - -export const SavedSourceConfigurationMessageColumnRuntimeType = runtimeTypes.type({ - messageColumn: runtimeTypes.type({ - id: runtimeTypes.string, - }), -}); - -export const SavedSourceConfigurationFieldColumnRuntimeType = runtimeTypes.type({ - fieldColumn: runtimeTypes.type({ - id: runtimeTypes.string, - field: runtimeTypes.string, - }), -}); - -export const SavedSourceConfigurationColumnRuntimeType = runtimeTypes.union([ - SavedSourceConfigurationTimestampColumnRuntimeType, - SavedSourceConfigurationMessageColumnRuntimeType, - SavedSourceConfigurationFieldColumnRuntimeType, -]); - -export const SavedSourceConfigurationRuntimeType = runtimeTypes.partial({ - name: runtimeTypes.string, - description: runtimeTypes.string, - metricAlias: runtimeTypes.string, - logAlias: runtimeTypes.string, - fields: SavedSourceConfigurationFieldsRuntimeType, - logColumns: runtimeTypes.array(SavedSourceConfigurationColumnRuntimeType), -}); - -export interface InfraSavedSourceConfiguration - extends runtimeTypes.TypeOf {} - -export const pickSavedSourceConfiguration = ( - value: InfraSourceConfiguration -): InfraSavedSourceConfiguration => { - const { name, description, metricAlias, logAlias, fields, logColumns } = value; - const { container, host, pod, tiebreaker, timestamp } = fields; - - return { - name, - description, - metricAlias, - logAlias, - fields: { container, host, pod, tiebreaker, timestamp }, - logColumns, - }; -}; - -/** - * Static source configuration as read from the configuration file - */ - -const StaticSourceConfigurationFieldsRuntimeType = runtimeTypes.partial({ - ...SavedSourceConfigurationFieldsRuntimeType.props, - message: runtimeTypes.array(runtimeTypes.string), -}); - -export const StaticSourceConfigurationRuntimeType = runtimeTypes.partial({ - name: runtimeTypes.string, - description: runtimeTypes.string, - metricAlias: runtimeTypes.string, - logAlias: runtimeTypes.string, - fields: StaticSourceConfigurationFieldsRuntimeType, - logColumns: runtimeTypes.array(SavedSourceConfigurationColumnRuntimeType), -}); - -export interface InfraStaticSourceConfiguration - extends runtimeTypes.TypeOf {} - -/** - * Full source configuration type after all cleanup has been done at the edges - */ - -const SourceConfigurationFieldsRuntimeType = runtimeTypes.type({ - ...StaticSourceConfigurationFieldsRuntimeType.props, -}); - -export const SourceConfigurationRuntimeType = runtimeTypes.type({ - ...SavedSourceConfigurationRuntimeType.props, - fields: SourceConfigurationFieldsRuntimeType, - logColumns: runtimeTypes.array(SavedSourceConfigurationColumnRuntimeType), -}); - -export interface InfraSourceConfiguration - extends runtimeTypes.TypeOf {} - -/** - * Saved object type with metadata - */ - -export const SourceConfigurationSavedObjectRuntimeType = runtimeTypes.intersection([ - runtimeTypes.type({ - id: runtimeTypes.string, - attributes: SavedSourceConfigurationRuntimeType, - }), - runtimeTypes.partial({ - version: runtimeTypes.string, - updated_at: TimestampFromString, - }), -]); - -export interface SourceConfigurationSavedObject - extends runtimeTypes.TypeOf {} diff --git a/x-pack/legacy/plugins/infra/server/new_platform_index.ts b/x-pack/legacy/plugins/infra/server/new_platform_index.ts deleted file mode 100644 index e59897a6b241dc..00000000000000 --- a/x-pack/legacy/plugins/infra/server/new_platform_index.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { PluginInitializerContext } from 'src/core/server'; -import { InfraServerPlugin, InfraPluginSetup } from './new_platform_plugin'; -import { config, InfraConfig } from '../../../../plugins/infra/server'; -import { InfraServerPluginDeps } from './lib/adapters/framework'; -export { config, InfraConfig, InfraServerPluginDeps, InfraPluginSetup }; - -export function plugin(context: PluginInitializerContext) { - return new InfraServerPlugin(context); -} diff --git a/x-pack/legacy/plugins/infra/server/new_platform_plugin.ts b/x-pack/legacy/plugins/infra/server/new_platform_plugin.ts deleted file mode 100644 index ad26663402adc4..00000000000000 --- a/x-pack/legacy/plugins/infra/server/new_platform_plugin.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { CoreSetup, PluginInitializerContext } from 'src/core/server'; -import { Server } from 'hapi'; -import { InfraConfig } from '../../../../plugins/infra/server'; -import { initInfraServer } from './infra_server'; -import { InfraBackendLibs, InfraDomainLibs } from './lib/infra_types'; -import { FrameworkFieldsAdapter } from './lib/adapters/fields/framework_fields_adapter'; -import { KibanaFramework } from './lib/adapters/framework/kibana_framework_adapter'; -import { InfraKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter'; -import { KibanaMetricsAdapter } from './lib/adapters/metrics/kibana_metrics_adapter'; -import { InfraElasticsearchSourceStatusAdapter } from './lib/adapters/source_status'; -import { InfraFieldsDomain } from './lib/domains/fields_domain'; -import { InfraLogEntriesDomain } from './lib/domains/log_entries_domain'; -import { InfraMetricsDomain } from './lib/domains/metrics_domain'; -import { InfraLogAnalysis } from './lib/log_analysis'; -import { InfraSnapshot } from './lib/snapshot'; -import { InfraSourceStatus } from './lib/source_status'; -import { InfraSources } from './lib/sources'; -import { InfraServerPluginDeps } from './lib/adapters/framework'; -import { METRICS_FEATURE, LOGS_FEATURE } from './features'; -import { UsageCollector } from './usage/usage_collector'; -import { InfraStaticSourceConfiguration } from './lib/sources/types'; - -export interface KbnServer extends Server { - usage: any; -} - -export interface InfraPluginSetup { - defineInternalSourceConfiguration: ( - sourceId: string, - sourceProperties: InfraStaticSourceConfiguration - ) => void; -} - -const DEFAULT_CONFIG: InfraConfig = { - enabled: true, - query: { - partitionSize: 75, - partitionFactor: 1.2, - }, -}; - -export class InfraServerPlugin { - public config: InfraConfig = DEFAULT_CONFIG; - public libs: InfraBackendLibs | undefined; - - constructor(context: PluginInitializerContext) { - const config$ = context.config.create(); - config$.subscribe(configValue => { - this.config = { - ...DEFAULT_CONFIG, - enabled: configValue.enabled, - query: { - ...DEFAULT_CONFIG.query, - ...configValue.query, - }, - }; - }); - } - - getLibs() { - if (!this.libs) { - throw new Error('libs not set up yet'); - } - return this.libs; - } - - setup(core: CoreSetup, plugins: InfraServerPluginDeps) { - const framework = new KibanaFramework(core, this.config, plugins); - const sources = new InfraSources({ - config: this.config, - }); - const sourceStatus = new InfraSourceStatus( - new InfraElasticsearchSourceStatusAdapter(framework), - { - sources, - } - ); - const snapshot = new InfraSnapshot({ sources, framework }); - const logAnalysis = new InfraLogAnalysis({ framework }); - - // TODO: separate these out individually and do away with "domains" as a temporary group - const domainLibs: InfraDomainLibs = { - fields: new InfraFieldsDomain(new FrameworkFieldsAdapter(framework), { - sources, - }), - logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { - sources, - }), - metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), - }; - - this.libs = { - configuration: this.config, - framework, - logAnalysis, - snapshot, - sources, - sourceStatus, - ...domainLibs, - }; - - plugins.features.registerFeature(METRICS_FEATURE); - plugins.features.registerFeature(LOGS_FEATURE); - - initInfraServer(this.libs); - - // Telemetry - UsageCollector.registerUsageCollector(plugins.usageCollection); - - return { - defineInternalSourceConfiguration(sourceId, sourceProperties) { - sources.defineInternalSourceConfiguration(sourceId, sourceProperties); - }, - } as InfraPluginSetup; - } -} diff --git a/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/index.ts b/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/index.ts deleted file mode 100644 index c7927d36d50f01..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { schema } from '@kbn/config-schema'; -import Boom from 'boom'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { InfraBackendLibs } from '../../lib/infra_types'; -import { throwErrors } from '../../../common/runtime_types'; -import { getAWSMetadata } from './lib/get_aws_metadata'; -import { - InventoryMetaRequestRT, - InventoryMetaResponseRT, -} from '../../../common/http_api/inventory_meta_api'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initInventoryMetaRoute = (libs: InfraBackendLibs) => { - const { framework } = libs; - - framework.registerRoute( - { - method: 'post', - path: '/api/infra/inventory/meta', - validate: { - body: escapeHatch, - }, - }, - async (requestContext, request, response) => { - try { - const { sourceId, nodeType } = pipe( - InventoryMetaRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const awsMetadata = await getAWSMetadata( - framework, - requestContext, - configuration, - nodeType - ); - - return response.ok({ - body: InventoryMetaResponseRT.encode(awsMetadata), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/lib/get_aws_metadata.ts b/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/lib/get_aws_metadata.ts deleted file mode 100644 index 9440d7b66c0be8..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/inventory_metadata/lib/get_aws_metadata.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'kibana/server'; -import { InventoryAWSAccount } from '../../../../common/http_api/inventory_meta_api'; -import { - InfraMetadataAggregationResponse, - InfraMetadataAggregationBucket, -} from '../../../lib/adapters/framework'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; -import { findInventoryModel } from '../../../../common/inventory_models'; - -export interface AWSInventoryMetadata { - accounts: InventoryAWSAccount[]; - projects: string[]; - regions: string[]; -} - -export const getAWSMetadata = async ( - framework: KibanaFramework, - req: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - nodeType: InventoryItemType -): Promise => { - const model = findInventoryModel(nodeType); - - const metricQuery = { - allowNoIndices: true, - ignoreUnavailable: true, - index: sourceConfiguration.metricAlias, - body: { - query: { - bool: { - must: [{ match: { 'event.module': model.requiredModule } }], - }, - }, - size: 0, - aggs: { - accounts: { - terms: { - field: 'cloud.account.id', - size: 1000, - }, - aggs: { - accountNames: { - terms: { - field: 'cloud.account.name', - size: 1000, - }, - }, - }, - }, - regions: { - terms: { - field: 'cloud.region', - size: 1000, - }, - }, - }, - }, - }; - - const response = await framework.callWithRequest< - {}, - { - accounts?: { - buckets: Array< - InfraMetadataAggregationBucket & { accountNames: InfraMetadataAggregationResponse } - >; - }; - projects?: InfraMetadataAggregationResponse; - regions?: InfraMetadataAggregationResponse; - } - >(req, 'search', metricQuery); - - const projectBuckets = - response.aggregations && response.aggregations.projects - ? response.aggregations.projects.buckets - : []; - - const regionBuckets = - response.aggregations && response.aggregations.regions - ? response.aggregations.regions.buckets - : []; - - const accounts: InventoryAWSAccount[] = []; - if (response.aggregations && response.aggregations.accounts) { - response.aggregations.accounts.buckets.forEach(b => { - if (b.accountNames.buckets.length) { - accounts.push({ - value: b.key, - // There should only be one account name for each account id. - name: b.accountNames.buckets[0].key, - }); - } - }); - } - return { - accounts, - projects: projectBuckets.map(b => b.key), - regions: regionBuckets.map(b => b.key), - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/ip_to_hostname.ts b/x-pack/legacy/plugins/infra/server/routes/ip_to_hostname.ts deleted file mode 100644 index 5ad79b3d17a135..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/ip_to_hostname.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { first } from 'lodash'; -import { schema } from '@kbn/config-schema'; -import { InfraBackendLibs } from '../lib/infra_types'; - -export interface IpToHostResponse { - host: string; -} - -interface HostDoc { - _source: { - host: { - name: string; - }; - }; -} - -const ipToHostSchema = schema.object({ - ip: schema.string(), - index_pattern: schema.string(), -}); - -export const initIpToHostName = ({ framework }: InfraBackendLibs) => { - const { callWithRequest } = framework; - framework.registerRoute( - { - method: 'post', - path: '/api/infra/ip_to_host', - validate: { - body: ipToHostSchema, - }, - }, - async (requestContext, { body }, response) => { - try { - const params = { - index: body.index_pattern, - body: { - size: 1, - query: { - match: { 'host.ip': body.ip }, - }, - _source: ['host.name'], - }, - }; - const { hits } = await callWithRequest(requestContext, 'search', params); - if (hits.total.value === 0) { - return response.notFound({ - body: { message: 'Host with matching IP address not found.' }, - }); - } - const hostDoc = first(hits.hits); - return response.ok({ body: { host: hostDoc._source.host.name } }); - } catch ({ statusCode = 500, message = 'Unknown error occurred' }) { - return response.customError({ - statusCode, - body: { message }, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/index.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/index.ts deleted file mode 100644 index 378e32cb3582ca..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './results'; -export * from './validation'; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/index.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/index.ts deleted file mode 100644 index 17494212777198..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './log_entry_rate'; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts deleted file mode 100644 index 9778311bd8e58c..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; -import { InfraBackendLibs } from '../../../lib/infra_types'; -import { - LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, - getLogEntryRateRequestPayloadRT, - getLogEntryRateSuccessReponsePayloadRT, - GetLogEntryRateSuccessResponsePayload, -} from '../../../../common/http_api/log_analysis'; -import { throwErrors } from '../../../../common/runtime_types'; -import { NoLogRateResultsIndexError } from '../../../lib/log_analysis'; - -const anyObject = schema.object({}, { allowUnknowns: true }); - -export const initGetLogEntryRateRoute = ({ framework, logAnalysis }: InfraBackendLibs) => { - framework.registerRoute( - { - method: 'post', - path: LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, - validate: { - // short-circuit forced @kbn/config-schema validation so we can do io-ts validation - body: anyObject, - }, - }, - async (requestContext, request, response) => { - try { - const payload = pipe( - getLogEntryRateRequestPayloadRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - - const logEntryRateBuckets = await logAnalysis.getLogEntryRateBuckets( - requestContext, - payload.data.sourceId, - payload.data.timeRange.startTime, - payload.data.timeRange.endTime, - payload.data.bucketDuration, - request - ); - - return response.ok({ - body: getLogEntryRateSuccessReponsePayloadRT.encode({ - data: { - bucketDuration: payload.data.bucketDuration, - histogramBuckets: logEntryRateBuckets, - totalNumberOfLogEntries: getTotalNumberOfLogEntries(logEntryRateBuckets), - }, - }), - }); - } catch (e) { - const { statusCode = 500, message = 'Unknown error occurred' } = e; - if (e instanceof NoLogRateResultsIndexError) { - return response.notFound({ body: { message } }); - } - return response.customError({ - statusCode, - body: { message }, - }); - } - } - ); -}; - -const getTotalNumberOfLogEntries = ( - logEntryRateBuckets: GetLogEntryRateSuccessResponsePayload['data']['histogramBuckets'] -) => { - return logEntryRateBuckets.reduce((sumNumberOfLogEntries, bucket) => { - const sumPartitions = bucket.partitions.reduce((partitionsTotal, partition) => { - return (partitionsTotal += partition.numberOfLogEntries); - }, 0); - return (sumNumberOfLogEntries += sumPartitions); - }, 0); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/index.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/index.ts deleted file mode 100644 index 727faca69298ee..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './indices'; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/indices.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/indices.ts deleted file mode 100644 index fe579124cfe104..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/validation/indices.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; -import { InfraBackendLibs } from '../../../lib/infra_types'; -import { - LOG_ANALYSIS_VALIDATE_INDICES_PATH, - validationIndicesRequestPayloadRT, - validationIndicesResponsePayloadRT, - ValidationIndicesError, -} from '../../../../common/http_api'; - -import { throwErrors } from '../../../../common/runtime_types'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initValidateLogAnalysisIndicesRoute = ({ framework }: InfraBackendLibs) => { - framework.registerRoute( - { - method: 'post', - path: LOG_ANALYSIS_VALIDATE_INDICES_PATH, - validate: { body: escapeHatch }, - }, - async (requestContext, request, response) => { - try { - const payload = pipe( - validationIndicesRequestPayloadRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - - const { fields, indices } = payload.data; - const errors: ValidationIndicesError[] = []; - - // Query each pattern individually, to map correctly the errors - await Promise.all( - indices.map(async index => { - const fieldCaps = await framework.callWithRequest(requestContext, 'fieldCaps', { - allow_no_indices: true, - fields: fields.map(field => field.name), - ignore_unavailable: true, - index, - }); - - if (fieldCaps.indices.length === 0) { - errors.push({ - error: 'INDEX_NOT_FOUND', - index, - }); - return; - } - - fields.forEach(({ name: fieldName, validTypes }) => { - const fieldMetadata = fieldCaps.fields[fieldName]; - - if (fieldMetadata === undefined) { - errors.push({ - error: 'FIELD_NOT_FOUND', - index, - field: fieldName, - }); - } else { - const fieldTypes = Object.keys(fieldMetadata); - - if (!fieldTypes.every(fieldType => validTypes.includes(fieldType))) { - errors.push({ - error: `FIELD_NOT_VALID`, - index, - field: fieldName, - }); - } - } - }); - }) - ); - - return response.ok({ - body: validationIndicesResponsePayloadRT.encode({ data: { errors } }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_entries/index.ts b/x-pack/legacy/plugins/infra/server/routes/log_entries/index.ts deleted file mode 100644 index ee2d150fdaac00..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_entries/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export * from './summary'; -export * from './summary_highlights'; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_entries/summary.ts b/x-pack/legacy/plugins/infra/server/routes/log_entries/summary.ts deleted file mode 100644 index 05643adbe781fa..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_entries/summary.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; - -import { throwErrors } from '../../../common/runtime_types'; - -import { InfraBackendLibs } from '../../lib/infra_types'; -import { - LOG_ENTRIES_SUMMARY_PATH, - logEntriesSummaryRequestRT, - logEntriesSummaryResponseRT, -} from '../../../common/http_api/log_entries'; -import { parseFilterQuery } from '../../utils/serialized_query'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBackendLibs) => { - framework.registerRoute( - { - method: 'post', - path: LOG_ENTRIES_SUMMARY_PATH, - validate: { body: escapeHatch }, - }, - async (requestContext, request, response) => { - try { - const payload = pipe( - logEntriesSummaryRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - const { sourceId, startDate, endDate, bucketSize, query } = payload; - - const buckets = await logEntries.getLogSummaryBucketsBetween( - requestContext, - sourceId, - startDate, - endDate, - bucketSize, - parseFilterQuery(query) - ); - - return response.ok({ - body: logEntriesSummaryResponseRT.encode({ - data: { - start: startDate, - end: endDate, - buckets, - }, - }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/log_entries/summary_highlights.ts b/x-pack/legacy/plugins/infra/server/routes/log_entries/summary_highlights.ts deleted file mode 100644 index ecccd931bb3718..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/log_entries/summary_highlights.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; - -import { throwErrors } from '../../../common/runtime_types'; - -import { InfraBackendLibs } from '../../lib/infra_types'; -import { - LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, - logEntriesSummaryHighlightsRequestRT, - logEntriesSummaryHighlightsResponseRT, -} from '../../../common/http_api/log_entries'; -import { parseFilterQuery } from '../../utils/serialized_query'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initLogEntriesSummaryHighlightsRoute = ({ - framework, - logEntries, -}: InfraBackendLibs) => { - framework.registerRoute( - { - method: 'post', - path: LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, - validate: { body: escapeHatch }, - }, - async (requestContext, request, response) => { - try { - const payload = pipe( - logEntriesSummaryHighlightsRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - const { sourceId, startDate, endDate, bucketSize, query, highlightTerms } = payload; - - const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween( - requestContext, - sourceId, - startDate, - endDate, - bucketSize, - highlightTerms, - parseFilterQuery(query) - ); - - return response.ok({ - body: logEntriesSummaryHighlightsResponseRT.encode({ - data: bucketsPerHighlightTerm.map(buckets => ({ - start: startDate, - end: endDate, - buckets, - })), - }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/index.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/index.ts deleted file mode 100644 index a1f6311a103eb5..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { schema } from '@kbn/config-schema'; -import Boom from 'boom'; -import { get } from 'lodash'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { - InfraMetadataFeature, - InfraMetadataRequestRT, - InfraMetadataRT, -} from '../../../common/http_api/metadata_api'; -import { InfraBackendLibs } from '../../lib/infra_types'; -import { getMetricMetadata } from './lib/get_metric_metadata'; -import { pickFeatureName } from './lib/pick_feature_name'; -import { hasAPMData } from './lib/has_apm_data'; -import { getCloudMetricsMetadata } from './lib/get_cloud_metric_metadata'; -import { getNodeInfo } from './lib/get_node_info'; -import { throwErrors } from '../../../common/runtime_types'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initMetadataRoute = (libs: InfraBackendLibs) => { - const { framework } = libs; - - framework.registerRoute( - { - method: 'post', - path: '/api/infra/metadata', - validate: { - body: escapeHatch, - }, - }, - async (requestContext, request, response) => { - try { - const { nodeId, nodeType, sourceId } = pipe( - InfraMetadataRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext, - sourceId - ); - const metricsMetadata = await getMetricMetadata( - framework, - requestContext, - configuration, - nodeId, - nodeType - ); - const metricFeatures = pickFeatureName(metricsMetadata.buckets).map( - nameToFeature('metrics') - ); - - const info = await getNodeInfo(framework, requestContext, configuration, nodeId, nodeType); - const cloudInstanceId = get(info, 'cloud.instance.id'); - - const cloudMetricsMetadata = cloudInstanceId - ? await getCloudMetricsMetadata(framework, requestContext, configuration, cloudInstanceId) - : { buckets: [] }; - const cloudMetricsFeatures = pickFeatureName(cloudMetricsMetadata.buckets).map( - nameToFeature('metrics') - ); - const hasAPM = await hasAPMData(framework, requestContext, configuration, nodeId, nodeType); - const apmMetricFeatures = hasAPM ? [{ name: 'apm.transaction', source: 'apm' }] : []; - - const id = metricsMetadata.id; - const name = metricsMetadata.name || id; - return response.ok({ - body: InfraMetadataRT.encode({ - id, - name, - features: [...metricFeatures, ...cloudMetricsFeatures, ...apmMetricFeatures], - info, - }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; - -const nameToFeature = (source: string) => (name: string): InfraMetadataFeature => ({ - name, - source, -}); diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_cloud_metric_metadata.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_cloud_metric_metadata.ts deleted file mode 100644 index 75ca3ae3caee21..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_cloud_metric_metadata.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { - InfraMetadataAggregationBucket, - InfraMetadataAggregationResponse, -} from '../../../lib/adapters/framework'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { CLOUD_METRICS_MODULES } from '../../../lib/constants'; - -export interface InfraCloudMetricsAdapterResponse { - buckets: InfraMetadataAggregationBucket[]; -} - -export const getCloudMetricsMetadata = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - instanceId: string -): Promise => { - const metricQuery = { - allowNoIndices: true, - ignoreUnavailable: true, - index: sourceConfiguration.metricAlias, - body: { - query: { - bool: { - filter: [{ match: { 'cloud.instance.id': instanceId } }], - should: CLOUD_METRICS_MODULES.map(module => ({ match: { 'event.module': module } })), - }, - }, - size: 0, - aggs: { - metrics: { - terms: { - field: 'event.dataset', - size: 1000, - }, - }, - }, - }, - }; - - const response = await framework.callWithRequest< - {}, - { - metrics?: InfraMetadataAggregationResponse; - } - >(requestContext, 'search', metricQuery); - - const buckets = - response.aggregations && response.aggregations.metrics - ? response.aggregations.metrics.buckets - : []; - - return { buckets }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_metric_metadata.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_metric_metadata.ts deleted file mode 100644 index 191339565b813f..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_metric_metadata.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { get } from 'lodash'; -import { RequestHandlerContext } from 'src/core/server'; -import { - InfraMetadataAggregationBucket, - InfraMetadataAggregationResponse, -} from '../../../lib/adapters/framework'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { findInventoryFields } from '../../../../common/inventory_models'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; - -export interface InfraMetricsAdapterResponse { - id: string; - name?: string; - buckets: InfraMetadataAggregationBucket[]; -} - -export const getMetricMetadata = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - nodeId: string, - nodeType: InventoryItemType -): Promise => { - const fields = findInventoryFields(nodeType, sourceConfiguration.fields); - const metricQuery = { - allowNoIndices: true, - ignoreUnavailable: true, - index: sourceConfiguration.metricAlias, - body: { - query: { - bool: { - must_not: [{ match: { 'event.dataset': 'aws.ec2' } }], - filter: [ - { - match: { [fields.id]: nodeId }, - }, - ], - }, - }, - size: 0, - aggs: { - nodeName: { - terms: { - field: fields.name, - size: 1, - }, - }, - metrics: { - terms: { - field: 'event.dataset', - size: 1000, - }, - }, - }, - }, - }; - - const response = await framework.callWithRequest< - {}, - { - metrics?: InfraMetadataAggregationResponse; - nodeName?: InfraMetadataAggregationResponse; - } - >(requestContext, 'search', metricQuery); - - const buckets = - response.aggregations && response.aggregations.metrics - ? response.aggregations.metrics.buckets - : []; - - return { - id: nodeId, - name: get(response, ['aggregations', 'nodeName', 'buckets', 0, 'key'], nodeId), - buckets, - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_node_info.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_node_info.ts deleted file mode 100644 index 4ff0df30abedd8..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_node_info.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { first, set, startsWith } from 'lodash'; -import { RequestHandlerContext } from 'src/core/server'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { InfraNodeType } from '../../../graphql/types'; -import { InfraMetadataInfo } from '../../../../common/http_api/metadata_api'; -import { getPodNodeName } from './get_pod_node_name'; -import { CLOUD_METRICS_MODULES } from '../../../lib/constants'; -import { findInventoryFields } from '../../../../common/inventory_models'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; - -export const getNodeInfo = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - nodeId: string, - nodeType: InventoryItemType -): Promise => { - // If the nodeType is a Kubernetes pod then we need to get the node info - // from a host record instead of a pod. This is due to the fact that any host - // can report pod details and we can't rely on the host/cloud information associated - // with the kubernetes.pod.uid. We need to first lookup the `kubernetes.node.name` - // then use that to lookup the host's node information. - if (nodeType === InfraNodeType.pod) { - const kubernetesNodeName = await getPodNodeName( - framework, - requestContext, - sourceConfiguration, - nodeId, - nodeType - ); - if (kubernetesNodeName) { - return getNodeInfo( - framework, - requestContext, - sourceConfiguration, - kubernetesNodeName, - InfraNodeType.host - ); - } - return {}; - } - const fields = findInventoryFields(nodeType, sourceConfiguration.fields); - const params = { - allowNoIndices: true, - ignoreUnavailable: true, - terminateAfter: 1, - index: sourceConfiguration.metricAlias, - body: { - size: 1, - _source: ['host.*', 'cloud.*'], - query: { - bool: { - filter: [{ match: { [fields.id]: nodeId } }], - }, - }, - }, - }; - if (!CLOUD_METRICS_MODULES.some(m => startsWith(nodeType, m))) { - set( - params, - 'body.query.bool.must_not', - CLOUD_METRICS_MODULES.map(module => ({ match: { 'event.module': module } })) - ); - } - const response = await framework.callWithRequest<{ _source: InfraMetadataInfo }, {}>( - requestContext, - 'search', - params - ); - const firstHit = first(response.hits.hits); - if (firstHit) { - return firstHit._source; - } - return {}; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_pod_node_name.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_pod_node_name.ts deleted file mode 100644 index be6e29a794d096..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/get_pod_node_name.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { first, get } from 'lodash'; -import { RequestHandlerContext } from 'src/core/server'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { findInventoryFields } from '../../../../common/inventory_models'; - -export const getPodNodeName = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - nodeId: string, - nodeType: 'host' | 'pod' | 'container' -): Promise => { - const fields = findInventoryFields(nodeType, sourceConfiguration.fields); - const params = { - allowNoIndices: true, - ignoreUnavailable: true, - terminateAfter: 1, - index: sourceConfiguration.metricAlias, - body: { - size: 1, - _source: ['kubernetes.node.name'], - query: { - bool: { - filter: [ - { match: { [fields.id]: nodeId } }, - { exists: { field: `kubernetes.node.name` } }, - ], - }, - }, - }, - }; - const response = await framework.callWithRequest< - { _source: { kubernetes: { node: { name: string } } } }, - {} - >(requestContext, 'search', params); - const firstHit = first(response.hits.hits); - if (firstHit) { - return get(firstHit, '_source.kubernetes.node.name'); - } -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts deleted file mode 100644 index 9ca0819d74d466..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; - -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraSourceConfiguration } from '../../../lib/sources'; -import { findInventoryFields } from '../../../../common/inventory_models'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; - -export const hasAPMData = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - sourceConfiguration: InfraSourceConfiguration, - nodeId: string, - nodeType: InventoryItemType -) => { - const apmIndices = await framework.plugins.apm.getApmIndices( - requestContext.core.savedObjects.client - ); - const apmIndex = apmIndices['apm_oss.transactionIndices'] || 'apm-*'; - const fields = findInventoryFields(nodeType, sourceConfiguration.fields); - - // There is a bug in APM ECS data where host.name is not set. - // This will fixed with: https://github.com/elastic/apm-server/issues/2502 - const nodeFieldName = nodeType === 'host' ? 'host.hostname' : fields.id; - const params = { - allowNoIndices: true, - ignoreUnavailable: true, - terminateAfter: 1, - index: apmIndex, - body: { - size: 0, - query: { - bool: { - filter: [ - { - match: { [nodeFieldName]: nodeId }, - }, - { - exists: { field: 'service.name' }, - }, - { - exists: { field: 'transaction.type' }, - }, - ], - }, - }, - }, - }; - const response = await framework.callWithRequest<{}, {}>(requestContext, 'search', params); - return response.hits.total.value !== 0; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/pick_feature_name.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/pick_feature_name.ts deleted file mode 100644 index 8b6bb49d9f645b..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/pick_feature_name.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraMetadataAggregationBucket } from '../../../lib/adapters/framework'; - -export const pickFeatureName = (buckets: InfraMetadataAggregationBucket[]): string[] => { - if (buckets) { - const metadata = buckets.map(bucket => bucket.key); - return metadata; - } else { - return []; - } -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/index.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/index.ts deleted file mode 100644 index 64cdb9318b6e18..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; -import { InfraBackendLibs } from '../../lib/infra_types'; -import { getGroupings } from './lib/get_groupings'; -import { populateSeriesWithTSVBData } from './lib/populate_series_with_tsvb_data'; -import { metricsExplorerRequestBodyRT, metricsExplorerResponseRT } from '../../../common/http_api'; -import { throwErrors } from '../../../common/runtime_types'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initMetricExplorerRoute = (libs: InfraBackendLibs) => { - const { framework } = libs; - const { callWithRequest } = framework; - - framework.registerRoute( - { - method: 'post', - path: '/api/infra/metrics_explorer', - validate: { - body: escapeHatch, - }, - }, - async (requestContext, request, response) => { - try { - const payload = pipe( - metricsExplorerRequestBodyRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - - const search = (searchOptions: object) => - callWithRequest<{}, Aggregation>(requestContext, 'search', searchOptions); - - // First we get the groupings from a composite aggregation - const groupings = await getGroupings(search, payload); - - // Then we take the results and fill in the data from TSVB with the - // user's custom metrics - const seriesWithMetrics = await Promise.all( - groupings.series.map( - populateSeriesWithTSVBData(request, payload, framework, requestContext) - ) - ); - return response.ok({ - body: metricsExplorerResponseRT.encode({ ...groupings, series: seriesWithMetrics }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/create_metrics_model.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/create_metrics_model.ts deleted file mode 100644 index 9e5fe16d482b2d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/create_metrics_model.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraMetricModelMetricType } from '../../../lib/adapters/metrics'; -import { MetricsExplorerRequestBody } from '../types'; -import { InfraMetric } from '../../../graphql/types'; -import { TSVBMetricModel } from '../../../../common/inventory_models/types'; -export const createMetricModel = (options: MetricsExplorerRequestBody): TSVBMetricModel => { - return { - id: InfraMetric.custom, - requires: [], - index_pattern: options.indexPattern, - interval: options.timerange.interval, - time_field: options.timerange.field, - type: 'timeseries', - // Create one series per metric requested. The series.id will be used to identify the metric - // when the responses are processed and combined with the grouping request. - series: options.metrics.map((metric, index) => { - // If the metric is a rate then we need to add TSVB metrics for calculating the derivative - if (metric.aggregation === 'rate') { - const aggType = 'max'; - return { - id: `metric_${index}`, - split_mode: 'everything', - metrics: [ - { - id: `metric_${aggType}_${index}`, - field: metric.field, - type: aggType, - }, - { - id: `metric_deriv_${aggType}_${index}`, - field: `metric_${aggType}_${index}`, - type: 'derivative', - unit: '1s', - }, - { - id: `metric_posonly_deriv_${aggType}_${index}`, - type: 'calculation', - variables: [ - { id: 'var-rate', name: 'rate', field: `metric_deriv_${aggType}_${index}` }, - ], - script: 'params.rate > 0.0 ? params.rate : 0.0', - }, - ], - }; - } - // Create a basic TSVB series with a single metric - const aggregation = metric.aggregation || 'avg'; - - return { - id: `metric_${index}`, - split_mode: 'everything', - metrics: [ - { - field: metric.field, - id: `metric_${aggregation}_${index}`, - type: InfraMetricModelMetricType[aggregation], - }, - ], - }; - }), - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts deleted file mode 100644 index 7111d3e7f8ca4d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { isObject, set } from 'lodash'; -import { InfraDatabaseSearchResponse } from '../../../lib/adapters/framework'; -import { MetricsExplorerRequestBody, MetricsExplorerResponse } from '../types'; - -interface GroupingAggregation { - groupingsCount: { - value: number; - }; - groupings: { - after_key?: { - [name: string]: string; - }; - buckets: Array<{ key: { [id: string]: string }; doc_count: number }>; - }; -} - -const EMPTY_RESPONSE = { - series: [{ id: 'ALL', columns: [], rows: [] }], - pageInfo: { total: 0, afterKey: null }, -}; - -export const getGroupings = async ( - search: (options: object) => Promise>, - options: MetricsExplorerRequestBody -): Promise => { - if (!options.groupBy) { - return EMPTY_RESPONSE; - } - const limit = options.limit || 9; - const params = { - allowNoIndices: true, - ignoreUnavailable: true, - index: options.indexPattern, - body: { - size: 0, - query: { - bool: { - should: [ - ...options.metrics - .filter(m => m.field) - .map(m => ({ - exists: { field: m.field }, - })), - ], - filter: [ - { - range: { - [options.timerange.field]: { - gte: options.timerange.from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ] as object[], - }, - }, - aggs: { - groupingsCount: { - cardinality: { field: options.groupBy }, - }, - groupings: { - composite: { - size: limit, - sources: [{ groupBy: { terms: { field: options.groupBy, order: 'asc' } } }], - }, - }, - }, - }, - }; - - if (params.body.query.bool.should.length !== 0) { - set(params, 'body.query.bool.minimum_should_match', 1); - } - - if (options.afterKey) { - set(params, 'body.aggs.groupings.composite.after', { groupBy: options.afterKey }); - } - - if (options.filterQuery) { - try { - const filterObject = JSON.parse(options.filterQuery); - if (isObject(filterObject)) { - params.body.query.bool.filter.push(filterObject); - } - } catch (err) { - params.body.query.bool.filter.push({ - query_string: { - query: options.filterQuery, - analyze_wildcard: true, - }, - }); - } - } - - const response = await search(params); - if (response.hits.total.value === 0) { - return { ...EMPTY_RESPONSE, series: [] }; - } - if (!response.aggregations) { - throw new Error('Aggregations should be present.'); - } - const { groupings, groupingsCount } = response.aggregations; - const { after_key: afterKey } = groupings; - return { - series: groupings.buckets.map(bucket => { - return { id: bucket.key.groupBy, rows: [], columns: [] }; - }), - pageInfo: { - total: groupingsCount.value, - afterKey: afterKey && groupings.buckets.length === limit ? afterKey.groupBy : null, - }, - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts deleted file mode 100644 index 3dfbfbb5c39797..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { union } from 'lodash'; -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; -import { - MetricsExplorerRow, - MetricsExplorerSeries, - MetricsExplorerRequestBody, - MetricsExplorerColumn, -} from '../types'; -import { createMetricModel } from './create_metrics_model'; -import { JsonObject } from '../../../../common/typed_json'; -import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; - -export const populateSeriesWithTSVBData = ( - request: KibanaRequest, - options: MetricsExplorerRequestBody, - framework: KibanaFramework, - requestContext: RequestHandlerContext -) => async (series: MetricsExplorerSeries) => { - // IF there are no metrics selected then we should return an empty result. - if (options.metrics.length === 0) { - return { - ...series, - columns: [], - rows: [], - }; - } - - // Set the filter for the group by or match everything - const filters: JsonObject[] = options.groupBy - ? [{ match: { [options.groupBy]: series.id } }] - : []; - if (options.filterQuery) { - try { - const filterQuery = JSON.parse(options.filterQuery); - filters.push(filterQuery); - } catch (error) { - filters.push({ - query_string: { - query: options.filterQuery, - analyze_wildcard: true, - }, - }); - } - } - const timerange = { min: options.timerange.from, max: options.timerange.to }; - - // Create the TSVB model based on the request options - const model = createMetricModel(options); - const calculatedInterval = await calculateMetricInterval( - framework, - requestContext, - { - indexPattern: options.indexPattern, - timestampField: options.timerange.field, - timerange: options.timerange, - }, - options.metrics - .filter(metric => metric.field) - .map(metric => { - return metric - .field!.split(/\./) - .slice(0, 2) - .join('.'); - }) - ); - - if (calculatedInterval) { - model.interval = `>=${calculatedInterval}s`; - } - - // Get TSVB results using the model, timerange and filters - const tsvbResults = await framework.makeTSVBRequest( - request, - model, - timerange, - filters, - requestContext - ); - - // If there is no data `custom` will not exist. - if (!tsvbResults.custom) { - return { - ...series, - columns: [], - rows: [], - }; - } - - // Setup the dynamic columns and row attributes depending on if the user is doing a group by - // and multiple metrics - const attributeColumns: MetricsExplorerColumn[] = - options.groupBy != null ? [{ name: 'groupBy', type: 'string' }] : []; - const metricColumns: MetricsExplorerColumn[] = options.metrics.map((m, i) => ({ - name: `metric_${i}`, - type: 'number', - })); - const rowAttributes = options.groupBy != null ? { groupBy: series.id } : {}; - - // To support multiple metrics, there are multiple TSVB series which need to be combined - // into one MetricExplorerRow (Canvas row). This is done by collecting all the timestamps - // across each TSVB series. Then for each timestamp we find the values and create a - // MetricsExplorerRow. - const timestamps = tsvbResults.custom.series.reduce( - (currentTimestamps, tsvbSeries) => - union( - currentTimestamps, - tsvbSeries.data.map(row => row[0]) - ).sort(), - [] as number[] - ); - // Combine the TSVB series for multiple metrics. - const rows = timestamps.map(timestamp => { - return tsvbResults.custom.series.reduce( - (currentRow, tsvbSeries) => { - const matches = tsvbSeries.data.find(d => d[0] === timestamp); - if (matches) { - return { ...currentRow, [tsvbSeries.id]: matches[1] }; - } - return currentRow; - }, - { timestamp, ...rowAttributes } as MetricsExplorerRow - ); - }); - return { - ...series, - rows, - columns: [ - { name: 'timestamp', type: 'date' } as MetricsExplorerColumn, - ...metricColumns, - ...attributeColumns, - ], - }; -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/types.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/types.ts deleted file mode 100644 index f4c5e26c5c6d13..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/types.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import * as rt from 'io-ts'; -import { - metricsExplorerMetricRT, - metricsExplorerPageInfoRT, - metricsExplorerColumnRT, - metricsExplorerRowRT, - metricsExplorerSeriesRT, - metricsExplorerRequestBodyRT, - metricsExplorerResponseRT, - metricsExplorerAggregationRT, - metricsExplorerColumnTypeRT, -} from '../../../common/http_api'; - -export type MetricsExplorerAggregation = rt.TypeOf; - -export type MetricsExplorerColumnType = rt.TypeOf; - -export type MetricsExplorerMetric = rt.TypeOf; - -export type MetricsExplorerPageInfo = rt.TypeOf; - -export type MetricsExplorerColumn = rt.TypeOf; - -export type MetricsExplorerRow = rt.TypeOf; - -export type MetricsExplorerSeries = rt.TypeOf; - -export type MetricsExplorerRequestBody = rt.TypeOf; - -export type MetricsExplorerResponse = rt.TypeOf; diff --git a/x-pack/legacy/plugins/infra/server/routes/node_details/index.ts b/x-pack/legacy/plugins/infra/server/routes/node_details/index.ts deleted file mode 100644 index a9419cd27e6840..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/node_details/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; -import { schema } from '@kbn/config-schema'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { InfraBackendLibs } from '../../lib/infra_types'; -import { UsageCollector } from '../../usage/usage_collector'; -import { InfraMetricsRequestOptions } from '../../lib/adapters/metrics'; -import { InfraNodeType, InfraMetric } from '../../graphql/types'; -import { - NodeDetailsRequestRT, - NodeDetailsMetricDataResponseRT, -} from '../../../common/http_api/node_details_api'; -import { throwErrors } from '../../../common/runtime_types'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initNodeDetailsRoute = (libs: InfraBackendLibs) => { - const { framework } = libs; - - framework.registerRoute( - { - method: 'post', - path: '/api/metrics/node_details', - validate: { - body: escapeHatch, - }, - }, - async (requestContext, request, response) => { - try { - const { nodeId, cloudId, nodeType, metrics, timerange, sourceId } = pipe( - NodeDetailsRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - const source = await libs.sources.getSourceConfiguration(requestContext, sourceId); - - UsageCollector.countNode(nodeType); - - const options: InfraMetricsRequestOptions = { - nodeIds: { - nodeId, - cloudId, - }, - nodeType: nodeType as InfraNodeType, - sourceConfiguration: source.configuration, - metrics: metrics as InfraMetric[], - timerange, - }; - return response.ok({ - body: NodeDetailsMetricDataResponseRT.encode({ - metrics: await libs.metrics.getMetrics(requestContext, options, request), - }), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/routes/snapshot/index.ts b/x-pack/legacy/plugins/infra/server/routes/snapshot/index.ts deleted file mode 100644 index dffeb04c92a8a1..00000000000000 --- a/x-pack/legacy/plugins/infra/server/routes/snapshot/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; -import { schema } from '@kbn/config-schema'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { InfraBackendLibs } from '../../lib/infra_types'; -import { UsageCollector } from '../../usage/usage_collector'; -import { parseFilterQuery } from '../../utils/serialized_query'; -import { InfraNodeType, InfraSnapshotMetricInput } from '../../../public/graphql/types'; -import { SnapshotRequestRT, SnapshotNodeResponseRT } from '../../../common/http_api/snapshot_api'; -import { throwErrors } from '../../../common/runtime_types'; -import { InfraSnapshotRequestOptions } from '../../lib/snapshot/types'; - -const escapeHatch = schema.object({}, { allowUnknowns: true }); - -export const initSnapshotRoute = (libs: InfraBackendLibs) => { - const { framework } = libs; - - framework.registerRoute( - { - method: 'post', - path: '/api/metrics/snapshot', - validate: { - body: escapeHatch, - }, - }, - async (requestContext, request, response) => { - try { - const { filterQuery, nodeType, groupBy, sourceId, metric, timerange } = pipe( - SnapshotRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - const source = await libs.sources.getSourceConfiguration(requestContext, sourceId); - UsageCollector.countNode(nodeType); - const options: InfraSnapshotRequestOptions = { - filterQuery: parseFilterQuery(filterQuery), - // TODO: Use common infra metric and replace graphql type - nodeType: nodeType as InfraNodeType, - groupBy, - sourceConfiguration: source.configuration, - // TODO: Use common infra metric and replace graphql type - metric: metric as InfraSnapshotMetricInput, - timerange, - }; - const nodesWithInterval = await libs.snapshot.getNodes(requestContext, options); - return response.ok({ - body: SnapshotNodeResponseRT.encode(nodesWithInterval), - }); - } catch (error) { - return response.internalError({ - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/saved_objects.ts b/x-pack/legacy/plugins/infra/server/saved_objects.ts deleted file mode 100644 index 2e554300b0ecb1..00000000000000 --- a/x-pack/legacy/plugins/infra/server/saved_objects.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { infraSourceConfigurationSavedObjectMappings } from './lib/sources'; -import { metricsExplorerViewSavedObjectMappings } from '../common/saved_objects/metrics_explorer_view'; -import { inventoryViewSavedObjectMappings } from '../common/saved_objects/inventory_view'; - -export const savedObjectMappings = { - ...infraSourceConfigurationSavedObjectMappings, - ...metricsExplorerViewSavedObjectMappings, - ...inventoryViewSavedObjectMappings, -}; diff --git a/x-pack/legacy/plugins/infra/server/usage/usage_collector.ts b/x-pack/legacy/plugins/infra/server/usage/usage_collector.ts deleted file mode 100644 index 60b9372b135df0..00000000000000 --- a/x-pack/legacy/plugins/infra/server/usage/usage_collector.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { InfraNodeType } from '../graphql/types'; -import { InventoryItemType } from '../../common/inventory_models/types'; - -const KIBANA_REPORTING_TYPE = 'infraops'; - -interface InfraopsSum { - infraopsHosts: number; - infraopsDocker: number; - infraopsKubernetes: number; - logs: number; -} - -export class UsageCollector { - public static registerUsageCollector(usageCollection: UsageCollectionSetup): void { - const collector = UsageCollector.getUsageCollector(usageCollection); - usageCollection.registerCollector(collector); - } - - public static getUsageCollector(usageCollection: UsageCollectionSetup) { - return usageCollection.makeUsageCollector({ - type: KIBANA_REPORTING_TYPE, - isReady: () => true, - fetch: async () => { - return this.getReport(); - }, - }); - } - - public static countNode(nodeType: InventoryItemType) { - const bucket = this.getBucket(); - this.maybeInitializeBucket(bucket); - - switch (nodeType) { - case InfraNodeType.pod: - this.counters[bucket].infraopsKubernetes += 1; - break; - case InfraNodeType.container: - this.counters[bucket].infraopsDocker += 1; - break; - default: - this.counters[bucket].infraopsHosts += 1; - } - } - - public static countLogs() { - const bucket = this.getBucket(); - this.maybeInitializeBucket(bucket); - this.counters[bucket].logs += 1; - } - - private static counters: any = {}; - private static BUCKET_SIZE = 3600; // seconds in an hour - private static BUCKET_NUMBER = 24; // report the last 24 hours - - private static getBucket() { - const now = Math.floor(Date.now() / 1000); - return now - (now % this.BUCKET_SIZE); - } - - private static maybeInitializeBucket(bucket: any) { - if (!this.counters[bucket]) { - this.counters[bucket] = { - infraopsHosts: 0, - infraopsDocker: 0, - infraopsKubernetes: 0, - logs: 0, - }; - } - } - - private static getReport() { - const keys = Object.keys(this.counters); - - // only keep the newest BUCKET_NUMBER buckets - const cutoff = this.getBucket() - this.BUCKET_SIZE * (this.BUCKET_NUMBER - 1); - keys.forEach(key => { - if (parseInt(key, 10) < cutoff) { - delete this.counters[key]; - } - }); - - // all remaining buckets are current - const sums = Object.keys(this.counters).reduce( - (a: InfraopsSum, b: any) => { - const key = parseInt(b, 10); - return { - infraopsHosts: a.infraopsHosts + this.counters[key].infraopsHosts, - infraopsDocker: a.infraopsDocker + this.counters[key].infraopsDocker, - infraopsKubernetes: a.infraopsKubernetes + this.counters[key].infraopsKubernetes, - logs: a.logs + this.counters[key].logs, - }; - }, - { - infraopsHosts: 0, - infraopsDocker: 0, - infraopsKubernetes: 0, - logs: 0, - } - ); - - return { - last_24_hours: { - hits: { - infraops_hosts: sums.infraopsHosts, - infraops_docker: sums.infraopsDocker, - infraops_kubernetes: sums.infraopsKubernetes, - logs: sums.logs, - }, - }, - }; - } -} diff --git a/x-pack/legacy/plugins/infra/server/utils/README.md b/x-pack/legacy/plugins/infra/server/utils/README.md deleted file mode 100644 index 8a6a27aa29867c..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/README.md +++ /dev/null @@ -1 +0,0 @@ -Utils should be data processing functions and other tools.... all in all utils is basicly everything that is not an adaptor, or presenter and yet too much to put in a lib. \ No newline at end of file diff --git a/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts b/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts deleted file mode 100644 index 586193a3c242db..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { InfraNodeType } from '../graphql/types'; -import { findInventoryModel } from '../../common/inventory_models'; -import { KibanaFramework } from '../lib/adapters/framework/kibana_framework_adapter'; - -interface Options { - indexPattern: string; - timestampField: string; - timerange: { - from: number; - to: number; - }; -} - -/** - * Look at the data from metricbeat and get the max period for a given timerange. - * This is useful for visualizing metric modules like s3 that only send metrics once per day. - */ -export const calculateMetricInterval = async ( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - options: Options, - modules?: string[], - nodeType?: InfraNodeType // TODO: check that this type still makes sense -) => { - let from = options.timerange.from; - if (nodeType) { - const inventoryModel = findInventoryModel(nodeType); - from = options.timerange.to - inventoryModel.metrics.defaultTimeRangeInSeconds * 1000; - } - const query = { - allowNoIndices: true, - index: options.indexPattern, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: [ - { - range: { - [options.timestampField]: { - gte: from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ], - }, - }, - size: 0, - aggs: { - modules: { - terms: { - field: 'event.dataset', - include: modules, - }, - aggs: { - period: { - max: { - field: 'metricset.period', - }, - }, - }, - }, - }, - }, - }; - - const resp = await framework.callWithRequest<{}, PeriodAggregationData>( - requestContext, - 'search', - query - ); - - // if ES doesn't return an aggregations key, something went seriously wrong. - if (!resp.aggregations) { - return; - } - - const intervals = resp.aggregations.modules.buckets.map(a => a.period.value).filter(v => !!v); - if (!intervals.length) { - return; - } - - return Math.max(...intervals) / 1000; -}; - -interface PeriodAggregationData { - modules: { - buckets: Array<{ - key: string; - doc_count: number; - period: { - value: number; - }; - }>; - }; -} diff --git a/x-pack/legacy/plugins/infra/server/utils/create_afterkey_handler.ts b/x-pack/legacy/plugins/infra/server/utils/create_afterkey_handler.ts deleted file mode 100644 index 559fba0799987d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/create_afterkey_handler.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { set } from 'lodash'; -import { InfraDatabaseSearchResponse } from '../lib/adapters/framework'; - -export const createAfterKeyHandler = ( - optionsAfterKeyPath: string | string[], - afterKeySelector: (input: InfraDatabaseSearchResponse) => any -) => (options: Options, response: InfraDatabaseSearchResponse): Options => { - if (!response.aggregations) { - return options; - } - const newOptions = { ...options }; - const afterKey = afterKeySelector(response); - set(newOptions, optionsAfterKeyPath, afterKey); - return newOptions; -}; diff --git a/x-pack/legacy/plugins/infra/server/utils/get_all_composite_data.ts b/x-pack/legacy/plugins/infra/server/utils/get_all_composite_data.ts deleted file mode 100644 index c7ff1b077f6853..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/get_all_composite_data.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { RequestHandlerContext } from 'src/core/server'; -import { KibanaFramework } from '../lib/adapters/framework/kibana_framework_adapter'; -import { InfraDatabaseSearchResponse } from '../lib/adapters/framework'; - -export const getAllCompositeData = async < - Aggregation = undefined, - Bucket = {}, - Options extends object = {} ->( - framework: KibanaFramework, - requestContext: RequestHandlerContext, - options: Options, - bucketSelector: (response: InfraDatabaseSearchResponse<{}, Aggregation>) => Bucket[], - onAfterKey: (options: Options, response: InfraDatabaseSearchResponse<{}, Aggregation>) => Options, - previousBuckets: Bucket[] = [] -): Promise => { - const response = await framework.callWithRequest<{}, Aggregation>( - requestContext, - 'search', - options - ); - - // Nothing available, return the previous buckets. - if (response.hits.total.value === 0) { - return previousBuckets; - } - - // if ES doesn't return an aggregations key, something went seriously wrong. - if (!response.aggregations) { - throw new Error('Whoops!, `aggregations` key must always be returned.'); - } - - const currentBuckets = bucketSelector(response); - - // if there are no currentBuckets then we are finished paginating through the results - if (currentBuckets.length === 0) { - return previousBuckets; - } - - // There is possibly more data, concat previous and current buckets and call ourselves recursively. - const newOptions = onAfterKey(options, response); - return getAllCompositeData( - framework, - requestContext, - newOptions, - bucketSelector, - onAfterKey, - previousBuckets.concat(currentBuckets) - ); -}; diff --git a/x-pack/legacy/plugins/infra/server/utils/get_interval_in_seconds.ts b/x-pack/legacy/plugins/infra/server/utils/get_interval_in_seconds.ts deleted file mode 100644 index 297e5828956af1..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/get_interval_in_seconds.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -const intervalUnits = ['y', 'M', 'w', 'd', 'h', 'm', 's', 'ms']; -const INTERVAL_STRING_RE = new RegExp('^([0-9\\.]*)\\s*(' + intervalUnits.join('|') + ')$'); - -interface UnitsToSeconds { - [unit: string]: number; -} - -const units: UnitsToSeconds = { - ms: 0.001, - s: 1, - m: 60, - h: 3600, - d: 86400, - w: 86400 * 7, - M: 86400 * 30, - y: 86400 * 356, -}; - -export const getIntervalInSeconds = (interval: string): number => { - const matches = interval.match(INTERVAL_STRING_RE); - if (matches) { - return parseFloat(matches[1]) * units[matches[2]]; - } - throw new Error('Invalid interval string format.'); -}; diff --git a/x-pack/legacy/plugins/infra/server/utils/serialized_query.ts b/x-pack/legacy/plugins/infra/server/utils/serialized_query.ts deleted file mode 100644 index 932df847e65d08..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/serialized_query.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UserInputError } from 'apollo-server-errors'; - -import { JsonObject } from '../../common/typed_json'; - -export const parseFilterQuery = ( - filterQuery: string | null | undefined -): JsonObject | undefined => { - try { - if (filterQuery) { - const parsedFilterQuery = JSON.parse(filterQuery); - if ( - !parsedFilterQuery || - ['string', 'number', 'boolean'].includes(typeof parsedFilterQuery) || - Array.isArray(parsedFilterQuery) - ) { - throw new Error('expected value to be an object'); - } - return parsedFilterQuery; - } else { - return undefined; - } - } catch (err) { - throw new UserInputError(`Failed to parse query: ${err}`, { - query: filterQuery, - originalError: err, - }); - } -}; diff --git a/x-pack/legacy/plugins/infra/server/utils/typed_elasticsearch_mappings.ts b/x-pack/legacy/plugins/infra/server/utils/typed_elasticsearch_mappings.ts deleted file mode 100644 index f18b9f3de55c9d..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/typed_elasticsearch_mappings.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export type ElasticsearchMappingOf = Type extends string - ? ElasticsearchStringFieldMapping - : Type extends number - ? ElasticsearchNumberFieldMapping - : Type extends boolean - ? ElasticsearchBooleanFieldMapping - : Type extends object[] - ? ElasticsearchNestedFieldMapping - : Type extends {} - ? ElasticsearchObjectFieldMapping - : never; - -export interface ElasticsearchStringFieldMapping { - type: 'keyword' | 'text'; -} - -export interface ElasticsearchBooleanFieldMapping { - type: 'boolean'; -} - -export interface ElasticsearchNumberFieldMapping { - type: - | 'long' - | 'integer' - | 'short' - | 'byte' - | 'double' - | 'float' - | 'half_float' - | 'scaled_float' - | 'date'; -} - -export interface ElasticsearchNestedFieldMapping { - type?: 'nested'; - properties: { [K in keyof Obj[0]]-?: ElasticsearchMappingOf }; -} - -export interface ElasticsearchObjectFieldMapping { - type?: 'object'; - properties: { [K in keyof Obj]-?: ElasticsearchMappingOf }; -} diff --git a/x-pack/legacy/plugins/infra/server/utils/typed_resolvers.ts b/x-pack/legacy/plugins/infra/server/utils/typed_resolvers.ts deleted file mode 100644 index d5f2d00abd5042..00000000000000 --- a/x-pack/legacy/plugins/infra/server/utils/typed_resolvers.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Resolver } from '../graphql/types'; - -type ResolverResult = R | Promise; - -type InfraResolverResult = - | Promise - | Promise<{ [P in keyof R]: () => Promise }> - | { [P in keyof R]: () => Promise } - | { [P in keyof R]: () => R[P] } - | R; - -export type ResultOf = Resolver_ extends Resolver> - ? Result - : never; - -export type SubsetResolverWithFields = R extends Resolver< - Array, - infer ParentInArray, - infer ContextInArray, - infer ArgsInArray -> - ? Resolver< - Array>>, - ParentInArray, - ContextInArray, - ArgsInArray - > - : R extends Resolver - ? Resolver>, Parent, Context, Args> - : never; - -export type SubsetResolverWithoutFields = R extends Resolver< - Array, - infer ParentInArray, - infer ContextInArray, - infer ArgsInArray -> - ? Resolver< - Array>>, - ParentInArray, - ContextInArray, - ArgsInArray - > - : R extends Resolver - ? Resolver>, Parent, Context, Args> - : never; - -export type ResolverWithParent = Resolver_ extends Resolver< - infer Result, - any, - infer Context, - infer Args -> - ? Resolver - : never; - -export type InfraResolver = Resolver< - InfraResolverResult, - Parent, - Context, - Args ->; - -export type InfraResolverOf = Resolver_ extends Resolver< - ResolverResult, - never, - infer ContextWithNeverParent, - infer ArgsWithNeverParent -> - ? InfraResolver - : Resolver_ extends Resolver< - ResolverResult, - infer Parent, - infer Context, - infer Args - > - ? InfraResolver - : never; - -export type InfraResolverWithFields = InfraResolverOf< - SubsetResolverWithFields ->; - -export type InfraResolverWithoutFields = InfraResolverOf< - SubsetResolverWithoutFields ->; - -export type ChildResolverOf = ResolverWithParent< - Resolver_, - ResultOf ->; diff --git a/x-pack/legacy/plugins/monitoring/index.js b/x-pack/legacy/plugins/monitoring/index.js index f78f8d45d6440b..17e836f49e353e 100644 --- a/x-pack/legacy/plugins/monitoring/index.js +++ b/x-pack/legacy/plugins/monitoring/index.js @@ -83,6 +83,6 @@ export const monitoring = kibana => uiExports: getUiExports(), postInit(server) { const serverConfig = server.config(); - initInfraSource(serverConfig, server.plugins.infra); + initInfraSource(serverConfig, server.newPlatform.setup.plugins.infra); }, }); diff --git a/x-pack/plugins/infra/common/time/time_key.ts b/x-pack/plugins/infra/common/time/time_key.ts index 117cd38314de07..e4f41615eb4845 100644 --- a/x-pack/plugins/infra/common/time/time_key.ts +++ b/x-pack/plugins/infra/common/time/time_key.ts @@ -5,7 +5,7 @@ */ import { ascending, bisector } from 'd3-array'; -import pick from 'lodash/fp/pick'; +import { pick } from 'lodash'; export interface TimeKey { time: number; @@ -27,7 +27,7 @@ export const isTimeKey = (value: any): value is TimeKey => typeof value.tiebreaker === 'number'; export const pickTimeKey = (value: T): TimeKey => - pick(['time', 'tiebreaker'], value); + pick(value, ['time', 'tiebreaker']); export function compareTimeKeys( firstKey: TimeKey, diff --git a/x-pack/plugins/infra/kibana.json b/x-pack/plugins/infra/kibana.json index ec5420a4d28d58..bf7146c9605c50 100644 --- a/x-pack/plugins/infra/kibana.json +++ b/x-pack/plugins/infra/kibana.json @@ -2,5 +2,7 @@ "id": "infra", "version": "8.0.0", "kibanaVersion": "kibana", - "server": true + "requiredPlugins": ["features", "apm", "usageCollection", "spaces"], + "server": true, + "ui": false } diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index 28d5f75c3fdaf8..6281c54ddd77a7 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -8,10 +8,10 @@ import { SearchResponse, GenericParams } from 'elasticsearch'; import { Lifecycle } from 'hapi'; import { ObjectType } from '@kbn/config-schema'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { RouteMethod, RouteConfig } from '../../../../../../../../src/core/server'; -import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../../plugins/features/server'; -import { SpacesPluginSetup } from '../../../../../../../plugins/spaces/server'; -import { APMPluginContract } from '../../../../../../../plugins/apm/server'; +import { RouteMethod, RouteConfig } from '../../../../../../../src/core/server'; +import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../plugins/features/server'; +import { SpacesPluginSetup } from '../../../../../../plugins/spaces/server'; +import { APMPluginContract } from '../../../../../../plugins/apm/server'; // NP_TODO: Compose real types from plugins we depend on, no "any" export interface InfraServerPluginDeps { diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index 46d32885600dfd..fc92dacde4f7bf 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InfraSourceConfiguration } from '../../public/graphql/types'; +import { InfraSourceConfiguration } from '../../common/graphql/types'; import { InfraFieldsDomain } from './domains/fields_domain'; import { InfraLogEntriesDomain } from './domains/log_entries_domain'; import { InfraMetricsDomain } from './domains/metrics_domain'; @@ -12,7 +12,7 @@ import { InfraLogAnalysis } from './log_analysis/log_analysis'; import { InfraSnapshot } from './snapshot'; import { InfraSources } from './sources'; import { InfraSourceStatus } from './source_status'; -import { InfraConfig } from '../../../../../plugins/infra/server'; +import { InfraConfig } from '../plugin'; import { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; // NP_TODO: We shouldn't need this context anymore but I am diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_analysis.ts index fac49a7980f264..f46713bb300a87 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_analysis.ts @@ -17,7 +17,7 @@ import { LogRateModelPlotBucket, CompositeTimestampPartitionKey, } from './queries'; -import { RequestHandlerContext, KibanaRequest } from '../../../../../../../src/core/server'; +import { RequestHandlerContext, KibanaRequest } from '../../../../../../src/core/server'; const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000;