diff --git a/CHANGELOG.next.md b/CHANGELOG.next.md index 944f9c6346..4c63b041eb 100644 --- a/CHANGELOG.next.md +++ b/CHANGELOG.next.md @@ -29,6 +29,7 @@ Thanks, you're awesome :-) --> #### Added * Added ability to supply free-form usage documentation per fieldset. #988 +* Added the `path` key when type is `alias`, to support the [alias field type](https://www.elastic.co/guide/en/elasticsearch/reference/current/alias.html). #877 #### Improvements diff --git a/schemas/README.md b/schemas/README.md index c87be195a3..88440c0354 100644 --- a/schemas/README.md +++ b/schemas/README.md @@ -151,6 +151,18 @@ Supported keys to describe expected values for a field Optionally, entries in this list can specify 'expected\_event\_types'. - expected\_event\_types: list of expected "event.type" values to use in association with that category. + +Supported keys when using the [alias field type](https://www.elastic.co/guide/en/elasticsearch/reference/current/alias.html) + +```YAML + - name: a_field + level: extended + type: alias + path: another_field + description: > + An alias of another field. +``` +- path (optional): The full path to the [aliases' target field](https://www.elastic.co/guide/en/elasticsearch/reference/current/alias.html#alias-targets). #### Multi\_fields diff --git a/scripts/generators/beats.py b/scripts/generators/beats.py index f305261407..457fecc5ec 100644 --- a/scripts/generators/beats.py +++ b/scripts/generators/beats.py @@ -34,7 +34,7 @@ def fieldset_field_array(source_fields, df_whitelist, fieldset_prefix): allowed_keys = ['name', 'level', 'required', 'type', 'object_type', 'ignore_above', 'multi_fields', 'format', 'input_format', 'output_format', 'output_precision', 'description', - 'example', 'enabled', 'index'] + 'example', 'enabled', 'index', 'path'] multi_fields_allowed_keys = ['name', 'type', 'norms', 'default_field', 'normalizer', 'ignore_above'] fields = [] diff --git a/scripts/generators/es_template.py b/scripts/generators/es_template.py index 5bf264a784..08e925f0ae 100644 --- a/scripts/generators/es_template.py +++ b/scripts/generators/es_template.py @@ -59,6 +59,8 @@ def entry_for(field): ecs_helpers.dict_copy_existing_keys(field, field_entry, ['ignore_above']) elif field['type'] == 'text': ecs_helpers.dict_copy_existing_keys(field, field_entry, ['norms']) + elif field['type'] == 'alias': + ecs_helpers.dict_copy_existing_keys(field, field_entry, ['path']) if 'multi_fields' in field: field_entry['fields'] = {} diff --git a/scripts/schema/cleaner.py b/scripts/schema/cleaner.py index 5f15d459fe..fa5838cbb7 100644 --- a/scripts/schema/cleaner.py +++ b/scripts/schema/cleaner.py @@ -158,6 +158,12 @@ def field_mandatory_attributes(field): return current_field_attributes = sorted(field['field_details'].keys()) missing_attributes = ecs_helpers.list_subtract(FIELD_MANDATORY_ATTRIBUTES, current_field_attributes) + + # The `alias` type requires a target path. + # https://github.com/elastic/ecs/issues/876 + if field['field_details'].get('type') == 'alias' and 'path' not in current_field_attributes: + missing_attributes.append('path') + if len(missing_attributes) > 0: msg = "Field is missing the following mandatory attributes: {}.\nFound these: {}.\nField details: {}" raise ValueError(msg.format(', '.join(missing_attributes), diff --git a/scripts/tests/test_es_template.py b/scripts/tests/test_es_template.py index 9ff4c30306..9136f8b99e 100644 --- a/scripts/tests/test_es_template.py +++ b/scripts/tests/test_es_template.py @@ -109,6 +109,19 @@ def test_entry_for_index(self): } self.assertEqual(es_template.entry_for(test_map), exp) + def test_entry_for_alias(self): + test_map = { + 'name': 'test.alias', + 'type': 'alias', + 'path': 'alias.target' + } + + exp = { + 'type': 'alias', + 'path': 'alias.target' + } + self.assertEqual(es_template.entry_for(test_map), exp) + if __name__ == '__main__': unittest.main() diff --git a/scripts/tests/unit/test_schema_cleaner.py b/scripts/tests/unit/test_schema_cleaner.py index 8298a32bb3..ba86728e2d 100644 --- a/scripts/tests/unit/test_schema_cleaner.py +++ b/scripts/tests/unit/test_schema_cleaner.py @@ -157,6 +157,13 @@ def test_field_raises_on_missing_required_attributes(self): "mandatory attributes: {}".format(missing_attribute)): cleaner.field_mandatory_attributes(field) + def test_field_raises_on_alias_missing_path_attribute(self): + field = self.schema_process()['process']['fields']['pid'] + field['field_details']['type'] = "alias" + with self.assertRaisesRegex(ValueError, + "mandatory attributes: {}".format("path")): + cleaner.field_mandatory_attributes(field) + def test_field_simple_cleanup(self): my_field = { 'field_details': {