[Entity Analytics] API changes for right placement of deleting the old component template (#199734)

## Summary

- Delete the old component template after the index template has
referenced to the new component template
- Test cases for the same flow


```JSON
# Let's assume this is 8.15.3
# Create the component template when Risk Score engine is initialised
# Create the index template which references the created component template

PUT /_component_template/.risk-score-mappings
{
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "properties": {
        "timestamp": {
          "type": "date"
        },
        "user": {
          "properties": {
            "id": {
              "type": "keyword"
            },
            "name": {
              "type": "text"
            }
          }
        }
      }
    }
  },
  "version": 1
}

PUT /_index_template/.risk-score.risk-score-default-index-template
{
  "index_patterns": [".risk-score.risk-score-default-index-template"],
  "template": {
    "settings": {
      "number_of_replicas": 1
    }
  },
  "composed_of": [".risk-score-mappings"],
  "priority": 100,
  "version": 1,
  "_meta": {
    "description": "Index template for indices with the pattern my_index-*"
  }
}

# The deployment is updated to 8.16
# User tries to enable the Entity store which init's the Risk Score engine (again!!) 
# Fails, but creates the component template and cannot update the index template to reference the new component template due to the error

PUT /_component_template/.risk-score-mappings-default
{
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "properties": {
        "timestamp": {
          "type": "date"
        },
        "user": {
          "properties": {
            "id": {
              "type": "keyword"
            },
            "name": {
              "type": "text"
            }
          }
        }
      }
    }
  },
  "version": 1
}

GET /_component_template?filter_path=component_templates.name&name=.risk-score-mappings*


DELETE /_component_template/.risk-score-mappings

# Fails 

# changed flow
PUT /_index_template/.risk-score.risk-score-default-index-template
{
  "index_patterns": [".risk-score.risk-score-default-index-template"],
  "template": {
    "settings": {
      "number_of_replicas": 1
    }
  },
  "composed_of": [".risk-score-mappings-default"],
  "priority": 100,
  "version": 1,
  "_meta": {
    "description": "Index template for indices with the pattern my_index-*"
  }
}

DELETE /_component_template/.risk-score-mappings

# Succeeds

#########
```


### Checklist

Delete any items that are not applicable to this PR.

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed



### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels)
- [ ] This will appear in the **Release Notes** and follow the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
Abhishek Bhatia 2024-11-18 20:37:13 +05:30 committed by GitHub
parent f94bb3354f
commit 771c139269
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 105 additions and 21 deletions

View file

@ -120,30 +120,10 @@ export class RiskScoreDataClient {
const oldComponentTemplateExists = await esClient.cluster.existsComponentTemplate({
name: mappingComponentName,
});
// If present then copy the contents to a new component template with the namespace in the name
if (oldComponentTemplateExists) {
const oldComponentTemplateResponse = await esClient.cluster.getComponentTemplate(
{
name: mappingComponentName,
},
{ ignore: [404] }
);
const oldComponentTemplate = oldComponentTemplateResponse?.component_templates[0];
const newComponentTemplateName = nameSpaceAwareMappingsComponentName(namespace);
await esClient.cluster.putComponentTemplate({
name: newComponentTemplateName,
body: oldComponentTemplate.component_template,
});
await this.updateComponentTemplateNamewithNamespace(namespace);
}
// Delete the component template without the namespace in the name
await esClient.cluster.deleteComponentTemplate(
{
name: mappingComponentName,
},
{ ignore: [404] }
);
// Update the new component template with the required data
await Promise.all([
createOrUpdateComponentTemplate({
@ -188,6 +168,14 @@ export class RiskScoreDataClient {
},
});
// Delete the component template without the namespace in the name
await esClient.cluster.deleteComponentTemplate(
{
name: mappingComponentName,
},
{ ignore: [404] }
);
await createDataStream({
logger: this.options.logger,
esClient,
@ -327,4 +315,20 @@ export class RiskScoreDataClient {
{ logger: this.options.logger }
);
}
private async updateComponentTemplateNamewithNamespace(namespace: string): Promise<void> {
const esClient = this.options.esClient;
const oldComponentTemplateResponse = await esClient.cluster.getComponentTemplate(
{
name: mappingComponentName,
},
{ ignore: [404] }
);
const oldComponentTemplate = oldComponentTemplateResponse?.component_templates[0];
const newComponentTemplateName = nameSpaceAwareMappingsComponentName(namespace);
await esClient.cluster.putComponentTemplate({
name: newComponentTemplateName,
body: oldComponentTemplate.component_template,
});
}
}

View file

@ -539,6 +539,86 @@ export default ({ getService }: FtrProviderContext) => {
firstResponse?.saved_objects?.[0]?.id
);
});
it('should update the existing component template and index template without any errors', async () => {
const componentTemplateName = '.risk-score-mappings';
const indexTemplateName = '.risk-score.risk-score-default-index-template';
const newComponentTemplateName = '.risk-score-mappings-default';
// Call API to put the component template and index template
await es.cluster.putComponentTemplate({
name: componentTemplateName,
body: {
template: {
settings: {
number_of_shards: 1,
},
mappings: {
properties: {
timestamp: {
type: 'date',
},
user: {
properties: {
id: {
type: 'keyword',
},
name: {
type: 'text',
},
},
},
},
},
},
version: 1,
},
});
// Call an API to put the index template
await es.indices.putIndexTemplate({
name: indexTemplateName,
body: {
index_patterns: [indexTemplateName],
composed_of: [componentTemplateName],
template: {
settings: {
number_of_shards: 1,
},
mappings: {
properties: {
timestamp: {
type: 'date',
},
user: {
properties: {
id: {
type: 'keyword',
},
name: {
type: 'text',
},
},
},
},
},
},
},
});
const response = await riskEngineRoutes.init();
expect(response.status).to.eql(200);
expect(response.body.result.errors).to.eql([]);
const response2 = await es.cluster.getComponentTemplate({
name: newComponentTemplateName,
});
expect(response2.component_templates.length).to.eql(1);
expect(response2.component_templates[0].name).to.eql(newComponentTemplateName);
});
// Failing: See https://github.com/elastic/kibana/issues/191637
describe.skip('remove legacy risk score transform', function () {
this.tags('skipFIPS');