Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Synthetics] add synthetics-private-location command #189531

Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8070ae3
add synthetics-private-location command
dominiqueclarke Jul 30, 2024
0a41e97
create synthetics private location
dominiqueclarke Jul 30, 2024
d6e008e
add kibana api client
dominiqueclarke Jul 31, 2024
7bee085
dynamically fetch version
dominiqueclarke Jul 31, 2024
206792e
update constants
dominiqueclarke Jul 31, 2024
ec87de6
add README
dominiqueclarke Jul 31, 2024
70e1138
Delete unintended file
dominiqueclarke Jul 31, 2024
db39747
update CODEOWNERS
dominiqueclarke Jul 31, 2024
8fe4e46
Merge branch 'chore/synthetics-private-locations-automation' of githu…
dominiqueclarke Jul 31, 2024
e75e728
Update packages/kbn-synthetics-private-location/src/lib/generate_flee…
dominiqueclarke Jul 31, 2024
f349279
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jul 31, 2024
13b156b
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Jul 31, 2024
b02bcd6
Update .github/CODEOWNERS
dominiqueclarke Jul 31, 2024
a65d819
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Jul 31, 2024
2550202
Merge branch 'main' into chore/synthetics-private-locations-automation
dominiqueclarke Jul 31, 2024
11caa5b
Merge branch 'main' of https://github.com/elastic/kibana into chore/s…
dominiqueclarke Jul 31, 2024
5682e31
spawn Sync
dominiqueclarke Aug 1, 2024
ebef5fc
Merge branch 'chore/synthetics-private-locations-automation' of githu…
dominiqueclarke Aug 1, 2024
58fcd1d
Merge branch 'main' into chore/synthetics-private-locations-automation
dominiqueclarke Aug 5, 2024
cdb5ba6
Merge branch 'main' into chore/synthetics-private-locations-automation
dominiqueclarke Aug 7, 2024
893b588
Update .github/CODEOWNERS
shahzad31 Aug 8, 2024
39e0982
Update packages/kbn-synthetics-private-location/kibana.jsonc
shahzad31 Aug 8, 2024
11c420f
move directory
dominiqueclarke Aug 8, 2024
79207ca
remove docker compose
dominiqueclarke Aug 8, 2024
60c9ee2
Merge branch 'chore/synthetics-private-locations-automation' of githu…
dominiqueclarke Aug 8, 2024
dab1c7f
Update .github/CODEOWNERS
dominiqueclarke Aug 8, 2024
718c8a6
Update x-pack/packages/kbn-synthetics-private-location/tsconfig.json
dominiqueclarke Aug 8, 2024
319e3b4
[CI] Auto-commit changed files from 'node scripts/lint_packages --fix'
kibanamachine Aug 8, 2024
a07f193
Update x-pack/packages/kbn-synthetics-private-location/jest.config.js
dominiqueclarke Aug 9, 2024
6caa260
Update x-pack/packages/kbn-synthetics-private-location/jest.config.js
dominiqueclarke Aug 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ packages/kbn-stdio-dev-helpers @elastic/kibana-operations
packages/kbn-storybook @elastic/kibana-operations
x-pack/plugins/observability_solution/synthetics/e2e @elastic/obs-ux-management-team
x-pack/plugins/observability_solution/synthetics @elastic/obs-ux-management-team
x-pack/packages/kbn-synthetics-private-location @elastic/obs-ux-management-team
x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture @elastic/response-ops
x-pack/test/plugin_api_perf/plugins/task_manager_performance @elastic/response-ops
x-pack/plugins/task_manager @elastic/response-ops
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@
"@kbn/status-plugin-b-plugin": "link:test/server_integration/plugins/status_plugin_b",
"@kbn/std": "link:packages/kbn-std",
"@kbn/synthetics-plugin": "link:x-pack/plugins/observability_solution/synthetics",
"@kbn/synthetics-private-location": "link:x-pack/packages/kbn-synthetics-private-location",
"@kbn/task-manager-fixture-plugin": "link:x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture",
"@kbn/task-manager-performance-plugin": "link:x-pack/test/plugin_api_perf/plugins/task_manager_performance",
"@kbn/task-manager-plugin": "link:x-pack/plugins/task_manager",
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,8 @@
"@kbn/synthetics-e2e/*": ["x-pack/plugins/observability_solution/synthetics/e2e/*"],
"@kbn/synthetics-plugin": ["x-pack/plugins/observability_solution/synthetics"],
"@kbn/synthetics-plugin/*": ["x-pack/plugins/observability_solution/synthetics/*"],
"@kbn/synthetics-private-location": ["x-pack/packages/kbn-synthetics-private-location"],
"@kbn/synthetics-private-location/*": ["x-pack/packages/kbn-synthetics-private-location/*"],
"@kbn/task-manager-fixture-plugin": ["x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture"],
"@kbn/task-manager-fixture-plugin/*": ["x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture/*"],
"@kbn/task-manager-performance-plugin": ["x-pack/test/plugin_api_perf/plugins/task_manager_performance"],
Expand Down
56 changes: 56 additions & 0 deletions x-pack/packages/kbn-synthetics-private-location/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# @kbn/synthetics-private-location

Quickily start Fleet, enroll Elastic Agent, and create a private location.

## Usage

```
node x-pack/scripts/synthetics_private_location.js
```

For available options, run `--help`.

## Prerequistes

This script requires `docker` and the following `kibama.yml` configuration.

```
# Create an agent policy for Fleet Server.
xpack.fleet.agentPolicies:
- name: Fleet Server policy
id: fleet-server-policy
is_default_fleet_server: true
# is_managed: true # Useful to mimic cloud environment
description: Fleet server policy
namespace: default
package_policies:
- name: Fleet Server
package:
name: fleet_server
inputs:
- type: fleet-server
keep_enabled: true
vars:
- name: host
value: 0.0.0.0
frozen: true
- name: port
value: 8220
frozen: true

# Set a default Fleet Server host.
xpack.fleet.fleetServerHosts:
- id: default-fleet-server
name: Default Fleet server
is_default: true
host_urls: ['https://host.docker.internal:8220'] # For running a Fleet Server Docker container

# Set a default Elasticsearch output.
xpack.fleet.outputs:
- id: es-default-output
name: Default output
type: elasticsearch
is_default: true
is_default_monitoring: true
hosts: ['http://host.docker.internal:9200'] # For enrolling dockerized agents
```
12 changes: 12 additions & 0 deletions x-pack/packages/kbn-synthetics-private-location/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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.
*/

export type { CliOptions } from './src/types';
export { run } from './src/run';
export { cli } from './src/cli';
// export { cleanup } from './src/cleanup';
export { DEFAULTS } from './src/constants';
12 changes: 12 additions & 0 deletions x-pack/packages/kbn-synthetics-private-location/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../..',
dominiqueclarke marked this conversation as resolved.
Show resolved Hide resolved
roots: ['<rootDir>/x-pack/packages/kbn-synthetics-private-location'],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/synthetics-private-location",
"owner": "@elastic/obs-ux-management-team"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@kbn/synthetics-private-location",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0"
}
17 changes: 17 additions & 0 deletions x-pack/packages/kbn-synthetics-private-location/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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 { ToolingLog } from '@kbn/tooling-log';
import { parseCliOptions } from './lib/parse_cli_options';
import { CliOptions } from './types';
import { run } from './run';

export async function cli(cliOptions?: CliOptions) {
const options = cliOptions ?? parseCliOptions();
const logger = new ToolingLog({ level: 'info', writeTo: process.stdout });
return run(options, logger);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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 { v4 as uuidv4 } from 'uuid';

export const DEFAULTS = {
LOCATION_NAME: `Default location ${uuidv4()}`,
AGENT_POLICY_NAME: `Synthetics agent policy ${uuidv4()}`,
ELASTICSEARCH_HOST: 'http://localhost:9200',
KIBANA_URL: 'http://localhost:5601',
KIBANA_USERNAME: 'elastic',
KIBANA_PASSWORD: 'changeme',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 { isError } from 'lodash';
import { ToolingLog } from '@kbn/tooling-log';
import { CliOptions } from '../types';
import type { KibanaAPIClient } from './kibana_api_client';

export async function createElasticAgentPolicy(
{ agentPolicyName }: CliOptions,
logger: ToolingLog,
kibanaApiClient: KibanaAPIClient
) {
try {
const response = await kibanaApiClient.sendRequest({
method: 'post',
url: 'api/fleet/agent_policies',
data: {
name: agentPolicyName,
description: '',
namespace: 'default',
monitoring_enabled: ['logs', 'metrics'],
inactivity_timeout: 1209600,
is_protected: false,
},
});

logger.info(`Generated elastic agent policy`);
return response.data;
} catch (error) {
if (isError(error)) {
logger.error(`Error generating elastic agent policy: ${error.message} ${error.stack}`);
}
throw error;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 { isError } from 'lodash';
import { ToolingLog } from '@kbn/tooling-log';
import { CliOptions } from '../types';
import { KibanaAPIClient } from './kibana_api_client';

export async function createPrivateLocation(
{ kibanaUrl, kibanaPassword, kibanaUsername, locationName }: CliOptions,
logger: ToolingLog,
kibanaApiClient: KibanaAPIClient,
agentPolicyId: string
) {
try {
const response = await kibanaApiClient.sendRequest({
method: 'post',
url: 'api/synthetics/private_locations',
data: {
label: locationName,
agentPolicyId,
},
});

logger.info(`Synthetics private location created successfully`);
return response.data;
} catch (error) {
if (isError(error)) {
logger.error(`Error creating synthetics private location: ${error.message} ${error.stack}`);
}
throw error;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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 { spawn, spawnSync } from 'child_process';
import * as path from 'path';
import { CliOptions } from '../types';
import { KibanaAPIClient } from './kibana_api_client';

export async function enrollAgent(
{ kibanaUrl, elasticsearchHost }: CliOptions,
enrollmentToken: string,
kibanaApiClient: KibanaAPIClient
) {
const formattedKibanaURL = new URL(kibanaUrl);
const formattedElasticsearchHost = new URL(elasticsearchHost);
if (formattedKibanaURL.hostname === 'localhost') {
formattedKibanaURL.hostname = 'host.docker.internal';
}
if (formattedElasticsearchHost.hostname === 'localhost') {
formattedElasticsearchHost.hostname = 'host.docker.internal';
}
const version = `${await kibanaApiClient.getKibanaVersion()}-SNAPSHOT`;
await new Promise((res, rej) => {
try {
const fleetProcess = spawn(
'docker',
[
'run',
'-e',
'FLEET_SERVER_ENABLE=1',
'-e',
`FLEET_SERVER_ELASTICSEARCH_HOST=${formattedElasticsearchHost.origin}`,
'-e',
'FLEET_SERVER_POLICY_ID=fleet-server-policy',
'-e',
'FLEET_INSECURE=1',
'-e',
`KIBANA_HOST=${formattedKibanaURL.origin}`,
'-e',
'KIBANA_USERNAME=elastic',
'-e',
'KIBANA_PASSWORD=changeme',
'-e',
'KIBANA_FLEET_SETUP=1',
'-p',
'8220:8220',
'--rm',
`docker.elastic.co/beats/elastic-agent:${version}`,
],
{
shell: true,
cwd: path.join(__dirname, '../'),
timeout: 120000,
}
);
setTimeout(res, 10_000);
fleetProcess.on('error', rej);
} catch (error) {
rej(error);
}
});

spawnSync(
'docker',
[
'run',
'-e',
'FLEET_URL=https://host.docker.internal:8220',
'-e',
'FLEET_ENROLL=1',
'-e',
`FLEET_ENROLLMENT_TOKEN=${enrollmentToken}`,
'-e',
'FLEET_INSECURE=1',
'--rm',
`docker.elastic.co/beats/elastic-agent-complete:${version}`,
],
{
stdio: 'inherit',
}
);
}
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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isError } from 'lodash';
import { ToolingLog } from '@kbn/tooling-log';
import { KibanaAPIClient } from './kibana_api_client';
import { CliOptions } from '../types';

export async function fetchAgentPolicyEnrollmentToken(
{ kibanaUrl, kibanaPassword, kibanaUsername }: CliOptions,
logger: ToolingLog,
kibanaApiClient: KibanaAPIClient,
agentPolicyId: string
) {
try {
const response = await kibanaApiClient.sendRequest({
method: 'get',
url: `api/fleet/enrollment_api_keys?kuery=policy_id:${agentPolicyId}`,
});

logger.info(`Fetching agent policy enrollment token`);
return response.data;
} catch (error) {
if (isError(error)) {
logger.error(`Error fetching agent enrollment token: ${error.message} ${error.stack}`);
}
throw error;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 { isError } from 'lodash';
import { ToolingLog } from '@kbn/tooling-log';
import { CliOptions } from '../types';
import { KibanaAPIClient } from './kibana_api_client';

export async function generateFleetServiceToken(
{ kibanaUrl, kibanaPassword, kibanaUsername }: CliOptions,
logger: ToolingLog,
kibanaApiClient: KibanaAPIClient
) {
try {
const response = await kibanaApiClient.sendRequest({
method: 'post',
url: 'api/fleet/service_tokens',
});

logger.info(`Generated fleet server service token saved`);
return response.data;
} catch (error) {
if (isError(error)) {
logger.error(`Error generating fleet server service token: ${error.message} ${error.stack}`);
}
throw error;
}
}
Loading