diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx
new file mode 100644
index 0000000000000..962e099f5b667
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx
@@ -0,0 +1,130 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { act } from 'react-dom/test-utils';
+import { setup, SetupResult, getProcessorValue } from './processor.helpers';
+
+// Default parameter values automatically added to the registered domain processor when saved
+const defaultRegisteredDomainParameters = {
+ description: undefined,
+ if: undefined,
+ ignore_missing: undefined,
+ ignore_failure: undefined,
+};
+
+const REGISTERED_DOMAIN_TYPE = 'registered_domain';
+
+describe('Processor: Registered Domain', () => {
+ let onUpdate: jest.Mock;
+ let testBed: SetupResult;
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
+ beforeEach(async () => {
+ onUpdate = jest.fn();
+
+ await act(async () => {
+ testBed = await setup({
+ value: {
+ processors: [],
+ },
+ onFlyoutOpen: jest.fn(),
+ onUpdate,
+ });
+ });
+
+ testBed.component.update();
+
+ // Open flyout to add new processor
+ testBed.actions.addProcessor();
+ // Add type (the other fields are not visible until a type is selected)
+ await testBed.actions.addProcessorType(REGISTERED_DOMAIN_TYPE);
+ });
+
+ test('prevents form submission if required fields are not provided', async () => {
+ const {
+ actions: { saveNewProcessor },
+ form,
+ } = testBed;
+
+ // Click submit button with only the type defined
+ await saveNewProcessor();
+
+ // Expect form error as "field" is required parameter
+ expect(form.getErrorsMessages()).toEqual(['A field value is required.']);
+ });
+
+ test('saves with default parameter values', async () => {
+ const {
+ actions: { saveNewProcessor },
+ form,
+ } = testBed;
+
+ // Add "field" value (required)
+ form.setInputValue('fieldNameField.input', 'field_1');
+ // Save the field
+ await saveNewProcessor();
+
+ const processors = getProcessorValue(onUpdate, REGISTERED_DOMAIN_TYPE);
+ expect(processors[0][REGISTERED_DOMAIN_TYPE]).toEqual({
+ field: 'field_1',
+ ...defaultRegisteredDomainParameters,
+ });
+ });
+
+ test('should still send ignore_missing:false when the toggle is disabled', async () => {
+ const {
+ actions: { saveNewProcessor },
+ form,
+ } = testBed;
+
+ // Add "field" value (required)
+ form.setInputValue('fieldNameField.input', 'field_1');
+
+ // Disable ignore missing toggle
+ form.toggleEuiSwitch('ignoreMissingSwitch.input');
+
+ // Save the field with new changes
+ await saveNewProcessor();
+
+ const processors = getProcessorValue(onUpdate, REGISTERED_DOMAIN_TYPE);
+ expect(processors[0][REGISTERED_DOMAIN_TYPE]).toEqual({
+ ...defaultRegisteredDomainParameters,
+ field: 'field_1',
+ ignore_missing: false,
+ });
+ });
+
+ test('allows optional parameters to be set', async () => {
+ const {
+ actions: { saveNewProcessor },
+ form,
+ } = testBed;
+
+ // Add "field" value (required)
+ form.setInputValue('fieldNameField.input', 'field_1');
+
+ // Set optional parameteres
+ form.setInputValue('targetField.input', 'target_field');
+
+ // Save the field with new changes
+ await saveNewProcessor();
+
+ const processors = getProcessorValue(onUpdate, REGISTERED_DOMAIN_TYPE);
+ expect(processors[0][REGISTERED_DOMAIN_TYPE]).toEqual({
+ field: 'field_1',
+ target_field: 'target_field',
+ ...defaultRegisteredDomainParameters,
+ });
+ });
+});
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/index.ts
index 9dec9d3f0384f..4fb4365c477b5 100644
--- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/index.ts
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/index.ts
@@ -28,6 +28,7 @@ export { Json } from './json';
export { Kv } from './kv';
export { Lowercase } from './lowercase';
export { Pipeline } from './pipeline';
+export { RegisteredDomain } from './registered_domain';
export { Remove } from './remove';
export { Rename } from './rename';
export { Script } from './script';
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/registered_domain.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/registered_domain.tsx
new file mode 100644
index 0000000000000..4118a125914b2
--- /dev/null
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/registered_domain.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { FunctionComponent } from 'react';
+import { i18n } from '@kbn/i18n';
+
+import { from } from './shared';
+import { FieldNameField } from './common_fields/field_name_field';
+import { TargetField } from './common_fields/target_field';
+import { IgnoreMissingField } from './common_fields/ignore_missing_field';
+import { SerializerFunc } from '../../../../../../shared_imports';
+
+export const RegisteredDomain: FunctionComponent = () => {
+ return (
+ <>
+
+
+
+
+ }
+ />
+ >
+ );
+};
diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/shared/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/shared/map_processor_type_to_form.tsx
index 5ab2d68aa193f..b5e42ea56bdf8 100644
--- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/shared/map_processor_type_to_form.tsx
+++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/shared/map_processor_type_to_form.tsx
@@ -34,6 +34,7 @@ import {
Kv,
Lowercase,
Pipeline,
+ RegisteredDomain,
Remove,
Rename,
Script,
@@ -518,6 +519,28 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = {
},
}),
},
+ registered_domain: {
+ FieldsComponent: RegisteredDomain,
+ docLinkPath: '/registered-domain-processor.html',
+ label: i18n.translate('xpack.ingestPipelines.processors.label.registeredDomain', {
+ defaultMessage: 'Registered domain',
+ }),
+ typeDescription: i18n.translate(
+ 'xpack.ingestPipelines.processors.description.registeredDomain',
+ {
+ defaultMessage:
+ 'Extracts the registered domain (effective top-level domain), sub-domain, and top-level domain from a fully qualified domain name.',
+ }
+ ),
+ getDefaultDescription: ({ field }) =>
+ i18n.translate('xpack.ingestPipelines.processors.defaultDescription.registeredDomain', {
+ defaultMessage:
+ 'Extracts the registered domain, sub-domain, and top-level domain from "{field}"',
+ values: {
+ field,
+ },
+ }),
+ },
remove: {
FieldsComponent: Remove,
docLinkPath: '/remove-processor.html',
diff --git a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts
index 4afd434b89372..8ed57221a1395 100644
--- a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts
+++ b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts
@@ -52,6 +52,7 @@ export {
ValidationConfig,
useFormData,
FormOptions,
+ SerializerFunc,
} from '../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib';
export {