Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport of feat: add reporting config with reload #16977

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,10 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co
cfg.RequestLimitsReadRate = runtimeCfg.RequestLimitsReadRate
cfg.RequestLimitsWriteRate = runtimeCfg.RequestLimitsWriteRate

cfg.Reporting.License.Enabled = runtimeCfg.Reporting.License.Enabled

enterpriseConsulConfig(cfg, runtimeCfg)

return cfg, nil
}

Expand Down Expand Up @@ -4185,6 +4188,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
Expand Down
46 changes: 46 additions & 0 deletions agent/agent_oss_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
4 changes: 4 additions & 0 deletions agent/config/builder_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,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
}
Expand Down
13 changes: 13 additions & 0 deletions agent/config/builder_oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,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,
Expand Down
11 changes: 11 additions & 0 deletions agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,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 {
Expand Down Expand Up @@ -943,3 +946,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"`
}
10 changes: 10 additions & 0 deletions agent/config/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -1479,9 +1479,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
Expand Down
81 changes: 81 additions & 0 deletions agent/config/runtime_oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"testing"

"github.com/hashicorp/consul/sdk/testutil"
"github.com/stretchr/testify/require"
)

var testRuntimeConfigSanitizeExpectedFilename = "TestRuntimeConfig_Sanitize.golden"
Expand All @@ -28,6 +29,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
Expand Down Expand Up @@ -84,3 +86,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)
})
}
5 changes: 5 additions & 0 deletions agent/config/testdata/TestRuntimeConfig_Sanitize.golden
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@
"ReconnectTimeoutLAN": "0s",
"ReconnectTimeoutWAN": "0s",
"RejoinAfterLeave": false,
"Reporting": {
"License": {
"Enabled": false
}
},
"RequestLimitsMode": 0,
"RequestLimitsReadRate": 0,
"RequestLimitsWriteRate": 0,
Expand Down
5 changes: 5 additions & 0 deletions agent/config/testdata/full-config.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,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" ]
Expand Down
5 changes: 5 additions & 0 deletions agent/config/testdata/full-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
11 changes: 11 additions & 0 deletions agent/consul/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ type Config struct {

PeeringTestAllowPeerRegistrations bool

Reporting Reporting

// Embedded Consul Enterprise specific configuration
*EnterpriseConfig
}
Expand Down Expand Up @@ -671,6 +673,7 @@ type ReloadableConfig struct {
RaftTrailingLogs int
HeartbeatTimeout time.Duration
ElectionTimeout time.Duration
Reporting Reporting
}

type RaftLogStoreConfig struct {
Expand All @@ -693,3 +696,11 @@ type RaftBoltDBConfig struct {
type WALConfig struct {
SegmentSize int
}

type License struct {
Enabled bool
}

type Reporting struct {
License License
}
2 changes: 2 additions & 0 deletions agent/consul/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,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 {
Expand Down
4 changes: 4 additions & 0 deletions agent/consul/server_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,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
}
43 changes: 43 additions & 0 deletions agent/consul/server_oss_test.go
Original file line number Diff line number Diff line change
@@ -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)
}