fix(agent): silence unchanged remote config refreshes

This commit is contained in:
pulse-triage[bot] 2026-08-28 21:56:26 +01:00
parent 47afce8171
commit 5570ac1e2e
3 changed files with 69 additions and 10 deletions

View file

@ -6690,6 +6690,17 @@ cleared rather than read as already-consumed, so a fresh token minted after
removal always re-enrolls the host instead of rejecting its reports
indefinitely with 400s that no reinstall can escape (#1772).
### Remote configuration refreshes are transition-quiet
The Unified Agent polls its authoritative remote configuration every minute,
but an unchanged response is reconciliation rather than an operator event.
Repeated values for the host report interval, report-IP override, Ceph
collection setting, availability assignments, and command-execution state
must not reset schedules, restart command clients, or emit info-level journal
entries. Actual state transitions and malformed or failed refreshes remain
visible at their existing levels. This keeps managed agents quiet during
healthy steady-state operation without hiding configuration changes or faults.
### Agent token issuance and revocation remain continuous across persistence failure
An operator-created API token carrying agent authority, including the shared

View file

@ -1444,28 +1444,40 @@ func (a *Agent) ApplyRemoteConfig(settings map[string]interface{}, commandsEnabl
a.configMu.Lock()
if a.interval != interval {
intervalChanged = true
a.interval = interval
a.cfg.Interval = interval
}
a.interval = interval
a.cfg.Interval = interval
a.configMu.Unlock()
if intervalChanged {
a.signalRemoteConfigChanged()
a.logger.Info().Dur("interval", interval).Msg("Applied remote host report interval")
}
a.logger.Info().Dur("interval", interval).Msg("Applied remote host report interval")
}
if reportIP, ok := remoteStringSetting(settings, "report_ip"); ok {
trimmedReportIP := strings.TrimSpace(reportIP)
reportIPChanged := false
a.configMu.Lock()
a.reportIP = trimmedReportIP
a.cfg.ReportIP = trimmedReportIP
if a.reportIP != trimmedReportIP {
reportIPChanged = true
a.reportIP = trimmedReportIP
a.cfg.ReportIP = trimmedReportIP
}
a.configMu.Unlock()
a.logger.Info().Str("report_ip", trimmedReportIP).Msg("Applied remote host report IP override")
if reportIPChanged {
a.logger.Info().Str("report_ip", trimmedReportIP).Msg("Applied remote host report IP override")
}
}
if disableCeph, ok := remoteBoolSetting(settings, "disable_ceph"); ok {
disableCephChanged := false
a.configMu.Lock()
a.cfg.DisableCeph = disableCeph
if a.cfg.DisableCeph != disableCeph {
disableCephChanged = true
a.cfg.DisableCeph = disableCeph
}
a.configMu.Unlock()
a.logger.Info().Bool("disable_ceph", disableCeph).Msg("Applied remote Ceph collection setting")
if disableCephChanged {
a.logger.Info().Bool("disable_ceph", disableCeph).Msg("Applied remote Ceph collection setting")
}
}
a.applyRemoteAvailabilityTargets(settings)
if remoteConfigAppliedWithoutRestart(settings) && remoteconfig.HasAppliedDesiredConfig(commandsEnabled, settings) {
@ -1528,8 +1540,6 @@ func (a *Agent) applyRemoteConfig(commandsEnabled bool) {
case commandsEnabled && !currentlyEnabled:
clientToStart = a.newCommandClient(commandCfg, a.agentID, a.hostname, a.platform, a.agentVersion)
a.commandClient = clientToStart
case commandsEnabled && currentlyEnabled:
clientToStart = a.commandClient
case !commandsEnabled && currentlyEnabled:
shouldStop = true
}

View file

@ -1,6 +1,7 @@
package hostagent
import (
"bytes"
"context"
"crypto/tls"
"errors"
@ -572,6 +573,43 @@ func TestAgentApplyRemoteConfigKeepsPriorFingerprintWhenRestartIsRequired(t *tes
}
}
func TestAgentApplyRemoteConfigDoesNotLogUnchangedSettings(t *testing.T) {
var logs bytes.Buffer
logger := zerolog.New(&logs).Level(zerolog.InfoLevel)
commandClient := &CommandClient{}
commandsEnabled := true
agent := &Agent{
cfg: Config{
EnableCommands: true,
Interval: 30 * time.Second,
ReportIP: "192.0.2.20",
DisableCeph: true,
},
interval: 30 * time.Second,
reportIP: "192.0.2.20",
remoteConfigChanged: make(chan struct{}, 1),
logger: logger,
commandClient: commandClient,
}
settings := map[string]interface{}{
"interval": "30s",
"report_ip": "192.0.2.20",
"disable_ceph": true,
}
agent.ApplyRemoteConfig(settings, &commandsEnabled)
agent.ApplyRemoteConfig(settings, &commandsEnabled)
if logs.Len() != 0 {
t.Fatalf("unchanged remote config emitted info logs: %s", logs.String())
}
select {
case <-agent.remoteConfigChanged:
t.Fatal("unchanged interval signaled a report-loop reset")
default:
}
}
func TestNewRejectsInvalidDeploySSHUser(t *testing.T) {
mc := &mockCollector{
hostInfoFn: func(context.Context) (*gohost.InfoStat, error) {