mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Revert "[Infra][ECO] Fix RBAC issue in hosts view" (#202418)
Reverts elastic/kibana#199841
This commit is contained in:
parent
a18be1fb17
commit
99463c7a0d
19 changed files with 158 additions and 49 deletions
|
@ -72,7 +72,10 @@ export function registerAssistantFunctions({
|
|||
ruleDataClient,
|
||||
plugins,
|
||||
getApmIndices: async () => {
|
||||
const apmIndices = await plugins.apmDataAccess.setup.getApmIndices();
|
||||
const coreContext = await resources.context.core;
|
||||
const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(
|
||||
coreContext.savedObjects.client
|
||||
);
|
||||
return apmIndices;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ import { registerAssistantFunctions } from './assistant_functions';
|
|||
import { registerDeprecations } from './deprecations';
|
||||
import { APM_FEATURE, registerFeaturesUsage } from './feature';
|
||||
import { createApmTelemetry } from './lib/apm_telemetry';
|
||||
import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client';
|
||||
import {
|
||||
APM_RULE_TYPE_ALERT_CONTEXT,
|
||||
apmRuleTypeAlertFieldMap,
|
||||
|
@ -114,6 +115,13 @@ export class APMPlugin
|
|||
};
|
||||
}) as APMRouteHandlerResources['plugins'];
|
||||
|
||||
const apmIndicesPromise = (async () => {
|
||||
const coreStart = await getCoreStart();
|
||||
const soClient = await getInternalSavedObjectsClient(coreStart);
|
||||
const { getApmIndices } = plugins.apmDataAccess;
|
||||
return getApmIndices(soClient);
|
||||
})();
|
||||
|
||||
// This if else block will go away in favour of removing Home Tutorial Integration
|
||||
// Ideally we will directly register a custom integration and pass the configs
|
||||
// for cloud, onPrem and Serverless so that the actual component can take
|
||||
|
@ -121,8 +129,7 @@ export class APMPlugin
|
|||
if (currentConfig.serverlessOnboarding && plugins.customIntegrations) {
|
||||
plugins.customIntegrations?.registerCustomIntegration(apmTutorialCustomIntegration);
|
||||
} else {
|
||||
plugins.apmDataAccess
|
||||
.getApmIndices()
|
||||
apmIndicesPromise
|
||||
.then((apmIndices) => {
|
||||
plugins.home?.tutorials.registerTutorial(
|
||||
tutorialProvider({
|
||||
|
|
|
@ -115,7 +115,10 @@ export function registerRoutes({
|
|||
);
|
||||
|
||||
const getApmIndices = async () => {
|
||||
const apmIndices = await plugins.apmDataAccess.setup.getApmIndices();
|
||||
const coreContext = await context.core;
|
||||
const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(
|
||||
coreContext.savedObjects.client
|
||||
);
|
||||
return apmIndices;
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ export const getAlertDetailsContextHandler = (
|
|||
return async (requestContext, query) => {
|
||||
const resources = {
|
||||
getApmIndices: async () => {
|
||||
return resourcePlugins.apmDataAccess.setup.getApmIndices();
|
||||
const coreContext = await requestContext.core;
|
||||
return resourcePlugins.apmDataAccess.setup.getApmIndices(coreContext.savedObjects.client);
|
||||
},
|
||||
request: requestContext.request,
|
||||
params: { query: { _inspect: false } },
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Logger, CoreStart } from '@kbn/core/server';
|
||||
import { Logger, CoreStart, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import {
|
||||
FleetStartContract,
|
||||
PostPackagePolicyCreateCallback,
|
||||
|
@ -22,6 +22,7 @@ import {
|
|||
SOURCE_MAP_API_KEY_PATH,
|
||||
} from './get_package_policy_decorators';
|
||||
import { createInternalESClient } from '../../lib/helpers/create_es_client/create_internal_es_client';
|
||||
import { getInternalSavedObjectsClient } from '../../lib/helpers/get_internal_saved_objects_client';
|
||||
import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
|
||||
|
||||
export async function registerFleetPolicyCallbacks({
|
||||
|
@ -148,7 +149,7 @@ function onPackagePolicyCreateOrUpdate({
|
|||
coreStart,
|
||||
}: {
|
||||
fleetPluginStart: FleetStartContract;
|
||||
getApmIndices: () => Promise<APMIndices>;
|
||||
getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMIndices>;
|
||||
coreStart: CoreStart;
|
||||
}): PutPackagePolicyUpdateCallback & PostPackagePolicyCreateCallback {
|
||||
return async (packagePolicy) => {
|
||||
|
@ -157,7 +158,8 @@ function onPackagePolicyCreateOrUpdate({
|
|||
}
|
||||
|
||||
const { asInternalUser } = coreStart.elasticsearch.client;
|
||||
const apmIndices = await getApmIndices();
|
||||
const savedObjectsClient = await getInternalSavedObjectsClient(coreStart);
|
||||
const apmIndices = await getApmIndices(savedObjectsClient);
|
||||
|
||||
const internalESClient = await createInternalESClient({
|
||||
debug: false,
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
"requiredPlugins": [
|
||||
"data"
|
||||
],
|
||||
"optionalPlugins": [],
|
||||
"optionalPlugins": [
|
||||
"security"
|
||||
],
|
||||
"requiredBundles": []
|
||||
}
|
||||
}
|
|
@ -91,6 +91,7 @@ export type {
|
|||
APMEventESSearchRequest,
|
||||
APMLogEventESSearchRequest,
|
||||
DocumentSourcesRequest,
|
||||
ApmDataAccessPrivilegesCheck,
|
||||
HostNamesRequest,
|
||||
GetDocumentTypeParams,
|
||||
} from './types';
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 { KibanaRequest } from '@kbn/core-http-server';
|
||||
import { SecurityPluginStart } from '@kbn/security-plugin-types-server';
|
||||
import { mapValues } from 'lodash';
|
||||
import { APMIndices } from '..';
|
||||
|
||||
export interface ApmDataAccessPrivilegesCheck {
|
||||
request: KibanaRequest;
|
||||
security?: SecurityPluginStart;
|
||||
getApmIndices: () => Promise<APMIndices>;
|
||||
}
|
||||
|
||||
export async function checkPrivileges({
|
||||
request,
|
||||
getApmIndices,
|
||||
security,
|
||||
}: ApmDataAccessPrivilegesCheck) {
|
||||
const authorization = security?.authz;
|
||||
if (!authorization) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const [apmIndices, checkPrivilegesFn] = await Promise.all([
|
||||
getApmIndices(),
|
||||
authorization.checkPrivilegesDynamicallyWithRequest(request),
|
||||
]);
|
||||
|
||||
const { hasAllRequested } = await checkPrivilegesFn({
|
||||
elasticsearch: {
|
||||
cluster: [],
|
||||
index: mapValues(apmIndices, () => ['read']),
|
||||
},
|
||||
});
|
||||
|
||||
return hasAllRequested;
|
||||
}
|
|
@ -5,19 +5,32 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server';
|
||||
import {
|
||||
PluginInitializerContext,
|
||||
CoreSetup,
|
||||
CoreStart,
|
||||
Plugin,
|
||||
SavedObjectsClientContract,
|
||||
Logger,
|
||||
} from '@kbn/core/server';
|
||||
import { APMDataAccessConfig } from '.';
|
||||
import { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types';
|
||||
import {
|
||||
ApmDataAccessPluginSetup,
|
||||
ApmDataAccessPluginStart,
|
||||
ApmDataAccessServerDependencies,
|
||||
} from './types';
|
||||
import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware';
|
||||
import {
|
||||
apmIndicesSavedObjectDefinition,
|
||||
getApmIndicesSavedObject,
|
||||
} from './saved_objects/apm_indices';
|
||||
import { getServices } from './services/get_services';
|
||||
import { ApmDataAccessPrivilegesCheck, checkPrivileges } from './lib/check_privileges';
|
||||
|
||||
export class ApmDataAccessPlugin
|
||||
implements Plugin<ApmDataAccessPluginSetup, ApmDataAccessPluginStart>
|
||||
{
|
||||
public server?: ApmDataAccessServerDependencies;
|
||||
public config: APMDataAccessConfig;
|
||||
public logger: Logger;
|
||||
|
||||
|
@ -26,34 +39,45 @@ export class ApmDataAccessPlugin
|
|||
this.logger = initContext.logger.get();
|
||||
}
|
||||
|
||||
getApmIndices = async (savedObjectsClient: SavedObjectsClientContract) => {
|
||||
const apmIndicesFromSavedObject = await getApmIndicesSavedObject(savedObjectsClient);
|
||||
return { ...this.config.indices, ...apmIndicesFromSavedObject };
|
||||
};
|
||||
|
||||
public setup(core: CoreSetup): ApmDataAccessPluginSetup {
|
||||
// register saved object
|
||||
core.savedObjects.registerType(apmIndicesSavedObjectDefinition);
|
||||
|
||||
const getApmIndices = async () => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
const soClient = await coreStart.savedObjects.createInternalRepository();
|
||||
|
||||
const apmIndicesFromSavedObject = await getApmIndicesSavedObject(soClient);
|
||||
return { ...this.config.indices, ...apmIndicesFromSavedObject };
|
||||
};
|
||||
|
||||
// expose
|
||||
return {
|
||||
apmIndicesFromConfigFile: this.config.indices,
|
||||
getApmIndices,
|
||||
getApmIndices: this.getApmIndices,
|
||||
getServices,
|
||||
};
|
||||
}
|
||||
|
||||
public start(core: CoreStart) {
|
||||
public start(core: CoreStart, plugins: ApmDataAccessServerDependencies) {
|
||||
// TODO: remove in 9.0
|
||||
migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger: this.logger }).catch((e) => {
|
||||
this.logger.error('Failed to run migration making APM indices space aware');
|
||||
this.logger.error(e);
|
||||
});
|
||||
|
||||
return {};
|
||||
const getApmIndicesWithInternalUserFn = async () => {
|
||||
const soClient = core.savedObjects.createInternalRepository();
|
||||
return this.getApmIndices(soClient);
|
||||
};
|
||||
|
||||
const startServices = {
|
||||
hasPrivileges: ({ request }: Pick<ApmDataAccessPrivilegesCheck, 'request'>) =>
|
||||
checkPrivileges({
|
||||
request,
|
||||
getApmIndices: getApmIndicesWithInternalUserFn,
|
||||
security: plugins.security,
|
||||
}),
|
||||
};
|
||||
|
||||
return { ...startServices };
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
|
|
|
@ -5,17 +5,28 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
|
||||
import type { SecurityPluginStart } from '@kbn/security-plugin-types-server';
|
||||
import type { APMIndices } from '.';
|
||||
import { getServices } from './services/get_services';
|
||||
import type { ApmDataAccessPrivilegesCheck } from './lib/check_privileges';
|
||||
|
||||
export interface ApmDataAccessPluginSetup {
|
||||
apmIndicesFromConfigFile: APMIndices;
|
||||
getApmIndices: () => Promise<APMIndices>;
|
||||
getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMIndices>;
|
||||
getServices: typeof getServices;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ApmDataAccessPluginStart {}
|
||||
export interface ApmDataAccessServerDependencies {
|
||||
security?: SecurityPluginStart;
|
||||
}
|
||||
|
||||
export interface ApmDataAccessPluginStart {
|
||||
hasPrivileges: (params: Pick<ApmDataAccessPrivilegesCheck, 'request'>) => Promise<boolean>;
|
||||
}
|
||||
export interface ApmDataAccessServerDependencies {
|
||||
security?: SecurityPluginStart;
|
||||
}
|
||||
|
||||
export type ApmDataAccessServices = ReturnType<typeof getServices>;
|
||||
export type { ApmDataAccessServicesParams } from './services/get_services';
|
||||
|
@ -27,3 +38,4 @@ export type {
|
|||
APMEventESSearchRequest,
|
||||
APMLogEventESSearchRequest,
|
||||
} from './lib/helpers';
|
||||
export type { ApmDataAccessPrivilegesCheck };
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"@kbn/config-schema",
|
||||
"@kbn/core",
|
||||
"@kbn/i18n",
|
||||
"@kbn/core-saved-objects-api-server",
|
||||
"@kbn/data-plugin",
|
||||
"@kbn/inspector-plugin",
|
||||
"@kbn/observability-plugin",
|
||||
|
@ -17,6 +18,8 @@
|
|||
"@kbn/apm-types",
|
||||
"@kbn/core-http-server-mocks",
|
||||
"@kbn/apm-utils",
|
||||
"@kbn/core-http-server",
|
||||
"@kbn/security-plugin-types-server",
|
||||
"@kbn/utility-types",
|
||||
"@kbn/elastic-agent-utils",
|
||||
"@kbn/observability-utils-common"
|
||||
|
|
|
@ -27,17 +27,23 @@ export const getApmDataAccessClient = ({
|
|||
context: InfraPluginRequestHandlerContext;
|
||||
request: KibanaRequest;
|
||||
}) => {
|
||||
const hasPrivileges = async () => {
|
||||
const apmDataAccessStart = await libs.plugins.apmDataAccess.start();
|
||||
return apmDataAccessStart.hasPrivileges({ request });
|
||||
};
|
||||
|
||||
const getServices = async () => {
|
||||
const apmDataAccess = libs.plugins.apmDataAccess.setup;
|
||||
|
||||
const coreContext = await context.core;
|
||||
|
||||
const { uiSettings, elasticsearch } = coreContext;
|
||||
const { savedObjects, uiSettings, elasticsearch } = coreContext;
|
||||
const savedObjectsClient = savedObjects.client;
|
||||
const esClient = elasticsearch.client.asCurrentUser;
|
||||
const uiSettingsClient = uiSettings.client;
|
||||
|
||||
const [apmIndices, includeFrozen] = await Promise.all([
|
||||
apmDataAccess.getApmIndices(),
|
||||
apmDataAccess.getApmIndices(savedObjectsClient),
|
||||
uiSettingsClient.get<boolean>(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
|
||||
]);
|
||||
|
||||
|
@ -80,5 +86,5 @@ export const getApmDataAccessClient = ({
|
|||
};
|
||||
};
|
||||
|
||||
return { getServices };
|
||||
return { hasPrivileges, getServices };
|
||||
};
|
||||
|
|
|
@ -41,11 +41,12 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => {
|
|||
|
||||
try {
|
||||
const apmDataAccessClient = getApmDataAccessClient({ request, libs, context });
|
||||
const hasApmPrivileges = await apmDataAccessClient.hasPrivileges();
|
||||
|
||||
const [infraMetricsClient, alertsClient, apmDataAccessServices] = await Promise.all([
|
||||
getInfraMetricsClient({ request, libs, context }),
|
||||
getInfraAlertsClient({ libs, request }),
|
||||
apmDataAccessClient.getServices(),
|
||||
hasApmPrivileges ? apmDataAccessClient.getServices() : undefined,
|
||||
]);
|
||||
|
||||
const hosts = await getHosts({
|
||||
|
@ -96,10 +97,11 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => {
|
|||
|
||||
try {
|
||||
const apmDataAccessClient = getApmDataAccessClient({ request, libs, context });
|
||||
const hasApmPrivileges = await apmDataAccessClient.hasPrivileges();
|
||||
|
||||
const [infraMetricsClient, apmDataAccessServices] = await Promise.all([
|
||||
getInfraMetricsClient({ request, libs, context }),
|
||||
apmDataAccessClient.getServices(),
|
||||
hasApmPrivileges ? apmDataAccessClient.getServices() : undefined,
|
||||
]);
|
||||
|
||||
const count = await getHostsCount({
|
||||
|
|
|
@ -9,7 +9,6 @@ import { findInventoryModel } from '@kbn/metrics-data-access-plugin/common';
|
|||
import { termQuery } from '@kbn/observability-plugin/server';
|
||||
import { ApmDocumentType, type TimeRangeMetadata } from '@kbn/apm-data-access-plugin/common';
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
import { castArray } from 'lodash';
|
||||
import type { ApmDataAccessServicesWrapper } from '../../../../lib/helpers/get_apm_data_access_client';
|
||||
import {
|
||||
EVENT_MODULE,
|
||||
|
@ -18,16 +17,12 @@ import {
|
|||
} from '../../../../../common/constants';
|
||||
import type { InfraAssetMetricType } from '../../../../../common/http_api/infra';
|
||||
|
||||
export const getFilterByIntegration = (
|
||||
integration: typeof SYSTEM_INTEGRATION,
|
||||
extraFilter: estypes.QueryDslQueryContainer[] = []
|
||||
) => {
|
||||
export const getFilterByIntegration = (integration: typeof SYSTEM_INTEGRATION) => {
|
||||
return {
|
||||
bool: {
|
||||
should: [
|
||||
...termQuery(EVENT_MODULE, integration),
|
||||
...termQuery(METRICSET_MODULE, integration),
|
||||
...extraFilter,
|
||||
],
|
||||
minimum_should_match: 1,
|
||||
},
|
||||
|
@ -68,6 +63,7 @@ export const getDocumentsFilter = async ({
|
|||
from: number;
|
||||
to: number;
|
||||
}) => {
|
||||
const filters: estypes.QueryDslQueryContainer[] = [getFilterByIntegration('system')];
|
||||
const apmDocumentsFilter =
|
||||
apmDataAccessServices && apmDocumentSources
|
||||
? await getApmDocumentsFilter({
|
||||
|
@ -78,9 +74,9 @@ export const getDocumentsFilter = async ({
|
|||
})
|
||||
: undefined;
|
||||
|
||||
const filters: estypes.QueryDslQueryContainer[] = [
|
||||
getFilterByIntegration('system', apmDocumentsFilter && castArray(apmDocumentsFilter)),
|
||||
];
|
||||
if (apmDocumentsFilter) {
|
||||
filters.push(apmDocumentsFilter);
|
||||
}
|
||||
|
||||
return filters;
|
||||
};
|
||||
|
|
|
@ -49,7 +49,6 @@ export const getHosts = async ({
|
|||
const [hostMetricsResponse, alertsCountResponse] = await Promise.all([
|
||||
getAllHosts({
|
||||
infraMetricsClient,
|
||||
apmDataAccessServices,
|
||||
apmDocumentSources,
|
||||
from,
|
||||
to,
|
||||
|
|
|
@ -25,14 +25,8 @@ export async function getHostsCount({
|
|||
}) {
|
||||
assertQueryStructure(query);
|
||||
|
||||
const apmDocumentSources = await apmDataAccessServices?.getDocumentSources({
|
||||
start: from,
|
||||
end: to,
|
||||
});
|
||||
|
||||
const documentsFilter = await getDocumentsFilter({
|
||||
apmDataAccessServices,
|
||||
apmDocumentSources,
|
||||
from,
|
||||
to,
|
||||
});
|
||||
|
@ -45,7 +39,7 @@ export async function getHostsCount({
|
|||
query: {
|
||||
bool: {
|
||||
filter: [query, ...rangeQuery(from, to)],
|
||||
must: [...documentsFilter],
|
||||
should: [...documentsFilter],
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
|
|
|
@ -13,5 +13,5 @@ import { InfraMetricsClient } from '../../../lib/helpers/get_infra_metrics_clien
|
|||
export interface GetHostParameters extends GetInfraMetricsRequestBodyPayload {
|
||||
infraMetricsClient: InfraMetricsClient;
|
||||
alertsClient: InfraAlertsClient;
|
||||
apmDataAccessServices: ApmDataAccessServicesWrapper;
|
||||
apmDataAccessServices?: ApmDataAccessServicesWrapper;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,16 @@ export const initServicesRoute = (libs: InfraBackendLibs) => {
|
|||
const { from, to, size = 10, validatedFilters } = request.query;
|
||||
|
||||
const apmDataAccessClient = getApmDataAccessClient({ request, libs, context });
|
||||
const hasApmPrivileges = await apmDataAccessClient.hasPrivileges();
|
||||
|
||||
if (!hasApmPrivileges) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: 'APM data access service is not available',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const apmDataAccessServices = await apmDataAccessClient.getServices();
|
||||
|
||||
|
|
|
@ -52,7 +52,9 @@ export function registerTopNFunctionsAPMTransactionsRoute({
|
|||
});
|
||||
}
|
||||
const core = await context.core;
|
||||
const { transaction: transactionIndices } = await apmDataAccess.getApmIndices();
|
||||
const { transaction: transactionIndices } = await apmDataAccess.getApmIndices(
|
||||
core.savedObjects.client
|
||||
);
|
||||
|
||||
const esClient = await getClient(context);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue