From c08792f066f137bb3f561cfcb0b759fd90af467a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Elek?= Date: Mon, 14 Aug 2023 13:30:27 +0200 Subject: [PATCH] satellite/overlay: implement an exclude filter for placement configuration https://github.com/storj/storj/issues/6126 Change-Id: I05215b5d46bec958001cc020edf1fa97b00d3299 --- satellite/nodeselection/filter.go | 19 +++++++++++++++++++ satellite/overlay/placement.go | 3 +++ satellite/overlay/placement_test.go | 12 ++++++++++++ 3 files changed, 34 insertions(+) diff --git a/satellite/nodeselection/filter.go b/satellite/nodeselection/filter.go index dc65c9230..9ff35260e 100644 --- a/satellite/nodeselection/filter.go +++ b/satellite/nodeselection/filter.go @@ -196,3 +196,22 @@ func (t TagFilter) MatchInclude(node *SelectedNode) bool { } var _ NodeFilter = TagFilter{} + +// ExcludeFilter excludes only the matched nodes. +type ExcludeFilter struct { + matchToExclude NodeFilter +} + +// MatchInclude implements NodeFilter interface. +func (e ExcludeFilter) MatchInclude(node *SelectedNode) bool { + return !e.matchToExclude.MatchInclude(node) +} + +// NewExcludeFilter creates filter, nodes matching the given filter will be excluded. +func NewExcludeFilter(filter NodeFilter) ExcludeFilter { + return ExcludeFilter{ + matchToExclude: filter, + } +} + +var _ NodeFilter = ExcludeFilter{} diff --git a/satellite/overlay/placement.go b/satellite/overlay/placement.go index 7b01416e4..9e9ad1656 100644 --- a/satellite/overlay/placement.go +++ b/satellite/overlay/placement.go @@ -126,6 +126,9 @@ func (d *ConfigurablePlacementRule) AddPlacementFromString(definitions string) e key: value, }, nil }, + "exclude": func(filter nodeselection.NodeFilter) (nodeselection.NodeFilter, error) { + return nodeselection.NewExcludeFilter(filter), nil + }, } for _, definition := range strings.Split(definitions, ";") { definition = strings.TrimSpace(definition) diff --git a/satellite/overlay/placement_test.go b/satellite/overlay/placement_test.go index 3312afca2..684e51834 100644 --- a/satellite/overlay/placement_test.go +++ b/satellite/overlay/placement_test.go @@ -124,6 +124,18 @@ func TestPlacementFromString(t *testing.T) { require.Equal(t, nodeselection.GetAnnotation(filters, "autoExcludeSubnet"), "off") }) + t.Run("exclude", func(t *testing.T) { + p := NewPlacementRules() + err := p.AddPlacementFromString(`11:exclude(country("GB"))`) + require.NoError(t, err) + filters := p.placements[storj.PlacementConstraint(11)] + require.False(t, filters.MatchInclude(&nodeselection.SelectedNode{ + CountryCode: location.UnitedKingdom, + })) + require.True(t, filters.MatchInclude(&nodeselection.SelectedNode{ + CountryCode: location.Germany, + })) + }) t.Run("legacy geofencing rules", func(t *testing.T) { p := NewPlacementRules()