Skip to content

Commit

Permalink
Merge pull request #411 from cocowh/sub_node_filter
Browse files Browse the repository at this point in the history
MotanCluster refers filter support subnet rule
  • Loading branch information
rayzhang0603 authored Dec 27, 2024
2 parents bb1f26f + 63c07e3 commit f33fd57
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 11 deletions.
42 changes: 37 additions & 5 deletions cluster/RefersFilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
motan "github.com/weibocom/motan-go/core"
vlog "github.com/weibocom/motan-go/log"
"net"
"strings"
)

Expand Down Expand Up @@ -58,13 +59,30 @@ type RefersFilter interface {
type filterRule struct {
mode string
prefixes []string
subnets []*net.IPNet
}

func (fr filterRule) IsMatch(refer motan.EndPoint) bool {
for _, prefix := range fr.prefixes {
if strings.HasPrefix(refer.GetURL().Host, prefix) {
if fr.mode == FilterModeExclude {
vlog.Infof("filter refer: %s, rule: %s, mode: %s", refer.GetURL().GetIdentity(), prefix, fr.mode)
vlog.Infof("filter refer: %s, prefix rule: %s, mode: %s", refer.GetURL().GetIdentity(), prefix, fr.mode)
}
return true
}
}
if len(fr.subnets) == 0 {
return false
}
ip := net.ParseIP(refer.GetURL().Host)
if ip == nil {
vlog.Errorf("invalid refer ip: %s", refer.GetURL().Host)
return false
}
for _, ipNet := range fr.subnets {
if ipNet.Contains(ip) {
if fr.mode == FilterModeExclude {
vlog.Infof("filter refer: %s, subnet rule: %s, mode: %s", refer.GetURL().GetIdentity(), ipNet.String(), fr.mode)
}
return true
}
Expand All @@ -81,14 +99,28 @@ func NewDefaultRefersFilter(filterConfig []RefersFilterConfig) *DefaultRefersFil
var includeRules []filterRule
var excludeRules []filterRule
for _, config := range filterConfig {
rule := filterRule{
rules := motan.TrimSplit(config.Rule, ",")
fr := filterRule{
mode: config.Mode,
prefixes: motan.TrimSplit(config.Rule, ","),
prefixes: []string{},
subnets: []*net.IPNet{},
}
for _, item := range rules {
if strings.Contains(item, "/") {
_, subnet, err := net.ParseCIDR(item)
if err != nil {
vlog.Errorf("invalid subnet rule: %s", item)
continue
}
fr.subnets = append(fr.subnets, subnet)
} else {
fr.prefixes = append(fr.prefixes, item)
}
}
if config.Mode == FilterModeExclude {
excludeRules = append(excludeRules, rule)
excludeRules = append(excludeRules, fr)
} else {
includeRules = append(includeRules, rule)
includeRules = append(includeRules, fr)
}
}
return &DefaultRefersFilter{includeRules: includeRules, excludeRules: excludeRules}
Expand Down
87 changes: 81 additions & 6 deletions cluster/RefersFilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestDefaultRefersFilter_Filter(t *testing.T) {
assertFunc func(t *testing.T, filter DefaultRefersFilter)
}{
{
desc: "include filter",
desc: "include prefix filter",
filter: NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeInclude,
Expand All @@ -143,34 +143,86 @@ func TestDefaultRefersFilter_Filter(t *testing.T) {
assertFunc: func(t *testing.T, filter DefaultRefersFilter) {
refers := []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "123.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "124.1.2.0"}},
}
newRefers := filter.Filter(refers)
assert.Equal(t, len(refers), len(newRefers))

refers = []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "110.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "111.1.2.0"}},
}
newRefers = filter.Filter(refers)
assert.Equal(t, 0, len(newRefers))
},
},
{
desc: "exclude filter",
desc: "include subnet filter",
filter: NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeInclude,
Rule: "10.93.0.0/16",
},
}),
assertFunc: func(t *testing.T, filter DefaultRefersFilter) {
refers := []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "10.93.1.1"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.93.2.10"}},
}
newRefers := filter.Filter(refers)
assert.Equal(t, len(refers), len(newRefers))

refers = []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "10.94.1.1"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.95.1.1"}},
}
newRefers = filter.Filter(refers)
assert.Equal(t, 0, len(newRefers))
},
},
{
desc: "exclude prefix filter",
filter: NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeExclude,
Rule: "123,356",
Rule: "123,177",
},
}),
assertFunc: func(t *testing.T, filter DefaultRefersFilter) {
refers := []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "123.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "177.1.2.0"}},
}
newRefers := filter.Filter(refers)
assert.Equal(t, 0, len(newRefers))

refers = []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "121.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "122.1.2.0"}},
}
newRefers = filter.Filter(refers)
assert.Equal(t, len(refers), len(newRefers))
},
},
{
desc: "exclude subnet filter",
filter: NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeExclude,
Rule: "10.93.0.0/16",
},
}),
assertFunc: func(t *testing.T, filter DefaultRefersFilter) {
refers := []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "10.93.1.1"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.93.2.10"}},
}
newRefers := filter.Filter(refers)
assert.Equal(t, 0, len(newRefers))

refers = []motan.EndPoint{
&motan.TestEndPoint{URL: &motan.URL{Host: "10.94.1.1"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.95.1.1"}},
}
newRefers = filter.Filter(refers)
assert.Equal(t, len(refers), len(newRefers))
Expand All @@ -181,11 +233,11 @@ func TestDefaultRefersFilter_Filter(t *testing.T) {
filter: NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeInclude,
Rule: "123,190",
Rule: "123,190,10.93.0.0/16",
},
{
Mode: FilterModeExclude,
Rule: "123,145",
Rule: "123,145,10.96.0.0/16",
},
}),
assertFunc: func(t *testing.T, filter DefaultRefersFilter) {
Expand All @@ -194,9 +246,12 @@ func TestDefaultRefersFilter_Filter(t *testing.T) {
&motan.TestEndPoint{URL: &motan.URL{Host: "145.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "190.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "110.1.2.0"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.93.1.2"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "10.96.1.2"}},
&motan.TestEndPoint{URL: &motan.URL{Host: "190.96"}}, // retained invalid host
}
newRefers := filter.Filter(refers)
assert.Equal(t, 1, len(newRefers))
assert.Equal(t, 3, len(newRefers))
},
},
}
Expand All @@ -207,3 +262,23 @@ func TestDefaultRefersFilter_Filter(t *testing.T) {
t.Logf("test case: %s finish", f.desc)
}
}

func TestNewDefaultRefersFilter(test *testing.T) {
fr := NewDefaultRefersFilter([]RefersFilterConfig{
{
Mode: FilterModeInclude,
Rule: "123.1,10.2,10.93.0.0/18,10.93.0.0/34", // discard invalid subnet rule
},
{
Mode: FilterModeExclude,
Rule: "124.1,10.1,10.14.0.0/18,10.14.0.0/34", // discard invalid subnet rule
},
})
assert.NotNil(test, fr)
assert.Equal(test, 1, len(fr.includeRules))
assert.Equal(test, 1, len(fr.excludeRules))
assert.Equal(test, 2, len(fr.includeRules[0].prefixes))
assert.Equal(test, 1, len(fr.includeRules[0].subnets))
assert.Equal(test, 2, len(fr.excludeRules[0].prefixes))
assert.Equal(test, 1, len(fr.excludeRules[0].subnets))
}

0 comments on commit f33fd57

Please sign in to comment.