Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composable Templates #53101

Closed
30 of 39 tasks
martijnvg opened this issue Mar 4, 2020 · 2 comments
Closed
30 of 39 tasks

Composable Templates #53101

martijnvg opened this issue Mar 4, 2020 · 2 comments
Assignees
Labels
:Data Management/Indices APIs APIs to create and manage indices and templates Meta Team:Data Management Meta label for data/management team Top Ask

Comments

@martijnvg
Copy link
Member

martijnvg commented Mar 4, 2020

The meta issue will track the development of the second version of index templates.

Tasks:


Tasks that may be done after initial release:

  • Mark APIs as stable for 7.9
  • Switch internal use of templates to use v2 templates (like ILM/SLM history indices, ML, etc)
  • Switch all internal tests to use v2 templates instead of v1 templates
  • Enforce only delete or update operations for v1 templates are allowed on 8.0+ (no creation of new v1 templates)
  • Deprecate the entire v1 template API in 8.0+
  • Add a method to migrate a v1 template into a v2 template? (maybe)
  • Add simulate API for a template ie. /_index_template/{template-name}/_simulate, without any body. It will return the final resolved version of the template (merging the component templates)

Background

Index templates as it stands today has a number of shortcomings mainly around index template inheritance:

  • At index creation time, multiple index templates can be applied. If no template order is specified or templates have the same order then how templates are applied to create the final mappings and index setting is undefined. This can result in settings/mappings being applied in an unexpected manner.
  • With template inheritance, multiple index templates can merged together. The end result of that merge can result in invalid settings and mappings.

Version 2 changes

The biggest change is that reuse of template configuration via template inheritance that exists today is going to get replaced by template composition. A new index will no longer be able to match with multiple index templates. If a new index matches with multiple index templates then the index template with the highest priority is selected and used. If multiple index templates match that have the same priority then that results into an error. Either at alias template creation time or when alias templates are evaluated as part of index creation.

New indices may require the same index template configuration be applied to them, but their names may be so different that a single index template's index pattern can't capture them and because with index templates v2 only a single template can match with a new index. To solve this problem, we'll abstract the index template config into reusable ‘component templates', which users can refer to when composing index templates. A component template only contains settings, mappings and aliases. Index templates can be composed of one or more component templates. The order in which the names of component templates are specified in an index template determines the order in which the component templates are applied. The setting, mapping and aliases specified inside an index template are applied last.

Component templates never match at index creation time directly and are only included via a matching index template. Component templates can’t be composed of other component templates.

Index and component templates can only contain settings and mappings that are valid on their own. The settings and mappings of an individual index template should result in a successful index creation.

Component template merging

The order in which the names of component templates are specified in an index template determines the order in which the component templates are applied. The setting, mapping and aliases specified inside an index template are applied last.

Settings and mappings are essentially nested key value pairs. If a component template is applied and a key already exists then it will replace the key and value even if that contains other key value pairs.

For example consider the following snippets:

{
  "my_field": {
      "type": "integer", 
      "ignore_malformed": true
  }
}
{
  "my_field": {
     "type": "keyword", 
     "ignore_above": 1024
  }
}

With the merging of index templates that exist today, the following result would be created:

{
  "my_field": {
      "ignore_malformed": true,
      "type": "keyword", 
      "ignore_above": 1024
  }
}

In order to avoid this, at the time a template with snippet B is applied then that would completely overwrite the ‘my_field’ key in order to avoid creating an illegal mapping. With this logic this would be the result:

{
  "my_field": {
     "type": "keyword", 
     "ignore_above": 1024
  }
}

Merging will happen on a field granular level, and the V2 templates will ensure no doc types are specified.

Also dynamic templates should be merged in the same manner.

Backwards compatibility

We should strive towards ensuring that existing index templates should be able to work like index templates v2. If index templates v1 are not relying on template inheritance then no action should be required.

With index templates v2 configuration reuse is achieved by selective composability whereas with index templates v1 this is achieved via template inheritance. Template inheritance should be allowed throughout the 7.x version timeline, so that users can upgrade their index templates to use component template. In this period of time we should emit deprecation warnings if a new index matches with more than one index template in the v1 structure. After the deprecation period, if multiple v1 templates match we should fail with an error at index creation time. Users will then have to upgrade to use component templates.

For interop with both v1 and v2 templates the following will be used:

If * in v1, allow but warn to put v2
Runtime resolution will favor v2
If PUT v1 (not ‘*’) and overlaps with v2, then error (v2 will take precedence)
If PUT v1 (with ‘*’) and overlaps with v2, then warn (v2 may take precedence)
If PUT v2 with ‘*’ allow the overlap, warn about taking precedence
If PUT v2 that matches a V1 template, warn that v2 will take precedence
In 8.0 - only allow update/delete of v1, not create (provide an escape hatch setting/property)
In 7.x, deprecate the entire /_template endpoint

In 9.0 the deprecated /_template endpoint will be removed.

The structure and field names have changed slightly with index templates v1. The current structure and field names will be supported throughout the 7.x version timeline. After which we can automatically rewrite the older format into the new format upon upgrading to version 8. (we may be able to provide a conversion API, but we cannot automatically upgrade them since v1 templates rely on inheritance)

Config and APIs

Component templates are stored in the cluster state as separate resources. Index templates remain to be stored in the same place inside the cluster state.

Index Templates v2 Config

Config:

{
    "index_patterns": [...],
    "priority": 0-9223372036854775808,
    "template": {
       "settings": {...},
       "mappings": {...},
       "aliases": {...}
    },
    "composed_of": [...],
    "version": 0-9223372036854775808,
    "_meta": { ... }
}

Explanation of the configuration fields:

  • index_patterns (required), a string array. Each string contains a wildcard pattern.
  • template (optional), a json object at least settings or mappings or aliases.
    • settings (optional), a json object representing index settings.
    • mappings (optional), a json object representing mappings.
    • aliases (optional), a json object representing aliases.
  • priority (optional), a numeric value indicating precedence over other index templates. When indexing into a non existing index/alias, the name may match with patterns of multiple index templates, the alias template with the highest order value will be selected. Other index templates will be ignored. Defaults to 0.
  • composed_of (optional), a string array with the names of components templates that will be applied on a new index together with the current template. The order in the string array determines the order in which the component templates are applied. If composed_of is specified then the index template is applied last. This is to ensure that the settings/mappings for the index template are never overwritten by component templates it references to.
  • version (optional), a numeric value. External systems can use this version number to simplify template management. The version parameter is completely optional and not automatically generated by Elasticsearch. Defaults to null.
  • _meta (optional), a json object with meta information about a template, not used by Elasticsearch, but for third party systems and users.
    Index Template APIs
    Index v2 templates will remain to use the existing index template APIs. Additionally there will be an api to simulate what index template would match with a given index name. Also the final index settings, mappings and aliases would be returned.

Simulate index template api:

GET /_index_template/[index_name]/_simulate

We should also support sending an index template (v2) body with the simulate API, so a UI can simulate adding an index template and seeing what it would look like.

Component Template Config

Config:

{
    "template": {
       "settings": {...},
       "mappings": {...},
       "aliases": {...}
    },
    "version": 0-9223372036854775808,
    "_meta": { ... }
}

Explanation of the configuration fields:

  • template (required), a json object at least settings or mappings or aliases.
    • settings (optional), a json object representing index settings.
    • mappings (optional), a json object representing mappings.
    • aliases (optional), a json object representing aliases.
  • version (optional), a numeric value. External systems can use this version number to simplify template management. The version parameter is completely optional and not automatically generated by Elasticsearch. Defaults to null.
  • _meta (optional), a json object with meta information about a template, not used by Elasticsearch, but for third party systems and users.

Component Template APIs

Put component template api:

PUT /_component_template/[name]
{
   ...
}

Get component template api:

GET /_component_template/[name]

Delete component template api:

DELETE /_component_template/[name]
@martijnvg martijnvg added Meta :Data Management/Indices APIs APIs to create and manage indices and templates labels Mar 4, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-features (:Core/Features/Indices APIs)

@martijnvg martijnvg mentioned this issue Mar 4, 2020
1 task
@dakrone dakrone self-assigned this Mar 4, 2020
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 9, 2020
This adds a `ComponentTemplate` datastructure that will be used as part of elastic#53101 (Index Templates
v2) to the `MetaData` class. Currently there are no APIs for interacting with this class, so it will
always be an empty map (other than in tests). This infrastructure will be built upon to add APIs in
a subsequent commit.

A `ComponentTemplate` is made up of a `Template`, a version, and an arbitrary metadata map. The
`Template` contains similar information to an `IndexTemplateMetaData` object— settings, mappings,
and alias configuration.
dakrone added a commit that referenced this issue Mar 12, 2020
* Add ComponentTemplate to MetaData

This adds a `ComponentTemplate` datastructure that will be used as part of #53101 (Index Templates
v2) to the `MetaData` class. Currently there are no APIs for interacting with this class, so it will
always be an empty map (other than in tests). This infrastructure will be built upon to add APIs in
a subsequent commit.

A `ComponentTemplate` is made up of a `Template`, a version, and a MetaData.Custom class. The
`Template` contains similar information to an `IndexTemplateMetaData` object— settings, mappings,
and alias configuration.
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 12, 2020
* Add ComponentTemplate to MetaData

This adds a `ComponentTemplate` datastructure that will be used as part of elastic#53101 (Index Templates
v2) to the `MetaData` class. Currently there are no APIs for interacting with this class, so it will
always be an empty map (other than in tests). This infrastructure will be built upon to add APIs in
a subsequent commit.

A `ComponentTemplate` is made up of a `Template`, a version, and a MetaData.Custom class. The
`Template` contains similar information to an `IndexTemplateMetaData` object— settings, mappings,
and alias configuration.
dakrone added a commit that referenced this issue Mar 12, 2020
* Add ComponentTemplate to MetaData (#53290)

* Add ComponentTemplate to MetaData

This adds a `ComponentTemplate` datastructure that will be used as part of #53101 (Index Templates
v2) to the `MetaData` class. Currently there are no APIs for interacting with this class, so it will
always be an empty map (other than in tests). This infrastructure will be built upon to add APIs in
a subsequent commit.

A `ComponentTemplate` is made up of a `Template`, a version, and a MetaData.Custom class. The
`Template` contains similar information to an `IndexTemplateMetaData` object— settings, mappings,
and alias configuration.

* Update minimal supported version constant

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 13, 2020
This adds the Put/Get/DeleteComponentTemplate APIs that allow inserting, retrieving, and removing
ComponentTemplateMetadata into the cluster state metadata.

These APIs are currently only available behind a feature flag system property -
`es.itv2_feature_flag_registered`.

Relates to elastic#53101
dakrone added a commit that referenced this issue Mar 17, 2020
* Add REST API for ComponentTemplate CRUD

This adds the Put/Get/DeleteComponentTemplate APIs that allow inserting, retrieving, and removing
ComponentTemplateMetadata into the cluster state metadata.

These APIs are currently only available behind a feature flag system property -
`es.itv2_feature_flag_registered`.

Relates to #53101

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 17, 2020
* Add REST API for ComponentTemplate CRUD

This adds the Put/Get/DeleteComponentTemplate APIs that allow inserting, retrieving, and removing
ComponentTemplateMetadata into the cluster state metadata.

These APIs are currently only available behind a feature flag system property -
`es.itv2_feature_flag_registered`.

Relates to elastic#53101

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit that referenced this issue Mar 17, 2020
* Add REST API for ComponentTemplate CRUD

This adds the Put/Get/DeleteComponentTemplate APIs that allow inserting, retrieving, and removing
ComponentTemplateMetadata into the cluster state metadata.

These APIs are currently only available behind a feature flag system property -
`es.itv2_feature_flag_registered`.

Relates to #53101

Co-authored-by: Elastic Machine <[email protected]>

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 18, 2020
This adds the `IndexTemplateV2` and `IndexTemplateV2Metadata` class to be used for the new
implementation of index templates. The new metadata is stored as a `MetaData.Custom` implementation.

Relates to elastic#53101
dakrone added a commit that referenced this issue Mar 19, 2020
* Add IndexTemplateV2 to MetaData

This adds the `IndexTemplateV2` and `IndexTemplateV2Metadata` class to be used for the new
implementation of index templates. The new metadata is stored as a `MetaData.Custom` implementation.

Relates to #53101

* Add ITV2Metadata unit tests

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 19, 2020
* Add IndexTemplateV2 to MetaData

This adds the `IndexTemplateV2` and `IndexTemplateV2Metadata` class to be used for the new
implementation of index templates. The new metadata is stored as a `MetaData.Custom` implementation.

Relates to elastic#53101

* Add ITV2Metadata unit tests

Co-authored-by: Elastic Machine <[email protected]>
dakrone added a commit that referenced this issue Mar 19, 2020
* Add IndexTemplateV2 to MetaData (#53753)

* Add IndexTemplateV2 to MetaData

This adds the `IndexTemplateV2` and `IndexTemplateV2Metadata` class to be used for the new
implementation of index templates. The new metadata is stored as a `MetaData.Custom` implementation.

Relates to #53101

* Add ITV2Metadata unit tests

Co-authored-by: Elastic Machine <[email protected]>

* Update min supported version constant

Co-authored-by: Elastic Machine <[email protected]>
probakowski added a commit to probakowski/elasticsearch that referenced this issue Mar 23, 2020
This change adds validation to make sure that settings and mappings are correct in
component template. It's done the same way as in index templates - code is reused.

Reletes to elastic#53101
dakrone added a commit to dakrone/elasticsearch that referenced this issue Mar 23, 2020
This commit adds the get/put/delete APIs for interacting with the now v2 versions of index
templates.

These APIs are behind the existing `es.itv2_feature_flag_registered` system property feature flag.

Relates to elastic#53101
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 11, 2020
This commit removes the `prefer_v2_templates` flag and setting. This was a brief setting that
allowed specifying whether V1 or V2 template should be used when an index is created. It has been
removed in favor of V2 templates always having priority.

Relates to elastic#53101
Resolves elastic#56528

This is not a breaking change because this flag was never in a released version.
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 11, 2020
This commit removes the `prefer_v2_templates` flag and setting. This was a brief setting that
allowed specifying whether V1 or V2 template should be used when an index is created. It has been
removed in favor of V2 templates always having priority.

Relates to elastic#53101
Resolves elastic#56528

This is not a breaking change because this flag was never in a released version.
dakrone added a commit that referenced this issue May 11, 2020
This commit removes the `prefer_v2_templates` flag and setting. This was a brief setting that
allowed specifying whether V1 or V2 template should be used when an index is created. It has been
removed in favor of V2 templates always having priority.

Relates to #53101
Resolves #56528

This is not a breaking change because this flag was never in a released version.
dakrone added a commit that referenced this issue May 11, 2020
This commit removes the `prefer_v2_templates` flag and setting. This was a brief setting that
allowed specifying whether V1 or V2 template should be used when an index is created. It has been
removed in favor of V2 templates always having priority.

Relates to #53101
Resolves #56528

This is not a breaking change because this flag was never in a released version.
dakrone added a commit that referenced this issue May 11, 2020
This commit removes the `prefer_v2_templates` flag and setting. This was a brief setting that
allowed specifying whether V1 or V2 template should be used when an index is created. It has been
removed in favor of V2 templates always having priority.

Relates to #53101
Resolves #56528

This is not a breaking change because this flag was never in a released version.
dakrone added a commit that referenced this issue May 14, 2020
This commit removes the ability to put V2 index templates that reference missing component templates.
It also prevents removing component templates that are being referenced by an existing V2 index
template.

Relates to #53101
Resolves #56314
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 14, 2020
This commit removes the ability to put V2 index templates that reference missing component templates.
It also prevents removing component templates that are being referenced by an existing V2 index
template.

Relates to elastic#53101
Resolves elastic#56314
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 14, 2020
When simulating index template composition, we should not require an index name if a body is
specified, instead if no index is specified we should assume the provided template matches.

Relates to elastic#53101
Resolves elastic#56255
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 15, 2020
This adds an API for simulating template composition with or without an index template.

It looks like:

```
POST /_index_template/_simulate/my-template
```

To simulate a template named `my-template` that already exists, or, to simulate a template that does
not already exist:

```
POST /_index_template/_simulate
{
  "index_patterns": ["my-index"]
  "composed_of": ["ct1", "ct2"],
}
```

This is related to elastic#55686, which adds an API to simulate composition based on an index name (hence
the `_simulate_index` vs `_simulate`).

This commit also adds reference documentation for both simulation APIs.

Relates to elastic#53101
Resolves elastic#56390
Resolves elastic#56255
dakrone added a commit that referenced this issue May 18, 2020
This adds an API for simulating template composition with or without an index template.

It looks like:

```
POST /_index_template/_simulate/my-template
```

To simulate a template named `my-template` that already exists, or, to simulate a template that does
not already exist:

```
POST /_index_template/_simulate
{
  "index_patterns": ["my-index"]
  "composed_of": ["ct1", "ct2"],
}
```

This is related to #55686, which adds an API to simulate composition based on an index name (hence
the `_simulate_index` vs `_simulate`).

This commit also adds reference documentation for both simulation APIs.

Relates to #53101
Resolves #56390
Resolves #56255
dakrone added a commit to dakrone/elasticsearch that referenced this issue May 18, 2020
…tic#56842)

This adds an API for simulating template composition with or without an index template.

It looks like:

```
POST /_index_template/_simulate/my-template
```

To simulate a template named `my-template` that already exists, or, to simulate a template that does
not already exist:

```
POST /_index_template/_simulate
{
  "index_patterns": ["my-index"]
  "composed_of": ["ct1", "ct2"],
}
```

This is related to elastic#55686, which adds an API to simulate composition based on an index name (hence
the `_simulate_index` vs `_simulate`).

This commit also adds reference documentation for both simulation APIs.

Relates to elastic#53101
Resolves elastic#56390
Resolves elastic#56255
@danhermann danhermann changed the title Index Templates v2 Composable Templates May 19, 2020
jtibshirani added a commit that referenced this issue Jun 29, 2020
This PR implements recursive mapping merging for composable index templates.

When creating an index, we perform the following:
* Add each component template mapping in order, merging each one in after the
last.
* Merge in the index template mappings (if present).
* Merge in the mappings on the index request itself (if present).

Some principles:
* All 'structural' changes are disallowed (but everything else is fine). An
object mapper can never be changed between `type: object` and `type: nested`. A
field mapper can never be changed to an object mapper, and vice versa.
* Generally, each section is merged recursively. This includes `object`
mappings, as well as root options like `dynamic_templates` and `meta`. Once we
reach 'leaf components' like field definitions, they always overwrite an
existing one instead of being merged.

Relates to #53101.
jtibshirani added a commit that referenced this issue Jun 30, 2020
This PR implements recursive mapping merging for composable index templates.

When creating an index, we perform the following:
* Add each component template mapping in order, merging each one in after the
last.
* Merge in the index template mappings (if present).
* Merge in the mappings on the index request itself (if present).

Some principles:
* All 'structural' changes are disallowed (but everything else is fine). An
object mapper can never be changed between `type: object` and `type: nested`. A
field mapper can never be changed to an object mapper, and vice versa.
* Generally, each section is merged recursively. This includes `object`
mappings, as well as root options like `dynamic_templates` and `meta`. Once we
reach 'leaf components' like field definitions, they always overwrite an
existing one instead of being merged.

Relates to #53101.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Data Management/Indices APIs APIs to create and manage indices and templates Meta Team:Data Management Meta label for data/management team Top Ask
Projects
None yet
Development

No branches or pull requests

7 participants