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

OSquery fix issue with document rejection by upgrading osquery_manager package and rolling over indices on upgrade #148991

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
190dd47
[Osquery] Fix 8.6.0 agent data_stream values
patrykkopycinski Jan 14, 2023
0d108bf
add try catch to avoid rollover breaking the package policy update
patrykkopycinski Jan 15, 2023
788a1c0
OSquery datastream rollover check moved to plugin start
kevinlog Jan 16, 2023
6a6641d
sort indicies, perform rollover, package update code
kevinlog Jan 16, 2023
7915504
get package update to work
kevinlog Jan 17, 2023
7d9cd2b
revert fleet integration change
kevinlog Jan 17, 2023
02d3c3f
revert uneeded change
kevinlog Jan 17, 2023
6df1c42
revert uneeded change
kevinlog Jan 17, 2023
86e6998
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Jan 17, 2023
197d573
ignore ts error to access mapping values
kevinlog Jan 17, 2023
3a12288
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Jan 17, 2023
1bec2c6
Merge branch 'main' into task/move-datastream-check-to-plugin-start
kibanamachine Jan 17, 2023
2574f24
Merge branch 'main' into task/move-datastream-check-to-plugin-start
kibanamachine Jan 17, 2023
b3794fd
move the logic into an async function
tomsonpl Jan 19, 2023
67e44ac
fix file name
tomsonpl Jan 19, 2023
a2971b3
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 19, 2023
79900fb
Merge branch 'main' into task/move-datastream-check-to-plugin-start
kibanamachine Jan 19, 2023
2ab7c4f
Merge branch 'main' into task/move-datastream-check-to-plugin-start
kibanamachine Jan 21, 2023
3b36267
Merge branch 'main' into task/move-datastream-check-to-plugin-start
kibanamachine Jan 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion x-pack/plugins/osquery/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import type {
import { SavedObjectsClient } from '@kbn/core/server';
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
import type { DataViewsService } from '@kbn/data-views-plugin/common';

import type { NewPackagePolicy, UpdatePackagePolicy } from '@kbn/fleet-plugin/common';

import { upgradeIntegration } from './utils/upgrade_integration';
import type { PackSavedObjectAttributes } from './common/types';
import { updateGlobalPacksCreateCallback } from './lib/update_global_packs';
import { packSavedObjectType } from '../common/types';
Expand Down Expand Up @@ -135,6 +136,9 @@ export class OsqueryPlugin implements Plugin<OsqueryPluginSetup, OsqueryPluginSt
await this.initialize(core, dataViewsService);
}

// Upgrade integration into 1.6.0 and rollover if found 'generic' dataset - we do not want to wait for it
upgradeIntegration({ packageInfo, client, esClient, logger: this.logger });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: as the upgrade is conditional, could this be renamed to something like upgradeIntegrationIfNeeded or checkAndUpgradeIntegrationIfNeeded


if (registerIngestCallback) {
registerIngestCallback(
'packagePolicyCreate',
Expand Down
98 changes: 98 additions & 0 deletions x-pack/plugins/osquery/server/utils/upgrade_integration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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 { satisfies } from 'semver';
import { installPackage } from '@kbn/fleet-plugin/server/services/epm/packages';
import { pkgToPkgKey } from '@kbn/fleet-plugin/server/services/epm/registry';
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants';
import { asyncForEach } from '@kbn/std';
import { orderBy } from 'lodash';
import type { Installation } from '@kbn/fleet-plugin/common';
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import type { Logger } from '@kbn/logging';
import { OSQUERY_INTEGRATION_NAME } from '../../common';

interface UpgradeIntegrationOptions {
packageInfo?: Installation;
client: SavedObjectsClientContract;
esClient: ElasticsearchClient;
logger: Logger;
}

// Conditionally upgrade osquery integration in order to fix 8.6.0 agent issue
export const upgradeIntegration = async ({
packageInfo,
client,
esClient,
logger,
}: UpgradeIntegrationOptions) => {
let updatedPackageResult;

if (packageInfo && satisfies(packageInfo?.version ?? '', '<1.6.0')) {
try {
logger.info('Updating osquery_manager integration');
updatedPackageResult = await installPackage({
installSource: 'registry',
savedObjectsClient: client,
pkgkey: pkgToPkgKey({
name: packageInfo.name,
version: '1.6.0', // This package upgrade is specific to a bug fix, so keeping the upgrade focused on 1.6.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You seem to be pinning the version to 1.6.0 here, is that correct? What if the newest version is higher than 1.6.0?

The reason this looks strange to me is because this PR is being merged to main which means it applies to v8.7++.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @paul-tavares! Thanks for raising the issue :) I haven’t really think about it, but the goal is to force upgrade older version than 1.6.0 to 1.6.0 which fixed the issue. The rest - update to any other versions are not crucial to us.
I think we can still discuss how to handle this 8.7 onwards, the most crucial part is to fix 8.6.1 and actually @kevinlog suggested another way to fix it: #149325

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paul-tavares - osquery doesn't normally upgrade it's package automatically. We wanted to make an exception in this case since 1.6.0 contains a critical fix. We'll only try to upgrade if the package version is below 1.6.0. We will make sure the package is at 1.6.0 and after that, users can check and upgrade the package as normal with newer changes pushed out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. As long as you realize that the forced upgrade here might be to a version (1.6.0) that is not the latest and thats ok condition, then 👍

Thanks for the responses @tomsonpl , @kevinlog

}),
esClient,
spaceId: packageInfo.installed_kibana_space_id || DEFAULT_SPACE_ID,
// Force install the package will update the index template and the datastream write indices
force: true,
});
logger.info('osquery_manager integration updated');
} catch (e) {
logger.error(e);
}
}

// Check to see if the package has already been updated to at least 1.6.0
if (
satisfies(packageInfo?.version ?? '', '>=1.6.0') ||
updatedPackageResult?.status === 'installed'
) {
try {
// First get all datastreams matching the pattern.
const dataStreams = await esClient.indices.getDataStream({
name: `logs-${OSQUERY_INTEGRATION_NAME}.result-*`,
});

// Then for each of those datastreams, we need to see if they need to rollover.
await asyncForEach(dataStreams.data_streams, async (dataStream) => {
Copy link
Contributor

@dasansol92 dasansol92 Jan 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't need to be changed, but if you would like to avoid asyncForEach import, you could just use a for loop:

for (const dataStream of dataStreams.data_streams) {
[....]
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be done in parallel? Wondering if you could use pMap here and speed up the process.

const mapping = await esClient.indices.getMapping({
index: dataStream.name,
});

const valuesToSort = Object.entries(mapping).map(([key, value]) => ({
index: key,
mapping: value,
}));

// Sort by index name to get the latest index for detecting if we need to rollover
const dataStreamMapping = orderBy(valuesToSort, ['index'], 'desc');

if (
dataStreamMapping &&
// @ts-expect-error 'properties' does not exist on type 'MappingMatchOnlyTextProperty'
dataStreamMapping[0]?.mapping?.mappings?.properties?.data_stream?.properties?.dataset
?.value === 'generic'
) {
logger.info('Rolling over index: ' + dataStream.name);
await esClient.indices.rollover({
alias: dataStream.name,
});
}
});
} catch (e) {
logger.error(e);
}
}
};
3 changes: 3 additions & 0 deletions x-pack/plugins/osquery/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,8 @@
"@kbn/core-elasticsearch-client-server-mocks",
"@kbn/std",
"@kbn/ecs",
"@kbn/core-elasticsearch-server",
"@kbn/core-saved-objects-api-server",
"@kbn/logging",
]
}