deepmerge in merging apm-configuration (#179048)

We faced an issue where APM global labels sourced from the kibana
configuration were overriden when `ELASTIC_APM_GLOBAL_LABELS` was set in
the run-time.

I suspect this is due to the fact hat the use a shallow merge at this
point,
and the labels are nested inside both configuration (
`configFromKibanaConfig`, and `configFromEnv` ).
```
config =  Object {
         ...
         "globalLabels": Object {
                ....
         },
         ...
}
```

Didn't set up my IDE to actually test this. But added a unit test which
will hopefully give some feedback

---------

Co-authored-by: Jean-Louis Leysens <jloleysens@gmail.com>
This commit is contained in:
Ramon Butter 2024-03-21 18:39:47 +01:00 committed by GitHub
parent 386c29094d
commit 771d97e8b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 3 deletions

View file

@ -7,9 +7,9 @@
*/
import type { AgentConfigOptions, Labels } from 'elastic-apm-node';
import {
packageMock,
mockedRootDir,
gitRevExecMock,
mockedRootDir,
packageMock,
readUuidFileMock,
resetAllMocks,
} from './config.test.mocks';
@ -152,6 +152,7 @@ describe('ApmConfiguration', () => {
delete process.env.ELASTIC_APM_SECRET_TOKEN;
delete process.env.ELASTIC_APM_API_KEY;
delete process.env.ELASTIC_APM_SERVER_URL;
delete process.env.ELASTIC_APM_GLOBAL_LABELS;
delete process.env.NODE_ENV;
});
@ -184,6 +185,21 @@ describe('ApmConfiguration', () => {
})
);
});
it('ELASTIC_APM_GLOBAL_LABELS', () => {
process.env.ELASTIC_APM_GLOBAL_LABELS = 'test1=1,test2=2';
const config = new ApmConfiguration(mockedRootDir, {}, true);
expect(config.getConfig('serviceName')).toEqual(
expect.objectContaining({
globalLabels: {
git_rev: 'sha',
test1: '1',
test2: '2',
},
})
);
});
});
it('does not override the environment from NODE_ENV if already set in the config file', () => {

View file

@ -7,6 +7,7 @@
*/
import { join } from 'path';
import deepmerge from 'deepmerge';
import { merge } from 'lodash';
import { execSync } from 'child_process';
import { getDataPath } from '@kbn/utils';
@ -295,7 +296,10 @@ export class ApmConfiguration {
const { servicesOverrides, redactUsers, ...configFromKibanaConfig } =
this.getConfigFromKibanaConfig();
const configFromEnv = this.getConfigFromEnv(configFromKibanaConfig);
const config = merge({}, configFromKibanaConfig, configFromEnv);
const config = [configFromKibanaConfig, configFromEnv].reduce<AgentConfigOptions>(
(acc, conf) => deepmerge(acc, conf),
{}
);
if (config.active === false && config.contextPropagationOnly !== false) {
throw new Error(