Fix reload test; address other PR feedback
This commit is contained in:
parent
85d425801c
commit
89e539a00d
|
@ -290,7 +290,6 @@ type Agent struct {
|
||||||
// IP.
|
// IP.
|
||||||
httpConnLimiter connlimit.Limiter
|
httpConnLimiter connlimit.Limiter
|
||||||
|
|
||||||
// enterpriseAgent embeds fields that we only access in consul-enterprise builds
|
|
||||||
enterpriseAgent
|
enterpriseAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3574,6 +3573,9 @@ func (a *Agent) reloadConfigInternal(newCfg *config.RuntimeConfig) error {
|
||||||
|
|
||||||
a.State.SetDiscardCheckOutput(newCfg.DiscardCheckOutput)
|
a.State.SetDiscardCheckOutput(newCfg.DiscardCheckOutput)
|
||||||
|
|
||||||
|
// Reload metrics config
|
||||||
|
a.uiConfig.Store(newCfg.UIConfig)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1109,11 +1109,26 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
||||||
return rt, nil
|
return rt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reBasicName validates that a field contains only lower case alphanumerics,
|
||||||
|
// underscore and dash and is non-empty.
|
||||||
|
var reBasicName = regexp.MustCompile("^[a-z0-9_-]+$")
|
||||||
|
|
||||||
|
func validateBasicName(field, value string, allowEmpty bool) error {
|
||||||
|
if value == "" {
|
||||||
|
if allowEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%s cannot be empty", field)
|
||||||
|
}
|
||||||
|
if !reBasicName.MatchString(value) {
|
||||||
|
return fmt.Errorf("%s can only contain lowercase alphanumeric, - or _ characters."+
|
||||||
|
" received: %q", field, value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Validate performs semantic validation of the runtime configuration.
|
// Validate performs semantic validation of the runtime configuration.
|
||||||
func (b *Builder) Validate(rt RuntimeConfig) error {
|
func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
// reDatacenter defines a regexp for a valid datacenter name
|
|
||||||
var reBasicName = regexp.MustCompile("^[a-z0-9_-]+$")
|
|
||||||
var reDatacenter = reBasicName
|
|
||||||
|
|
||||||
// validContentPath defines a regexp for a valid content path name.
|
// validContentPath defines a regexp for a valid content path name.
|
||||||
var validContentPath = regexp.MustCompile(`^[A-Za-z0-9/_-]+$`)
|
var validContentPath = regexp.MustCompile(`^[A-Za-z0-9/_-]+$`)
|
||||||
|
@ -1122,11 +1137,8 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
// check required params we cannot recover from first
|
// check required params we cannot recover from first
|
||||||
//
|
//
|
||||||
|
|
||||||
if rt.Datacenter == "" {
|
if err := validateBasicName("datacenter", rt.Datacenter, false); err != nil {
|
||||||
return fmt.Errorf("datacenter cannot be empty")
|
return err
|
||||||
}
|
|
||||||
if !reDatacenter.MatchString(rt.Datacenter) {
|
|
||||||
return fmt.Errorf("datacenter cannot be %q. Please use only [a-z0-9-_]", rt.Datacenter)
|
|
||||||
}
|
}
|
||||||
if rt.DataDir == "" && !rt.DevMode {
|
if rt.DataDir == "" && !rt.DevMode {
|
||||||
return fmt.Errorf("data_dir cannot be empty")
|
return fmt.Errorf("data_dir cannot be empty")
|
||||||
|
@ -1140,17 +1152,14 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
return fmt.Errorf("ui-content-path cannot have 'v[0-9]'. received: %q", rt.UIConfig.ContentPath)
|
return fmt.Errorf("ui-content-path cannot have 'v[0-9]'. received: %q", rt.UIConfig.ContentPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rt.UIConfig.MetricsProvider != "" &&
|
if err := validateBasicName("ui_config.metrics_provider", rt.UIConfig.MetricsProvider, true); err != nil {
|
||||||
!reBasicName.MatchString(rt.UIConfig.MetricsProvider) {
|
return err
|
||||||
return fmt.Errorf("ui_config.metrics_provider can only contain lowercase "+
|
|
||||||
"alphanumeric or _ characters. received: %q", rt.UIConfig.MetricsProvider)
|
|
||||||
}
|
}
|
||||||
if rt.UIConfig.MetricsProviderOptionsJSON != "" {
|
if rt.UIConfig.MetricsProviderOptionsJSON != "" {
|
||||||
// Attempt to parse the JSON to ensure it's valid, parsing into a map
|
// Attempt to parse the JSON to ensure it's valid, parsing into a map
|
||||||
// ensures we get an object.
|
// ensures we get an object.
|
||||||
var dummyMap map[string]interface{}
|
var dummyMap map[string]interface{}
|
||||||
err := json.Unmarshal([]byte(rt.UIConfig.MetricsProviderOptionsJSON),
|
err := json.Unmarshal([]byte(rt.UIConfig.MetricsProviderOptionsJSON), &dummyMap)
|
||||||
&dummyMap)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ui_config.metrics_provider_options_json must be empty "+
|
return fmt.Errorf("ui_config.metrics_provider_options_json must be empty "+
|
||||||
"or a string containing a valid JSON object. received: %q",
|
"or a string containing a valid JSON object. received: %q",
|
||||||
|
@ -1166,9 +1175,8 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k, v := range rt.UIConfig.DashboardURLTemplates {
|
for k, v := range rt.UIConfig.DashboardURLTemplates {
|
||||||
if !reBasicName.MatchString(k) {
|
if err := validateBasicName("ui_config.dashboard_url_templates key names", k, false); err != nil {
|
||||||
return fmt.Errorf("ui_config.dashboard_url_templates key names can only "+
|
return err
|
||||||
"contain lowercase alphanumeric or _ characters. received: %q", k)
|
|
||||||
}
|
}
|
||||||
u, err := url.Parse(v)
|
u, err := url.Parse(v)
|
||||||
if err != nil || !(u.Scheme == "http" || u.Scheme == "https") {
|
if err != nil || !(u.Scheme == "http" || u.Scheme == "https") {
|
||||||
|
@ -1247,8 +1255,8 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
if rt.AutopilotMaxTrailingLogs < 0 {
|
if rt.AutopilotMaxTrailingLogs < 0 {
|
||||||
return fmt.Errorf("autopilot.max_trailing_logs cannot be %d. Must be greater than or equal to zero", rt.AutopilotMaxTrailingLogs)
|
return fmt.Errorf("autopilot.max_trailing_logs cannot be %d. Must be greater than or equal to zero", rt.AutopilotMaxTrailingLogs)
|
||||||
}
|
}
|
||||||
if rt.ACLDatacenter != "" && !reDatacenter.MatchString(rt.ACLDatacenter) {
|
if err := validateBasicName("acl_datacenter", rt.ACLDatacenter, true); err != nil {
|
||||||
return fmt.Errorf("acl_datacenter cannot be %q. Please use only [a-z0-9-_]", rt.ACLDatacenter)
|
return err
|
||||||
}
|
}
|
||||||
// In DevMode, UI is enabled by default, so to enable rt.UIDir, don't perform this check
|
// In DevMode, UI is enabled by default, so to enable rt.UIDir, don't perform this check
|
||||||
if !rt.DevMode && rt.UIConfig.Enabled && rt.UIConfig.Dir != "" {
|
if !rt.DevMode && rt.UIConfig.Enabled && rt.UIConfig.Dir != "" {
|
||||||
|
|
|
@ -1712,7 +1712,7 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
},
|
},
|
||||||
json: []string{`{ "acl_datacenter": "%" }`},
|
json: []string{`{ "acl_datacenter": "%" }`},
|
||||||
hcl: []string{`acl_datacenter = "%"`},
|
hcl: []string{`acl_datacenter = "%"`},
|
||||||
err: `acl_datacenter cannot be "%". Please use only [a-z0-9-_]`,
|
err: `acl_datacenter can only contain lowercase alphanumeric, - or _ characters.`,
|
||||||
warns: []string{`The 'acl_datacenter' field is deprecated. Use the 'primary_datacenter' field instead.`},
|
warns: []string{`The 'acl_datacenter' field is deprecated. Use the 'primary_datacenter' field instead.`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1881,7 +1881,7 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
args: []string{`-data-dir=` + dataDir},
|
args: []string{`-data-dir=` + dataDir},
|
||||||
json: []string{`{ "datacenter": "%" }`},
|
json: []string{`{ "datacenter": "%" }`},
|
||||||
hcl: []string{`datacenter = "%"`},
|
hcl: []string{`datacenter = "%"`},
|
||||||
err: `datacenter cannot be "%". Please use only [a-z0-9-_]`,
|
err: `datacenter can only contain lowercase alphanumeric, - or _ characters.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "dns does not allow socket",
|
desc: "dns does not allow socket",
|
||||||
|
@ -4306,7 +4306,7 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
metrics_provider = "((((lisp 4 life))))"
|
metrics_provider = "((((lisp 4 life))))"
|
||||||
}
|
}
|
||||||
`},
|
`},
|
||||||
err: `ui_config.metrics_provider can only contain lowercase alphanumeric or _ characters.`,
|
err: `ui_config.metrics_provider can only contain lowercase alphanumeric, - or _ characters.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "metrics_provider_options_json invalid JSON",
|
desc: "metrics_provider_options_json invalid JSON",
|
||||||
|
@ -4393,7 +4393,7 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`},
|
`},
|
||||||
err: `ui_config.dashboard_url_templates key names can only contain lowercase alphanumeric or _ characters.`,
|
err: `ui_config.dashboard_url_templates key names can only contain lowercase alphanumeric, - or _ characters.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "dashboard_url_templates value format",
|
desc: "dashboard_url_templates value format",
|
||||||
|
|
|
@ -29,7 +29,6 @@ import (
|
||||||
"github.com/hashicorp/go-cleanhttp"
|
"github.com/hashicorp/go-cleanhttp"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/ryboe/q"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MethodNotAllowedError should be returned by a handler when the HTTP method is not allowed.
|
// MethodNotAllowedError should be returned by a handler when the HTTP method is not allowed.
|
||||||
|
@ -170,7 +169,6 @@ func (fs *settingsInjectedIndexFS) Open(name string) (http.File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := ioutil.ReadAll(file)
|
content, err := ioutil.ReadAll(file)
|
||||||
q.Q(err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed reading index.html: %s", err)
|
return nil, fmt.Errorf("failed reading index.html: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -184,7 +182,6 @@ func (fs *settingsInjectedIndexFS) Open(name string) (http.File, error) {
|
||||||
|
|
||||||
// First built an escaped, JSON blob from the settings passed.
|
// First built an escaped, JSON blob from the settings passed.
|
||||||
bs, err := json.Marshal(fs.UISettings)
|
bs, err := json.Marshal(fs.UISettings)
|
||||||
q.Q(string(bs))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed marshalling UI settings JSON: %s", err)
|
return nil, fmt.Errorf("failed marshalling UI settings JSON: %s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue