From eaad79ecdb4d0b26b35a0bc981efc2d16963b536 Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Thu, 20 Mar 2025 14:21:41 +0100 Subject: [PATCH] Add new parameter 'enablePrefixFilter' true by default. If set to false the the generated function only return true or false with no prefixes filtering --- birdwatcher/bird_test.go | 36 ++++++++++++++++++-- birdwatcher/config.go | 3 ++ birdwatcher/config_test.go | 1 + birdwatcher/healthcheck.go | 8 ++--- birdwatcher/prefixset.go | 14 +++++--- birdwatcher/prefixset_test.go | 4 +-- birdwatcher/servicecheck.go | 2 +- birdwatcher/servicecheck_test.go | 1 - birdwatcher/templates/functions.tpl | 13 +++++-- birdwatcher/testdata/bird/config_return_true | 5 +++ 10 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 birdwatcher/testdata/bird/config_return_true diff --git a/birdwatcher/bird_test.go b/birdwatcher/bird_test.go index 4e62aaf..3d80c5c 100644 --- a/birdwatcher/bird_test.go +++ b/birdwatcher/bird_test.go @@ -22,7 +22,7 @@ func TestWriteBirdConfig(t *testing.T) { defer os.Remove(tmpFile.Name()) prefixes := make(PrefixCollection) - prefixes["match_route"] = NewPrefixSet("match_route") + prefixes["match_route"] = NewPrefixSet("match_route", true) // write bird config with empty prefix list err = writeBirdConfig(tmpFile.Name(), prefixes, false) @@ -47,7 +47,7 @@ func TestWriteBirdConfig(t *testing.T) { defer os.Remove(tmpFile.Name()) prefixes := make(PrefixCollection) - prefixes["match_route"] = NewPrefixSet("match_route") + prefixes["match_route"] = NewPrefixSet("match_route", true) for _, pref := range []string{"1.2.3.4/32", "2.3.4.5/26", "3.4.5.6/24", "4.5.6.7/21"} { _, prf, _ := net.ParseCIDR(pref) @@ -68,6 +68,36 @@ func TestWriteBirdConfig(t *testing.T) { assert.Equal(t, string(fixture), string(data)) }) + t.Run("one prefixset, do not filter", func(t *testing.T) { + t.Parallel() + + // open tempfile + tmpFile, err := os.CreateTemp(t.TempDir(), "bird_test") + require.NoError(t, err) + defer os.Remove(tmpFile.Name()) + + prefixes := make(PrefixCollection) + prefixes["match_route"] = NewPrefixSet("match_route", /* enablePrefixFilter */false ) + + for _, pref := range []string{"1.2.3.4/32", "2.3.4.5/26", "3.4.5.6/24", "4.5.6.7/21"} { + _, prf, _ := net.ParseCIDR(pref) + prefixes["match_route"].Add(*prf) + } + + // write bird config to it + err = writeBirdConfig(tmpFile.Name(), prefixes, false) + require.NoError(t, err) + + // read data from temp file and compare it to file fixture + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + + fixture, err := os.ReadFile("testdata/bird/config_return_true") + require.NoError(t, err) + + assert.Equal(t, string(fixture), string(data)) + }) + t.Run("one prefix, compat", func(t *testing.T) { t.Parallel() @@ -78,7 +108,7 @@ func TestWriteBirdConfig(t *testing.T) { prefixes := make(PrefixCollection) - prefixes["other_function"] = NewPrefixSet("other_function") + prefixes["other_function"] = NewPrefixSet("other_function", true) for _, pref := range []string{"5.6.7.8/32", "6.7.8.9/26", "7.8.9.10/24"} { _, prf, _ := net.ParseCIDR(pref) prefixes["other_function"].Add(*prf) diff --git a/birdwatcher/config.go b/birdwatcher/config.go index 3d62ac8..b2f7a98 100644 --- a/birdwatcher/config.go +++ b/birdwatcher/config.go @@ -111,6 +111,9 @@ func ReadConfig(conf *Config, configFile string) error { allPrefixes[ipn.String()] = true } + // TODO: How to make it true by default, if toml.DecodeFile set boolean to false by default ? + s.enablePrefixFilter = true + // map name to each search conf.Services[name] = s } diff --git a/birdwatcher/config_test.go b/birdwatcher/config_test.go index 32857e5..3dcebfc 100644 --- a/birdwatcher/config_test.go +++ b/birdwatcher/config_test.go @@ -4,6 +4,7 @@ import ( "regexp" "testing" "time" + "fmt" "github.com/stretchr/testify/assert" ) diff --git a/birdwatcher/healthcheck.go b/birdwatcher/healthcheck.go index d7c11ef..aa5e64f 100644 --- a/birdwatcher/healthcheck.go +++ b/birdwatcher/healthcheck.go @@ -216,20 +216,20 @@ func (h *HealthCheck) applyConfig(config Config, prefixes PrefixCollection) erro } func (h *HealthCheck) addPrefix(svc *ServiceCheck, prefix net.IPNet) { - h.ensurePrefixSet(svc.FunctionName) + h.ensurePrefixSet(svc.FunctionName, svc.enablePrefixFilter) h.prefixes[svc.FunctionName].Add(prefix) prefixStateMetric.WithLabelValues(svc.Name(), prefix.String()).Set(1.0) } func (h *HealthCheck) removePrefix(svc *ServiceCheck, prefix net.IPNet) { - h.ensurePrefixSet(svc.FunctionName) + h.ensurePrefixSet(svc.FunctionName, svc.enablePrefixFilter) h.prefixes[svc.FunctionName].Remove(prefix) prefixStateMetric.WithLabelValues(svc.Name(), prefix.String()).Set(0.0) } -func (h *HealthCheck) ensurePrefixSet(functionName string) { +func (h *HealthCheck) ensurePrefixSet(functionName string, enablePrefixFilter bool) { // make sure the top level map is prepared if h.prefixes == nil { h.prefixes = make(PrefixCollection) @@ -237,7 +237,7 @@ func (h *HealthCheck) ensurePrefixSet(functionName string) { // make sure a mapping for this function name exists if _, found := h.prefixes[functionName]; !found { - h.prefixes[functionName] = NewPrefixSet(functionName) + h.prefixes[functionName] = NewPrefixSet(functionName, enablePrefixFilter) } } diff --git a/birdwatcher/prefixset.go b/birdwatcher/prefixset.go index 1c57a79..18a30ed 100644 --- a/birdwatcher/prefixset.go +++ b/birdwatcher/prefixset.go @@ -14,13 +14,14 @@ type PrefixCollection map[string]*PrefixSet // PrefixSet represents a list of prefixes alongside a function name type PrefixSet struct { - prefixes []net.IPNet - functionName string + prefixes []net.IPNet + enablePrefixFilter bool + functionName string } // NewPrefixSet returns a new prefixset with given function name -func NewPrefixSet(functionName string) *PrefixSet { - return &PrefixSet{functionName: functionName} +func NewPrefixSet(functionName string, enablePrefixFilter bool) *PrefixSet { + return &PrefixSet{functionName: functionName, prefixes: make([]net.IPNet, 0), enablePrefixFilter: enablePrefixFilter} } // FunctionName returns the function name @@ -28,6 +29,11 @@ func (p PrefixSet) FunctionName() string { return p.functionName } +// EnablePrefixFilter returns if we should filter `net` with the prefixes, or just return true/false +func (p PrefixSet) EnablePrefixFilter() bool { + return p.enablePrefixFilter +} + // Prefixes returns the prefixes func (p PrefixSet) Prefixes() []net.IPNet { return p.prefixes diff --git a/birdwatcher/prefixset_test.go b/birdwatcher/prefixset_test.go index 766ef91..9ad1e43 100644 --- a/birdwatcher/prefixset_test.go +++ b/birdwatcher/prefixset_test.go @@ -10,7 +10,7 @@ import ( func TestPrefixSet_Add(t *testing.T) { t.Parallel() - p := NewPrefixSet("foobar") + p := NewPrefixSet("foobar", true) // should be empty assert.Empty(t, p.prefixes) @@ -44,7 +44,7 @@ func TestPrefixSet_Add(t *testing.T) { func TestPrefixSet_Remove(t *testing.T) { t.Parallel() - p := NewPrefixSet("foobar") + p := NewPrefixSet("foobar", true) // add some prefixes prefixes := make([]net.IPNet, 4) diff --git a/birdwatcher/servicecheck.go b/birdwatcher/servicecheck.go index f2d36cb..3efa95f 100644 --- a/birdwatcher/servicecheck.go +++ b/birdwatcher/servicecheck.go @@ -89,7 +89,7 @@ type ServiceCheck struct { //nolint:revive // these prefixes are converted into net.IPNet prefixes []net.IPNet state ServiceState - disablePrefixCheck bool + enablePrefixFilter bool stopped chan any } diff --git a/birdwatcher/servicecheck_test.go b/birdwatcher/servicecheck_test.go index 4fc33d4..0fc3c18 100644 --- a/birdwatcher/servicecheck_test.go +++ b/birdwatcher/servicecheck_test.go @@ -13,7 +13,6 @@ func TestServiceCheckPushChannel(t *testing.T) { buf := make(chan *Action) sc := ServiceCheck{ - disablePrefixCheck: true, name: "test", Command: "/usr/bin/true", Fail: 3, diff --git a/birdwatcher/templates/functions.tpl b/birdwatcher/templates/functions.tpl index cb1eed0..a0d58ce 100644 --- a/birdwatcher/templates/functions.tpl +++ b/birdwatcher/templates/functions.tpl @@ -2,14 +2,23 @@ {{- range .Collections }} function {{.FunctionName}}(){{- if not $.CompatBird213 }} -> bool{{- end }} { +{{- if .EnablePrefixFilter }} {{- with .Prefixes}} return net ~ [ {{- range prefixPad . }} {{.}} -{{- end }} +{{- end }}{{/* end of range prefixPad */}} ]; {{- else }} return false; {{- end }} -} +{{- else }}{{/* else of if .enablePrefixFilter */}} +{{- with .Prefixes}} + return true; +{{- else }} + return false; {{- end }} + +{{- end }}{{/* end of if .enablePrefixFilter */}} +} +{{- end }}{{/* end of range .Collections */}} diff --git a/birdwatcher/testdata/bird/config_return_true b/birdwatcher/testdata/bird/config_return_true new file mode 100644 index 0000000..b326196 --- /dev/null +++ b/birdwatcher/testdata/bird/config_return_true @@ -0,0 +1,5 @@ +# DO NOT EDIT MANUALLY +function match_route() -> bool +{ + return true; +}