2
0
mirror of https://github.com/status-im/consul.git synced 2025-01-12 14:55:02 +00:00

connect: change router syntax for matching query parameters to resemble the syntax for matching paths and headers for consistency. ()

This is a breaking change, but only in the context of the beta series.
This commit is contained in:
R.B. Boyer 2019-07-23 20:55:26 -05:00 committed by GitHub
parent 880d149c19
commit 85cf2706e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 170 additions and 63 deletions

@ -3121,16 +3121,16 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
"path_prefix": "/foo",
"query_param": [
{
"name": "hack1"
"name": "hack1",
"present": true
},
{
"name": "hack2",
"value": "1"
"exact": "1"
},
{
"name": "hack3",
"value": "a.*z",
"regex": true
"regex": "a.*z"
}
]
}
@ -3205,15 +3205,15 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
query_param = [
{
name = "hack1"
present = true
},
{
name = "hack2"
value = "1"
exact = "1"
},
{
name = "hack3"
value = "a.*z"
regex = true
regex = "a.*z"
},
]
}
@ -3286,16 +3286,16 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
PathPrefix: "/foo",
QueryParam: []structs.ServiceRouteHTTPMatchQueryParam{
{
Name: "hack1",
Name: "hack1",
Present: true,
},
{
Name: "hack2",
Value: "1",
Exact: "1",
},
{
Name: "hack3",
Value: "a.*z",
Regex: true,
Regex: "a.*z",
},
},
},

@ -124,6 +124,20 @@ func (e *ServiceRouterConfigEntry) Validate() error {
if qm.Name == "" {
return fmt.Errorf("Route[%d] QueryParam[%d] missing required Name field", i, j)
}
qmParts := 0
if qm.Present {
qmParts++
}
if qm.Exact != "" {
qmParts++
}
if qm.Regex != "" {
qmParts++
}
if qmParts != 1 {
return fmt.Errorf("Route[%d] QueryParam[%d] should only contain one of Present, Exact, or Regex", i, j)
}
}
}
@ -229,9 +243,10 @@ type ServiceRouteHTTPMatchHeader struct {
}
type ServiceRouteHTTPMatchQueryParam struct {
Name string
Value string `json:",omitempty"`
Regex bool `json:",omitempty"`
Name string
Present bool `json:",omitempty"`
Exact string `json:",omitempty"`
Regex string `json:",omitempty"`
}
// ServiceRouteDestination describes how to proxy the actual matching request

@ -960,11 +960,68 @@ func TestServiceRouterConfigEntry(t *testing.T) {
{
name: "route with no name query param",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Value: "foo",
Exact: "foo",
}))),
validateErr: "missing required Name field",
},
{
name: "route with query param exact match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Exact: "bar",
}))),
},
{
name: "route with query param regex match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Regex: "bar",
}))),
},
{
name: "route with query param present match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Present: true,
}))),
},
{
name: "route with query param exact and regex match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Exact: "bar",
Regex: "bar",
}))),
validateErr: "should only contain one of Present, Exact, or Regex",
},
{
name: "route with query param exact and present match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Exact: "bar",
Present: true,
}))),
validateErr: "should only contain one of Present, Exact, or Regex",
},
{
name: "route with query param regex and present match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Regex: "bar",
Present: true,
}))),
validateErr: "should only contain one of Present, Exact, or Regex",
},
{
name: "route with query param exact, regex, and present match",
entry: makerouter(routeMatch(httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Exact: "bar",
Regex: "bar",
Present: true,
}))),
validateErr: "should only contain one of Present, Exact, or Regex",
},
////////////////
{
name: "route with no match and prefix rewrite",
@ -1033,7 +1090,7 @@ func TestServiceRouterConfigEntry(t *testing.T) {
entry: makerouter(ServiceRoute{
Match: httpMatchParam(ServiceRouteHTTPMatchQueryParam{
Name: "foo",
Value: "bar",
Exact: "bar",
}),
Destination: &ServiceRouteDestination{
Service: "other",

@ -171,15 +171,15 @@ func TestDecodeConfigEntry(t *testing.T) {
query_param = [
{
name = "hack1"
present = true
},
{
name = "hack2"
value = "1"
exact = "1"
},
{
name = "hack3"
value = "a.*z"
regex = true
regex = "a.*z"
},
]
}
@ -249,15 +249,15 @@ func TestDecodeConfigEntry(t *testing.T) {
QueryParam = [
{
Name = "hack1"
Present = true
},
{
Name = "hack2"
Value = "1"
Exact = "1"
},
{
Name = "hack3"
Value = "a.*z"
Regex = true
Regex = "a.*z"
},
]
}
@ -326,16 +326,16 @@ func TestDecodeConfigEntry(t *testing.T) {
PathPrefix: "/foo",
QueryParam: []ServiceRouteHTTPMatchQueryParam{
{
Name: "hack1",
Name: "hack1",
Present: true,
},
{
Name: "hack2",
Value: "1",
Exact: "1",
},
{
Name: "hack3",
Value: "a.*z",
Regex: true,
Regex: "a.*z",
},
},
},

@ -256,9 +256,19 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute, pro
em.QueryParameters = make([]*envoyroute.QueryParameterMatcher, 0, len(match.HTTP.QueryParam))
for _, qm := range match.HTTP.QueryParam {
eq := &envoyroute.QueryParameterMatcher{
Name: qm.Name,
Value: qm.Value,
Regex: makeBoolValue(qm.Regex),
Name: qm.Name,
}
switch {
case qm.Exact != "":
eq.Value = qm.Exact
case qm.Regex != "":
eq.Value = qm.Regex
eq.Regex = makeBoolValue(true)
case qm.Present:
eq.Value = ""
default:
continue // skip this impossible situation
}
em.QueryParameters = append(em.QueryParameters, eq)

@ -192,19 +192,25 @@ func TestRoutesFromSnapshot(t *testing.T) {
},
{
Match: httpMatchParam(structs.ServiceRouteHTTPMatchQueryParam{
Name: "secretparam",
Value: "exact",
Name: "secretparam1",
Exact: "exact",
}),
Destination: toService("prm-exact"),
},
{
Match: httpMatchParam(structs.ServiceRouteHTTPMatchQueryParam{
Name: "secretparam",
Value: "regex",
Regex: true,
Name: "secretparam2",
Regex: "regex",
}),
Destination: toService("prm-regex"),
},
{
Match: httpMatchParam(structs.ServiceRouteHTTPMatchQueryParam{
Name: "secretparam3",
Present: true,
}),
Destination: toService("prm-present"),
},
{
Match: nil,
Destination: toService("nil-match"),

@ -125,9 +125,8 @@
"prefix": "/",
"queryParameters": [
{
"name": "secretparam",
"value": "exact",
"regex": false
"name": "secretparam1",
"value": "exact"
}
]
},
@ -140,7 +139,7 @@
"prefix": "/",
"queryParameters": [
{
"name": "secretparam",
"name": "secretparam2",
"value": "regex",
"regex": true
}
@ -150,6 +149,19 @@
"cluster": "prm-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
}
},
{
"match": {
"prefix": "/",
"queryParameters": [
{
"name": "secretparam3"
}
]
},
"route": {
"cluster": "prm-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
}
},
{
"match": {
"prefix": "/"

@ -49,9 +49,10 @@ type ServiceRouteHTTPMatchHeader struct {
}
type ServiceRouteHTTPMatchQueryParam struct {
Name string
Value string `json:",omitempty"`
Regex bool `json:",omitempty"`
Name string
Present bool `json:",omitempty"`
Exact string `json:",omitempty"`
Regex string `json:",omitempty"`
}
type ServiceRouteDestination struct {

@ -200,7 +200,7 @@ func TestAPI_ConfigEntry_DiscoveryChain(t *testing.T) {
{Name: "x-debug", Exact: "1"},
},
QueryParam: []ServiceRouteHTTPMatchQueryParam{
{Name: "debug", Value: "1"},
{Name: "debug", Exact: "1"},
},
},
},

@ -265,15 +265,15 @@ func TestParseConfigEntry(t *testing.T) {
query_param = [
{
name = "hack1"
present = true
},
{
name = "hack2"
value = "1"
exact = "1"
},
{
name = "hack3"
value = "a.*z"
regex = true
regex = "a.*z"
},
]
}
@ -343,15 +343,15 @@ func TestParseConfigEntry(t *testing.T) {
QueryParam = [
{
Name = "hack1"
Present = true
},
{
Name = "hack2"
Value = "1"
Exact = "1"
},
{
Name = "hack3"
Value = "a.*z"
Regex = true
Regex = "a.*z"
},
]
}
@ -420,16 +420,16 @@ func TestParseConfigEntry(t *testing.T) {
PathPrefix: "/foo",
QueryParam: []api.ServiceRouteHTTPMatchQueryParam{
{
Name: "hack1",
Name: "hack1",
Present: true,
},
{
Name: "hack2",
Value: "1",
Exact: "1",
},
{
Name: "hack3",
Value: "a.*z",
Regex: true,
Regex: "a.*z",
},
},
},

@ -84,7 +84,7 @@ routes = [
query_param = [
{
name = "x-debug"
value = "1"
exact = "1"
},
]
}
@ -176,16 +176,22 @@ routes = [
- `Name` `(string: <required>)` - The name of the query parameter to
match on.
- `Value` `(string: <required>)` - String to match against the query
parameter value. The behavior changes with the definition of the
`Regex` field.
- `Regex` `(bool: false)` - Controls how the `Value` field is used. If
`Regex` is `false` then `Value` matches exactly. If `Regex` is
`true` then `Value` matches as a regular expression pattern.
- `Present` `(bool: false)` - Match if the query parameter with the given name
is present with any value.
The syntax when using the Envoy proxy is [documented
here](https://en.cppreference.com/w/cpp/regex/ecmascript).
At most only one of `Exact`, `Regex`, or `Present` may be configured.
- `Exact` `(string: "")` - Match if the query parameter with the given
name is this value.
At most only one of `Exact`, `Regex`, or `Present` may be configured.
- `Regex` `(string: "")` - Match if the query parameter with the given
name matches this pattern.
The syntax when using the Envoy proxy is [documented here](https://en.cppreference.com/w/cpp/regex/ecmascript).
At most only one of `Exact`, `Regex`, or `Present` may be configured.
- `Destination` `(ServiceRouteDestination: <optional>)` - Controls how to
proxy the actual matching request to a service.