Skip to content

Commit d16a665

Browse files
Consume APMConfig from input units in agent mode (#3277)
* Consume APMConfig from input units in agent mode Consume and prefer APMConfig from the expected input component while operating in agent mode over config in inputs[0].server.instrumentation. --------- Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
1 parent 726a74f commit d16a665

File tree

3 files changed

+388
-6
lines changed

3 files changed

+388
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: enhancement
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Prefer elastic-agent-client APMConfig in agent mode
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
description: |
20+
While running in agent-mode fleet-server will use the APMConfig
21+
settings of expected input if it's set over the settings in
22+
inputs[0].server.instrumentation; this should make it easier for
23+
managing agents to inject APM config data.
24+
25+
# Affected component; a word indicating the component this changeset affects.
26+
component:
27+
28+
# PR URL; optional; the PR number that added the changeset.
29+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
30+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
31+
# Please provide it if you are adding a fragment for a different PR.
32+
pr: 3277
33+
34+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
35+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
36+
issue: 2868

internal/pkg/server/agent.go

+48-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/rs/zerolog"
2121

2222
"github.com/elastic/elastic-agent-client/v7/pkg/client"
23+
"github.com/elastic/elastic-agent-client/v7/pkg/proto"
2324
"github.com/elastic/go-ucfg"
2425
"gopkg.in/yaml.v3"
2526
)
@@ -285,7 +286,7 @@ func (a *Agent) start(ctx context.Context) error {
285286
return a.reconfigure(ctx)
286287
}
287288

288-
cfg, err := a.configFromUnits()
289+
cfg, err := a.configFromUnits(ctx)
289290
if err != nil {
290291
return err
291292
}
@@ -331,7 +332,7 @@ func (a *Agent) reconfigure(ctx context.Context) error {
331332
return a.start(ctx)
332333
}
333334

334-
cfg, err := a.configFromUnits()
335+
cfg, err := a.configFromUnits(ctx)
335336
if err != nil {
336337
return err
337338
}
@@ -373,7 +374,7 @@ func (a *Agent) stop() {
373374

374375
// configFromUnits takes both inputUnit and outputUnit and creates a single configuration just like fleet server was
375376
// being started from a configuration file.
376-
func (a *Agent) configFromUnits() (*config.Config, error) {
377+
func (a *Agent) configFromUnits(ctx context.Context) (*config.Config, error) {
377378
agentID := ""
378379
agentVersion := ""
379380
agentInfo := a.agent.AgentInfo()
@@ -420,10 +421,54 @@ func (a *Agent) configFromUnits() (*config.Config, error) {
420421
return nil, err
421422
}
422423

424+
if expAPMCFG := expInput.APMConfig; expAPMCFG != nil {
425+
instrumentationCfg, err := apmConfigToInstrumentation(expAPMCFG)
426+
if err != nil {
427+
zerolog.Ctx(ctx).Warn().Err(err).Msg("Unable to parse expected APM config as instrumentation config")
428+
} else {
429+
obj := map[string]interface{}{
430+
"inputs": []interface{}{map[string]interface{}{
431+
"server": map[string]interface{}{
432+
"instrumentation": instrumentationCfg,
433+
},
434+
},
435+
}}
436+
err = cfgData.Merge(obj, config.DefaultOptions...)
437+
if err != nil {
438+
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to merge APM config into cfgData")
439+
}
440+
}
441+
442+
}
443+
423444
cliCfg := ucfg.MustNewFrom(a.cliCfg, config.DefaultOptions...)
424445
err = cliCfg.Merge(cfgData, config.DefaultOptions...)
425446
if err != nil {
426447
return nil, err
427448
}
428449
return config.FromConfig(cliCfg)
429450
}
451+
452+
// apmConfigToInstrumentation transforms the passed APMConfig into the Instrumentation config that is used by fleet-server.
453+
func apmConfigToInstrumentation(src *proto.APMConfig) (config.Instrumentation, error) {
454+
if apmest := src.GetElastic(); apmest != nil {
455+
apmTLS := apmest.GetTls()
456+
iTLS := config.InstrumentationTLS{
457+
SkipVerify: apmTLS.GetSkipVerify(),
458+
ServerCertificate: apmTLS.GetServerCert(),
459+
ServerCA: apmTLS.GetServerCa(),
460+
}
461+
462+
cfg := config.Instrumentation{
463+
Enabled: true,
464+
TLS: iTLS,
465+
Environment: apmest.GetEnvironment(),
466+
APIKey: apmest.GetApiKey(),
467+
SecretToken: apmest.GetSecretToken(),
468+
Hosts: apmest.GetHosts(),
469+
GlobalLabels: apmest.GetGlobalLabels(),
470+
}
471+
return cfg, nil
472+
}
473+
return config.Instrumentation{}, fmt.Errorf("unable to transform APMConfig to instrumentation")
474+
}

0 commit comments

Comments
 (0)