mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Fleet] Configure fleet default output on prem with ES host and CA fingerprint (#120276)
This commit is contained in:
parent
4436b267b7
commit
265c8dcd43
2 changed files with 78 additions and 1 deletions
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
jest.mock('fs/promises');
|
||||
jest.mock('crypto');
|
||||
import { constants } from 'fs';
|
||||
|
||||
import { loggingSystemMock } from 'src/core/server/mocks';
|
||||
|
@ -28,6 +29,16 @@ describe('KibanaConfigWriter', () => {
|
|||
|
||||
mockReadFile.mockResolvedValue('');
|
||||
|
||||
const mockCrypto = jest.requireMock('crypto');
|
||||
mockCrypto.X509Certificate = function (cert: string) {
|
||||
if (cert === 'invalid-cert') {
|
||||
throw new Error('Invalid certificate');
|
||||
}
|
||||
return {
|
||||
fingerprint256: 'fingerprint256',
|
||||
};
|
||||
};
|
||||
|
||||
kibanaConfigWriter = new KibanaConfigWriter(
|
||||
'/some/path/kibana.yml',
|
||||
'/data',
|
||||
|
@ -120,6 +131,7 @@ describe('KibanaConfigWriter', () => {
|
|||
elasticsearch.hosts: [some-host]
|
||||
elasticsearch.serviceAccountToken: some-value
|
||||
elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt]
|
||||
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: [some-host], ca_sha256: fingerprint256}]
|
||||
|
||||
",
|
||||
],
|
||||
|
@ -186,6 +198,7 @@ describe('KibanaConfigWriter', () => {
|
|||
elasticsearch.username: username
|
||||
elasticsearch.password: password
|
||||
elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt]
|
||||
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: [some-host], ca_sha256: fingerprint256}]
|
||||
|
||||
",
|
||||
],
|
||||
|
@ -193,6 +206,18 @@ describe('KibanaConfigWriter', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('throws if it cannot parse CA certificate', async () => {
|
||||
await expect(
|
||||
kibanaConfigWriter.writeConfig({
|
||||
caCert: 'invalid-cert',
|
||||
host: 'some-host',
|
||||
serviceAccountToken: { name: 'some-token', value: 'some-value' },
|
||||
})
|
||||
).rejects.toMatchInlineSnapshot(`[Error: Invalid certificate]`);
|
||||
|
||||
expect(mockWriteFile).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('can successfully write elasticsearch config without CA certificate', async () => {
|
||||
await expect(
|
||||
kibanaConfigWriter.writeConfig({
|
||||
|
@ -250,6 +275,7 @@ describe('KibanaConfigWriter', () => {
|
|||
elasticsearch.hosts: [some-host]
|
||||
elasticsearch.serviceAccountToken: some-value
|
||||
elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt]
|
||||
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: [some-host], ca_sha256: fingerprint256}]
|
||||
|
||||
",
|
||||
],
|
||||
|
@ -303,6 +329,7 @@ describe('KibanaConfigWriter', () => {
|
|||
monitoring.ui.container.elasticsearch.enabled: true
|
||||
elasticsearch.serviceAccountToken: some-value
|
||||
elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt]
|
||||
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: [some-host], ca_sha256: fingerprint256}]
|
||||
|
||||
",
|
||||
],
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { X509Certificate } from 'crypto';
|
||||
import { constants } from 'fs';
|
||||
import fs from 'fs/promises';
|
||||
import yaml from 'js-yaml';
|
||||
|
@ -30,6 +31,16 @@ export type WriteConfigParameters = {
|
|||
| {}
|
||||
);
|
||||
|
||||
interface FleetOutputConfig {
|
||||
id: string;
|
||||
name: string;
|
||||
is_default: boolean;
|
||||
is_default_monitoring: boolean;
|
||||
type: 'elasticsearch';
|
||||
hosts: string[];
|
||||
ca_sha256: string;
|
||||
}
|
||||
|
||||
export class KibanaConfigWriter {
|
||||
constructor(
|
||||
private readonly configPath: string,
|
||||
|
@ -61,7 +72,9 @@ export class KibanaConfigWriter {
|
|||
*/
|
||||
public async writeConfig(params: WriteConfigParameters) {
|
||||
const caPath = path.join(this.dataDirectoryPath, `ca_${Date.now()}.crt`);
|
||||
const config: Record<string, string | string[]> = { 'elasticsearch.hosts': [params.host] };
|
||||
const config: Record<string, string | string[] | FleetOutputConfig[]> = {
|
||||
'elasticsearch.hosts': [params.host],
|
||||
};
|
||||
if ('serviceAccountToken' in params && params.serviceAccountToken) {
|
||||
config['elasticsearch.serviceAccountToken'] = params.serviceAccountToken.value;
|
||||
} else if ('username' in params && params.username) {
|
||||
|
@ -72,6 +85,21 @@ export class KibanaConfigWriter {
|
|||
config['elasticsearch.ssl.certificateAuthorities'] = [caPath];
|
||||
}
|
||||
|
||||
// If a certificate is passed configure Fleet default output
|
||||
if (params.caCert) {
|
||||
try {
|
||||
config['xpack.fleet.outputs'] = KibanaConfigWriter.getFleetDefaultOutputConfig(
|
||||
params.caCert,
|
||||
params.host
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error(
|
||||
`Failed to generate Fleet default output: ${getDetailedErrorMessage(err)}.`
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Load and parse existing configuration file to check if it already has values for the config
|
||||
// entries we want to write.
|
||||
const existingConfig = await this.loadAndParseKibanaConfig();
|
||||
|
@ -152,6 +180,28 @@ export class KibanaConfigWriter {
|
|||
return { raw: rawConfig, parsed: parsedConfig };
|
||||
}
|
||||
|
||||
/**
|
||||
* Build config for Fleet outputs
|
||||
* @param caCert
|
||||
* @param host
|
||||
*/
|
||||
private static getFleetDefaultOutputConfig(caCert: string, host: string): FleetOutputConfig[] {
|
||||
const cert = new X509Certificate(caCert);
|
||||
const certFingerprint = cert.fingerprint256;
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'fleet-default-output',
|
||||
name: 'default',
|
||||
is_default: true,
|
||||
is_default_monitoring: true,
|
||||
type: 'elasticsearch',
|
||||
hosts: [host],
|
||||
ca_sha256: certFingerprint,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Comments out all non-commented entries in the Kibana configuration file.
|
||||
* @param rawConfig Content of the Kibana configuration file.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue