-
Notifications
You must be signed in to change notification settings - Fork 543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement "rewrite" using Wasm Plugin #339
Draft
WeixinX
wants to merge
2
commits into
alibaba:main
Choose a base branch
from
WeixinX:feat/wasm-plugin-rewrite
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# 功能说明 | ||
|
||
`rewrite` 插件可以用于修改请求域名(Host)以及请求路径(Path),通常用于后端服务的域名/路由与网关侧域名/路由不一致时的配置,与 [Rewrite Annotation](https://higress.io/zh-cn/docs/user/annotation-use-case/#rewrite%E9%87%8D%E5%86%99path%E5%92%8Chost) 实现的效果一致。 | ||
|
||
|
||
# 配置字段 | ||
|
||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 | | ||
|---------------|-----------------|------|-----|------------------------------| | ||
| rewrite_rules | array of object | 选填 | - | 配置请求域名(Host)与请求路径(Path)的重写规则 | | ||
|
||
`rewrite_rules` 中配置字段说明如下: | ||
|
||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 | | ||
|-----------------|-----------------|------|-------|-------------------------------------------------------------------------------| | ||
| match_path_type | string | 选填 | - | 配置请求路径的匹配类型,可选值为:前缀匹配 prefix, 精确匹配 exact, 正则匹配 regex | | ||
| case_sensitive | bool | 选填 | false | 配置匹配时是否区分大小写,默认不区分 | | ||
| match_hosts | array of string | 选填 | - | 配置会被重写的请求域名列表,支持精确匹配(hello.world.com),最左通配(\*.world.com)和最右通配(hello.world.\*) | | ||
| match_paths | array of string | 选填 | - | 配置会被重写的请求路径列表,支持 [RE2](https://pkg.go.dev/regexp/syntax) 正则表达式语法 | | ||
| rewrite_host | string | 选填 | - | 配置重写的目标域名 | | ||
| rewrite_path | string | 选填 | - | 配置重写的目标路径 | | ||
|
||
**注意:** | ||
- 只有当请求域名(Host)和请求路径(Path)都对应匹配到某条重写规则的 `match_hosts`、`match_paths` 中的一项时,才会将请求域名和请求路径分别重写为该条重写规则的 `rewrite_host`、`rewrite_path`; | ||
- 当配置多条重写规则,将按照规则编写顺序进行匹配; | ||
- 在一条重写规则中,`match_hosts` 和 `match_paths` 按照编写顺序进行匹配; | ||
- `case_sensitive` 也会作用到正则表达式的匹配上。 | ||
|
||
|
||
# 配置示例 | ||
|
||
## 前缀匹配请求路径 | ||
|
||
以下配置将请求路径的匹配类型设置为前缀匹配(prefix): | ||
|
||
```yaml | ||
rewrite_rules: | ||
- match_path_type: prefix # 前缀匹配 | ||
case_sensitive: false | ||
match_hosts: | ||
- foo.bar.com | ||
match_paths: | ||
- /v1/api/get | ||
rewrite_host: prefix.example.com | ||
rewrite_path: /get | ||
``` | ||
|
||
示例请求 `foo.bar.com/v1/api/get/something` 将被重写为 `prefix.example.com/get`。 | ||
|
||
## 正则匹配请求路径 | ||
|
||
以下配置将请求路径的匹配类型设置为正则匹配(regex): | ||
|
||
```yaml | ||
rewrite_rules: | ||
- match_path_type: regex # 正则匹配 | ||
case_sensitive: false | ||
match_hosts: | ||
- aa.bb.cc | ||
- foo.bar.com | ||
match_paths: | ||
- /abc/(get) | ||
- /(get)/.*\.html | ||
rewrite_host: regex.example.com | ||
rewrite_path: /$1 | ||
``` | ||
|
||
以下示例请求将被重写为 `regex.example.com/get`: | ||
- `foo.bar.com/abc/get`; | ||
- `aa.bb.cc/get/index.html`。 | ||
|
||
|
||
## 通配请求域名 | ||
|
||
以下配置演示请求域名的精准匹配和最左、最右通配: | ||
|
||
```yaml | ||
rewrite_rules: | ||
- match_path_type: exact | ||
case_sensitive: false | ||
match_hosts: | ||
- "hello.world.com" # 精准匹配 | ||
- "*.example.com" # 最左通配 | ||
- "aa.bb.*" # 最右通配 | ||
match_paths: | ||
- /v1/get | ||
- /abc/get/ | ||
rewrite_host: wildcard.example.com | ||
rewrite_path: /get | ||
``` | ||
|
||
以下示例请求将被重写为 `wildcard.example.com/get`: | ||
- `hello.world.com/abc/get/`; | ||
- `my.example.com/v1/get`; | ||
- `aa.bb.com/v1/get`。 | ||
|
||
## 大小写敏感 | ||
|
||
以下配置将请求域名和请求路径的匹配设置为大小写敏感: | ||
|
||
```yaml | ||
rewrite_rules: | ||
- match_path_type: regex | ||
case_sensitive: true # 大小写敏感 | ||
match_hosts: | ||
- xx.yy.ZZ | ||
match_paths: | ||
- /API/(get) | ||
- /test/(get)/.*\.HTML | ||
rewrite_host: case-sensitive.example.com | ||
rewrite_path: /$1 | ||
``` | ||
|
||
以下示例请求将被重写为 `case-sensitive.example.com/get`: | ||
- `xx.yy.ZZ/API/get`; | ||
- `xx.yy.ZZ/test/get/index.HTML`。 | ||
|
||
而以下示例请求则因为大小写敏感而无法正确匹配: | ||
- `xx.yy.ZZ/api/get`; | ||
- `xx.yy.zz/test/get/index.HTML`。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
version: '3.7' | ||
services: | ||
envoy: | ||
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/envoy:1.20 | ||
depends_on: | ||
- httpbin | ||
networks: | ||
- wasmtest | ||
ports: | ||
- "10000:10000" | ||
- "9901:9901" | ||
volumes: | ||
- ./envoy.yaml:/etc/envoy/envoy.yaml | ||
- ./plugin.wasm:/etc/envoy/main.wasm | ||
|
||
httpbin: | ||
image: kennethreitz/httpbin:latest | ||
networks: | ||
- wasmtest | ||
ports: | ||
- "12345:80" | ||
|
||
networks: | ||
wasmtest: {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
admin: | ||
address: | ||
socket_address: | ||
protocol: TCP | ||
address: 0.0.0.0 | ||
port_value: 9901 | ||
static_resources: | ||
listeners: | ||
- name: listener_0 | ||
address: | ||
socket_address: | ||
protocol: TCP | ||
address: 0.0.0.0 | ||
port_value: 10000 | ||
filter_chains: | ||
- filters: | ||
- name: envoy.filters.network.http_connection_manager | ||
typed_config: | ||
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager | ||
scheme_header_transformation: | ||
scheme_to_overwrite: https | ||
stat_prefix: ingress_http | ||
route_config: | ||
name: local_route | ||
virtual_hosts: | ||
- name: local_service | ||
domains: ["*"] | ||
routes: | ||
- match: | ||
prefix: "/" | ||
name: "foo" | ||
route: | ||
cluster: httpbin | ||
http_filters: | ||
- name: wasmdemo | ||
typed_config: | ||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct | ||
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm | ||
value: | ||
config: | ||
name: wasmdemo | ||
vm_config: | ||
runtime: envoy.wasm.runtime.v8 | ||
code: | ||
local: | ||
filename: /etc/envoy/main.wasm | ||
configuration: | ||
"@type": "type.googleapis.com/google.protobuf.StringValue" | ||
value: | | ||
{ | ||
"rewrite_rules": [ | ||
{ | ||
"match_path_type": "prefix", | ||
"case_sensitive": false, | ||
"match_hosts": ["foo.bar.com"], | ||
"match_paths": ["/v1/api/get"], | ||
"rewrite_host": "prefix.example.com", | ||
"rewrite_path": "/get" | ||
}, | ||
{ | ||
"match_path_type": "regex", | ||
"case_sensitive": false, | ||
"match_hosts": ["aa.bb.cc", "foo.bar.com"], | ||
"match_paths": ["/abc/(get)", "/(get)/.*\\.html"], | ||
"rewrite_host": "regex.example.com", | ||
"rewrite_path": "/$1" | ||
}, | ||
{ | ||
"match_path_type": "exact", | ||
"case_sensitive": false, | ||
"match_hosts": ["hello.world.com", "*.example.com", "aa.bb.*"], | ||
"match_paths": ["/v1/get", "/abc/get/"], | ||
"rewrite_host": "wildcard.example.com", | ||
"rewrite_path": "/get" | ||
}, | ||
{ | ||
"match_path_type": "regex", | ||
"case_sensitive": true, | ||
"match_hosts": ["xx.yy.ZZ"], | ||
"match_paths": ["/API/(get)", "/test/(get)/.*\\.HTML"], | ||
"rewrite_host": "case-sensitive.example.com", | ||
"rewrite_path": "/$1" | ||
} | ||
] | ||
} | ||
- name: envoy.filters.http.router | ||
clusters: | ||
- name: httpbin | ||
connect_timeout: 30s | ||
type: LOGICAL_DNS | ||
dns_lookup_family: V4_ONLY | ||
lb_policy: ROUND_ROBIN | ||
load_assignment: | ||
cluster_name: httpbin | ||
endpoints: | ||
- lb_endpoints: | ||
- endpoint: | ||
address: | ||
socket_address: | ||
address: httpbin | ||
port_value: 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module github.com/alibaba/higress/plugins/wasm-go/extensions/rewrite | ||
|
||
go 1.19 | ||
|
||
require ( | ||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230512062358-6b483189acb9 | ||
github.com/dlclark/regexp2 v1.10.0 | ||
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c | ||
github.com/tidwall/gjson v1.14.3 | ||
) | ||
|
||
require ( | ||
github.com/google/uuid v1.3.0 // indirect | ||
github.com/tidwall/match v1.1.1 // indirect | ||
github.com/tidwall/pretty v1.2.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230512062358-6b483189acb9 h1:j5Q2jO2EB3wPJeyUbpcRMAQb+InH+VeARNpt9lNgH7M= | ||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230512062358-6b483189acb9/go.mod h1:AzSnkuon5c26nIePTiJQIAFsKdhkNdncLcTuahpGtQs= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= | ||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= | ||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= | ||
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c h1:OCUFXVGixHLfNjg6/QYEhv+jHJ5mRGhpEUVFv9eWPJE= | ||
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c/go.mod h1:5t/pWFNJ9eMyu/K/Z+OeGhDJ9sN9eCo8fc2pyM/Qjg4= | ||
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= | ||
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= | ||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= | ||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= | ||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= | ||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match_hosts 和 match_paths 的功能跟插件机制自带的匹配功能重复了,这个插件应当只处理匹配后的重写机制。
此外,路径重写需要考虑正则重写(看到已经支持)和前缀重写。目前重写 annotation 的设计是根据当前路径匹配类型自动设定重写类型,例如精确匹配->精确重写;前缀匹配->前缀重写。
这个插件可以提供用户更灵活的选择,让用户自行选择重写机制。对于前缀和正则重写,需要设定一个重写目标,字段名可以是 rewrite_target。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johnlanni 感谢指出问题 ~
那么这个插件的模型是否可以改写为:
根据文档中 rewrite annotation 的使用示例,我觉得 rewrite_target 和这里的 rewrite_path 功能一样,但在源码中同时有 rewrite-path 和 -target 两个 annotation,我想请问它们的区别是什么?🙏🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我上面说的是 rewrite-path 的机制;
rewrite-target 是为了兼容 nginx ingress 注解设计的,可以看下 nginx ingress的文档:https://kubernetes.github.io/ingress-nginx/examples/rewrite/
这个配置可以的,不过对于正则重写,还需有个配置用于正则匹配捕获,来实现上面 rewrite target 的能力
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
还有一个问题想讨教 ~
前缀重写指的是例如:
请求路径 /v1/api/get 匹配到了路由 /v1/api,此时重写类型为 prefix,重写路径为 /v2,因此该请求路径被重写为 /v2/get 吗?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这样可能更好,作用字段含义更明确些
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
参考上面配置格式,如果 type是 prefix,matchPath是 /v1/api,rewritePath是/v2,那么会被重写为 /v2/get
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感谢 ~ 我有空重构一下。另外是否需要添加 e2e usecase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嗯,目前做插件的 e2e 需要提供现成的 oci 镜像,这个我记个 issue ,需要优化下 e2e 流程来支持