Skip to content

Commit

Permalink
[APM] Diagnostics: Add support for cloudId and apiKey (#160959)
Browse files Browse the repository at this point in the history
Adds support for cloud id and api key:

```
node ./x-pack/plugins/apm/scripts/create_diagnostics_bundle.js \
  --cloudId mydeployment:ZXVyb3BlLXdlc3QyLmdjcC5lbGFzdGljLWNsb3VkLmNvbTo0NDMkYWJjZGVmZyRoaWprbG1u \
  --apiKey foobarbaz
```

It is still possible to use username, password and host urls
```
node ./x-pack/plugins/apm/scripts/create_diagnostics_bundle.js \
  --kbHost https://mydeployment.kb.europe-west2.gcp.elastic-cloud.com:9243 \
  --esHost https://mydeployment.es.europe-west2.gcp.elastic-cloud.com:9243 \
  --username elastic \
  --password very_secret
```
  • Loading branch information
sorenlouv authored and bryce-b committed Aug 22, 2023
1 parent d64b73f commit 510ca4a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 13 deletions.
41 changes: 35 additions & 6 deletions x-pack/plugins/apm/scripts/diagnostics_bundle/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,34 @@
/* eslint-disable no-console */

import datemath from '@elastic/datemath';
import { errors } from '@elastic/elasticsearch';
import { AxiosError } from 'axios';
import yargs from 'yargs';
import { initDiagnosticsBundle } from './diagnostics_bundle';

const { argv } = yargs(process.argv.slice(2))
.option('esHost', {
demandOption: true,
type: 'string',
description: 'Elasticsearch host name',
})
.option('kbHost', {
demandOption: true,
type: 'string',
description: 'Kibana host name',
})
.option('username', {
demandOption: true,
type: 'string',
description: 'Kibana host name',
})
.option('password', {
demandOption: true,
type: 'string',
description: 'Kibana host name',
})
.option('cloudId', {
type: 'string',
})
.option('apiKey', {
type: 'string',
})
.option('rangeFrom', {
type: 'string',
description: 'Time-range start',
Expand All @@ -48,10 +52,20 @@ const { argv } = yargs(process.argv.slice(2))
})
.help();

const { esHost, kbHost, password, username, kuery } = argv;
const { esHost, kbHost, password, username, kuery, apiKey, cloudId } = argv;
const rangeFrom = argv.rangeFrom as unknown as number;
const rangeTo = argv.rangeTo as unknown as number;

if ((!esHost || !kbHost) && !cloudId) {
console.error('Either esHost and kbHost or cloudId must be provided');
process.exit(1);
}

if ((!username || !password) && !apiKey) {
console.error('Either username and password or apiKey must be provided');
process.exit(1);
}

if (rangeFrom) {
console.log(`rangeFrom = ${new Date(rangeFrom).toISOString()}`);
}
Expand All @@ -64,6 +78,8 @@ initDiagnosticsBundle({
esHost,
kbHost,
password,
apiKey,
cloudId,
username,
start: rangeFrom,
end: rangeTo,
Expand All @@ -73,7 +89,20 @@ initDiagnosticsBundle({
console.log(res);
})
.catch((err) => {
console.log(err);
process.exitCode = 1;
if (err instanceof AxiosError && err.response?.data) {
console.error(err.response.data);
return;
}

// @ts-expect-error
if (err instanceof errors.ResponseError && err.meta.body.error.reason) {
// @ts-expect-error
console.error(err.meta.body.error.reason);
return;
}

console.error(err);
});

function convertDate(dateString: string): number {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,43 @@ type DiagnosticsBundle = APIReturnType<'GET /internal/apm/diagnostics'>;
export async function initDiagnosticsBundle({
esHost,
kbHost,
cloudId,
username,
password,
apiKey,
start,
end,
kuery,
}: {
esHost: string;
kbHost: string;
username: string;
password: string;
esHost?: string;
kbHost?: string;
cloudId?: string;
start: number | undefined;
end: number | undefined;
kuery: string | undefined;
username?: string;
password?: string;
apiKey?: string;
}) {
const esClient = new Client({ node: esHost, auth: { username, password } });
const auth = username && password ? { username, password } : undefined;
const apiKeyHeader = apiKey ? { Authorization: `ApiKey ${apiKey}` } : {};
const { kibanaHost } = parseCloudId(cloudId);

const esClient = new Client({
...(esHost ? { node: esHost } : {}),
...(cloudId ? { cloud: { id: cloudId } } : {}),
auth,
headers: { ...apiKeyHeader },
});

const kibanaClient = axios.create({
baseURL: kbHost,
auth: { username, password },
baseURL: kbHost ?? kibanaHost,
auth,
// @ts-expect-error
headers: { 'kbn-xsrf': 'true', ...apiKeyHeader },
});
const apmIndices = await getApmIndices(kibanaClient);

const bundle = await getDiagnosticsBundle({
esClient,
apmIndices,
Expand Down Expand Up @@ -99,3 +115,19 @@ async function getKibanaVersion(kibanaClient: AxiosInstance) {
const res = await kibanaClient.get('/api/status');
return res.data.version.number;
}

function parseCloudId(cloudId?: string) {
if (!cloudId) {
return {};
}

const [instanceAlias, encodedString] = cloudId.split(':');
const decodedString = Buffer.from(encodedString, 'base64').toString('utf8');
const [hostname, esId, kbId] = decodedString.split('$');

return {
kibanaHost: `https://${kbId}.${hostname}`,
esHost: `https://${esId}.${hostname}`,
instanceAlias,
};
}

0 comments on commit 510ca4a

Please sign in to comment.