feat: add reporting config with reload (#16890)
This commit is contained in:
parent
c4d27e436e
commit
c8d21de074
|
@ -1499,7 +1499,10 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co
|
|||
cfg.RequestLimitsWriteRate = runtimeCfg.RequestLimitsWriteRate
|
||||
cfg.Locality = runtimeCfg.StructLocality()
|
||||
|
||||
cfg.Reporting.License.Enabled = runtimeCfg.Reporting.License.Enabled
|
||||
|
||||
enterpriseConsulConfig(cfg, runtimeCfg)
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
@ -4187,6 +4190,11 @@ func (a *Agent) reloadConfigInternal(newCfg *config.RuntimeConfig) error {
|
|||
HeartbeatTimeout: newCfg.ConsulRaftHeartbeatTimeout,
|
||||
ElectionTimeout: newCfg.ConsulRaftElectionTimeout,
|
||||
RaftTrailingLogs: newCfg.RaftTrailingLogs,
|
||||
Reporting: consul.Reporting{
|
||||
License: consul.License{
|
||||
Enabled: newCfg.Reporting.License.Enabled,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := a.delegate.ReloadConfig(cc); err != nil {
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//go:build !consulent
|
||||
// +build !consulent
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAgent_consulConfig_Reporting(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
hcl := `
|
||||
reporting {
|
||||
license {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
`
|
||||
a := NewTestAgent(t, hcl)
|
||||
defer a.Shutdown()
|
||||
require.Equal(t, false, a.consulConfig().Reporting.License.Enabled)
|
||||
}
|
||||
|
||||
func TestAgent_consulConfig_Reporting_Default(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
hcl := `
|
||||
reporting {
|
||||
}
|
||||
`
|
||||
a := NewTestAgent(t, hcl)
|
||||
defer a.Shutdown()
|
||||
require.Equal(t, false, a.consulConfig().Reporting.License.Enabled)
|
||||
}
|
|
@ -60,6 +60,10 @@ func validateEnterpriseConfigKeys(config *Config) []error {
|
|||
add("license_path")
|
||||
config.LicensePath = nil
|
||||
}
|
||||
if config.Reporting.License.Enabled != nil {
|
||||
add("reporting.license.enabled")
|
||||
config.Reporting.License.Enabled = nil
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -110,6 +110,19 @@ func TestValidateEnterpriseConfigKeys(t *testing.T) {
|
|||
require.Empty(t, c.LicensePath)
|
||||
},
|
||||
},
|
||||
"reporting.license.enabled": {
|
||||
config: Config{
|
||||
Reporting: Reporting{
|
||||
License: License{
|
||||
Enabled: &boolVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
badKeys: []string{"reporting.license.enabled"},
|
||||
check: func(t *testing.T, c *Config) {
|
||||
require.Nil(t, c.Reporting.License.Enabled)
|
||||
},
|
||||
},
|
||||
"multi": {
|
||||
config: Config{
|
||||
ReadReplica: &boolVal,
|
||||
|
|
|
@ -295,6 +295,9 @@ type Config struct {
|
|||
LicensePollMaxTime *string `mapstructure:"license_poll_max_time" json:"-"`
|
||||
LicenseUpdateBaseTime *string `mapstructure:"license_update_base_time" json:"-"`
|
||||
LicenseUpdateMaxTime *string `mapstructure:"license_update_max_time" json:"-"`
|
||||
|
||||
// license reporting
|
||||
Reporting Reporting `mapstructure:"reporting" json:"-"`
|
||||
}
|
||||
|
||||
type GossipLANConfig struct {
|
||||
|
@ -956,3 +959,11 @@ type RaftBoltDBConfigRaw struct {
|
|||
type RaftWALConfigRaw struct {
|
||||
SegmentSizeMB *int `mapstructure:"segment_size_mb" json:"segment_size_mb,omitempty"`
|
||||
}
|
||||
|
||||
type License struct {
|
||||
Enabled *bool `mapstructure:"enabled"`
|
||||
}
|
||||
|
||||
type Reporting struct {
|
||||
License License `mapstructure:"license"`
|
||||
}
|
||||
|
|
|
@ -1484,9 +1484,19 @@ type RuntimeConfig struct {
|
|||
// here so that tests can use a smaller value.
|
||||
LocalProxyConfigResyncInterval time.Duration
|
||||
|
||||
Reporting ReportingConfig
|
||||
|
||||
EnterpriseRuntimeConfig
|
||||
}
|
||||
|
||||
type LicenseConfig struct {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
type ReportingConfig struct {
|
||||
License LicenseConfig
|
||||
}
|
||||
|
||||
type AutoConfig struct {
|
||||
Enabled bool
|
||||
IntroToken string
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var testRuntimeConfigSanitizeExpectedFilename = "TestRuntimeConfig_Sanitize.golden"
|
||||
|
@ -31,6 +32,7 @@ var enterpriseConfigKeyWarnings = []string{
|
|||
enterpriseConfigKeyError{key: "acl.msp_disable_bootstrap"}.Error(),
|
||||
enterpriseConfigKeyError{key: "acl.tokens.managed_service_provider"}.Error(),
|
||||
enterpriseConfigKeyError{key: "audit"}.Error(),
|
||||
enterpriseConfigKeyError{key: "reporting.license.enabled"}.Error(),
|
||||
}
|
||||
|
||||
// OSS-only equivalent of TestConfigFlagsAndEdgecases
|
||||
|
@ -87,3 +89,82 @@ func TestLoad_IntegrationWithFlags_OSS(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_ReportingConfig(t *testing.T) {
|
||||
dir := testutil.TempDir(t, t.Name())
|
||||
|
||||
t.Run("load from JSON defaults to false", func(t *testing.T) {
|
||||
content := `{
|
||||
"reporting": {}
|
||||
}`
|
||||
|
||||
opts := LoadOpts{
|
||||
FlagValues: FlagValuesTarget{Config: Config{
|
||||
DataDir: &dir,
|
||||
}},
|
||||
Overrides: []Source{
|
||||
FileSource{
|
||||
Name: "reporting.json",
|
||||
Format: "json",
|
||||
Data: content,
|
||||
},
|
||||
},
|
||||
}
|
||||
patchLoadOptsShims(&opts)
|
||||
result, err := Load(opts)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, result.Warnings, 0)
|
||||
require.Equal(t, false, result.RuntimeConfig.Reporting.License.Enabled)
|
||||
})
|
||||
|
||||
t.Run("load from HCL defaults to false", func(t *testing.T) {
|
||||
content := `
|
||||
reporting {}
|
||||
`
|
||||
|
||||
opts := LoadOpts{
|
||||
FlagValues: FlagValuesTarget{Config: Config{
|
||||
DataDir: &dir,
|
||||
}},
|
||||
Overrides: []Source{
|
||||
FileSource{
|
||||
Name: "reporting.hcl",
|
||||
Format: "hcl",
|
||||
Data: content,
|
||||
},
|
||||
},
|
||||
}
|
||||
patchLoadOptsShims(&opts)
|
||||
result, err := Load(opts)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, result.Warnings, 0)
|
||||
require.Equal(t, false, result.RuntimeConfig.Reporting.License.Enabled)
|
||||
})
|
||||
|
||||
t.Run("with value set returns warning and defaults to false", func(t *testing.T) {
|
||||
content := `reporting {
|
||||
license {
|
||||
enabled = true
|
||||
}
|
||||
}`
|
||||
|
||||
opts := LoadOpts{
|
||||
FlagValues: FlagValuesTarget{Config: Config{
|
||||
DataDir: &dir,
|
||||
}},
|
||||
Overrides: []Source{
|
||||
FileSource{
|
||||
Name: "reporting.hcl",
|
||||
Format: "hcl",
|
||||
Data: content,
|
||||
},
|
||||
},
|
||||
}
|
||||
patchLoadOptsShims(&opts)
|
||||
result, err := Load(opts)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, result.Warnings, 1)
|
||||
require.Contains(t, result.Warnings[0], "\"reporting.license.enabled\" is a Consul Enterprise configuration and will have no effect")
|
||||
require.Equal(t, false, result.RuntimeConfig.Reporting.License.Enabled)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -295,6 +295,11 @@
|
|||
"ReconnectTimeoutLAN": "0s",
|
||||
"ReconnectTimeoutWAN": "0s",
|
||||
"RejoinAfterLeave": false,
|
||||
"Reporting": {
|
||||
"License": {
|
||||
"Enabled": false
|
||||
}
|
||||
},
|
||||
"RequestLimitsMode": 0,
|
||||
"RequestLimitsReadRate": 0,
|
||||
"RequestLimitsWriteRate": 0,
|
||||
|
|
|
@ -375,6 +375,11 @@ reconnect_timeout = "23739s"
|
|||
reconnect_timeout_wan = "26694s"
|
||||
recursors = [ "63.38.39.58", "92.49.18.18" ]
|
||||
rejoin_after_leave = true
|
||||
reporting = {
|
||||
license = {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
retry_interval = "8067s"
|
||||
retry_interval_wan = "28866s"
|
||||
retry_join = [ "pbsSFY7U", "l0qLtWij" ]
|
||||
|
|
|
@ -428,6 +428,11 @@
|
|||
"92.49.18.18"
|
||||
],
|
||||
"rejoin_after_leave": true,
|
||||
"reporting": {
|
||||
"license": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"retry_interval": "8067s",
|
||||
"retry_interval_wan": "28866s",
|
||||
"retry_join": [
|
||||
|
|
|
@ -441,6 +441,8 @@ type Config struct {
|
|||
|
||||
Locality *structs.Locality
|
||||
|
||||
Reporting Reporting
|
||||
|
||||
// Embedded Consul Enterprise specific configuration
|
||||
*EnterpriseConfig
|
||||
}
|
||||
|
@ -676,6 +678,7 @@ type ReloadableConfig struct {
|
|||
RaftTrailingLogs int
|
||||
HeartbeatTimeout time.Duration
|
||||
ElectionTimeout time.Duration
|
||||
Reporting Reporting
|
||||
}
|
||||
|
||||
type RaftLogStoreConfig struct {
|
||||
|
@ -698,3 +701,11 @@ type RaftBoltDBConfig struct {
|
|||
type WALConfig struct {
|
||||
SegmentSize int
|
||||
}
|
||||
|
||||
type License struct {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
type Reporting struct {
|
||||
License License
|
||||
}
|
||||
|
|
|
@ -1803,6 +1803,8 @@ func (s *Server) ReloadConfig(config ReloadableConfig) error {
|
|||
return err
|
||||
}
|
||||
|
||||
s.updateReportingConfig(config)
|
||||
|
||||
s.rpcLimiter.Store(rate.NewLimiter(config.RPCRateLimit, config.RPCMaxBurst))
|
||||
|
||||
if config.RequestLimits != nil {
|
||||
|
|
|
@ -182,3 +182,7 @@ func addSerfMetricsLabels(conf *serf.Config, wan bool, segment string, partition
|
|||
|
||||
conf.MetricLabels = append(conf.MetricLabels, networkMetric)
|
||||
}
|
||||
|
||||
func (s *Server) updateReportingConfig(config ReloadableConfig) {
|
||||
// no-op
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
//go:build !consulent
|
||||
// +build !consulent
|
||||
|
||||
package consul
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/testrpc"
|
||||
)
|
||||
|
||||
func TestAgent_ReloadConfig_Reporting(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
dir1, s := testServerWithConfig(t, func(c *Config) {
|
||||
c.Reporting.License.Enabled = false
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s.Shutdown()
|
||||
|
||||
testrpc.WaitForTestAgent(t, s.RPC, "dc1")
|
||||
|
||||
require.Equal(t, false, s.config.Reporting.License.Enabled)
|
||||
|
||||
rc := ReloadableConfig{
|
||||
Reporting: Reporting{
|
||||
License: License{
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.ReloadConfig(rc))
|
||||
|
||||
// Check config reload is no-op
|
||||
require.Equal(t, false, s.config.Reporting.License.Enabled)
|
||||
}
|
Loading…
Reference in New Issue