This is an automated email from the ASF dual-hosted git repository.
kvn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push:
new 6461186 chore: redesign nginxVars to exprs (#306)
6461186 is described below
commit 646118696c3eb998ec1619cfdd6560f8c6662105
Author: Alex Zhang <[email protected]>
AuthorDate: Sat Mar 20 20:58:19 2021 +0800
chore: redesign nginxVars to exprs (#306)
---
docs/en/latest/concepts/apisix_route.md | 13 +-
docs/en/latest/references/apisix_route_v2alpha1.md | 12 +-
pkg/kube/apisix/apis/config/v2alpha1/types.go | 28 +++-
.../apis/config/v2alpha1/zz_generated.deepcopy.go | 27 +++-
pkg/kube/translation/apisix_route.go | 29 +++-
pkg/kube/translation/apisix_route_test.go | 178 +++++++++++----------
.../{nginx_vars.go => route_match_exprs.go} | 62 ++++---
7 files changed, 222 insertions(+), 127 deletions(-)
diff --git a/docs/en/latest/concepts/apisix_route.md
b/docs/en/latest/concepts/apisix_route.md
index 52a9a7e..9d0c11f 100644
--- a/docs/en/latest/concepts/apisix_route.md
+++ b/docs/en/latest/concepts/apisix_route.md
@@ -67,7 +67,7 @@ Advanced route features
-----------------------
Path based route are most common, but if it's not enough, try
-other route features in `ApisixRoute` such as `methods`, `nginxVars`.
+other route features in `ApisixRoute` such as `methods`, `exprs`.
The `methods` splits traffic according to the HTTP method, the following
configurations routes requests
with `GET` method to `foo` service (a Kubernetes Service).
@@ -90,7 +90,7 @@ spec:
servicePort: 80
```
-The `nginxVars` allows user to configure match conditions with arbitrary
predicates in HTTP, such as queries, HTTP headers and etc.
+The `exprs` allows user to configure match conditions with arbitrary
predicates in HTTP, such as queries, HTTP headers, Cookie.
It's composed by several expressions, which in turn composed by subject,
operator and value/set.
```yaml
@@ -104,8 +104,10 @@ spec:
match:
paths:
- /
- nginxVars:
- - subject: arg_id
+ exprs:
+ - subject:
+ scope: Query
+ name: id
op: Equal
value: 2143
backend:
@@ -114,8 +116,7 @@ spec:
```
The above configuration configures an extra route match condition, which asks
the
-query `id` must be equal to `2143`. Note the subject is in [Nginx
Variables](http://nginx.org/en/docs/varindex.html) style
-(but without the leading `$` symbol).
+query `id` must be equal to `2143`.
Service Resolution Granularity
------------------------------
diff --git a/docs/en/latest/references/apisix_route_v2alpha1.md
b/docs/en/latest/references/apisix_route_v2alpha1.md
index 40795c5..827d411 100644
--- a/docs/en/latest/references/apisix_route_v2alpha1.md
+++ b/docs/en/latest/references/apisix_route_v2alpha1.md
@@ -35,11 +35,13 @@ Meaning of each field in the spec of ApisixRoute are
followed, the top level fie
| http[].match.hosts | array | A series of hosts that should be matched
(oneof) to use this route rule.
| http[].match.methods | array | A series of HTTP methods(`GET`, `POST`,
`PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`, `CONNECT`, `TRACE`) that should be
matched (oneof) to use this route rule.
| http[].match.remote_addrs | array | A series of IP address (CIDR
format) that should be matched (oneof) to use this route rule.
-| http[].match.nginxVars | array | A series expressions that the
results should be matched (oneof) to use this route rule.
-| http[].match.nginxVars[].subject | string | Expression subject,
which is in [Nginx Variables](http://nginx.org/en/docs/varindex.html) style.
-| http[].match.nginxVars[].op | string | Expression operator, see [Expression
Operators](#expression-operators) for the detail of enumerations.
-| http[].match.nginxVars[].value | string | Expected expression result, it's
exclusive with `http[].match.nginxVars[].set`.
-| http[].match.nginxVars[].set | array | Expected expression result set, only
used when the operator is `In` or `NotIn`, it's exclusive with
`http[].match.nginxVars[].value`.
+| http[].match.exprs | array | A series expressions that the
results should be matched (oneof) to use this route rule.
+| http[].match.exprs[].subject | object | Expression subject.
+| http[].match.exprs[].subject.scope | string | Specify where to find
the subject, values can be `Header`, `Query`, `Cookie` and `Path`.
+| http[].match.exprs[].subject.name | string | Specify subject name,
when scope is `Path`, this field can be absent.
+| http[].match.exprs[].op | string | Expression operator, see [Expression
Operators](#expression-operators) for the detail of enumerations.
+| http[].match.exprs[].value | string | Expected expression result, it's
exclusive with `http[].match.exprs[].set`.
+| http[].match.exprs[].set | array | Expected expression result set, only used
when the operator is `In` or `NotIn`, it's exclusive with
`http[].match.exprs[].value`.
| http[].backend | object | The backend service
| http[].backend.serviceName | string | The backend service name, note the
service and ApisixRoute should be created in the same namespace. Cross
namespace referencing is not allowed.
| http[].backend.servicePort | integer or string | The backend service port,
can be the port number of the name defined in the service object.
diff --git a/pkg/kube/apisix/apis/config/v2alpha1/types.go
b/pkg/kube/apisix/apis/config/v2alpha1/types.go
index 64c009b..4fb4c4d 100644
--- a/pkg/kube/apisix/apis/config/v2alpha1/types.go
+++ b/pkg/kube/apisix/apis/config/v2alpha1/types.go
@@ -49,6 +49,15 @@ const (
OpIn = "In"
// OpNotIn means the not in operator ("not_in") in nginxVars.
OpNotIn = "NotIn"
+
+ // ScopeQuery means the route match expression subject is in the
querystring.
+ ScopeQuery = "Query"
+ // ScopeHeader means the route match expression subject is in request
headers.
+ ScopeHeader = "Header"
+ // ScopePath means the route match expression subject is the uri path.
+ ScopePath = "Path"
+ // ScopeCookie means the route match expression subject is in cookie.
+ ScopeCookie = "Cookie"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -104,15 +113,15 @@ type ApisixRouteHTTPMatch struct {
// value:
// - "127.0.0.1"
// - "10.0.5.11"
- NginxVars []ApisixRouteHTTPMatchNginxVar `json:"nginxVars,omitempty"`
+ NginxVars []ApisixRouteHTTPMatchExpr `json:"exprs,omitempty"`
}
-// ApisixRouteHTTPMatchNginxVar represents a binary expression for the Nginx
vars.
-type ApisixRouteHTTPMatchNginxVar struct {
+// ApisixRouteHTTPMatchExpre represents a binary route match expression .
+type ApisixRouteHTTPMatchExpr struct {
// Subject is the expression subject, it can
// be any string composed by literals and nginx
// vars.
- Subject string `json:"subject"`
+ Subject ApisixRouteHTTPMatchExprSubject `json:"subject"`
// Op is the operator.
Op string `json:"op"`
// Set is an array type object of the expression.
@@ -125,6 +134,17 @@ type ApisixRouteHTTPMatchNginxVar struct {
Value *string `json:"value"`
}
+// ApisixRouteHTTPMatchExprSubject describes the route match expression
subject.
+type ApisixRouteHTTPMatchExprSubject struct {
+ // The subject scope, can be:
+ // ScopeQuery, ScopeHeader, ScopePath
+ // when subject is ScopePath, Name field
+ // will be ignored.
+ Scope string `json:"scope"`
+ // The name of subject.
+ Name string `json:"name"`
+}
+
// ApisixRouteHTTPBackend represents a HTTP backend (a Kuberentes Service).
type ApisixRouteHTTPBackend struct {
// The name (short) of the service, note cross namespace is forbidden,
diff --git a/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
b/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
index 7dc2f84..225314d 100644
--- a/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
+++ b/pkg/kube/apisix/apis/config/v2alpha1/zz_generated.deepcopy.go
@@ -134,7 +134,7 @@ func (in *ApisixRouteHTTPMatch) DeepCopyInto(out
*ApisixRouteHTTPMatch) {
}
if in.NginxVars != nil {
in, out := &in.NginxVars, &out.NginxVars
- *out = make([]ApisixRouteHTTPMatchNginxVar, len(*in))
+ *out = make([]ApisixRouteHTTPMatchExpr, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -153,8 +153,9 @@ func (in *ApisixRouteHTTPMatch) DeepCopy()
*ApisixRouteHTTPMatch {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
-func (in *ApisixRouteHTTPMatchNginxVar) DeepCopyInto(out
*ApisixRouteHTTPMatchNginxVar) {
+func (in *ApisixRouteHTTPMatchExpr) DeepCopyInto(out
*ApisixRouteHTTPMatchExpr) {
*out = *in
+ out.Subject = in.Subject
if in.Set != nil {
in, out := &in.Set, &out.Set
*out = make([]string, len(*in))
@@ -168,12 +169,28 @@ func (in *ApisixRouteHTTPMatchNginxVar) DeepCopyInto(out
*ApisixRouteHTTPMatchNg
return
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new ApisixRouteHTTPMatchNginxVar.
-func (in *ApisixRouteHTTPMatchNginxVar) DeepCopy()
*ApisixRouteHTTPMatchNginxVar {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new ApisixRouteHTTPMatchExpr.
+func (in *ApisixRouteHTTPMatchExpr) DeepCopy() *ApisixRouteHTTPMatchExpr {
if in == nil {
return nil
}
- out := new(ApisixRouteHTTPMatchNginxVar)
+ out := new(ApisixRouteHTTPMatchExpr)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *ApisixRouteHTTPMatchExprSubject) DeepCopyInto(out
*ApisixRouteHTTPMatchExprSubject) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new ApisixRouteHTTPMatchExprSubject.
+func (in *ApisixRouteHTTPMatchExprSubject) DeepCopy()
*ApisixRouteHTTPMatchExprSubject {
+ if in == nil {
+ return nil
+ }
+ out := new(ApisixRouteHTTPMatchExprSubject)
in.DeepCopyInto(out)
return out
}
diff --git a/pkg/kube/translation/apisix_route.go
b/pkg/kube/translation/apisix_route.go
index d9f1bea..548c1c9 100644
--- a/pkg/kube/translation/apisix_route.go
+++ b/pkg/kube/translation/apisix_route.go
@@ -16,6 +16,7 @@ package translation
import (
"errors"
+ "strings"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/intstr"
@@ -157,7 +158,7 @@ func (t *translator) TranslateRouteV2alpha1(ar
*configv2alpha1.ApisixRoute) ([]*
}
}
if part.Match.NginxVars != nil {
- vars, err = t.translateNginxVars(part.Match.NginxVars)
+ vars, err =
t.translateRouteMatchExprs(part.Match.NginxVars)
if err != nil {
log.Errorw("ApisixRoute with bad nginxVars",
zap.Error(err),
@@ -214,7 +215,7 @@ func (t *translator) TranslateRouteV2alpha1(ar
*configv2alpha1.ApisixRoute) ([]*
return routes, upstreams, nil
}
-func (t *translator) translateNginxVars(nginxVars
[]configv2alpha1.ApisixRouteHTTPMatchNginxVar) ([][]apisixv1.StringOrSlice,
error) {
+func (t *translator) translateRouteMatchExprs(nginxVars
[]configv2alpha1.ApisixRouteHTTPMatchExpr) ([][]apisixv1.StringOrSlice, error) {
var (
vars [][]apisixv1.StringOrSlice
op string
@@ -222,13 +223,33 @@ func (t *translator) translateNginxVars(nginxVars
[]configv2alpha1.ApisixRouteHT
for _, expr := range nginxVars {
var (
invert bool
+ subj string
this []apisixv1.StringOrSlice
)
- if expr.Subject == "" {
+ if expr.Subject.Name == "" && expr.Subject.Scope !=
configv2alpha1.ScopePath {
+ return nil, errors.New("empty subject name")
+ }
+ switch expr.Subject.Scope {
+ case configv2alpha1.ScopeQuery:
+ subj = "arg_" + strings.ToLower(expr.Subject.Name)
+ case configv2alpha1.ScopeHeader:
+ name := strings.ToLower(expr.Subject.Name)
+ name = strings.ReplaceAll(name, "-", "_")
+ subj = "http_" + name
+ case configv2alpha1.ScopeCookie:
+ name := strings.ToLower(expr.Subject.Name)
+ name = strings.ReplaceAll(name, "-", "_")
+ subj = "cookie_" + name
+ case configv2alpha1.ScopePath:
+ subj = "uri"
+ default:
+ return nil, errors.New("bad subject name")
+ }
+ if expr.Subject.Scope == "" {
return nil, errors.New("empty nginxVar subject")
}
this = append(this, apisixv1.StringOrSlice{
- StrVal: expr.Subject,
+ StrVal: subj,
})
switch expr.Op {
diff --git a/pkg/kube/translation/apisix_route_test.go
b/pkg/kube/translation/apisix_route_test.go
index 0911a6b..0a7a80e 100644
--- a/pkg/kube/translation/apisix_route_test.go
+++ b/pkg/kube/translation/apisix_route_test.go
@@ -22,123 +22,137 @@ import (
configv2alpha1
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1"
)
-func TestNginxVars(t *testing.T) {
+func TestRouteMatchExpr(t *testing.T) {
tr := &translator{}
value1 := "text/plain"
value2 := "gzip"
value3 := "13"
value4 := ".*\\.php"
- ngxVars := []configv2alpha1.ApisixRouteHTTPMatchNginxVar{
+ exprs := []configv2alpha1.ApisixRouteHTTPMatchExpr{
{
- Subject: "http_content_type",
- Op: configv2alpha1.OpEqual,
- Value: &value1,
- },
- {
- Subject: "http_content_encoding",
- Op: configv2alpha1.OpNotEqual,
- Value: &value2,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeHeader,
+ Name: "Content-Type",
+ },
+ Op: configv2alpha1.OpEqual,
+ Value: &value1,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpGreaterThan,
- Value: &value3,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeHeader,
+ Name: "Content-Encoding",
+ },
+ Op: configv2alpha1.OpNotEqual,
+ Value: &value2,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpLessThan,
- Value: &value3,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
+ },
+ Op: configv2alpha1.OpGreaterThan,
+ Value: &value3,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpRegexMatch,
- Value: &value4,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
+ },
+ Op: configv2alpha1.OpLessThan,
+ Value: &value3,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpRegexMatchCaseInsensitive,
- Value: &value4,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
+ },
+ Op: configv2alpha1.OpRegexMatch,
+ Value: &value4,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpRegexNotMatch,
- Value: &value4,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
+ },
+ Op: configv2alpha1.OpRegexMatchCaseInsensitive,
+ Value: &value4,
},
{
- Subject: "arg_id",
- Op: configv2alpha1.OpRegexNotMatchCaseInsensitive,
- Value: &value4,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
+ },
+ Op: configv2alpha1.OpRegexNotMatch,
+ Value: &value4,
},
{
- Subject: "remote_addr",
- Op: configv2alpha1.OpIn,
- Set: []string{
- "10.0.5.3",
- "10.0.5.4",
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeQuery,
+ Name: "ID",
},
+ Op: configv2alpha1.OpRegexNotMatchCaseInsensitive,
+ Value: &value4,
},
{
- Subject: "remote_addr",
- Op: configv2alpha1.OpNotIn,
+ Subject: configv2alpha1.ApisixRouteHTTPMatchExprSubject{
+ Scope: configv2alpha1.ScopeCookie,
+ Name: "domain",
+ },
+ Op: configv2alpha1.OpIn,
Set: []string{
- "10.0.5.6",
+ "a.com",
+ "b.com",
},
},
}
- vars, err := tr.translateNginxVars(ngxVars)
+ results, err := tr.translateRouteMatchExprs(exprs)
assert.Nil(t, err)
- assert.Len(t, vars, 10)
-
- assert.Len(t, vars[0], 3)
- assert.Equal(t, vars[0][0].StrVal, "http_content_type")
- assert.Equal(t, vars[0][1].StrVal, "==")
- assert.Equal(t, vars[0][2].StrVal, "text/plain")
+ assert.Len(t, results, 9)
- assert.Len(t, vars[1], 3)
- assert.Equal(t, vars[1][0].StrVal, "http_content_encoding")
- assert.Equal(t, vars[1][1].StrVal, "~=")
- assert.Equal(t, vars[1][2].StrVal, "gzip")
+ assert.Len(t, results[0], 3)
+ assert.Equal(t, results[0][0].StrVal, "http_content_type")
+ assert.Equal(t, results[0][1].StrVal, "==")
+ assert.Equal(t, results[0][2].StrVal, "text/plain")
- assert.Len(t, vars[2], 3)
- assert.Equal(t, vars[2][0].StrVal, "arg_id")
- assert.Equal(t, vars[2][1].StrVal, ">")
- assert.Equal(t, vars[2][2].StrVal, "13")
+ assert.Len(t, results[1], 3)
+ assert.Equal(t, results[1][0].StrVal, "http_content_encoding")
+ assert.Equal(t, results[1][1].StrVal, "~=")
+ assert.Equal(t, results[1][2].StrVal, "gzip")
- assert.Len(t, vars[3], 3)
- assert.Equal(t, vars[3][0].StrVal, "arg_id")
- assert.Equal(t, vars[3][1].StrVal, "<")
- assert.Equal(t, vars[3][2].StrVal, "13")
+ assert.Len(t, results[2], 3)
+ assert.Equal(t, results[2][0].StrVal, "arg_id")
+ assert.Equal(t, results[2][1].StrVal, ">")
+ assert.Equal(t, results[2][2].StrVal, "13")
- assert.Len(t, vars[4], 3)
- assert.Equal(t, vars[4][0].StrVal, "arg_id")
- assert.Equal(t, vars[4][1].StrVal, "~~")
- assert.Equal(t, vars[4][2].StrVal, ".*\\.php")
+ assert.Len(t, results[3], 3)
+ assert.Equal(t, results[3][0].StrVal, "arg_id")
+ assert.Equal(t, results[3][1].StrVal, "<")
+ assert.Equal(t, results[3][2].StrVal, "13")
- assert.Len(t, vars[5], 3)
- assert.Equal(t, vars[5][0].StrVal, "arg_id")
- assert.Equal(t, vars[5][1].StrVal, "~*")
- assert.Equal(t, vars[5][2].StrVal, ".*\\.php")
+ assert.Len(t, results[4], 3)
+ assert.Equal(t, results[4][0].StrVal, "arg_id")
+ assert.Equal(t, results[4][1].StrVal, "~~")
+ assert.Equal(t, results[4][2].StrVal, ".*\\.php")
- assert.Len(t, vars[6], 4)
- assert.Equal(t, vars[6][0].StrVal, "arg_id")
- assert.Equal(t, vars[6][1].StrVal, "!")
- assert.Equal(t, vars[6][2].StrVal, "~~")
- assert.Equal(t, vars[6][3].StrVal, ".*\\.php")
+ assert.Len(t, results[5], 3)
+ assert.Equal(t, results[5][0].StrVal, "arg_id")
+ assert.Equal(t, results[5][1].StrVal, "~*")
+ assert.Equal(t, results[5][2].StrVal, ".*\\.php")
- assert.Len(t, vars[7], 4)
- assert.Equal(t, vars[7][0].StrVal, "arg_id")
- assert.Equal(t, vars[7][1].StrVal, "!")
- assert.Equal(t, vars[7][2].StrVal, "~*")
- assert.Equal(t, vars[7][3].StrVal, ".*\\.php")
+ assert.Len(t, results[6], 4)
+ assert.Equal(t, results[6][0].StrVal, "arg_id")
+ assert.Equal(t, results[6][1].StrVal, "!")
+ assert.Equal(t, results[6][2].StrVal, "~~")
+ assert.Equal(t, results[6][3].StrVal, ".*\\.php")
- assert.Len(t, vars[8], 3)
- assert.Equal(t, vars[8][0].StrVal, "remote_addr")
- assert.Equal(t, vars[8][1].StrVal, "in")
- assert.Equal(t, vars[8][2].SliceVal, []string{"10.0.5.3", "10.0.5.4"})
+ assert.Len(t, results[7], 4)
+ assert.Equal(t, results[7][0].StrVal, "arg_id")
+ assert.Equal(t, results[7][1].StrVal, "!")
+ assert.Equal(t, results[7][2].StrVal, "~*")
+ assert.Equal(t, results[7][3].StrVal, ".*\\.php")
- assert.Len(t, vars[9], 4)
- assert.Equal(t, vars[9][0].StrVal, "remote_addr")
- assert.Equal(t, vars[9][1].StrVal, "!")
- assert.Equal(t, vars[9][2].StrVal, "in")
- assert.Equal(t, vars[9][3].SliceVal, []string{"10.0.5.6"})
+ assert.Len(t, results[8], 3)
+ assert.Equal(t, results[8][0].StrVal, "cookie_domain")
+ assert.Equal(t, results[8][1].StrVal, "in")
+ assert.Equal(t, results[8][2].SliceVal, []string{"a.com", "b.com"})
}
diff --git a/test/e2e/features/nginx_vars.go
b/test/e2e/features/route_match_exprs.go
similarity index 94%
rename from test/e2e/features/nginx_vars.go
rename to test/e2e/features/route_match_exprs.go
index 1a2bd21..cedec1a 100644
--- a/test/e2e/features/nginx_vars.go
+++ b/test/e2e/features/route_match_exprs.go
@@ -23,7 +23,7 @@ import (
"github.com/stretchr/testify/assert"
)
-var _ = ginkgo.Describe("nginx vars", func() {
+var _ = ginkgo.Describe("route match exprs", func() {
opts := &scaffold.Options{
Name: "default",
Kubeconfig: scaffold.GetKubeconfig(),
@@ -50,8 +50,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_foo
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Foo
op: Equal
value: bar
backend:
@@ -98,8 +100,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_foo
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Foo
op: NotEqual
value: bar
backend:
@@ -145,8 +149,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: arg_id
+ exprs:
+ - subject:
+ scope: Query
+ name: id
op: GreaterThan
value: "13"
backend:
@@ -201,8 +207,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: arg_id
+ exprs:
+ - subject:
+ scope: Query
+ name: ID
op: LessThan
value: "13"
backend:
@@ -257,8 +265,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_content_type
+ exprs:
+ - subject:
+ scope: Header
+ name: Content-Type
op: In
set: ["text/plain", "text/html", "image/jpeg"]
backend:
@@ -313,8 +323,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_content_type
+ exprs:
+ - subject:
+ scope: Header
+ name: Content-Type
op: NotIn
set: ["text/plain", "text/html", "image/jpeg"]
backend:
@@ -368,8 +380,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_real_uri
+ exprs:
+ - subject:
+ scope: Header
+ name: x-Real-URI
op: RegexMatch
value: "^/ip/0\\d{2}/.*$"
backend:
@@ -424,8 +438,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_real_uri
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Real-URI
op: RegexNotMatch
value: "^/ip/0\\d{2}/.*$"
backend:
@@ -479,8 +495,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_real_uri
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Real-URI
op: RegexMatchCaseInsensitive
value: "^/ip/0\\d{2}/.*$"
backend:
@@ -535,8 +553,10 @@ spec:
- httpbin.org
paths:
- /ip
- nginxVars:
- - subject: http_x_real_uri
+ exprs:
+ - subject:
+ scope: Header
+ name: X-Real-URI
op: RegexNotMatchCaseInsensitive
value: "^/ip/0\\d{2}/.*$"
backend: