Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

databroker: build config concurrently, option to bypass validation #4655

Merged
merged 7 commits into from Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/options.go
Expand Up @@ -460,7 +460,7 @@ func (o *Options) parsePolicy() error {
}
}
for i := range o.AdditionalPolicies {
p := &o.AdditionalPolicies[i]
p := o.AdditionalPolicies[i]
if err := p.Validate(); err != nil {
return err
}
Expand Down
71 changes: 67 additions & 4 deletions config/policy.go
Expand Up @@ -8,6 +8,7 @@ import (
"net/url"
"os"
"regexp"
"sort"
"strings"
"time"

Expand All @@ -25,6 +26,8 @@ import (

// Policy contains route specific configuration and access settings.
type Policy struct {
ID string `mapstructure:"-" yaml:"-" json:"-"`

From string `mapstructure:"from" yaml:"from"`
To WeightedURLs `mapstructure:"to" yaml:"to"`

Expand All @@ -41,10 +44,11 @@ type Policy struct {
AllowedIDPClaims identity.FlattenedClaims `mapstructure:"allowed_idp_claims" yaml:"allowed_idp_claims,omitempty" json:"allowed_idp_claims,omitempty"`

// Additional route matching options
Prefix string `mapstructure:"prefix" yaml:"prefix,omitempty" json:"prefix,omitempty"`
Path string `mapstructure:"path" yaml:"path,omitempty" json:"path,omitempty"`
Regex string `mapstructure:"regex" yaml:"regex,omitempty" json:"regex,omitempty"`
compiledRegex *regexp.Regexp
Prefix string `mapstructure:"prefix" yaml:"prefix,omitempty" json:"prefix,omitempty"`
Path string `mapstructure:"path" yaml:"path,omitempty" json:"path,omitempty"`
Regex string `mapstructure:"regex" yaml:"regex,omitempty" json:"regex,omitempty"`
RegexPriorityOrder *int64 `mapstructure:"regex_priority_order" yaml:"regex_priority_order,omitempty" json:"regex_priority_order,omitempty"`
compiledRegex *regexp.Regexp

// Path Rewrite Options
PrefixRewrite string `mapstructure:"prefix_rewrite" yaml:"prefix_rewrite,omitempty" json:"prefix_rewrite,omitempty"`
Expand Down Expand Up @@ -223,6 +227,7 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
}

p := &Policy{
ID: pb.GetId(),
From: pb.GetFrom(),
AllowedUsers: pb.GetAllowedUsers(),
AllowedDomains: pb.GetAllowedDomains(),
Expand All @@ -233,6 +238,7 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
PrefixRewrite: pb.GetPrefixRewrite(),
RegexRewritePattern: pb.GetRegexRewritePattern(),
RegexRewriteSubstitution: pb.GetRegexRewriteSubstitution(),
RegexPriorityOrder: pb.RegexPriorityOrder,
CORSAllowPreflight: pb.GetCorsAllowPreflight(),
AllowPublicUnauthenticatedAccess: pb.GetAllowPublicUnauthenticatedAccess(),
AllowAnyAuthenticatedUser: pb.GetAllowAnyAuthenticatedUser(),
Expand Down Expand Up @@ -667,3 +673,60 @@ type routeID struct {
Regex string
Redirect *PolicyRedirect
}

/*
SortPolicies sorts policies to match the following SQL order:

ORDER BY from ASC,
path DESC NULLS LAST,
regex_priority_order DESC NULLS LAST,
regex DESC NULLS LAST
prefix DESC NULLS LAST,
id ASC
*/
func SortPolicies(pp []Policy) {
sort.SliceStable(pp, func(i, j int) bool {
strDesc := func(a, b string) (val bool, equal bool) {
return a > b, a == b
}

strAsc := func(a, b string) (val bool, equal bool) {
return a < b, a == b
}

intPDesc := func(a, b *int64) (val bool, equal bool) {
if a == nil && b == nil {
return false, true
}
if a == nil && b != nil {
return false, false
}
if a != nil && b == nil {
return true, false
}
return *a > *b, *a == *b
}

if val, equal := strAsc(pp[i].From, pp[j].From); !equal {
return val
}

if val, equal := strDesc(pp[i].Path, pp[j].Path); !equal {
return val
}

if val, equal := intPDesc(pp[i].RegexPriorityOrder, pp[j].RegexPriorityOrder); !equal {
return val
}

if val, equal := strDesc(pp[i].Regex, pp[j].Regex); !equal {
return val
}

if val, equal := strDesc(pp[i].Prefix, pp[j].Prefix); !equal {
return val
}

return pp[i].ID < pp[j].ID // Ascending order for ID
})
}
61 changes: 61 additions & 0 deletions config/policy_test.go
Expand Up @@ -279,3 +279,64 @@ func TestPolicy_Matches(t *testing.T) {
assert.True(t, p.Matches(urlutil.MustParseAndValidateURL(`https://redis.example.com:6379`)))
})
}

func TestPolicy_SortOrder(t *testing.T) {
ptr := func(i int64) *int64 {
return &i
}

testCases := []struct {
name string
policies []Policy
wantIDs []string
}{
{
name: "regexPriorityOrder DESC NULLS LAST",
policies: []Policy{
{From: "a", Path: "/a", RegexPriorityOrder: nil, ID: "3"},
{From: "a", Path: "/a", RegexPriorityOrder: ptr(2), ID: "2"},
{From: "a", Path: "/a", RegexPriorityOrder: ptr(1), ID: "1"},
},
wantIDs: []string{"2", "1", "3"},
},
{
name: "from ASC",
policies: []Policy{
{From: "", Path: "", RegexPriorityOrder: nil, ID: "B"},
{From: "", Path: "", RegexPriorityOrder: ptr(0), ID: "C"},
{From: "source", Path: "/a", RegexPriorityOrder: ptr(1), ID: "A"},
},
wantIDs: []string{"C", "B", "A"},
},
{
name: "id ASC",
policies: []Policy{
{From: "source", Path: "/a", RegexPriorityOrder: ptr(1), Regex: "regex", Prefix: "prefix", ID: "2"},
{From: "source", Path: "/a", RegexPriorityOrder: ptr(1), Regex: "regex", Prefix: "prefix", ID: "1"},
},
wantIDs: []string{"1", "2"},
},
{
name: "path DESC",
policies: []Policy{
{From: "source", Path: "/b", RegexPriorityOrder: ptr(1), ID: "3"},
{From: "source", Path: "/a", RegexPriorityOrder: nil, ID: "2"},
{From: "source", Path: "/a", RegexPriorityOrder: ptr(2), ID: "1"},
},
wantIDs: []string{"3", "1", "2"},
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
SortPolicies(tt.policies)

gotIDs := make([]string, 0, len(tt.policies))
for _, entity := range tt.policies {
gotIDs = append(gotIDs, entity.ID)
}

assert.Equal(t, tt.wantIDs, gotIDs)
})
}
}