Skip to content

Commit

Permalink
Merge branch 'main' into 207322_fleet_server_hosts_ssl_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Mar 3, 2025
2 parents e173ae1 + 3fc5022 commit 1da08c6
Show file tree
Hide file tree
Showing 99 changed files with 1,824 additions and 1,582 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,7 @@
"fetch-mock": "^10.1.0",
"file-loader": "^4.2.0",
"find-cypress-specs": "^1.41.4",
"form-data": "^4.0.1",
"form-data": "^4.0.2",
"geckodriver": "^5.0.0",
"gulp-brotli": "^3.0.0",
"gulp-postcss": "^9.0.1",
Expand Down
5 changes: 0 additions & 5 deletions src/platform/packages/shared/deeplinks/security/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ export enum SecurityPageName {
cloudSecurityPostureDashboard = 'cloud_security_posture-dashboard',
cloudSecurityPostureFindings = 'cloud_security_posture-findings',
cloudSecurityPostureRules = 'cloud_security_posture-rules',
/*
* Warning: Computed values are not permitted in an enum with string valued members
* All cloud defend page names must match `CloudDefendPageId` in x-pack/solutions/security/plugins/cloud_defend/public/common/navigation/types.ts
*/
cloudDefend = 'cloud_defend',
cloudDefendPolicies = 'cloud_defend-policies',
dashboards = 'dashboards',
dataQuality = 'data_quality',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/

import { createEsClientForTesting, KbnClient } from '@kbn/test';
import { ToolingLog } from '@kbn/tooling-log';
import { ScoutLogger } from './logger';
import { ScoutTestConfig, EsClient } from '../../types';

Expand All @@ -17,25 +16,23 @@ interface ClientOptions {
url: string;
username: string;
password: string;
log: ScoutLogger | ToolingLog;
log: ScoutLogger;
}

function createClientUrlWithAuth({ serviceName, url, username, password, log }: ClientOptions) {
const clientUrl = new URL(url);
clientUrl.username = username;
clientUrl.password = password;

if (log instanceof ScoutLogger) {
log.serviceLoaded(`${serviceName}Client`);
}
log.serviceLoaded(`${serviceName}Client`);

return clientUrl.toString();
}

let esClientInstance: EsClient | null = null;
let kbnClientInstance: KbnClient | null = null;

export function getEsClient(config: ScoutTestConfig, log: ScoutLogger | ToolingLog) {
export function getEsClient(config: ScoutTestConfig, log: ScoutLogger) {
if (!esClientInstance) {
const { username, password } = config.auth;
const elasticsearchUrl = createClientUrlWithAuth({
Expand Down
14 changes: 13 additions & 1 deletion src/platform/packages/shared/kbn-scout/src/common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,19 @@ export async function silence(log: ToolingLog, milliseconds: number) {
await Rx.firstValueFrom(
log.getWritten$().pipe(
Rx.startWith(null),
Rx.switchMap(() => Rx.timer(milliseconds))
Rx.switchMap((message) => {
if (
// TODO: remove workaround to ignore ES authc debug logs for stateful run
message?.args[0]?.includes(
'Authentication of [kibana_system] using realm [reserved/reserved]'
) ||
message?.args[0]?.includes('realm [reserved] authenticated user [kibana_system]')
) {
return Rx.of(null);
} else {
return Rx.timer(milliseconds);
}
})
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import type { ToolingLog } from '@kbn/tooling-log';
import { REPO_ROOT } from '@kbn/repo-info';
import type { ArtifactLicense, ServerlessProjectType } from '@kbn/es';
import { isServerlessProjectType } from '@kbn/es/src/utils';
import { createTestEsCluster, esTestConfig, cleanupElasticsearch } from '@kbn/test';
import {
createTestEsCluster,
esTestConfig,
cleanupElasticsearch,
createEsClientForTesting,
} from '@kbn/test';
import { Config } from '../config';

interface RunElasticsearchOptions {
Expand Down Expand Up @@ -81,6 +86,27 @@ export async function runElasticsearch(
logsDir,
config,
});

// TODO: Remove this once we find out why SAML callback randomly fails with 401
log.info('Enable authc debug logs for ES');
const clientUrl = new URL(
Url.format({
protocol: options.config.get('servers.elasticsearch.protocol'),
hostname: options.config.get('servers.elasticsearch.hostname'),
port: options.config.get('servers.elasticsearch.port'),
})
);
clientUrl.username = options.config.get('servers.kibana.username');
clientUrl.password = options.config.get('servers.kibana.password');
const esClient = createEsClientForTesting({
esUrl: clientUrl.toString(),
});
await esClient.cluster.putSettings({
persistent: {
'logger.org.elasticsearch.xpack.security.authc': 'debug',
},
});

return async () => {
await cleanupElasticsearch(node, config.serverless, logsDir, log);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { runElasticsearch } from './run_elasticsearch';
import { getExtraKbnOpts, runKibanaServer } from './run_kibana_server';
import { StartServerOptions } from './flags';
import { loadServersConfig } from '../config';
import { getEsClient, silence } from '../common';
import { silence } from '../common';

export async function startServers(log: ToolingLog, options: StartServerOptions) {
const runStartTime = Date.now();
Expand All @@ -32,14 +32,6 @@ export async function startServers(log: ToolingLog, options: StartServerOptions)
logsDir: options.logsDir,
});

log.info('Enable authc debug logs for ES');
const client = getEsClient(config.getScoutTestConfig(), log);
await client.cluster.putSettings({
persistent: {
'logger.org.elasticsearch.xpack.security.authc': 'debug',
},
});

await runKibanaServer({
procs,
config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export const createLegacyUrlForwardApp = (
forwards: ForwardDefinition[]
): App => ({
id: 'kibana',
chromeless: true,
title: 'Legacy URL migration',
appRoute: '/app/kibana#/',
visibleIn: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import * as React from 'react';
import useObservable from 'react-use/lib/useObservable';

import { EuiPageTemplate } from '@elastic/eui';
import { EuiPageTemplate, EuiDelayRender } from '@elastic/eui';
import type { CustomBrandingSetup } from '@kbn/core-custom-branding-browser';
import type { ChromeDocTitle, ThemeServiceSetup } from '@kbn/core/public';
import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme';
Expand Down Expand Up @@ -42,7 +42,7 @@ export const Page: React.FC<PageProps> = ({
if (error) {
return (
<KibanaThemeProvider {...startServices}>
<EuiPageTemplate>
<EuiPageTemplate minHeight={0} offset={0}>
<RedirectEmptyPrompt docTitle={docTitle} error={error} homeHref={homeHref} />
</EuiPageTemplate>
</KibanaThemeProvider>
Expand All @@ -51,9 +51,11 @@ export const Page: React.FC<PageProps> = ({

return (
<KibanaThemeProvider {...startServices}>
<EuiPageTemplate>
<Spinner showPlainSpinner={Boolean(hasCustomBranding)} />
</EuiPageTemplate>
<EuiDelayRender>
<EuiPageTemplate minHeight={0} offset={0}>
<Spinner showPlainSpinner={Boolean(hasCustomBranding)} />
</EuiPageTemplate>
</EuiDelayRender>
</KibanaThemeProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ export class RedirectManager {
application.register({
id: 'r',
title: 'Redirect endpoint',
chromeless: true,
visibleIn: [],
mount: async (params) => {
const abortController = new AbortController();
this.onMount(params.history.location, abortController.signal);

const { render } = await import('./render');
const [start] = await core.getStartServices();
const { chrome, uiSettings, userProfile } = start;
Expand All @@ -50,9 +53,8 @@ export class RedirectManager {
homeHref: getHomeHref(http, uiSettings),
});

this.onMount(params.history.location);

return () => {
abortController.abort();
unmount();
};
},
Expand Down Expand Up @@ -92,29 +94,35 @@ export class RedirectManager {
});
}

public onMount(location: Location) {
public onMount(location: Location, abortSignal?: AbortSignal) {
const pathname = location.pathname;
const isShortUrlRedirectBySlug = pathname.startsWith('/s/');
if (isShortUrlRedirectBySlug) {
this.navigateToShortUrlBySlug(pathname.substring('/s/'.length));
this.navigateToShortUrlBySlug(pathname.substring('/s/'.length), abortSignal);
return;
}
const urlLocationSearch = location.search;
const options = this.parseSearchParams(urlLocationSearch);
this.navigate(options);
}

private navigateToShortUrlBySlug(slug: string) {
private navigateToShortUrlBySlug(slug: string, abortSignal?: AbortSignal) {
(async () => {
const urlService = this.deps.url;
const shortUrls = urlService.shortUrls.get(null);
const shortUrl = await shortUrls.resolve(slug);

if (abortSignal?.aborted)
return; /* it means that the user navigated away before the short url resolved */

const locatorId = shortUrl.data.locator.id;
const locator = urlService.locators.get(locatorId);
if (!locator) throw new Error(`Locator "${locatorId}" not found.`);
const locatorState = shortUrl.data.locator.state;
await locator.navigate(locatorState, { replace: true });
})().catch((error) => {
if (abortSignal?.aborted) return;

this.error$.next(error);
// eslint-disable-next-line no-console
console.error(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33936,7 +33936,6 @@
"xpack.securitySolution.appLinks.category.entityAnalytics": "Analyse des entités",
"xpack.securitySolution.appLinks.category.investigations": "Investigations",
"xpack.securitySolution.appLinks.category.management": "Gestion",
"xpack.securitySolution.appLinks.cloudDefendPoliciesDescription": "Sécurisez les charges de travail conteneurisées dans Kubernetes contre les attaques et les dérives grâce à des politiques d'exécution granulaires et flexibles.",
"xpack.securitySolution.appLinks.cloudSecurityPostureBenchmarksDescription": "Voir les règles de benchmark pour la gestion du niveau de sécurité du cloud.",
"xpack.securitySolution.appLinks.cloudSecurityPostureDashboardDescription": "Un aperçu des résultats de toutes les intégrations CSP.",
"xpack.securitySolution.appLinks.coverageOverviewDashboard": "Couverture MITRE ATT&CK",
Expand Down Expand Up @@ -38327,8 +38326,6 @@
"xpack.securitySolution.navigation.rules": "Règles",
"xpack.securitySolution.navigation.timelines": "Chronologies",
"xpack.securitySolution.navigation.users": "Utilisateurs",
"xpack.securitySolution.navLinks.assets.cloud_defend.description": "Hôtes du cloud exécutant Elastic Defend",
"xpack.securitySolution.navLinks.assets.cloud_defend.title": "Cloud",
"xpack.securitySolution.navLinks.assets.fleet.agents.title": "Agents",
"xpack.securitySolution.navLinks.assets.fleet.dataStreams.title": "Flux de données",
"xpack.securitySolution.navLinks.assets.fleet.description": "Gestion centralisée des agents Elastic Agent",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33798,7 +33798,6 @@
"xpack.securitySolution.appLinks.category.entityAnalytics": "エンティティ分析",
"xpack.securitySolution.appLinks.category.investigations": "調査",
"xpack.securitySolution.appLinks.category.management": "管理",
"xpack.securitySolution.appLinks.cloudDefendPoliciesDescription": "粒度の高い柔軟なランタイムポリシーによって、Kubernetesのコンテナーワークロードを攻撃とドリフトから保護します。",
"xpack.securitySolution.appLinks.cloudSecurityPostureBenchmarksDescription": "Cloud Security Posture Managementのベンチマークルールを表示します。",
"xpack.securitySolution.appLinks.cloudSecurityPostureDashboardDescription": "すべてのCSP統合の結果の概要。",
"xpack.securitySolution.appLinks.coverageOverviewDashboard": "MITRE ATT&CKの範囲",
Expand Down Expand Up @@ -38188,8 +38187,6 @@
"xpack.securitySolution.navigation.rules": "ルール",
"xpack.securitySolution.navigation.timelines": "タイムライン",
"xpack.securitySolution.navigation.users": "ユーザー",
"xpack.securitySolution.navLinks.assets.cloud_defend.description": "Elastic Defendを実行しているクラウドホスト",
"xpack.securitySolution.navLinks.assets.cloud_defend.title": "クラウド",
"xpack.securitySolution.navLinks.assets.fleet.agents.title": "エージェント",
"xpack.securitySolution.navLinks.assets.fleet.dataStreams.title": "データストリーム",
"xpack.securitySolution.navLinks.assets.fleet.description": "ElasticElasticエージェントの集中管理",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33274,7 +33274,6 @@
"xpack.securitySolution.appLinks.category.entityAnalytics": "实体分析",
"xpack.securitySolution.appLinks.category.investigations": "调查",
"xpack.securitySolution.appLinks.category.management": "管理",
"xpack.securitySolution.appLinks.cloudDefendPoliciesDescription": "通过细粒度、灵活的运行时策略保护 Kubernetes 中的容器工作负载,使其免于受到攻击和出现漂移。",
"xpack.securitySolution.appLinks.cloudSecurityPostureBenchmarksDescription": "查看用于云安全态势管理的基准规则。",
"xpack.securitySolution.appLinks.cloudSecurityPostureDashboardDescription": "所有 CSP 集成中的结果概述。",
"xpack.securitySolution.appLinks.coverageOverviewDashboard": "MITRE ATT&CK 支持",
Expand Down Expand Up @@ -37623,8 +37622,6 @@
"xpack.securitySolution.navigation.rules": "规则",
"xpack.securitySolution.navigation.timelines": "时间线",
"xpack.securitySolution.navigation.users": "用户",
"xpack.securitySolution.navLinks.assets.cloud_defend.description": "运行 Elastic Defend 的云主机",
"xpack.securitySolution.navLinks.assets.cloud_defend.title": "云",
"xpack.securitySolution.navLinks.assets.fleet.agents.title": "代理",
"xpack.securitySolution.navLinks.assets.fleet.dataStreams.title": "数据流",
"xpack.securitySolution.navLinks.assets.fleet.description": "Elastic 代理的集中管理",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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 { waitFor, renderHook } from '@testing-library/react';

import { AppMockRenderer, createAppMockRenderer } from '../lib/test_utils';
import { useDeleteMaintenanceWindow } from './use_delete_maintenance_window';

const mockAddDanger = jest.fn();
const mockAddSuccess = jest.fn();

jest.mock('../utils/kibana_react', () => {
const originalModule = jest.requireActual('../utils/kibana_react');
return {
...originalModule,
useKibana: () => {
const { services } = originalModule.useKibana();
return {
services: {
...services,
notifications: { toasts: { addSuccess: mockAddSuccess, addDanger: mockAddDanger } },
},
};
},
};
});
jest.mock('../services/maintenance_windows_api/delete', () => ({
deleteMaintenanceWindow: jest.fn(),
}));

const { deleteMaintenanceWindow } = jest.requireMock('../services/maintenance_windows_api/delete');

let appMockRenderer: AppMockRenderer;

describe('useDeleteMaintenanceWindow', () => {
beforeEach(() => {
jest.clearAllMocks();

appMockRenderer = createAppMockRenderer();
});

it('should call onSuccess if api succeeds', async () => {
const { result } = renderHook(() => useDeleteMaintenanceWindow(), {
wrapper: appMockRenderer.AppWrapper,
});

result.current.mutate({ maintenanceWindowId: '123' });

await waitFor(() => expect(mockAddSuccess).toBeCalledWith('Deleted maintenance window'));
});

it('should call onError if api fails', async () => {
deleteMaintenanceWindow.mockRejectedValue('');

const { result } = renderHook(() => useDeleteMaintenanceWindow(), {
wrapper: appMockRenderer.AppWrapper,
});

result.current.mutate({ maintenanceWindowId: '123' });

await waitFor(() =>
expect(mockAddDanger).toBeCalledWith('Failed to delete maintenance window.')
);
});
});
Loading

0 comments on commit 1da08c6

Please sign in to comment.