Skip to content

Commit

Permalink
[8.x] [Entity Analytics][Entity Store] Init: Put engine in error stat…
Browse files Browse the repository at this point in the history
…e if data view does not exist (#201140) (#201414)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Entity Analytics][Entity Store] Init: Put engine in error state if
data view does not exist
(#201140)](#201140)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Mark
Hopkin","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-11-22T15:09:23Z","message":"[Entity
Analytics][Entity Store] Init: Put engine in error state if data view
does not exist (#201140)\n\n## Summary\n\nFixes a bug where if the
securite default data view does not exist the\nentity engine would get
stuck in 'installing' status. After this fix,\nthe engine is put into
'error' state.\n\nThe entity engine uses the security default data view
by default to\ngenerate it's source index pattern.\n\n## Testing\n\n1.
Delete the security default data view `security-solution-default`\n2.
Init the entity store\n3. Observe that the entity store is in an error
state (the UI should\nshow the
error)","sha":"c3c872c6da7ca1cf3fd90ef13ce6ae758c53c9e8","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","v9.0.0","Team:
SecuritySolution","Team:Entity
Analytics","backport:version","v8.17.0","v8.18.0","v8.16.2"],"title":"[Entity
Analytics][Entity Store] Init: Put engine in error state if data view
does not
exist","number":201140,"url":"https://github.com/elastic/kibana/pull/201140","mergeCommit":{"message":"[Entity
Analytics][Entity Store] Init: Put engine in error state if data view
does not exist (#201140)\n\n## Summary\n\nFixes a bug where if the
securite default data view does not exist the\nentity engine would get
stuck in 'installing' status. After this fix,\nthe engine is put into
'error' state.\n\nThe entity engine uses the security default data view
by default to\ngenerate it's source index pattern.\n\n## Testing\n\n1.
Delete the security default data view `security-solution-default`\n2.
Init the entity store\n3. Observe that the entity store is in an error
state (the UI should\nshow the
error)","sha":"c3c872c6da7ca1cf3fd90ef13ce6ae758c53c9e8"}},"sourceBranch":"main","suggestedTargetBranches":["8.17","8.x","8.16"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201140","number":201140,"mergeCommit":{"message":"[Entity
Analytics][Entity Store] Init: Put engine in error state if data view
does not exist (#201140)\n\n## Summary\n\nFixes a bug where if the
securite default data view does not exist the\nentity engine would get
stuck in 'installing' status. After this fix,\nthe engine is put into
'error' state.\n\nThe entity engine uses the security default data view
by default to\ngenerate it's source index pattern.\n\n## Testing\n\n1.
Delete the security default data view `security-solution-default`\n2.
Init the entity store\n3. Observe that the entity store is in an error
state (the UI should\nshow the
error)","sha":"c3c872c6da7ca1cf3fd90ef13ce6ae758c53c9e8"}},{"branch":"8.17","label":"v8.17.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.16","label":"v8.16.2","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Mark Hopkin <[email protected]>
  • Loading branch information
kibanamachine and hop-dev authored Nov 22, 2024
1 parent 6cb23a8 commit 722d718
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,19 @@ export class EntityStoreDataClient {
) {
const setupStartTime = moment().utc().toISOString();
const { logger, namespace, appClient, dataViewsService } = this.options;
const indexPatterns = await buildIndexPatterns(namespace, appClient, dataViewsService);
try {
const indexPatterns = await buildIndexPatterns(namespace, appClient, dataViewsService);

const unitedDefinition = getUnitedEntityDefinition({
indexPatterns,
entityType,
namespace,
fieldHistoryLength,
syncDelay: `${config.syncDelay.asSeconds()}s`,
frequency: `${config.frequency.asSeconds()}s`,
});
const { entityManagerDefinition } = unitedDefinition;
const unitedDefinition = getUnitedEntityDefinition({
indexPatterns,
entityType,
namespace,
fieldHistoryLength,
syncDelay: `${config.syncDelay.asSeconds()}s`,
frequency: `${config.frequency.asSeconds()}s`,
});
const { entityManagerDefinition } = unitedDefinition;

try {
// clean up any existing entity store
await this.delete(entityType, taskManager, { deleteData: false, deleteEngine: false });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ export default ({ getService }: FtrProviderContext) => {
});
});

describe('init error handling', () => {
afterEach(async () => {
await dataView.create('security-solution');
await utils.cleanEngines();
});

it('should return "error" when the security data view does not exist', async () => {
await dataView.delete('security-solution');
await utils.initEntityEngineForEntityType('host');
await utils.waitForEngineStatus('host', 'error');
});
});

describe('enablement', () => {
afterEach(async () => {
await utils.cleanEngines();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ export const dataViewRouteHelpersFactory = (
supertest: SuperTest.Agent,
namespace: string = 'default'
) => ({
create: (name: string) => {
create: async (name: string) => {
const { body: existingDataView, statusCode } = await supertest.get(
`/s/${namespace}/api/data_views/data_view/${name}-${namespace}`
);

if (statusCode === 200) {
// data view exists
return existingDataView;
}

return supertest
.post(`/s/${namespace}/api/data_views/data_view`)
.set('kbn-xsrf', 'foo')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const EntityStoreUtils = (
}
};

const _initEntityEngineForEntityType = async (entityType: EntityType) => {
const initEntityEngineForEntityType = async (entityType: EntityType) => {
log.info(
`Initializing engine for entity type ${entityType} in namespace ${namespace || 'default'}`
);
Expand All @@ -72,7 +72,7 @@ export const EntityStoreUtils = (
};

const initEntityEngineForEntityTypesAndWait = async (entityTypes: EntityType[]) => {
await Promise.all(entityTypes.map((entityType) => _initEntityEngineForEntityType(entityType)));
await Promise.all(entityTypes.map((entityType) => initEntityEngineForEntityType(entityType)));

await retry.waitForWithTimeout(
`Engines to start for entity types: ${entityTypes.join(', ')}`,
Expand All @@ -90,6 +90,20 @@ export const EntityStoreUtils = (
);
};

const waitForEngineStatus = async (entityType: EntityType, status: string) => {
await retry.waitForWithTimeout(
`Engine for entity type ${entityType} to be in status ${status}`,
60_000,
async () => {
const { body } = await api
.getEntityEngine({ params: { entityType } }, namespace)
.expect(200);
log.debug(`Engine status for ${entityType}: ${body.status}`);
return body.status === status;
}
);
};

const enableEntityStore = async () => {
const res = await api.initEntityStore({ body: {} }, namespace);
if (res.status !== 200) {
Expand Down Expand Up @@ -155,5 +169,7 @@ export const EntityStoreUtils = (
expectEngineAssetsExist,
expectEngineAssetsDoNotExist,
enableEntityStore,
waitForEngineStatus,
initEntityEngineForEntityType,
};
};

0 comments on commit 722d718

Please sign in to comment.