Skip to content

Commit

Permalink
add prefix and regex rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
wardviaene committed Apr 7, 2021
1 parent ff96e67 commit 909392f
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 8 deletions.
15 changes: 10 additions & 5 deletions pkg/api/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ type RuleActions struct {
DirectResponse RuleActionsDirectResponse `json:"directResponse" yaml:"directResponse"`
}
type RuleActionsProxy struct {
Hostname string `json:"hostname"`
Port int64 `json:"port"`
HealthCheck RuleActionHealthCheck `json:"healthCheck" yaml:"healthCheck"`
EnableWebsockets bool `json:"enableWebsockets" yaml:"enableWebsockets"`
Hostname string `json:"hostname"`
Port int64 `json:"port"`
HealthCheck RuleActionHealthCheck `json:"healthCheck" yaml:"healthCheck"`
EnableWebsockets bool `json:"enableWebsockets" yaml:"enableWebsockets"`
PrefixRewrite string `json:"prefixRewrite" yaml:"prefixRewrite"`
RegexRewrite RuleActionsRegexRewrite `json:"regexRewrite" yaml:"regexRewrite"`
}
type RuleActionsRegexRewrite struct {
Regex string `json:"regex" yaml:"regex"`
Substitution string `json:"substitution" yaml:"substitution"`
}

type RuleActionHealthCheck struct {
HTTPHealthCheck HTTPHealthCheck `json:"httpHealthCheck" yaml:"httpHealthCheck"`
Timeout string `json:"timeout" yaml:"timeout"`
Expand Down
18 changes: 15 additions & 3 deletions pkg/envoy/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,12 @@ func (l *Listener) updateListenerWithChallenge(cache *WorkQueueCache, challenge
return nil
}

func (l *Listener) getVirtualHost(listenerName, hostname, targetHostname, targetPrefix, clusterName, virtualHostName string, methods []string, matchType string, directResponse DirectResponse, enableWebsocket bool) *route.VirtualHost {
func (l *Listener) getVirtualHost(listenerName, hostname, targetHostname, targetPrefix, clusterName, virtualHostName string, methods []string, matchType string, directResponse DirectResponse, enableWebsocket bool, prefixRewrite string, regexRewrite RegexRewrite) *route.VirtualHost {
var hostRewriteSpecifier *route.RouteAction_HostRewriteLiteral
var routes []*route.Route
var routeAction *route.Route_Route
var upgradeConfigs []*route.RouteAction_UpgradeConfig
var envoyRegexRewrite *matcher.RegexMatchAndSubstitute
if hostname == "" {
hostname = "*"
}
Expand All @@ -199,13 +200,24 @@ func (l *Listener) getVirtualHost(listenerName, hostname, targetHostname, target
},
}
}
if regexRewrite.Regex != "" {
envoyRegexRewrite = &matcher.RegexMatchAndSubstitute{
Pattern: &matcher.RegexMatcher{
EngineType: &matcher.RegexMatcher_GoogleRe2{},
Regex: regexRewrite.Regex,
},
Substitution: regexRewrite.Substitution,
}
}
routeAction = &route.Route_Route{
Route: &route.RouteAction{
HostRewriteSpecifier: hostRewriteSpecifier,
ClusterSpecifier: &route.RouteAction_Cluster{
Cluster: clusterName,
},
UpgradeConfigs: upgradeConfigs,
PrefixRewrite: prefixRewrite,
RegexRewrite: envoyRegexRewrite,
},
}
} else {
Expand Down Expand Up @@ -407,7 +419,7 @@ func (l *Listener) updateListener(cache *WorkQueueCache, params ListenerParams,
}

// create new virtualhost
v := l.getVirtualHost(ll.Name, params.Conditions.Hostname, params.TargetHostname, targetPrefix, params.Name, virtualHostname, params.Conditions.Methods, matchType, params.DirectResponse, params.EnableWebSockets)
v := l.getVirtualHost(ll.Name, params.Conditions.Hostname, params.TargetHostname, targetPrefix, params.Name, virtualHostname, params.Conditions.Methods, matchType, params.DirectResponse, params.EnableWebSockets, params.PrefixRewrite, params.RegexRewrite)

// check if we need to overwrite the virtualhost
virtualHostKey := -1
Expand Down Expand Up @@ -635,7 +647,7 @@ func (l *Listener) DeleteRoute(cache *WorkQueueCache, params ListenerParams, par
return err
}

v := l.getVirtualHost(ll.Name, params.Conditions.Hostname, params.TargetHostname, targetPrefix, params.Name, virtualHostname, params.Conditions.Methods, matchType, params.DirectResponse, params.EnableWebSockets)
v := l.getVirtualHost(ll.Name, params.Conditions.Hostname, params.TargetHostname, targetPrefix, params.Name, virtualHostname, params.Conditions.Methods, matchType, params.DirectResponse, params.EnableWebSockets, params.PrefixRewrite, params.RegexRewrite)

virtualHostKey := -1
for k, curVirtualHost := range routeSpecifier.RouteConfig.VirtualHosts {
Expand Down
13 changes: 13 additions & 0 deletions pkg/envoy/testdata/test-prefixrewrite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
api: proxy.in4it.io/v1
kind: rule
metadata:
name: test-prefixrewrite
spec:
conditions:
- hostname: test-prefixrewrite.example.com
path: /test-prefixrewrite
actions:
- proxy:
hostname: target-example.com
port: 443
prefixRewrite: /addthis
15 changes: 15 additions & 0 deletions pkg/envoy/testdata/test-regexrewrite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
api: proxy.in4it.io/v1
kind: rule
metadata:
name: test-prefixrewrite
spec:
conditions:
- hostname: test-prefixrewrite.example.com
path: /test-prefixrewrite
actions:
- proxy:
hostname: target-example.com
port: 443
regexRewrite:
regex: "^/service/([^/]+)(/.*)$"
substitution: "\\2/instance/\\1"
9 changes: 9 additions & 0 deletions pkg/envoy/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type ListenerParams struct {
Protocol string
TargetHostname string
EnableWebSockets bool
PrefixRewrite string
RegexRewrite RegexRewrite
Conditions Conditions
Auth Auth
Authz Authz
Expand Down Expand Up @@ -105,6 +107,13 @@ type ActionProxy struct {
Port int64
HealthCheck HealthCheck
EnableWebsockets bool
PrefixRewrite string
RegexRewrite RegexRewrite
}

type RegexRewrite struct {
Regex string
Substitution string
}

type HealthCheck struct {
Expand Down
9 changes: 9 additions & 0 deletions pkg/envoy/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,13 @@ func (x *XDS) getAction(ruleName string, actions []pkgApi.RuleActions) Action {
if ruleAction.Proxy.EnableWebsockets {
action.Proxy.EnableWebsockets = ruleAction.Proxy.EnableWebsockets
}
if ruleAction.Proxy.PrefixRewrite != "" {
action.Proxy.PrefixRewrite = ruleAction.Proxy.PrefixRewrite
}
if ruleAction.Proxy.RegexRewrite.Regex != "" {
action.Proxy.RegexRewrite.Regex = ruleAction.Proxy.RegexRewrite.Regex
action.Proxy.RegexRewrite.Substitution = ruleAction.Proxy.RegexRewrite.Substitution
}
} else if ruleAction.DirectResponse.Status > 0 {
action.Type = "directResponse"
action.RuleName = ruleName
Expand All @@ -520,6 +527,8 @@ func (x *XDS) getListenerParams(action Action, condition pkgApi.RuleConditions)
Name: action.RuleName,
TargetHostname: action.Proxy.TargetHostname,
EnableWebSockets: action.Proxy.EnableWebsockets,
PrefixRewrite: action.Proxy.PrefixRewrite,
RegexRewrite: action.Proxy.RegexRewrite,
Conditions: Conditions{
Hostname: condition.Hostname,
Prefix: condition.Prefix,
Expand Down
110 changes: 110 additions & 0 deletions pkg/envoy/xds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
listenerAPI "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
als "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/grpc/v3"
matcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
"github.com/golang/protobuf/ptypes"
"github.com/in4it/roxprox/pkg/storage"
Expand Down Expand Up @@ -596,6 +597,115 @@ func TestClusterWithWebsockets(t *testing.T) {
}
}
}
func TestClusterWithPathRewrite(t *testing.T) {
logger.SetLogLevel(loggo.DEBUG)
s, err := initStorage()
if err != nil {
t.Errorf("Couldn't initialize storage: %s", err)
return
}
x := NewXDS(s, "", "")
ObjectFileNames := []string{"test-prefixrewrite.yaml"}
for _, filename := range ObjectFileNames {
newItems, err := x.putObject(filename)
if err != nil {
t.Errorf("PutObject failed: %s", err)
return
}
_, err = x.workQueue.Submit(newItems)
if err != nil {
t.Errorf("WorkQueue error: %s", err)
return
}
}

var prefixRewrite string

for _, listener := range x.workQueue.cache.listeners {
ll := listener.(*listenerAPI.Listener)
manager, err := getListenerHTTPConnectionManager(ll)
if err != nil {
t.Errorf("Error while getting listener: %s", err)
return
}
routeSpecifier, err := getListenerRouteSpecifier(manager)
if err != nil {
t.Errorf("Error while getting routes: %s", err)
return
}
for _, virtualHost := range routeSpecifier.RouteConfig.VirtualHosts {
for _, virtualHostRoute := range virtualHost.Routes {
if virtualHostRoute.Action != nil {
switch reflect.TypeOf(virtualHostRoute.Action).String() {
case "*envoy_config_route_v3.Route_Route":
prefixRewrite = virtualHostRoute.Action.(*route.Route_Route).Route.GetPrefixRewrite()
}
}
}
}
if prefixRewrite != "/addthis" {
t.Errorf("Prefix rewrite not found")
return
}
}
}

func TestClusterWithRegexRewrite(t *testing.T) {
logger.SetLogLevel(loggo.DEBUG)
s, err := initStorage()
if err != nil {
t.Errorf("Couldn't initialize storage: %s", err)
return
}
x := NewXDS(s, "", "")
ObjectFileNames := []string{"test-regexrewrite.yaml"}
for _, filename := range ObjectFileNames {
newItems, err := x.putObject(filename)
if err != nil {
t.Errorf("PutObject failed: %s", err)
return
}
_, err = x.workQueue.Submit(newItems)
if err != nil {
t.Errorf("WorkQueue error: %s", err)
return
}
}

var regexRewrite *matcher.RegexMatchAndSubstitute

for _, listener := range x.workQueue.cache.listeners {
ll := listener.(*listenerAPI.Listener)
manager, err := getListenerHTTPConnectionManager(ll)
if err != nil {
t.Errorf("Error while getting listener: %s", err)
return
}
routeSpecifier, err := getListenerRouteSpecifier(manager)
if err != nil {
t.Errorf("Error while getting routes: %s", err)
return
}
for _, virtualHost := range routeSpecifier.RouteConfig.VirtualHosts {
for _, virtualHostRoute := range virtualHost.Routes {
if virtualHostRoute.Action != nil {
switch reflect.TypeOf(virtualHostRoute.Action).String() {
case "*envoy_config_route_v3.Route_Route":
regexRewrite = virtualHostRoute.Action.(*route.Route_Route).Route.GetRegexRewrite()
}
}
}
}
if regexRewrite.Pattern.Regex != "^/service/([^/]+)(/.*)$" {
t.Errorf("Regex pattern in regex rewrite not found")
return
}
if regexRewrite.GetSubstitution() != "\\2/instance/\\1" {
t.Errorf("Regex substitution in regex rewrite not found")
return
}
}
}
func TestCompressionObject(t *testing.T) {
logger.SetLogLevel(loggo.DEBUG)
s, err := initStorage()
Expand Down

0 comments on commit 909392f

Please sign in to comment.