Skip to content

Commit 80c29c0

Browse files
authored
Upgrader applies agent.download.proxy_url on policy update (elastic#3803)
The Upgrader now applies the whole artifact.Config on Upgrader.Reload
1 parent 092d205 commit 80c29c0

File tree

5 files changed

+130
-26
lines changed

5 files changed

+130
-26
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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: bug-fix
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Fixes the Elastic Agent ignoring agent.download.proxy_url on policy update
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+
21+
# Affected component; a word indicating the component this changeset affects.
22+
component: Upgrader
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
#pr: https://github.com/owner/repo/1234
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
issue: https://github.com/elastic/elastic-agent/issues/3560

internal/pkg/agent/application/upgrade/step_download.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ func (u *Upgrader) downloadWithRetries(
257257
}
258258

259259
opFailureNotificationFn := func(err error, retryAfter time.Duration) {
260-
u.log.Warnf("%s; retrying (will be retry %d) in %s.", err.Error(), attempt, retryAfter)
260+
u.log.Warnf("download attempt %d failed: %s; retrying in %s.",
261+
attempt, err.Error(), retryAfter)
261262
}
262263

263264
if err := backoff.RetryNotify(opFn, boCtx, opFailureNotificationFn); err != nil {

internal/pkg/agent/application/upgrade/step_download_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func TestDownloadWithRetries(t *testing.T) {
139139
logs := obs.TakeAll()
140140
require.Len(t, logs, 3)
141141
require.Equal(t, "download attempt 1", logs[0].Message)
142-
require.Contains(t, logs[1].Message, "unable to create fetcher: failed to construct downloader; retrying (will be retry 1)")
142+
require.Contains(t, logs[1].Message, "unable to create fetcher: failed to construct downloader")
143143
require.Equal(t, "download attempt 2", logs[2].Message)
144144
})
145145

@@ -178,7 +178,7 @@ func TestDownloadWithRetries(t *testing.T) {
178178
logs := obs.TakeAll()
179179
require.Len(t, logs, 3)
180180
require.Equal(t, "download attempt 1", logs[0].Message)
181-
require.Contains(t, logs[1].Message, "unable to download package: download failed; retrying (will be retry 1)")
181+
require.Contains(t, logs[1].Message, "unable to download package: download failed; retrying")
182182
require.Equal(t, "download attempt 2", logs[2].Message)
183183
})
184184

@@ -207,7 +207,7 @@ func TestDownloadWithRetries(t *testing.T) {
207207
require.GreaterOrEqual(t, len(logs), minNmExpectedAttempts*2)
208208
for i := 0; i < minNmExpectedAttempts; i++ {
209209
require.Equal(t, fmt.Sprintf("download attempt %d", i+1), logs[(2*i)].Message)
210-
require.Contains(t, logs[(2*i+1)].Message, fmt.Sprintf("unable to download package: download failed; retrying (will be retry %d)", i+1))
210+
require.Contains(t, logs[(2*i+1)].Message, "unable to download package: download failed; retrying")
211211
}
212212
})
213213
}

internal/pkg/agent/application/upgrade/upgrade.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec"
2121
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
2222
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details"
23+
"github.com/elastic/elastic-agent/internal/pkg/agent/configuration"
2324
"github.com/elastic/elastic-agent/internal/pkg/agent/errors"
2425
"github.com/elastic/elastic-agent/internal/pkg/agent/install"
2526
"github.com/elastic/elastic-agent/internal/pkg/config"
@@ -89,35 +90,39 @@ func (u *Upgrader) SetClient(c fleetclient.Sender) {
8990

9091
// Reload reloads the artifact configuration for the upgrader.
9192
func (u *Upgrader) Reload(rawConfig *config.Config) error {
92-
type reloadConfig struct {
93-
// SourceURI: source of the artifacts, e.g https://artifacts.elastic.co/downloads/
94-
SourceURI string `json:"agent.download.sourceURI" config:"agent.download.sourceURI"`
93+
cfg, err := configuration.NewFromConfig(rawConfig)
94+
if err != nil {
95+
return fmt.Errorf("invalid config: %w", err)
96+
}
9597

96-
// FleetSourceURI: source of the artifacts, e.g https://artifacts.elastic.co/downloads/ coming from fleet which uses
97-
// different naming.
98+
// the source URI coming from fleet which uses a different naming.
99+
type fleetCfg struct {
100+
// FleetSourceURI: source of the artifacts, e.g https://artifacts.elastic.co/downloads/
98101
FleetSourceURI string `json:"agent.download.source_uri" config:"agent.download.source_uri"`
99102
}
100-
cfg := &reloadConfig{}
101-
if err := rawConfig.Unpack(&cfg); err != nil {
103+
fleetSourceURI := &fleetCfg{}
104+
if err := rawConfig.Unpack(&fleetSourceURI); err != nil {
102105
return errors.New(err, "failed to unpack config during reload")
103106
}
104107

105-
var newSourceURI string
106-
if cfg.FleetSourceURI != "" {
107-
// fleet configuration takes precedence
108-
newSourceURI = cfg.FleetSourceURI
109-
} else if cfg.SourceURI != "" {
110-
newSourceURI = cfg.SourceURI
108+
// fleet configuration takes precedence
109+
if fleetSourceURI.FleetSourceURI != "" {
110+
cfg.Settings.DownloadConfig.SourceURI = fleetSourceURI.FleetSourceURI
111111
}
112112

113-
if newSourceURI != "" {
114-
u.log.Infof("Source URI changed from %q to %q", u.settings.SourceURI, newSourceURI)
115-
u.settings.SourceURI = newSourceURI
113+
if cfg.Settings.DownloadConfig.SourceURI != "" {
114+
u.log.Infof("Source URI changed from %q to %q",
115+
u.settings.SourceURI,
116+
cfg.Settings.DownloadConfig.SourceURI)
116117
} else {
117118
// source uri unset, reset to default
118-
u.log.Infof("Source URI reset from %q to %q", u.settings.SourceURI, artifact.DefaultSourceURI)
119-
u.settings.SourceURI = artifact.DefaultSourceURI
119+
u.log.Infof("Source URI reset from %q to %q",
120+
u.settings.SourceURI,
121+
artifact.DefaultSourceURI)
122+
cfg.Settings.DownloadConfig.SourceURI = artifact.DefaultSourceURI
120123
}
124+
125+
u.settings = cfg.Settings.DownloadConfig
121126
return nil
122127
}
123128

internal/pkg/agent/application/upgrade/upgrade_test.go

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ import (
1414
"strings"
1515
"testing"
1616

17-
"github.com/elastic/elastic-agent/pkg/control/v2/client"
18-
"github.com/elastic/elastic-agent/pkg/control/v2/client/mocks"
19-
"github.com/elastic/elastic-agent/pkg/control/v2/cproto"
20-
2117
"github.com/gofrs/flock"
18+
"github.com/stretchr/testify/assert"
2219
"github.com/stretchr/testify/require"
2320

21+
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
2422
"github.com/elastic/elastic-agent/internal/pkg/agent/errors"
23+
"github.com/elastic/elastic-agent/internal/pkg/config"
2524
"github.com/elastic/elastic-agent/internal/pkg/release"
25+
"github.com/elastic/elastic-agent/pkg/control/v2/client"
26+
"github.com/elastic/elastic-agent/pkg/control/v2/client/mocks"
27+
"github.com/elastic/elastic-agent/pkg/control/v2/cproto"
2628
"github.com/elastic/elastic-agent/pkg/core/logger"
2729
)
2830

@@ -209,3 +211,67 @@ func TestIsInProgress(t *testing.T) {
209211
})
210212
}
211213
}
214+
215+
func TestUpgraderReload(t *testing.T) {
216+
defaultCfg := artifact.DefaultConfig()
217+
tcs := []struct {
218+
name string
219+
sourceURL string
220+
proxyURL string
221+
cfg string
222+
}{
223+
{
224+
name: "proxy_url is applied",
225+
sourceURL: defaultCfg.SourceURI,
226+
proxyURL: "http://someBrokenURL/",
227+
cfg: `
228+
agent.download:
229+
proxy_url: http://someBrokenURL/
230+
`,
231+
},
232+
{
233+
name: "source_uri has precedence over sourceURI",
234+
sourceURL: "https://this.sourceURI.co/downloads/beats/",
235+
cfg: `
236+
agent.download:
237+
source_uri: "https://this.sourceURI.co/downloads/beats/"
238+
sourceURI: "https://NOT.sourceURI.co/downloads/beats/"
239+
`}, {
240+
name: "only sourceURI",
241+
sourceURL: "https://this.sourceURI.co/downloads/beats/",
242+
cfg: `
243+
agent.download:
244+
sourceURI: "https://this.sourceURI.co/downloads/beats/"
245+
`}, {
246+
name: "only source_uri",
247+
sourceURL: "https://this.sourceURI.co/downloads/beats/",
248+
cfg: `
249+
agent.download:
250+
source_uri: "https://this.sourceURI.co/downloads/beats/"
251+
`},
252+
}
253+
254+
for _, tc := range tcs {
255+
t.Run(tc.name, func(t *testing.T) {
256+
log, _ := logger.NewTesting("")
257+
258+
u := Upgrader{
259+
log: log,
260+
settings: artifact.DefaultConfig(),
261+
}
262+
263+
cfg, err := config.NewConfigFrom(tc.cfg)
264+
require.NoError(t, err, "failed to create new config")
265+
266+
err = u.Reload(cfg)
267+
require.NoError(t, err, "error reloading config")
268+
269+
assert.Equal(t, tc.sourceURL, u.settings.SourceURI)
270+
if tc.proxyURL != "" {
271+
require.NotNilf(t, u.settings.Proxy.URL,
272+
"ProxyURI should not be nil, want %s", tc.proxyURL)
273+
assert.Equal(t, tc.proxyURL, u.settings.Proxy.URL.String())
274+
}
275+
})
276+
}
277+
}

0 commit comments

Comments
 (0)