nebula/config/config_test.go

226 lines
5.5 KiB
Go
Raw Permalink Normal View History

package config
2019-11-19 10:00:20 -07:00
import (
"os"
"path/filepath"
"testing"
"time"
"dario.cat/mergo"
"github.com/slackhq/nebula/test"
"github.com/stretchr/testify/assert"
Update dependencies (2022-11) (#780) * update dependencies Update to latest dependencies on Nov 21, 2022. Here are the diffs for deps that actually end up in the binaries (based on `go version -m`) Updated github.com/imdario/mergo https://github.com/imdario/mergo/compare/v0.3.12...v0.3.13 Updated github.com/matttproud/golang_protobuf_extensions https://github.com/matttproud/golang_protobuf_extensions/compare/v1.0.1...v1.0.4 Updated github.com/miekg/dns https://github.com/miekg/dns/compare/v1.1.48...v1.1.50 Updated github.com/prometheus/client_golang https://github.com/prometheus/client_golang/compare/v1.12.1...v1.14.0 Updated github.com/prometheus/client_model https://github.com/prometheus/client_model/compare/v0.2.0...v0.3.0 Updated github.com/prometheus/common https://github.com/prometheus/common/compare/v0.33.0...v0.37.0 Updated github.com/prometheus/procfs https://github.com/prometheus/procfs/compare/v0.7.3...v0.8.0 Updated github.com/sirupsen/logrus https://github.com/sirupsen/logrus/compare/v1.8.1...v1.9.0 Updated github.com/vishvananda/netns https://github.com/vishvananda/netns/compare/50045581ed74...v0.0.1 Updated golang.org/x/crypto https://github.com/golang/crypto/compare/ae2d96664a29...v0.3.0 Updated golang.org/x/net https://github.com/golang/net/compare/749bd193bc2b...v0.2.0 Updated golang.org/x/sys https://github.com/golang/sys/compare/289d7a0edf71...v0.2.0 Updated golang.org/x/term https://github.com/golang/term/compare/03fcf44c2211...v0.2.0 Updated google.golang.org/protobuf v1.28.0...v1.28.1 * test that mergo merges like we expect
2022-11-23 08:46:41 -07:00
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
2019-11-19 10:00:20 -07:00
)
func TestConfig_Load(t *testing.T) {
l := test.NewLogger()
dir, err := os.MkdirTemp("", "config-test")
2019-11-19 10:00:20 -07:00
// invalid yaml
c := NewC(l)
os.WriteFile(filepath.Join(dir, "01.yaml"), []byte(" invalid yaml"), 0644)
2019-11-19 10:00:20 -07:00
assert.EqualError(t, c.Load(dir), "yaml: unmarshal errors:\n line 1: cannot unmarshal !!str `invalid...` into map[interface {}]interface {}")
// simple multi config merge
c = NewC(l)
2019-11-19 10:00:20 -07:00
os.RemoveAll(dir)
os.Mkdir(dir, 0755)
assert.Nil(t, err)
os.WriteFile(filepath.Join(dir, "01.yaml"), []byte("outer:\n inner: hi"), 0644)
os.WriteFile(filepath.Join(dir, "02.yml"), []byte("outer:\n inner: override\nnew: hi"), 0644)
2019-11-19 10:00:20 -07:00
assert.Nil(t, c.Load(dir))
expected := map[interface{}]interface{}{
"outer": map[interface{}]interface{}{
"inner": "override",
},
"new": "hi",
}
assert.Equal(t, expected, c.Settings)
//TODO: test symlinked file
//TODO: test symlinked directory
}
func TestConfig_Get(t *testing.T) {
l := test.NewLogger()
2019-11-19 10:00:20 -07:00
// test simple type
c := NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["firewall"] = map[interface{}]interface{}{"outbound": "hi"}
assert.Equal(t, "hi", c.Get("firewall.outbound"))
// test complex type
inner := []map[interface{}]interface{}{{"port": "1", "code": "2"}}
c.Settings["firewall"] = map[interface{}]interface{}{"outbound": inner}
assert.EqualValues(t, inner, c.Get("firewall.outbound"))
// test missing
assert.Nil(t, c.Get("firewall.nope"))
}
func TestConfig_GetStringSlice(t *testing.T) {
l := test.NewLogger()
c := NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["slice"] = []interface{}{"one", "two"}
assert.Equal(t, []string{"one", "two"}, c.GetStringSlice("slice", []string{}))
}
func TestConfig_GetBool(t *testing.T) {
l := test.NewLogger()
c := NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["bool"] = true
assert.Equal(t, true, c.GetBool("bool", false))
c.Settings["bool"] = "true"
assert.Equal(t, true, c.GetBool("bool", false))
c.Settings["bool"] = false
assert.Equal(t, false, c.GetBool("bool", true))
c.Settings["bool"] = "false"
assert.Equal(t, false, c.GetBool("bool", true))
c.Settings["bool"] = "Y"
assert.Equal(t, true, c.GetBool("bool", false))
c.Settings["bool"] = "yEs"
assert.Equal(t, true, c.GetBool("bool", false))
c.Settings["bool"] = "N"
assert.Equal(t, false, c.GetBool("bool", true))
c.Settings["bool"] = "nO"
assert.Equal(t, false, c.GetBool("bool", true))
}
func TestConfig_HasChanged(t *testing.T) {
l := test.NewLogger()
2019-11-19 10:00:20 -07:00
// No reload has occurred, return false
c := NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["test"] = "hi"
assert.False(t, c.HasChanged(""))
// Test key change
c = NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["test"] = "hi"
c.oldSettings = map[interface{}]interface{}{"test": "no"}
assert.True(t, c.HasChanged("test"))
assert.True(t, c.HasChanged(""))
// No key change
c = NewC(l)
2019-11-19 10:00:20 -07:00
c.Settings["test"] = "hi"
c.oldSettings = map[interface{}]interface{}{"test": "hi"}
assert.False(t, c.HasChanged("test"))
assert.False(t, c.HasChanged(""))
}
func TestConfig_ReloadConfig(t *testing.T) {
l := test.NewLogger()
2019-11-19 10:00:20 -07:00
done := make(chan bool, 1)
dir, err := os.MkdirTemp("", "config-test")
2019-11-19 10:00:20 -07:00
assert.Nil(t, err)
os.WriteFile(filepath.Join(dir, "01.yaml"), []byte("outer:\n inner: hi"), 0644)
2019-11-19 10:00:20 -07:00
c := NewC(l)
2019-11-19 10:00:20 -07:00
assert.Nil(t, c.Load(dir))
assert.False(t, c.HasChanged("outer.inner"))
assert.False(t, c.HasChanged("outer"))
assert.False(t, c.HasChanged(""))
os.WriteFile(filepath.Join(dir, "01.yaml"), []byte("outer:\n inner: ho"), 0644)
2019-11-19 10:00:20 -07:00
c.RegisterReloadCallback(func(c *C) {
2019-11-19 10:00:20 -07:00
done <- true
})
c.ReloadConfig()
assert.True(t, c.HasChanged("outer.inner"))
assert.True(t, c.HasChanged("outer"))
assert.True(t, c.HasChanged(""))
// Make sure we call the callbacks
select {
case <-done:
case <-time.After(1 * time.Second):
panic("timeout")
}
}
Update dependencies (2022-11) (#780) * update dependencies Update to latest dependencies on Nov 21, 2022. Here are the diffs for deps that actually end up in the binaries (based on `go version -m`) Updated github.com/imdario/mergo https://github.com/imdario/mergo/compare/v0.3.12...v0.3.13 Updated github.com/matttproud/golang_protobuf_extensions https://github.com/matttproud/golang_protobuf_extensions/compare/v1.0.1...v1.0.4 Updated github.com/miekg/dns https://github.com/miekg/dns/compare/v1.1.48...v1.1.50 Updated github.com/prometheus/client_golang https://github.com/prometheus/client_golang/compare/v1.12.1...v1.14.0 Updated github.com/prometheus/client_model https://github.com/prometheus/client_model/compare/v0.2.0...v0.3.0 Updated github.com/prometheus/common https://github.com/prometheus/common/compare/v0.33.0...v0.37.0 Updated github.com/prometheus/procfs https://github.com/prometheus/procfs/compare/v0.7.3...v0.8.0 Updated github.com/sirupsen/logrus https://github.com/sirupsen/logrus/compare/v1.8.1...v1.9.0 Updated github.com/vishvananda/netns https://github.com/vishvananda/netns/compare/50045581ed74...v0.0.1 Updated golang.org/x/crypto https://github.com/golang/crypto/compare/ae2d96664a29...v0.3.0 Updated golang.org/x/net https://github.com/golang/net/compare/749bd193bc2b...v0.2.0 Updated golang.org/x/sys https://github.com/golang/sys/compare/289d7a0edf71...v0.2.0 Updated golang.org/x/term https://github.com/golang/term/compare/03fcf44c2211...v0.2.0 Updated google.golang.org/protobuf v1.28.0...v1.28.1 * test that mergo merges like we expect
2022-11-23 08:46:41 -07:00
// Ensure mergo merges are done the way we expect.
// This is needed to test for potential regressions, like:
// - https://github.com/imdario/mergo/issues/187
func TestConfig_MergoMerge(t *testing.T) {
configs := [][]byte{
[]byte(`
listen:
port: 1234
`),
[]byte(`
firewall:
inbound:
- port: 443
proto: tcp
groups:
- server
- port: 443
proto: tcp
groups:
- webapp
`),
[]byte(`
listen:
host: 0.0.0.0
port: 4242
firewall:
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: icmp
host: any
`),
}
var m map[any]any
// merge the same way config.parse() merges
for _, b := range configs {
var nm map[any]any
err := yaml.Unmarshal(b, &nm)
require.NoError(t, err)
// We need to use WithAppendSlice so that firewall rules in separate
// files are appended together
err = mergo.Merge(&nm, m, mergo.WithAppendSlice)
m = nm
require.NoError(t, err)
}
t.Logf("Merged Config: %#v", m)
mYaml, err := yaml.Marshal(m)
require.NoError(t, err)
t.Logf("Merged Config as YAML:\n%s", mYaml)
// If a bug is present, some items might be replaced instead of merged like we expect
expected := map[any]any{
"firewall": map[any]any{
"inbound": []any{
map[any]any{"host": "any", "port": "any", "proto": "icmp"},
map[any]any{"groups": []any{"server"}, "port": 443, "proto": "tcp"},
map[any]any{"groups": []any{"webapp"}, "port": 443, "proto": "tcp"}},
"outbound": []any{
map[any]any{"host": "any", "port": "any", "proto": "any"}}},
"listen": map[any]any{
"host": "0.0.0.0",
"port": 4242,
},
}
assert.Equal(t, expected, m)
}