Skip to content

Commit fe4a8aa

Browse files
authored
ruler: ignore non-config values when checking defaults (grafana#2894)
* ruler: ignore non-config values when checking defaults The idea of `rulestore.IsDefaults()` is to check whether the ruler has been configured by the user. However `reflect.DeepEqual()` checks all data within the Config struct, including things which are not actually config. This change skips any fields within the config marked as `yaml:"-"`, which are not settable from yaml and therefore not config. Using package `github.com/google/go-cmp/cmp`, which is documented as "not for use in production" since it panics when it cannot compare things. However we should catch that in unit testing, so should be ok. (Note gRPC also uses this package). Added a test which (artificially) induces the problem. * Fix up go.mod
1 parent 04a0fd7 commit fe4a8aa

3 files changed

Lines changed: 33 additions & 2 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ require (
5353

5454
require (
5555
github.com/alecthomas/chroma v0.10.0
56+
github.com/google/go-cmp v0.5.8
5657
github.com/google/go-github/v32 v32.1.0
5758
github.com/google/uuid v1.3.0
5859
github.com/grafana-tools/sdk v0.0.0-20211220201350-966b3088eec9
@@ -135,7 +136,6 @@ require (
135136
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
136137
github.com/google/btree v1.0.1 // indirect
137138
github.com/google/gnostic v0.5.7-v3refs // indirect
138-
github.com/google/go-cmp v0.5.8 // indirect
139139
github.com/google/go-querystring v1.1.0 // indirect
140140
github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3 // indirect
141141
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect

pkg/ruler/rulestore/config.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"flag"
1010
"reflect"
1111

12+
"github.com/google/go-cmp/cmp"
1213
"github.com/grafana/dskit/flagext"
1314

1415
"github.com/grafana/mimir/pkg/ruler/rulestore/local"
@@ -35,5 +36,28 @@ func (cfg *Config) IsDefaults() bool {
3536
defaults := Config{}
3637
flagext.DefaultValues(&defaults)
3738

38-
return reflect.DeepEqual(*cfg, defaults)
39+
// Note: cmp.Equal will panic if it encounters anything it cannot handle.
40+
return cmp.Equal(*cfg, defaults, cmp.FilterPath(filterNonYaml, cmp.Ignore()), cmp.Comparer(equalSecrets))
41+
}
42+
43+
// Return true if the path contains a struct field with tag `yaml:"-"`.
44+
func filterNonYaml(path cmp.Path) bool {
45+
for i, step := range path {
46+
// If we're not looking at a struct, or next step not available, skip.
47+
if step.Type().Kind() != reflect.Struct || i >= len(path)-1 {
48+
continue
49+
}
50+
field := step.Type().Field((path[i+1].(cmp.StructField)).Index())
51+
if tag, ok := field.Tag.Lookup("yaml"); ok {
52+
if tag == "-" {
53+
return true
54+
}
55+
}
56+
}
57+
return false
58+
}
59+
60+
// Helper for cmp.Equal to compare Secret values for equality, since it has unexported fields.
61+
func equalSecrets(a, b flagext.Secret) bool {
62+
return a == b
3963
}

pkg/ruler/rulestore/config_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ func TestIsDefaults(t *testing.T) {
3434
},
3535
expected: false,
3636
},
37+
"should return true if only a non-config field has changed": {
38+
setup: func(cfg *Config) {
39+
flagext.DefaultValues(cfg)
40+
cfg.Middlewares = append(cfg.Middlewares, nil)
41+
},
42+
expected: true,
43+
},
3744
}
3845

3946
for testName, testData := range tests {

0 commit comments

Comments
 (0)