From 2a53b107c18e97d6240e2e94ac63fae18e0c4277 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Fri, 17 Jul 2015 16:12:33 +0200 Subject: [PATCH 1/2] Fix missing defaults in empty configurations --- config/config.go | 5 +++++ config/config_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/config/config.go b/config/config.go index 888d5d628d..eddd440879 100644 --- a/config/config.go +++ b/config/config.go @@ -26,6 +26,11 @@ var ( // Load parses the YAML input s into a Config. func Load(s string) (*Config, error) { cfg := &Config{} + // If the entire config body is empty the UnmarshalYAML method is + // never called. We thus have to set the DefaultConfig at the entry + // point as well. + *cfg = DefaultConfig + err := yaml.Unmarshal([]byte(s), cfg) if err != nil { return nil, err diff --git a/config/config_test.go b/config/config_test.go index bba5fea1a3..d7aab0b489 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -249,3 +249,15 @@ func TestBadTargetGroup(t *testing.T) { t.Errorf("Expected unmarshal error but got none.") } } + +func TestEmptyConfig(t *testing.T) { + c, err := Load("") + if err != nil { + t.Fatalf("Unexpected error parsing empty config file: %s", err) + } + exp := DefaultConfig + + if !reflect.DeepEqual(*c, exp) { + t.Fatalf("want %v, got %v", exp, c) + } +} From 187fe4e3d31f0ecaa0d7a386940acb3dcbf4e005 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Fri, 17 Jul 2015 19:58:34 +0200 Subject: [PATCH 2/2] Fix missing defaults for empty global config blocks --- config/config.go | 14 ++++++++++++++ config/config_test.go | 13 +++++++++++++ 2 files changed, 27 insertions(+) diff --git a/config/config.go b/config/config.go index eddd440879..46fbc9e757 100644 --- a/config/config.go +++ b/config/config.go @@ -147,6 +147,12 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal((*plain)(c)); err != nil { return err } + // If a global block was open but empty the default global config is overwritten. + // We have to restore it here. + if c.GlobalConfig.isZero() { + c.GlobalConfig = DefaultGlobalConfig + } + for _, rf := range c.RuleFiles { if !patRulePath.MatchString(rf) { return fmt.Errorf("invalid rule file path %q", rf) @@ -196,6 +202,14 @@ func (c *GlobalConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { return checkOverflow(c.XXX, "global config") } +// isZero returns true iff the global config is the zero value. +func (c *GlobalConfig) isZero() bool { + return c.Labels == nil && + c.ScrapeInterval == 0 && + c.ScrapeTimeout == 0 && + c.EvaluationInterval == 0 +} + // ScrapeConfig configures a scraping unit for Prometheus. type ScrapeConfig struct { // The job name to which the job label is set by default. diff --git a/config/config_test.go b/config/config_test.go index d7aab0b489..844aef8cdd 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -261,3 +261,16 @@ func TestEmptyConfig(t *testing.T) { t.Fatalf("want %v, got %v", exp, c) } } + +func TestEmptyGlobalBlock(t *testing.T) { + c, err := Load("global:\n") + if err != nil { + t.Fatalf("Unexpected error parsing empty config file: %s", err) + } + exp := DefaultConfig + exp.original = "global:\n" + + if !reflect.DeepEqual(*c, exp) { + t.Fatalf("want %v, got %v", exp, c) + } +}