mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Dataset quality] Authz migration (#208343)](https://github.com/elastic/kibana/pull/208343) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Yngrid Coello","email":"yngrid.coello@elastic.co"},"sourceCommit":{"committedDate":"2025-01-29T17:59:59Z","message":"[Dataset quality] Authz migration (#208343)\n\nCloses https://github.com/elastic/kibana/issues/206392.\n\n---------\n\nCo-authored-by: Joe Reuter <johannes.reuter@elastic.co>","sha":"cefe0c823b5a84c0f008b8fb7c3779f17ae4c511","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor"],"title":"[Dataset quality] Authz migration","number":208343,"url":"https://github.com/elastic/kibana/pull/208343","mergeCommit":{"message":"[Dataset quality] Authz migration (#208343)\n\nCloses https://github.com/elastic/kibana/issues/206392.\n\n---------\n\nCo-authored-by: Joe Reuter <johannes.reuter@elastic.co>","sha":"cefe0c823b5a84c0f008b8fb7c3779f17ae4c511"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208343","number":208343,"mergeCommit":{"message":"[Dataset quality] Authz migration (#208343)\n\nCloses https://github.com/elastic/kibana/issues/206392.\n\n---------\n\nCo-authored-by: Joe Reuter <johannes.reuter@elastic.co>","sha":"cefe0c823b5a84c0f008b8fb7c3779f17ae4c511"}}]}] BACKPORT--> Co-authored-by: Yngrid Coello <yngrid.coello@elastic.co>
This commit is contained in:
parent
24f82ee808
commit
55de686094
5 changed files with 146 additions and 21 deletions
|
@ -32,6 +32,13 @@ const failedDocsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<{
|
||||
failedDocs: DataStreamDocsStat[];
|
||||
}> {
|
||||
|
@ -75,6 +82,13 @@ const failedDocsDetailsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<FailedDocsDetails> {
|
||||
const { context, params, getEsCapabilities } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
@ -106,6 +120,13 @@ const failedDocsErrorsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<FailedDocsErrorsResponse> {
|
||||
const { context, params, getEsCapabilities } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
|
|
@ -52,6 +52,13 @@ const statsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<{
|
||||
datasetUserPrivileges: DatasetUserPrivileges;
|
||||
dataStreamsStats: DataStreamStat[];
|
||||
|
@ -111,6 +118,13 @@ const degradedDocsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<{
|
||||
degradedDocs: DataStreamDocsStat[];
|
||||
}> {
|
||||
|
@ -138,6 +152,13 @@ const totalDocsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<{
|
||||
totalDocs: DataStreamDocsStat[];
|
||||
}> {
|
||||
|
@ -177,6 +198,13 @@ const nonAggregatableDatasetsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<NonAggregatableDatasets> {
|
||||
const { context, params } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
@ -201,6 +229,13 @@ const nonAggregatableDatasetRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<NonAggregatableDatasets> {
|
||||
const { context, params } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
@ -228,6 +263,13 @@ const degradedFieldsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DegradedFieldResponse> {
|
||||
const { context, params } = resources;
|
||||
const { dataStream } = params.path;
|
||||
|
@ -255,6 +297,13 @@ const degradedFieldValuesRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DegradedFieldValues> {
|
||||
const { context, params } = resources;
|
||||
const { dataStream, degradedField } = params.path;
|
||||
|
@ -280,6 +329,13 @@ const dataStreamSettingsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DataStreamSettings> {
|
||||
const { context, params } = resources;
|
||||
const { dataStream } = params.path;
|
||||
|
@ -307,8 +363,15 @@ const checkAndLoadIntegrationRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<CheckAndLoadIntegrationResponse> {
|
||||
const { context, params, plugins, logger } = resources;
|
||||
const { context, params, plugins, logger, request } = resources;
|
||||
const { dataStream } = params.path;
|
||||
const coreContext = await context.core;
|
||||
|
||||
|
@ -316,7 +379,7 @@ const checkAndLoadIntegrationRoute = createDatasetQualityServerRoute({
|
|||
const esClient = coreContext.elasticsearch.client.asCurrentUser;
|
||||
|
||||
const fleetPluginStart = await plugins.fleet.start();
|
||||
const packageClient = fleetPluginStart.packageService.asInternalUser;
|
||||
const packageClient = fleetPluginStart.packageService.asScoped(request);
|
||||
|
||||
const integration = await checkAndLoadIntegration({
|
||||
esClient,
|
||||
|
@ -340,6 +403,13 @@ const dataStreamDetailsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DataStreamDetails> {
|
||||
const { context, params, getEsCapabilities } = resources;
|
||||
const { dataStream } = params.path;
|
||||
|
@ -376,6 +446,13 @@ const analyzeDegradedFieldRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DegradedFieldAnalysis> {
|
||||
const { context, params } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
@ -405,6 +482,13 @@ const updateFieldLimitRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<UpdateFieldLimitResponse> {
|
||||
const { context, params } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
@ -430,6 +514,13 @@ const rolloverDataStream = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<DataStreamRolloverResponse> {
|
||||
const { context, params } = resources;
|
||||
const coreContext = await context.core;
|
||||
|
|
|
@ -16,13 +16,20 @@ const integrationsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<{
|
||||
integrations: IntegrationType[];
|
||||
}> {
|
||||
const { plugins, logger } = resources;
|
||||
const { plugins, logger, request } = resources;
|
||||
|
||||
const fleetPluginStart = await plugins.fleet.start();
|
||||
const packageClient = fleetPluginStart.packageService.asInternalUser;
|
||||
const packageClient = fleetPluginStart.packageService.asScoped(request);
|
||||
|
||||
const integrations = await getIntegrations({ packageClient, logger });
|
||||
|
||||
|
@ -40,13 +47,20 @@ const integrationDashboardsRoute = createDatasetQualityServerRoute({
|
|||
options: {
|
||||
tags: [],
|
||||
},
|
||||
security: {
|
||||
authz: {
|
||||
enabled: false,
|
||||
reason:
|
||||
'This API delegates security to the currently logged in user and their Elasticsearch permissions.',
|
||||
},
|
||||
},
|
||||
async handler(resources): Promise<IntegrationDashboardsResponse> {
|
||||
const { context, params, plugins } = resources;
|
||||
const { context, params, plugins, request } = resources;
|
||||
const { integration } = params.path;
|
||||
const { savedObjects } = await context.core;
|
||||
|
||||
const fleetPluginStart = await plugins.fleet.start();
|
||||
const packageClient = fleetPluginStart.packageService.asInternalUser;
|
||||
const packageClient = fleetPluginStart.packageService.asScoped(request);
|
||||
|
||||
const integrationDashboards = await getIntegrationDashboards(
|
||||
packageClient,
|
||||
|
|
|
@ -170,19 +170,12 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid
|
|||
await PageObjects.datasetQuality.navigateTo();
|
||||
});
|
||||
|
||||
it('"View dashboards" and "See integration" are hidden for underprivileged user', async () => {
|
||||
it('"View dashboards" is hidden for underprivileged user', async () => {
|
||||
await PageObjects.datasetQuality.navigateToDetails({
|
||||
dataStream: apacheAccessDataStreamName,
|
||||
});
|
||||
await PageObjects.datasetQuality.openIntegrationActionsMenu();
|
||||
|
||||
// "See Integration" is hidden
|
||||
await testSubjects.missingOrFail(
|
||||
PageObjects.datasetQuality.testSubjectSelectors.datasetQualityDetailsIntegrationAction(
|
||||
'Overview'
|
||||
)
|
||||
);
|
||||
|
||||
// "View Dashboards" is hidden
|
||||
await testSubjects.missingOrFail(
|
||||
PageObjects.datasetQuality.testSubjectSelectors.datasetQualityDetailsIntegrationAction(
|
||||
|
@ -217,7 +210,7 @@ async function createDatasetQualityUserWithRole(
|
|||
feature: {
|
||||
dataQuality: [hasDataQualityPrivileges ? 'all' : 'none'],
|
||||
discover: ['all'],
|
||||
fleet: ['none'],
|
||||
fleet: ['read'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
import { datasetNames, getInitialTestLogs, getLogsForDataset } from './data';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects([
|
||||
'common',
|
||||
'datasetQuality',
|
||||
|
@ -61,12 +62,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
it('shows poor, degraded and good count as 0 and all dataset as healthy', async () => {
|
||||
await PageObjects.datasetQuality.refreshTable();
|
||||
const summary = await PageObjects.datasetQuality.parseSummaryPanel(excludeKeysFromServerless);
|
||||
expect(summary).to.eql({
|
||||
datasetHealthPoor: '0',
|
||||
datasetHealthDegraded: '0',
|
||||
datasetHealthGood: '3',
|
||||
activeDatasets: '0 of 3',
|
||||
// Sometimes the summary flashes with wrong count, retry to stabilize. This should be fixed at the root, but for now we retry.
|
||||
await retry.try(async () => {
|
||||
const summary = await PageObjects.datasetQuality.parseSummaryPanel(
|
||||
excludeKeysFromServerless
|
||||
);
|
||||
expect(summary).to.eql({
|
||||
datasetHealthPoor: '0',
|
||||
datasetHealthDegraded: '0',
|
||||
datasetHealthGood: '3',
|
||||
activeDatasets: '0 of 3',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue