mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-19 10:33:29 +00:00
fix(agent): silence unchanged remote config refreshes
This commit is contained in:
parent
47afce8171
commit
5570ac1e2e
3 changed files with 69 additions and 10 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue