You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by zh...@apache.org on 2023/01/29 07:26:27 UTC
[apisix-ingress-controller] branch master updated: feat: add support for filter_func for ApisixRoute (#1545)
This is an automated email from the ASF dual-hosted git repository.
zhangjintao 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 123d080d feat: add support for filter_func for ApisixRoute (#1545)
123d080d is described below
commit 123d080d4e92e7becb95da0835e7775365a71d2a
Author: Aryan <75...@users.noreply.github.com>
AuthorDate: Sun Jan 29 12:56:22 2023 +0530
feat: add support for filter_func for ApisixRoute (#1545)
Signed-off-by: Aryan <75...@users.noreply.github.com>
---
pkg/kube/apisix/apis/config/v2/types.go | 4 ++
pkg/providers/apisix/translation/apisix_route.go | 3 +
pkg/types/apisix/v1/types.go | 1 +
samples/deploy/crd/v1/ApisixRoute.yaml | 2 +
test/e2e/suite-features/route_filter_func.go | 79 ++++++++++++++++++++++++
5 files changed, 89 insertions(+)
diff --git a/pkg/kube/apisix/apis/config/v2/types.go b/pkg/kube/apisix/apis/config/v2/types.go
index a4a43fbb..5bab54d8 100644
--- a/pkg/kube/apisix/apis/config/v2/types.go
+++ b/pkg/kube/apisix/apis/config/v2/types.go
@@ -131,6 +131,10 @@ type ApisixRouteHTTPMatch struct {
// - "127.0.0.1"
// - "10.0.5.11"
NginxVars []ApisixRouteHTTPMatchExpr `json:"exprs,omitempty" yaml:"exprs,omitempty"`
+ // Matches based on a user-defined filtering function.
+ // These functions can accept an input parameter `vars`
+ // which can be used to access the Nginx variables.
+ FilterFunc string `json:"filter_func,omitempty" yaml:"filter_func,omitempty"`
}
// ApisixRouteHTTPMatchExpr represents a binary route match expression .
diff --git a/pkg/providers/apisix/translation/apisix_route.go b/pkg/providers/apisix/translation/apisix_route.go
index 2706f0f8..6d1c3f26 100644
--- a/pkg/providers/apisix/translation/apisix_route.go
+++ b/pkg/providers/apisix/translation/apisix_route.go
@@ -325,9 +325,12 @@ func (t *translator) translateHTTPRouteV2(ctx *translation.TranslateContext, ar
route.EnableWebsocket = part.Websocket
route.Plugins = pluginMap
route.Timeout = timeout
+ route.FilterFunc = part.Match.FilterFunc
+
if part.PluginConfigName != "" {
route.PluginConfigId = id.GenID(apisixv1.ComposePluginConfigName(ar.Namespace, part.PluginConfigName))
}
+
for k, v := range ar.ObjectMeta.Labels {
route.Metadata.Labels[k] = v
}
diff --git a/pkg/types/apisix/v1/types.go b/pkg/types/apisix/v1/types.go
index cf7a2618..e59a2f19 100644
--- a/pkg/types/apisix/v1/types.go
+++ b/pkg/types/apisix/v1/types.go
@@ -115,6 +115,7 @@ type Route struct {
UpstreamId string `json:"upstream_id,omitempty" yaml:"upstream_id,omitempty"`
Plugins Plugins `json:"plugins,omitempty" yaml:"plugins,omitempty"`
PluginConfigId string `json:"plugin_config_id,omitempty" yaml:"plugin_config_id,omitempty"`
+ FilterFunc string `json:"filter_func,omitempty" yaml:"filter_func,omitempty"`
}
// Vars represents the route match expressions of APISIX.
diff --git a/samples/deploy/crd/v1/ApisixRoute.yaml b/samples/deploy/crd/v1/ApisixRoute.yaml
index e241bd5a..4d1f9870 100644
--- a/samples/deploy/crd/v1/ApisixRoute.yaml
+++ b/samples/deploy/crd/v1/ApisixRoute.yaml
@@ -450,6 +450,8 @@ spec:
oneOf:
- required: ["subject", "op", "value"]
- required: ["subject", "op", "set"]
+ filter_func:
+ type: string
websocket:
type: boolean
plugin_config_name:
diff --git a/test/e2e/suite-features/route_filter_func.go b/test/e2e/suite-features/route_filter_func.go
new file mode 100644
index 00000000..95c1d710
--- /dev/null
+++ b/test/e2e/suite-features/route_filter_func.go
@@ -0,0 +1,79 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package features
+
+import (
+ "fmt"
+ "net/http"
+
+ ginkgo "github.com/onsi/ginkgo/v2"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("suite-features: filter_func", func() {
+ suites := func(scaffoldFunc func() *scaffold.Scaffold) {
+ s := scaffoldFunc()
+ ginkgo.It("filter using body", func() {
+ backendSvc, backendPorts := s.DefaultHTTPBackend()
+ ar := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: httpbin-route
+spec:
+ http:
+ - name: rule1
+ match:
+ hosts:
+ - httpbin.org
+ paths:
+ - /ip
+ filter_func: "function(vars)\n local core = require ('apisix.core')\n local body, err = core.request.get_body()\n if not body then\n return false\n end\n\n local data, err = core.json.decode(body)\n if not data then\n return false\n end\n\n if data['foo'] == 'bar' then\n return true\n end\n\n return false\nend"
+ backends:
+ - serviceName: %s
+ servicePort: %d
+`, backendSvc, backendPorts[0])
+ assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(ar))
+
+ err := s.EnsureNumApisixUpstreamsCreated(1)
+ assert.Nil(ginkgo.GinkgoT(), err, "Checking number of upstreams")
+ err = s.EnsureNumApisixRoutesCreated(1)
+ assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+
+ _ = s.NewAPISIXClient().GET("/ip").
+ WithHeader("Host", "httpbin.org").
+ Expect().
+ Status(http.StatusNotFound).
+ Body().
+ Contains("404 Route Not Found")
+
+ type MyJSON struct {
+ Foo string `json:"foo"`
+ }
+
+ _ = s.NewAPISIXClient().GET("/ip").
+ WithHeader("Host", "httpbin.org").
+ WithJSON(MyJSON{Foo: "bar"}).
+ Expect().
+ Status(http.StatusOK)
+ })
+ }
+
+ ginkgo.Describe("suite-features: scaffold v2", func() {
+ suites(scaffold.NewDefaultV2Scaffold)
+ })
+})