Skip to content

Commit 5a58740

Browse files
wip
1 parent f3b4eec commit 5a58740

File tree

3 files changed

+137
-1
lines changed

3 files changed

+137
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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: feature
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Send fleet-server component output under bootstrap key
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+
Alter the fleet-server bootstrap component modifier to insert all (elasticsearch)
21+
output configuration options specified by enrollment args under a new elasticsearch.boostrap key
22+
instead of overwriting any existing keys. This will allow elastic-agent to send the list of hosts
23+
(and other config options) retrieved from a policy to fleet server as well as the config needed
24+
to form the initial connection to elasticsearch used to collect policy information.
25+
Fleet-server will be altered to use the bootstrap config that is passed if the policy attributes
26+
are unspecified or fail.
27+
28+
# Affected component; a word indicating the component this changeset affects.
29+
component:
30+
31+
# PR URL; optional; the PR number that added the changeset.
32+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
33+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
34+
# Please provide it if you are adding a fragment for a different PR.
35+
#pr: https://github.com/owner/repo/1234
36+
37+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
38+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
39+
issue: 2784

internal/pkg/agent/application/fleet_server_bootstrap.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,13 @@ func FleetServerComponentModifier(serverCfg *configuration.FleetServerConfig) co
6565
} else {
6666
for j, unit := range comp.Units {
6767
if unit.Type == client.UnitTypeOutput && unit.Config.Type == elasticsearch {
68-
unitCfgMap, err := toMapStr(unit.Config.Source.AsMap(), &serverCfg.Output.Elasticsearch)
68+
unitCfgMap, err := toMapStr(unit.Config.Source.AsMap())
6969
if err != nil {
7070
return nil, err
7171
}
72+
if err := addBootstrapCfg(unitCfgMap, &serverCfg.Output.Elasticsearch); err != nil {
73+
return nil, err
74+
}
7275
fixOutputMap(unitCfgMap)
7376
unitCfg, err := component.ExpectedConfig(unitCfgMap)
7477
if err != nil {
@@ -100,6 +103,19 @@ func FleetServerComponentModifier(serverCfg *configuration.FleetServerConfig) co
100103
}
101104
}
102105

106+
// addBootrapCfg will transform the passed configuration.Elasticsearch to a map and add it to dst under the bootstrap key.
107+
func addBootstrapCfg(dst map[string]interface{}, es *configuration.Elasticsearch) error {
108+
if es == nil {
109+
return fmt.Errorf("fleet-server bootstrap output config is undefined")
110+
}
111+
mp, err := toMapStr(es)
112+
if err != nil {
113+
return err
114+
}
115+
dst["bootstrap"] = mp
116+
return nil
117+
}
118+
103119
// InjectFleetConfigComponentModifier The modifier that injects the fleet configuration for the components
104120
// that need to be able to connect to fleet server.
105121
func InjectFleetConfigComponentModifier(fleetCfg *configuration.FleetAgentConfig, agentInfo info.Agent) coordinator.ComponentsModifier {

internal/pkg/agent/application/fleet_server_bootstrap_test.go

+81
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,87 @@ func TestFleetServerComponentModifier_NoServerConfig(t *testing.T) {
7474
}
7575
}
7676

77+
func TestFleetServerComponentModifier(t *testing.T) {
78+
tests := []struct {
79+
name string
80+
source map[string]interface{}
81+
expect map[string]interface{}
82+
}{{
83+
name: "empty output component",
84+
source: map[string]interface{}{},
85+
expect: map[string]interface{}{
86+
"bootstrap": map[string]interface{}{
87+
"protocol": "https",
88+
"hosts": []interface{}{"elasticsearch:9200"},
89+
"service_token": "example-token",
90+
},
91+
},
92+
}, {
93+
name: "output component provided",
94+
source: map[string]interface{}{
95+
"protocol": "http",
96+
"hosts": []interface{}{"elasticsearch:9200", "host:9200"},
97+
},
98+
expect: map[string]interface{}{
99+
"protocol": "http",
100+
"hosts": []interface{}{"elasticsearch:9200", "host:9200"},
101+
"bootstrap": map[string]interface{}{
102+
"protocol": "https",
103+
"hosts": []interface{}{"elasticsearch:9200"},
104+
"service_token": "example-token",
105+
},
106+
},
107+
}}
108+
cfg := &configuration.FleetServerConfig{
109+
Output: configuration.FleetServerOutputConfig{
110+
Elasticsearch: configuration.Elasticsearch{
111+
Protocol: "https",
112+
Hosts: []string{"elasticsearch:9200"},
113+
ServiceToken: "example-token",
114+
},
115+
},
116+
}
117+
modifier := FleetServerComponentModifier(cfg)
118+
119+
for _, tc := range tests {
120+
t.Run(tc.name, func(t *testing.T) {
121+
src, err := structpb.NewStruct(tc.source)
122+
require.NoError(t, err)
123+
comps, err := modifier([]component.Component{{
124+
InputSpec: &component.InputRuntimeSpec{
125+
InputType: "fleet-server",
126+
},
127+
Units: []component.Unit{{
128+
Type: client.UnitTypeOutput,
129+
Config: &proto.UnitExpectedConfig{
130+
Type: "elasticsearch",
131+
Source: src,
132+
},
133+
}},
134+
}}, nil)
135+
require.NoError(t, err)
136+
137+
require.Len(t, comps, 1)
138+
require.Len(t, comps[0].Units, 1)
139+
res := comps[0].Units[0].Config.Source.AsMap()
140+
for k, v := range tc.expect {
141+
val, ok := res[k]
142+
require.Truef(t, ok, "expected %q to be in output unit config", k)
143+
if mp, ok := v.(map[string]interface{}); ok {
144+
rMap, ok := val.(map[string]interface{})
145+
require.Truef(t, ok, "expected %q to be map[string]interface{} was %T", k, val)
146+
for kk, vv := range mp {
147+
assert.Contains(t, rMap, kk)
148+
assert.Equal(t, rMap[kk], vv)
149+
}
150+
} else {
151+
assert.Equal(t, v, val)
152+
}
153+
}
154+
})
155+
}
156+
}
157+
77158
func TestInjectFleetConfigComponentModifier(t *testing.T) {
78159
fleetConfig := &configuration.FleetAgentConfig{
79160
Enabled: true,

0 commit comments

Comments
 (0)