Selaa lähdekoodia

Detect group array usage and try to be kind

Nate Brown 5 vuotta sitten
vanhempi
commit
a9c93da8cb
2 muutettua tiedostoa jossa 51 lisäystä ja 3 poistoa
  1. 13 3
      firewall.go
  2. 38 0
      firewall_test.go

+ 13 - 3
firewall.go

@@ -272,7 +272,7 @@ func AddFirewallRulesFromConfig(inbound bool, config *Config, fw FirewallInterfa
 
 	for i, t := range rs {
 		var groups []string
-		r, err := convertRule(t)
+		r, err := convertRule(t, table, i)
 		if err != nil {
 			return fmt.Errorf("%s rule #%v; %s", table, i, err)
 		}
@@ -664,7 +664,7 @@ type rule struct {
 	CASha  string
 }
 
-func convertRule(p interface{}) (rule, error) {
+func convertRule(p interface{}, table string, i int) (rule, error) {
 	r := rule{}
 
 	m, ok := p.(map[interface{}]interface{})
@@ -684,11 +684,21 @@ func convertRule(p interface{}) (rule, error) {
 	r.Code = toString("code", m)
 	r.Proto = toString("proto", m)
 	r.Host = toString("host", m)
-	r.Group = toString("group", m)
 	r.Cidr = toString("cidr", m)
 	r.CAName = toString("ca_name", m)
 	r.CASha = toString("ca_sha", m)
 
+	// Make sure group isn't an array
+	if v, ok := m["group"].([]interface{}); ok {
+		if len(v) > 1 {
+			return r, errors.New("group should contain a single value, an array with more than one entry was provided")
+		}
+
+		l.Warnf("%s rule #%v; group was an array with a single value, converting to simple value", table, i)
+		m["group"] = v[0]
+	}
+	r.Group = toString("group", m)
+
 	if rg, ok := m["groups"]; ok {
 		switch reflect.TypeOf(rg).Kind() {
 		case reflect.Slice:

+ 38 - 0
firewall_test.go

@@ -1,6 +1,7 @@
 package nebula
 
 import (
+	"bytes"
 	"encoding/binary"
 	"errors"
 	"math"
@@ -676,6 +677,43 @@ func TestTCPRTTTracking(t *testing.T) {
 	assert.Equal(t, uint32(0), c.Seq)
 }
 
+func TestFirewall_convertRule(t *testing.T) {
+	ob := &bytes.Buffer{}
+	out := l.Out
+	l.SetOutput(ob)
+	defer l.SetOutput(out)
+
+	// Ensure group array of 1 is converted and a warning is printed
+	c := map[interface{}]interface{}{
+		"group": []interface{}{"group1"},
+	}
+
+	r, err := convertRule(c, "test", 1)
+	assert.Contains(t, ob.String(), "test rule #1; group was an array with a single value, converting to simple value")
+	assert.Nil(t, err)
+	assert.Equal(t, "group1", r.Group)
+
+	// Ensure group array of > 1 is errord
+	ob.Reset()
+	c = map[interface{}]interface{}{
+		"group": []interface{}{"group1", "group2"},
+	}
+
+	r, err = convertRule(c, "test", 1)
+	assert.Equal(t, "", ob.String())
+	assert.Error(t, err, "group should contain a single value, an array with more than one entry was provided")
+
+	// Make sure a well formed group is alright
+	ob.Reset()
+	c = map[interface{}]interface{}{
+		"group": "group1",
+	}
+
+	r, err = convertRule(c, "test", 1)
+	assert.Nil(t, err)
+	assert.Equal(t, "group1", r.Group)
+}
+
 type addRuleCall struct {
 	incoming  bool
 	proto     uint8