mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-02 16:30:17 +02:00
authorize: hot path identity provider lookup optimizations
This commit is contained in:
parent
7eca911292
commit
e18c04216e
29 changed files with 387 additions and 284 deletions
184
config/identity_benchmark_test.go
Normal file
184
config/identity_benchmark_test.go
Normal file
|
@ -0,0 +1,184 @@
|
|||
package config_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func BenchmarkGetIdentityProviderForRequestURL_Old(b *testing.B) {
|
||||
runBench := func(numPolicies int) func(b *testing.B) {
|
||||
return func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
options := config.NewDefaultOptions()
|
||||
sharedKey := cryptutil.NewKey()
|
||||
options.SharedKey = base64.StdEncoding.EncodeToString(sharedKey)
|
||||
options.Provider = "oidc"
|
||||
options.ProviderURL = "https://oidc.example.com"
|
||||
options.ClientID = "client_id"
|
||||
options.ClientSecret = "client_secret"
|
||||
urlFormat := "https://*.foo.bar.test-%d.example.com"
|
||||
for i := range numPolicies {
|
||||
options.Policies = append(options.Policies,
|
||||
config.Policy{
|
||||
From: fmt.Sprintf(urlFormat, i),
|
||||
To: mustParseWeightedURLs(b, fmt.Sprintf("https://p2-%d", i)),
|
||||
IDPClientID: fmt.Sprintf("client_id_%d", i),
|
||||
IDPClientSecret: fmt.Sprintf("client_secret_%d", i),
|
||||
},
|
||||
)
|
||||
}
|
||||
require.NoError(b, options.Validate())
|
||||
|
||||
b.ResetTimer()
|
||||
for range b.N {
|
||||
idp, err := options.GetIdentityProviderForRequestURL(context.Background(), fmt.Sprintf(urlFormat, numPolicies-1))
|
||||
require.NoError(b, err)
|
||||
require.Equal(b, fmt.Sprintf("client_id_%d", numPolicies-1), idp.ClientId)
|
||||
require.Equal(b, fmt.Sprintf("client_secret_%d", numPolicies-1), idp.ClientSecret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b.Run("5 policies", runBench(5))
|
||||
b.Run("50 policies", runBench(50))
|
||||
b.Run("500 policies", runBench(500))
|
||||
b.Run("5000 policies", runBench(5000))
|
||||
}
|
||||
|
||||
var bench = func(fill func(i int, p *config.Policy) string, numPolicies int) func(b *testing.B) {
|
||||
return func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
options := config.NewDefaultOptions()
|
||||
sharedKey := cryptutil.NewKey()
|
||||
options.SharedKey = base64.StdEncoding.EncodeToString(sharedKey)
|
||||
options.Provider = "oidc"
|
||||
options.ProviderURL = "https://oidc.example.com"
|
||||
options.ClientID = "client_id"
|
||||
options.ClientSecret = "client_secret"
|
||||
var allUrls []string
|
||||
for i := range numPolicies {
|
||||
p := config.Policy{
|
||||
To: mustParseWeightedURLs(b, fmt.Sprintf("https://p2-%d", i)),
|
||||
IDPClientID: fmt.Sprintf("client_id_%d", i),
|
||||
IDPClientSecret: fmt.Sprintf("client_secret_%d", i),
|
||||
}
|
||||
|
||||
allUrls = append(allUrls, fill(i, &p))
|
||||
options.Policies = append(options.Policies, p)
|
||||
}
|
||||
require.NoError(b, options.Validate())
|
||||
|
||||
cache, err := config.NewPolicyCache(options)
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := range b.N {
|
||||
reqUrl := strings.Replace(allUrls[i%numPolicies], "*", fmt.Sprint(i), 1)
|
||||
idp, err := cache.GetIdentityProviderForRequestURL(context.Background(), options, reqUrl)
|
||||
require.NoError(b, err)
|
||||
require.Equal(b, fmt.Sprintf("client_id_%d", i%numPolicies), idp.ClientId)
|
||||
require.Equal(b, fmt.Sprintf("client_secret_%d", i%numPolicies), idp.ClientSecret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetIdentityProviderForRequestURL_New_DomainMatchOnly(b *testing.B) {
|
||||
domainMatchingOnly := func(i int, p *config.Policy) string {
|
||||
p.From = fmt.Sprintf("https://*.foo.bar.test-%d.example.com", i)
|
||||
return p.From
|
||||
}
|
||||
|
||||
b.Run("5 policies (domain matching only)", bench(domainMatchingOnly, 5))
|
||||
b.Run("50 policies (domain matching only)", bench(domainMatchingOnly, 50))
|
||||
b.Run("500 policies (domain matching only)", bench(domainMatchingOnly, 500))
|
||||
b.Run("5000 policies (domain matching only)", bench(domainMatchingOnly, 5000))
|
||||
}
|
||||
|
||||
func BenchmarkGetIdentityProviderForRequestURL_New_PathMatchOnly(b *testing.B) {
|
||||
pathMatchingOnly := func(i int, p *config.Policy) string {
|
||||
p.From = "https://example.com"
|
||||
p.Path = fmt.Sprintf("/foo/bar/path%d", i)
|
||||
return p.From + p.Path
|
||||
}
|
||||
b.Run("5 policies (path matching only)", bench(pathMatchingOnly, 5))
|
||||
b.Run("50 policies (path matching only)", bench(pathMatchingOnly, 50))
|
||||
b.Run("500 policies (path matching only)", bench(pathMatchingOnly, 500))
|
||||
b.Run("5000 policies (path matching only)", bench(pathMatchingOnly, 5000))
|
||||
}
|
||||
|
||||
func BenchmarkGetIdentityProviderForRequestURL_New_DomainAndPathMatching(b *testing.B) {
|
||||
combinedMatching := func(numPathsPerDomain int) func(i int, p *config.Policy) string {
|
||||
// returns a sequence of policies (ex: numPathsPerDomain=3)
|
||||
// https://*.foo.bar.test-0.example.com
|
||||
// https://*.foo.bar.test-0.example.com/foo/bar/path1
|
||||
// https://*.foo.bar.test-0.example.com/foo/bar/path2
|
||||
// https://*.foo.bar.test-1.example.com
|
||||
// https://*.foo.bar.test-1.example.com/foo/bar/path1
|
||||
// https://*.foo.bar.test-1.example.com/foo/bar/path2
|
||||
return func(i int, p *config.Policy) string {
|
||||
domain := fmt.Sprintf("https://*.foo.bar.test-%d.example.com", i/numPathsPerDomain)
|
||||
pathIdx := i % numPathsPerDomain
|
||||
var path string
|
||||
if pathIdx == 0 {
|
||||
path = ""
|
||||
} else {
|
||||
path = fmt.Sprintf("/foo/bar/path%d", pathIdx)
|
||||
}
|
||||
p.From = domain
|
||||
p.Path = path
|
||||
return domain + path
|
||||
}
|
||||
}
|
||||
|
||||
b.Run("25 policies (5 domains, 5 paths per domain)", bench(combinedMatching(5), 25))
|
||||
b.Run("500 policies (50 domains, 10 paths per domain)", bench(combinedMatching(10), 500))
|
||||
b.Run("500 policies (10 domains, 50 paths per domain)", bench(combinedMatching(50), 500))
|
||||
b.Run("2500 policies (50 domains, 50 paths per domain)", bench(combinedMatching(50), 2500))
|
||||
b.Run("5000 policies (100 domains, 50 paths per domain)", bench(combinedMatching(50), 5000))
|
||||
b.Run("5000 policies (50 domains, 100 paths per domain)", bench(combinedMatching(100), 5000))
|
||||
b.Run("10000 policies (100 domains, 100 paths per domain)", bench(combinedMatching(100), 10000))
|
||||
}
|
||||
|
||||
func BenchmarkGetIdentityProviderForRequestURL_New_DomainAndPrefixMatching(b *testing.B) {
|
||||
combinedMatching := func(numPathsPerDomain int) func(i int, p *config.Policy) string {
|
||||
// returns a sequence of policies (ex: numPathsPerDomain=3)
|
||||
// https://*.foo.bar.test-0.example.com/0
|
||||
// https://*.foo.bar.test-0.example.com/0/1
|
||||
// https://*.foo.bar.test-0.example.com/0/1/2
|
||||
// https://*.foo.bar.test-1.example.com/0
|
||||
// https://*.foo.bar.test-1.example.com/0/1
|
||||
// https://*.foo.bar.test-1.example.com/0/1/2
|
||||
return func(i int, p *config.Policy) string {
|
||||
domain := fmt.Sprintf("https://*.foo.bar.test-%d.example.com", i/numPathsPerDomain)
|
||||
pathIdx := i % numPathsPerDomain
|
||||
var prefix strings.Builder
|
||||
for i := range pathIdx + 1 {
|
||||
fmt.Fprintf(&prefix, "/%d", i)
|
||||
}
|
||||
p.From = domain
|
||||
p.Prefix = prefix.String()
|
||||
return domain + p.Prefix
|
||||
}
|
||||
}
|
||||
|
||||
b.Run("25 policies (5 domains, 5 paths per domain)", bench(combinedMatching(5), 25))
|
||||
b.Run("500 policies (50 domains, 10 paths per domain)", bench(combinedMatching(10), 500))
|
||||
b.Run("500 policies (10 domains, 50 paths per domain)", bench(combinedMatching(50), 500))
|
||||
b.Run("2500 policies (50 domains, 50 paths per domain)", bench(combinedMatching(50), 2500))
|
||||
b.Run("5000 policies (100 domains, 50 paths per domain)", bench(combinedMatching(50), 5000))
|
||||
b.Run("5000 policies (50 domains, 100 paths per domain)", bench(combinedMatching(100), 5000))
|
||||
b.Run("10000 policies (100 domains, 100 paths per domain)", bench(combinedMatching(100), 10000))
|
||||
}
|
||||
|
||||
func mustParseWeightedURLs(t testing.TB, urls ...string) []config.WeightedURL {
|
||||
wu, err := config.ParseWeightedUrls(urls...)
|
||||
require.NoError(t, err)
|
||||
return wu
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue