mirror of
https://github.com/alibaba/higress.git
synced 2026-02-27 14:10:51 +08:00
Compare commits
145 Commits
v2.0.0-rc.
...
v2.0.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85c7b1f501 | ||
|
|
8f660211e3 | ||
|
|
433227323d | ||
|
|
b36e5ea26b | ||
|
|
ce66ff68ce | ||
|
|
d026f0fca5 | ||
|
|
22790aa149 | ||
|
|
7ce6d7aba1 | ||
|
|
e705a0344f | ||
|
|
d6094974c2 | ||
|
|
6187be97e5 | ||
|
|
bb64b43f23 | ||
|
|
ca7458cf1c | ||
|
|
ee2dd76ae1 | ||
|
|
8154cf95f1 | ||
|
|
a7593381e1 | ||
|
|
e68a8ac25f | ||
|
|
96575b982e | ||
|
|
c2d405b2a7 | ||
|
|
6efb3109f2 | ||
|
|
1b1c08afb7 | ||
|
|
d24123a55f | ||
|
|
f2a5df3949 | ||
|
|
ebc5b2987e | ||
|
|
ca97cbd75a | ||
|
|
a787e237ce | ||
|
|
6a1bf90d42 | ||
|
|
60e476da87 | ||
|
|
2cb8558cda | ||
|
|
4d1a037942 | ||
|
|
39b6eac9d0 | ||
|
|
7697af9d2b | ||
|
|
3660715506 | ||
|
|
7bd438877b | ||
|
|
0fbeb39cac | ||
|
|
d02c974af4 | ||
|
|
8ad4970231 | ||
|
|
aee37c5e22 | ||
|
|
73cf32aadd | ||
|
|
1ab69fcf82 | ||
|
|
9b995321bb | ||
|
|
00cac813e3 | ||
|
|
548cf2f081 | ||
|
|
c1f2504e87 | ||
|
|
7e8b0445ad | ||
|
|
63d5422da6 | ||
|
|
035e81a5ca | ||
|
|
9a1edcd4c8 | ||
|
|
2219a17898 | ||
|
|
93c1e5c2bb | ||
|
|
7c2d2b2855 | ||
|
|
b1550e91ab | ||
|
|
0b42836e85 | ||
|
|
7c33ebf6ea | ||
|
|
acec48ed8b | ||
|
|
d309bf2e25 | ||
|
|
496d365a95 | ||
|
|
d952fa562b | ||
|
|
e7561c30e5 | ||
|
|
cdd71155a9 | ||
|
|
a5ccb90b28 | ||
|
|
d76f574ab3 | ||
|
|
bb6c43c767 | ||
|
|
b8f5826a32 | ||
|
|
0d79386ce2 | ||
|
|
871ae179c3 | ||
|
|
f8d62a8ac3 | ||
|
|
badf4b7101 | ||
|
|
fc6902ded2 | ||
|
|
d96994767c | ||
|
|
32e5a59ae0 | ||
|
|
49bb5ec2b9 | ||
|
|
11ff2d1d31 | ||
|
|
c67f494b49 | ||
|
|
299621476f | ||
|
|
7e6168a644 | ||
|
|
e923cbaecc | ||
|
|
6f86c31bac | ||
|
|
51c956f0b3 | ||
|
|
d0693d8c4b | ||
|
|
e298078065 | ||
|
|
85f8eb5166 | ||
|
|
0a112d1a1e | ||
|
|
04ce776f14 | ||
|
|
952c9ec5dc | ||
|
|
1a53c7b4d3 | ||
|
|
ae6dab919d | ||
|
|
601b205abc | ||
|
|
9972e7611a | ||
|
|
c30ca5dd9e | ||
|
|
e26a2a37d7 | ||
|
|
f20c48e960 | ||
|
|
e126f3a888 | ||
|
|
93317adbc7 | ||
|
|
ecf52aecfc | ||
|
|
3ed28f2a66 | ||
|
|
4d0d8a7f50 | ||
|
|
1f8d50c0b1 | ||
|
|
14b11dcb05 | ||
|
|
71aae9ddf6 | ||
|
|
1b119ed371 | ||
|
|
ea99159d51 | ||
|
|
567d7c25f3 | ||
|
|
708e7af79a | ||
|
|
260772926c | ||
|
|
af4e34b7ed | ||
|
|
8293042c25 | ||
|
|
1acaaea222 | ||
|
|
e004321cb0 | ||
|
|
b82853c653 | ||
|
|
bef9139753 | ||
|
|
dc61bfc5c5 | ||
|
|
b24731593f | ||
|
|
e7761a2ecc | ||
|
|
86239c4a4b | ||
|
|
c923e5cb42 | ||
|
|
ee67553816 | ||
|
|
ffc5458a91 | ||
|
|
55f6ed7953 | ||
|
|
9e5188cfca | ||
|
|
f51408d7ff | ||
|
|
0471249e7f | ||
|
|
59fe661cd2 | ||
|
|
7610c9f504 | ||
|
|
452bd4ef2d | ||
|
|
1db37f988a | ||
|
|
c7c4ae1da2 | ||
|
|
0f9113ed82 | ||
|
|
3eda1f3c70 | ||
|
|
6439b2d4da | ||
|
|
a4e696b957 | ||
|
|
f471c0a99f | ||
|
|
ffe3aceefc | ||
|
|
d18e22432a | ||
|
|
d682e05c75 | ||
|
|
a382bb201c | ||
|
|
6777d29c6e | ||
|
|
93fd1a5772 | ||
|
|
d6a67c05e6 | ||
|
|
28d5145514 | ||
|
|
1ab8025c96 | ||
|
|
ea862cfd4c | ||
|
|
f03ce572be | ||
|
|
aefa3b94c4 | ||
|
|
b7a30669a1 |
@@ -3,9 +3,16 @@ name: Build and Push Wasm Plugin Image
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "wasm-go-*-v*.*.*" # 匹配 wasm-go-{pluginName}-vX.Y.Z 格式的标签
|
||||
- "wasm-*-*-v*.*.*" # 匹配 wasm-{go|rust}-{pluginName}-vX.Y.Z 格式的标签
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
plugin_type:
|
||||
description: 'Type of the plugin'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- go
|
||||
- rust
|
||||
plugin_name:
|
||||
description: 'Name of the plugin'
|
||||
required: true
|
||||
@@ -23,32 +30,42 @@ jobs:
|
||||
env:
|
||||
IMAGE_REGISTRY_SERVICE: ${{ vars.IMAGE_REGISTRY || 'higress-registry.cn-hangzhou.cr.aliyuncs.com' }}
|
||||
IMAGE_REPOSITORY: ${{ vars.PLUGIN_IMAGE_REPOSITORY || 'plugins' }}
|
||||
RUST_VERSION: 1.82
|
||||
GO_VERSION: 1.19
|
||||
TINYGO_VERSION: 0.28.1
|
||||
ORAS_VERSION: 1.0.0
|
||||
steps:
|
||||
- name: Set plugin_name and version from inputs or ref_name
|
||||
- name: Set plugin_type, plugin_name and version from inputs or ref_name
|
||||
id: set_vars
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
plugin_type="${{ github.event.inputs.plugin_type }}"
|
||||
plugin_name="${{ github.event.inputs.plugin_name }}"
|
||||
version="${{ github.event.inputs.version }}"
|
||||
else
|
||||
ref_name=${{ github.ref_name }}
|
||||
plugin_type=${ref_name#*-} # 删除插件类型前面的字段(wasm-)
|
||||
plugin_type=${plugin_type%%-*} # 删除插件类型后面的字段(-{plugin_name}-vX.Y.Z)
|
||||
plugin_name=${ref_name#*-*-} # 删除插件名前面的字段(wasm-go-)
|
||||
plugin_name=${plugin_name%-*} # 删除插件名后面的字段(-vX.Y.Z)
|
||||
version=$(echo "$ref_name" | awk -F'v' '{print $2}')
|
||||
fi
|
||||
|
||||
if [[ "$plugin_type" == "rust" ]]; then
|
||||
builder_image="higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/wasm-rust-builder:rust${{ env.RUST_VERSION }}-oras${{ env.ORAS_VERSION }}"
|
||||
else
|
||||
builder_image="higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/wasm-go-builder:go${{ env.GO_VERSION }}-tinygo${{ env.TINYGO_VERSION }}-oras${{ env.ORAS_VERSION }}"
|
||||
fi
|
||||
echo "PLUGIN_TYPE=$plugin_type" >> $GITHUB_ENV
|
||||
echo "PLUGIN_NAME=$plugin_name" >> $GITHUB_ENV
|
||||
echo "VERSION=$version" >> $GITHUB_ENV
|
||||
echo "BUILDER_IMAGE=$builder_image" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: File Check
|
||||
run: |
|
||||
workspace=${{ github.workspace }}/plugins/wasm-go/extensions/${PLUGIN_NAME}
|
||||
workspace=${{ github.workspace }}/plugins/wasm-${PLUGIN_TYPE}/extensions/${PLUGIN_NAME}
|
||||
push_command="./plugin.tar.gz:application/vnd.oci.image.layer.v1.tar+gzip"
|
||||
|
||||
# 查找spec.yaml
|
||||
@@ -75,10 +92,10 @@ jobs:
|
||||
|
||||
echo "PUSH_COMMAND=\"$push_command\"" >> $GITHUB_ENV
|
||||
|
||||
- name: Run a wasm-go-builder
|
||||
- name: Run a wasm-builder
|
||||
env:
|
||||
PLUGIN_NAME: ${{ env.PLUGIN_NAME }}
|
||||
BUILDER_IMAGE: higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/wasm-go-builder:go${{ env.GO_VERSION }}-tinygo${{ env.TINYGO_VERSION }}-oras${{ env.ORAS_VERSION }}
|
||||
BUILDER_IMAGE: ${{ env.BUILDER_IMAGE }}
|
||||
run: |
|
||||
docker run -itd --name builder -v ${{ github.workspace }}:/workspace -e PLUGIN_NAME=${{ env.PLUGIN_NAME }} --rm ${{ env.BUILDER_IMAGE }} /bin/bash
|
||||
|
||||
@@ -89,9 +106,11 @@ jobs:
|
||||
push_command=${push_command%\"} # 删除PUSH_COMMAND中的双引号,确保oras push正常解析
|
||||
|
||||
target_image="${{ env.IMAGE_REGISTRY_SERVICE }}/${{ env.IMAGE_REPOSITORY}}/${{ env.PLUGIN_NAME }}:${{ env.VERSION }}"
|
||||
target_image_latest="${{ env.IMAGE_REGISTRY_SERVICE }}/${{ env.IMAGE_REPOSITORY}}/${{ env.PLUGIN_NAME }}:latest"
|
||||
echo "TargetImage=${target_image}"
|
||||
echo "TargetImageLatest=${target_image_latest}"
|
||||
|
||||
cd ${{ github.workspace }}/plugins/wasm-go/extensions/${PLUGIN_NAME}
|
||||
cd ${{ github.workspace }}/plugins/wasm-${PLUGIN_TYPE}/extensions/${PLUGIN_NAME}
|
||||
if [ -f ./.buildrc ]; then
|
||||
echo 'Found .buildrc file, sourcing it...'
|
||||
. ./.buildrc
|
||||
@@ -99,7 +118,7 @@ jobs:
|
||||
echo '.buildrc file not found'
|
||||
fi
|
||||
echo "EXTRA_TAGS=${EXTRA_TAGS}"
|
||||
|
||||
if [ "${PLUGIN_TYPE}" == "go" ]; then
|
||||
command="
|
||||
set -e
|
||||
cd /workspace/plugins/wasm-go/extensions/${PLUGIN_NAME}
|
||||
@@ -108,7 +127,23 @@ jobs:
|
||||
tar czvf plugin.tar.gz plugin.wasm
|
||||
echo ${{ secrets.REGISTRY_PASSWORD }} | oras login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin ${{ env.IMAGE_REGISTRY_SERVICE }}
|
||||
oras push ${target_image} ${push_command}
|
||||
oras push ${target_image_latest} ${push_command}
|
||||
"
|
||||
docker exec builder bash -c "$command"
|
||||
elif [ "${PLUGIN_TYPE}" == "rust" ]; then
|
||||
command="
|
||||
set -e
|
||||
cd /workspace/plugins/wasm-rust/extensions/${PLUGIN_NAME}
|
||||
cargo build --target wasm32-wasi --release
|
||||
cp target/wasm32-wasi/release/*.wasm plugin.wasm
|
||||
tar czvf plugin.tar.gz plugin.wasm
|
||||
echo ${{ secrets.REGISTRY_PASSWORD }} | oras login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin ${{ env.IMAGE_REGISTRY_SERVICE }}
|
||||
oras push ${target_image} ${push_command}
|
||||
oras push ${target_image_latest} ${push_command}
|
||||
"
|
||||
else
|
||||
|
||||
|
||||
command="
|
||||
echo "unkown type ${PLUGIN_TYPE}"
|
||||
"
|
||||
fi
|
||||
docker exec builder bash -c "$command"
|
||||
|
||||
8
.github/workflows/build-and-test-plugin.yaml
vendored
8
.github/workflows/build-and-test-plugin.yaml
vendored
@@ -64,14 +64,6 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-cache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-cache
|
||||
|
||||
- run: git stash # restore patch
|
||||
|
||||
- name: "Run Ingress WasmPlugins Tests"
|
||||
|
||||
24
.github/workflows/build-and-test.yaml
vendored
24
.github/workflows/build-and-test.yaml
vendored
@@ -37,14 +37,6 @@ jobs:
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-cache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-cache
|
||||
|
||||
- run: git stash # restore patch
|
||||
|
||||
# test
|
||||
@@ -83,14 +75,6 @@ jobs:
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-cache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-cache
|
||||
|
||||
- run: git stash # restore patch
|
||||
|
||||
- name: "Build Higress Binary"
|
||||
@@ -137,14 +121,6 @@ jobs:
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-cache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-cache
|
||||
|
||||
- run: git stash # restore patch
|
||||
|
||||
|
||||
30
.github/workflows/build-image-and-push.yaml
vendored
30
.github/workflows/build-image-and-push.yaml
vendored
@@ -44,16 +44,6 @@ jobs:
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
envoy
|
||||
istio
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-new-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-new
|
||||
|
||||
- name: Calculate Docker metadata
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -120,16 +110,6 @@ jobs:
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
envoy
|
||||
istio
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-new
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
@@ -208,16 +188,6 @@ jobs:
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-go
|
||||
|
||||
- name: Setup Submodule Caches
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
envoy
|
||||
istio
|
||||
.git/modules
|
||||
key: ${{ runner.os }}-submodules-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-submodules-new
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
|
||||
35
.github/workflows/helm-docs.yaml
vendored
Normal file
35
.github/workflows/helm-docs.yaml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: "Helm Docs"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
push:
|
||||
|
||||
jobs:
|
||||
|
||||
helm:
|
||||
name: Helm Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.9'
|
||||
|
||||
- name: Run helm-docs
|
||||
run: |
|
||||
GOBIN=$PWD GO111MODULE=on go install github.com/norwoodj/helm-docs/cmd/helm-docs@v1.14.2
|
||||
./helm-docs -c ${GITHUB_WORKSPACE}/helm/higress -f ../core/values.yaml
|
||||
DIFF=$(git diff ${GITHUB_WORKSPACE}/helm/higress/*md)
|
||||
if [ ! -z "$DIFF" ]; then
|
||||
echo "Please use helm-docs in your clone, of your fork, of the project, and commit a updated README.md for the chart."
|
||||
fi
|
||||
git diff --exit-code
|
||||
rm -f ./helm-docs
|
||||
24
.github/workflows/release-crd.yaml
vendored
Normal file
24
.github/workflows/release-crd.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Release CRD to GitHub
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
workflow_dispatch: ~
|
||||
|
||||
jobs:
|
||||
release-crd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: generate crds
|
||||
run: |
|
||||
cat helm/core/crds/customresourcedefinitions.gen.yaml helm/core/crds/istio-envoyfilter.yaml > crd.yaml
|
||||
|
||||
- name: Upload hgctl packages to the GitHub release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: |
|
||||
crd.yaml
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,4 +16,5 @@ helm/**/charts/**.tgz
|
||||
target/
|
||||
tools/hack/cluster.conf
|
||||
envoy/1.20
|
||||
istio/1.12
|
||||
istio/1.12
|
||||
Cargo.lock
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/istio @SpecialYang @johnlanni
|
||||
/pkg @SpecialYang @johnlanni @CH3CHO
|
||||
/plugins @johnlanni @WeixinX @CH3CHO
|
||||
/plugins/wasm-rust @007gzs @jizhuozhi
|
||||
/registry @NameHaibinZhang @2456868764 @johnlanni
|
||||
/test @Xunzhuo @2456868764 @CH3CHO
|
||||
/tools @johnlanni @Xunzhuo @2456868764
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Contributing to Higress
|
||||
|
||||
It is warmly welcomed if you have interest to hack on Higress. First, we encourage this kind of willing very much. And here is a list of contributing guide for you.
|
||||
Your interest in contributing to Higress is warmly welcomed. First, we encourage this kind of willing very much. And here is a list of contributing guide for you.
|
||||
|
||||
[[中文贡献文档](./CONTRIBUTING_CN.md)]
|
||||
|
||||
|
||||
195
CONTRIBUTING_JP.md
Normal file
195
CONTRIBUTING_JP.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# Higress への貢献
|
||||
|
||||
Higress のハッキングに興味がある場合は、温かく歓迎します。まず、このような意欲を非常に奨励します。そして、以下は貢献ガイドのリストです。
|
||||
|
||||
[[中文](./CONTRIBUTING.md)] | [[English Contributing Document](./CONTRIBUTING_EN.md)]
|
||||
|
||||
## トピック
|
||||
|
||||
- [Higress への貢献](#higress-への貢献)
|
||||
- [トピック](#トピック)
|
||||
- [セキュリティ問題の報告](#セキュリティ問題の報告)
|
||||
- [一般的な問題の報告](#一般的な問題の報告)
|
||||
- [コードとドキュメントの貢献](#コードとドキュメントの貢献)
|
||||
- [ワークスペースの準備](#ワークスペースの準備)
|
||||
- [ブランチの定義](#ブランチの定義)
|
||||
- [コミットルール](#コミットルール)
|
||||
- [コミットメッセージ](#コミットメッセージ)
|
||||
- [コミット内容](#コミット内容)
|
||||
- [PR 説明](#pr-説明)
|
||||
- [テストケースの貢献](#テストケースの貢献)
|
||||
- [何かを手伝うための参加](#何かを手伝うための参加)
|
||||
- [コードスタイル](#コードスタイル)
|
||||
|
||||
## セキュリティ問題の報告
|
||||
|
||||
セキュリティ問題は常に真剣に扱われます。通常の原則として、セキュリティ問題を広めることは推奨しません。Higress のセキュリティ問題を発見した場合は、公開で議論せず、公開の問題を開かないでください。代わりに、[higress@googlegroups.com](mailto:higress@googlegroups.com) にプライベートなメールを送信して報告することをお勧めします。
|
||||
|
||||
## 一般的な問題の報告
|
||||
|
||||
正直なところ、Higress のすべてのユーザーを非常に親切な貢献者と見なしています。Higress を体験した後、プロジェクトに対するフィードバックがあるかもしれません。その場合は、[NEW ISSUE](https://github.com/alibaba/higress/issues/new/choose) を通じて問題を開くことを自由に行ってください。
|
||||
|
||||
Higress プロジェクトを分散型で協力しているため、**よく書かれた**、**詳細な**、**明確な**問題報告を高く評価します。コミュニケーションをより効率的にするために、問題が検索リストに存在するかどうかを検索することを希望します。存在する場合は、新しい問題を開くのではなく、既存の問題のコメントに詳細を追加してください。
|
||||
|
||||
問題の詳細をできるだけ標準化するために、問題報告者のために [ISSUE TEMPLATE](./.github/ISSUE_TEMPLATE) を設定しました。テンプレートのフィールドに従って指示に従って記入してください。
|
||||
|
||||
問題を開く場合は多くのケースがあります:
|
||||
|
||||
* バグ報告
|
||||
* 機能要求
|
||||
* パフォーマンス問題
|
||||
* 機能提案
|
||||
* 機能設計
|
||||
* 助けが必要
|
||||
* ドキュメントが不完全
|
||||
* テストの改善
|
||||
* プロジェクトに関する質問
|
||||
* その他
|
||||
|
||||
また、新しい問題を記入する際には、投稿から機密データを削除することを忘れないでください。機密データには、パスワード、秘密鍵、ネットワークの場所、プライベートなビジネスデータなどが含まれる可能性があります。
|
||||
|
||||
## コードとドキュメントの貢献
|
||||
|
||||
Higress プロジェクトをより良くするためのすべての行動が奨励されます。GitHub では、Higress のすべての改善は PR(プルリクエストの略)を通じて行うことができます。
|
||||
|
||||
* タイプミスを見つけた場合は、修正してみてください!
|
||||
* バグを見つけた場合は、修正してみてください!
|
||||
* 冗長なコードを見つけた場合は、削除してみてください!
|
||||
* 欠落しているテストケースを見つけた場合は、追加してみてください!
|
||||
* 機能を強化できる場合は、**ためらわないでください**!
|
||||
* コードが不明瞭な場合は、コメントを追加して明確にしてください!
|
||||
* コードが醜い場合は、リファクタリングしてみてください!
|
||||
* ドキュメントの改善に役立つ場合は、さらに良いです!
|
||||
* ドキュメントが不正確な場合は、修正してください!
|
||||
* ...
|
||||
|
||||
実際には、それらを完全にリストすることは不可能です。1つの原則を覚えておいてください:
|
||||
|
||||
> あなたからの PR を楽しみにしています。
|
||||
|
||||
Higress を PR で改善する準備ができたら、ここで PR ルールを確認することをお勧めします。
|
||||
|
||||
* [ワークスペースの準備](#ワークスペースの準備)
|
||||
* [ブランチの定義](#ブランチの定義)
|
||||
* [コミットルール](#コミットルール)
|
||||
* [PR 説明](#pr-説明)
|
||||
|
||||
### ワークスペースの準備
|
||||
|
||||
PR を提出するために、GitHub ID に登録していることを前提とします。その後、以下の手順で準備を完了できます:
|
||||
|
||||
1. Higress を自分のリポジトリに **FORK** します。この作業を行うには、[alibaba/higress](https://github.com/alibaba/higress) のメインページの右上にある Fork ボタンをクリックするだけです。その後、`https://github.com/<your-username>/higress` に自分のリポジトリが作成されます。ここで、`your-username` はあなたの GitHub ユーザー名です。
|
||||
|
||||
2. 自分のリポジトリをローカルに **CLONE** します。`git clone git@github.com:<your-username>/higress.git` を使用してリポジトリをローカルマシンにクローンします。その後、新しいブランチを作成して、行いたい変更を完了できます。
|
||||
|
||||
3. リモートを `git@github.com:alibaba/higress.git` に設定します。以下の2つのコマンドを使用します:
|
||||
|
||||
```bash
|
||||
git remote add upstream git@github.com:alibaba/higress.git
|
||||
git remote set-url --push upstream no-pushing
|
||||
```
|
||||
|
||||
このリモート設定を使用すると、git リモート設定を次のように確認できます:
|
||||
|
||||
```shell
|
||||
$ git remote -v
|
||||
origin git@github.com:<your-username>/higress.git (fetch)
|
||||
origin git@github.com:<your-username>/higress.git (push)
|
||||
upstream git@github.com:alibaba/higress.git (fetch)
|
||||
upstream no-pushing (push)
|
||||
```
|
||||
|
||||
これを追加すると、ローカルブランチを上流ブランチと簡単に同期できます。
|
||||
|
||||
### ブランチの定義
|
||||
|
||||
現在、プルリクエストを通じたすべての貢献は Higress の [main ブランチ](https://github.com/alibaba/higress/tree/main) に対するものであると仮定します。貢献する前に、ブランチの定義を理解することは非常に役立ちます。
|
||||
|
||||
貢献者として、プルリクエストを通じたすべての貢献は main ブランチに対するものであることを再度覚えておいてください。Higress プロジェクトには、リリースブランチ(例:0.6.0、0.6.1)、機能ブランチ、ホットフィックスブランチなど、いくつかの他のブランチがあります。
|
||||
|
||||
正式にバージョンをリリースする際には、リリースブランチが作成され、バージョン番号で命名されます。
|
||||
|
||||
リリース後、リリースブランチのコミットを main ブランチにマージします。
|
||||
|
||||
特定のバージョンにバグがある場合、後のバージョンで修正するか、特定のホットフィックスバージョンで修正するかを決定します。ホットフィックスバージョンで修正することを決定した場合、対応するリリースブランチに基づいてホットフィックスブランチをチェックアウトし、コード修正と検証を行い、main ブランチにマージします。
|
||||
|
||||
大きな機能については、開発と検証のために機能ブランチを引き出します。
|
||||
|
||||
### コミットルール
|
||||
|
||||
実際には、Higress ではコミット時に2つのルールを真剣に考えています:
|
||||
|
||||
* [コミットメッセージ](#コミットメッセージ)
|
||||
* [コミット内容](#コミット内容)
|
||||
|
||||
#### コミットメッセージ
|
||||
|
||||
コミットメッセージは、提出された PR の目的をレビュアーがよりよく理解するのに役立ちます。また、コードレビューの手続きを加速するのにも役立ちます。貢献者には、曖昧なメッセージではなく、**明確な**コミットメッセージを使用することを奨励します。一般的に、以下のコミットメッセージタイプを推奨します:
|
||||
|
||||
* docs: xxxx. 例:"docs: add docs about Higress cluster installation".
|
||||
* feature: xxxx. 例:"feature: use higress config instead of istio config".
|
||||
* bugfix: xxxx. 例:"bugfix: fix panic when input nil parameter".
|
||||
* refactor: xxxx. 例:"refactor: simplify to make codes more readable".
|
||||
* test: xxx. 例:"test: add unit test case for func InsertIntoArray".
|
||||
* その他の読みやすく明確な表現方法。
|
||||
|
||||
一方で、以下のような方法でのコミットメッセージは推奨しません:
|
||||
|
||||
* ~~バグ修正~~
|
||||
* ~~更新~~
|
||||
* ~~ドキュメント追加~~
|
||||
|
||||
迷った場合は、[Git コミットメッセージの書き方](http://chris.beams.io/posts/git-commit/) を参照してください。
|
||||
|
||||
#### コミット内容
|
||||
|
||||
コミット内容は、1つのコミットに含まれるすべての内容の変更を表します。1つのコミットに、他のコミットの助けを借りずにレビュアーが完全にレビューできる内容を含めるのが最善です。言い換えれば、1つのコミットの内容は CI を通過でき、コードの混乱を避けることができます。簡単に言えば、次の3つの小さなルールを覚えておく必要があります:
|
||||
|
||||
* コミットで非常に大きな変更を避ける;
|
||||
* 各コミットが完全でレビュー可能であること。
|
||||
* コミット時に git config(`user.name`、`user.email`)を確認して、それが GitHub ID に関連付けられていることを確認します。
|
||||
|
||||
```bash
|
||||
git config --get user.name
|
||||
git config --get user.email
|
||||
```
|
||||
|
||||
* pr を提出する際には、'changes/' フォルダーの下の XXX.md ファイルに現在の変更の簡単な説明を追加してください。
|
||||
|
||||
さらに、コード変更部分では、すべての貢献者が Higress の [コードスタイル](#コードスタイル) を読むことをお勧めします。
|
||||
|
||||
コミットメッセージやコミット内容に関係なく、コードレビューに重点を置いています。
|
||||
|
||||
### PR 説明
|
||||
|
||||
PR は Higress プロジェクトファイルを変更する唯一の方法です。レビュアーが目的をよりよく理解できるようにするために、PR 説明は詳細すぎることはありません。貢献者には、[PR テンプレート](./.github/PULL_REQUEST_TEMPLATE.md) に従ってプルリクエストを完了することを奨励します。
|
||||
|
||||
### 開発前の準備
|
||||
|
||||
```shell
|
||||
make prebuild && go mod tidy
|
||||
```
|
||||
|
||||
## テストケースの貢献
|
||||
|
||||
テストケースは歓迎されます。現在、Higress の機能テストケースが高優先度です。
|
||||
|
||||
* 単体テストの場合、同じモジュールの test ディレクトリに xxxTest.go という名前のテストファイルを作成する必要があります。
|
||||
* 統合テストの場合、統合テストを test ディレクトリに配置できます。
|
||||
//TBD
|
||||
|
||||
## 何かを手伝うための参加
|
||||
|
||||
GitHub を Higress の協力の主要な場所として選択しました。したがって、Higress の最新の更新は常にここにあります。PR を通じた貢献は明確な助けの方法ですが、他の方法も呼びかけています。
|
||||
|
||||
* 可能であれば、他の人の質問に返信する;
|
||||
* 他のユーザーの問題を解決するのを手伝う;
|
||||
* 他の人の PR 設計をレビューするのを手伝う;
|
||||
* 他の人の PR のコードをレビューするのを手伝う;
|
||||
* Higress について議論して、物事を明確にする;
|
||||
* GitHub 以外で Higress 技術を宣伝する;
|
||||
* Higress に関するブログを書くなど。
|
||||
|
||||
## コードスタイル
|
||||
//TBD
|
||||
要するに、**どんな助けも貢献です。**
|
||||
4
Makefile
4
Makefile
@@ -32,7 +32,7 @@ export BUILD_WITH_CONTAINER ?= 0
|
||||
|
||||
ifeq ($(BUILD_WITH_CONTAINER),1)
|
||||
|
||||
# An export free of arugments in a Makefile places all variables in the Makefile into the
|
||||
# An export free of arguments in a Makefile places all variables in the Makefile into the
|
||||
# environment. This is needed to allow overrides from Makefile.overrides.mk.
|
||||
export
|
||||
|
||||
@@ -60,7 +60,7 @@ else
|
||||
$(shell mkdir -p out)
|
||||
$(shell $(shell pwd)/tools/hack/setup_env.sh envfile > out/.env)
|
||||
include out/.env
|
||||
# An export free of arugments in a Makefile places all variables in the Makefile into the
|
||||
# An export free of arguments in a Makefile places all variables in the Makefile into the
|
||||
# environment. This behavior may be surprising to many that use shell often, which simply
|
||||
# displays the existing environment
|
||||
export
|
||||
|
||||
@@ -25,7 +25,7 @@ TARGET_ARCH ?= amd64
|
||||
|
||||
GOARCH_LOCAL := $(TARGET_ARCH)
|
||||
GOOS_LOCAL := $(TARGET_OS)
|
||||
RELEASE_LDFLAGS='$(GO_LDFLAGS) -extldflags -static -s -w -X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'
|
||||
RELEASE_LDFLAGS='$(GO_LDFLAGS) -extldflags -static -s -w'
|
||||
|
||||
export OUT:=$(TARGET_OUT)
|
||||
export OUT_LINUX:=$(TARGET_OUT_LINUX)
|
||||
@@ -68,21 +68,21 @@ default: build
|
||||
|
||||
.PHONY: go.test.coverage
|
||||
go.test.coverage: prebuild
|
||||
go test -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" ./cmd/... ./pkg/... -race -coverprofile=coverage.xml -covermode=atomic
|
||||
go test ./cmd/... ./pkg/... -race -coverprofile=coverage.xml -covermode=atomic
|
||||
|
||||
.PHONY: build
|
||||
build: prebuild $(OUT)
|
||||
GOPROXY=$(GOPROXY) GOOS=$(GOOS_LOCAL) GOARCH=$(GOARCH_LOCAL) LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh $(OUT)/ $(HIGRESS_BINARIES)
|
||||
GOPROXY="$(GOPROXY)" GOOS=$(GOOS_LOCAL) GOARCH=$(GOARCH_LOCAL) LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh $(OUT)/ $(HIGRESS_BINARIES)
|
||||
|
||||
.PHONY: build-linux
|
||||
build-linux: prebuild $(OUT)
|
||||
GOPROXY=$(GOPROXY) GOOS=linux GOARCH=$(GOARCH_LOCAL) LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh $(OUT_LINUX)/ $(HIGRESS_BINARIES)
|
||||
GOPROXY="$(GOPROXY)" GOOS=linux GOARCH=$(GOARCH_LOCAL) LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh $(OUT_LINUX)/ $(HIGRESS_BINARIES)
|
||||
|
||||
$(AMD64_OUT_LINUX)/higress:
|
||||
GOPROXY=$(GOPROXY) GOOS=linux GOARCH=amd64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_amd64/ $(HIGRESS_BINARIES)
|
||||
GOPROXY="$(GOPROXY)" GOOS=linux GOARCH=amd64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_amd64/ $(HIGRESS_BINARIES)
|
||||
|
||||
$(ARM64_OUT_LINUX)/higress:
|
||||
GOPROXY=$(GOPROXY) GOOS=linux GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_arm64/ $(HIGRESS_BINARIES)
|
||||
GOPROXY="$(GOPROXY)" GOOS=linux GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_arm64/ $(HIGRESS_BINARIES)
|
||||
|
||||
.PHONY: build-hgctl
|
||||
build-hgctl: prebuild $(OUT)
|
||||
@@ -101,11 +101,11 @@ build-hgctl-multiarch: prebuild $(OUT)
|
||||
|
||||
.PHONY: build-hgctl-macos-arm64
|
||||
build-hgctl-macos-arm64: prebuild $(OUT)
|
||||
CGO_ENABLED=1 GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=arm64 LDFLAGS="-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" PROJECT_DIR="$(HGCTL_PROJECT_DIR)" tools/hack/gobuild.sh ../out/darwin_arm64/ $(HGCTL_BINARIES)
|
||||
CGO_ENABLED=1 STATIC=0 GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=arm64 PROJECT_DIR="$(HGCTL_PROJECT_DIR)" tools/hack/gobuild.sh ../out/darwin_arm64/ $(HGCTL_BINARIES)
|
||||
|
||||
.PHONY: build-hgctl-macos-amd64
|
||||
build-hgctl-macos-amd64: prebuild $(OUT)
|
||||
CGO_ENABLED=1 GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=amd64 LDFLAGS="-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" PROJECT_DIR="$(HGCTL_PROJECT_DIR)" tools/hack/gobuild.sh ../out/darwin_amd64/ $(HGCTL_BINARIES)
|
||||
CGO_ENABLED=1 STATIC=0 GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=amd64 PROJECT_DIR="$(HGCTL_PROJECT_DIR)" tools/hack/gobuild.sh ../out/darwin_amd64/ $(HGCTL_BINARIES)
|
||||
|
||||
# Create targets for OUT_LINUX/binary
|
||||
# There are two use cases here:
|
||||
@@ -144,7 +144,7 @@ docker-buildx-push: clean-env docker.higress-buildx
|
||||
export PARENT_GIT_TAG:=$(shell cat VERSION)
|
||||
export PARENT_GIT_REVISION:=$(TAG)
|
||||
|
||||
export ENVOY_PACKAGE_URL_PATTERN?=https://github.com/higress-group/proxy/releases/download/v2.0.0-rc.1/envoy-symbol-ARCH.tar.gz
|
||||
export ENVOY_PACKAGE_URL_PATTERN?=https://github.com/higress-group/proxy/releases/download/v2.1.0/envoy-symbol-ARCH.tar.gz
|
||||
|
||||
build-envoy: prebuild
|
||||
./tools/hack/build-envoy.sh
|
||||
@@ -187,8 +187,8 @@ install: pre-install
|
||||
cd helm/higress; helm dependency build
|
||||
helm install higress helm/higress -n higress-system --create-namespace --set 'global.local=true'
|
||||
|
||||
ENVOY_LATEST_IMAGE_TAG ?= a6c313d41b3b54f0e3ed81fc676c520160cfed05
|
||||
ISTIO_LATEST_IMAGE_TAG ?= a9a55b3895bbf64a1ad8f724b2de3de017831e38
|
||||
ENVOY_LATEST_IMAGE_TAG ?= 2.0.3
|
||||
ISTIO_LATEST_IMAGE_TAG ?= 8be82d2e4c280c29f4952fbeca1e2a79230b7836
|
||||
|
||||
install-dev: pre-install
|
||||
helm install higress helm/core -n higress-system --create-namespace --set 'controller.tag=$(TAG)' --set 'gateway.replicas=1' --set 'pilot.tag=$(ISTIO_LATEST_IMAGE_TAG)' --set 'gateway.tag=$(ENVOY_LATEST_IMAGE_TAG)' --set 'global.local=true'
|
||||
@@ -221,11 +221,15 @@ clean-higress: ## Cleans all the intermediate files and folders previously gener
|
||||
rm -rf $(DIRS_TO_CLEAN)
|
||||
|
||||
clean-istio:
|
||||
rm -rf external/api
|
||||
rm -rf external/client-go
|
||||
rm -rf external/istio
|
||||
rm -rf external/pkg
|
||||
|
||||
clean-gateway: clean-istio
|
||||
rm -rf external/envoy
|
||||
rm -rf external/proxy
|
||||
rm -rf external/go-control-plane
|
||||
rm -rf external/package/envoy.tar.gz
|
||||
|
||||
clean-env:
|
||||
@@ -284,28 +288,32 @@ delete-cluster: $(tools/kind) ## Delete kind cluster.
|
||||
.PHONY: kube-load-image
|
||||
kube-load-image: $(tools/kind) ## Install the Higress image to a kind cluster using the provided $IMAGE and $TAG.
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/higress $(TAG)
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/pilot $(ISTIO_LATEST_IMAGE_TAG)
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/gateway $(ENVOY_LATEST_IMAGE_TAG)
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/dubbo-provider-demo 0.0.3-x86
|
||||
tools/hack/docker-pull-image.sh docker.io/alihigress/nacos-standlone-rc3 1.0.0-RC3
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/nacos-standlone-rc3 1.0.0-RC3
|
||||
tools/hack/docker-pull-image.sh docker.io/hashicorp/consul 1.16.0
|
||||
tools/hack/docker-pull-image.sh docker.io/charlie1380/eureka-registry-provider v0.3.0
|
||||
tools/hack/docker-pull-image.sh docker.io/bitinit/eureka latest
|
||||
tools/hack/docker-pull-image.sh docker.io/alihigress/httpbin 1.0.2
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/httpbin 1.0.2
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-server 1.3.0
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-server v1.0
|
||||
tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-body 1.0.0
|
||||
tools/hack/docker-pull-image.sh openpolicyagent/opa latest
|
||||
tools/hack/docker-pull-image.sh curlimages/curl latest
|
||||
tools/hack/docker-pull-image.sh registry.cn-hangzhou.aliyuncs.com/2456868764/httpbin 1.0.2
|
||||
tools/hack/docker-pull-image.sh registry.cn-hangzhou.aliyuncs.com/hinsteny/nacos-standlone-rc3 1.0.0-RC3
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/dubbo-provider-demo 0.0.3-x86
|
||||
tools/hack/kind-load-image.sh docker.io/alihigress/nacos-standlone-rc3 1.0.0-RC3
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/nacos-standlone-rc3 1.0.0-RC3
|
||||
tools/hack/kind-load-image.sh docker.io/hashicorp/consul 1.16.0
|
||||
tools/hack/kind-load-image.sh docker.io/alihigress/httpbin 1.0.2
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/httpbin 1.0.2
|
||||
tools/hack/kind-load-image.sh docker.io/charlie1380/eureka-registry-provider v0.3.0
|
||||
tools/hack/kind-load-image.sh docker.io/bitinit/eureka latest
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-server 1.3.0
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-server v1.0
|
||||
tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/echo-body 1.0.0
|
||||
tools/hack/kind-load-image.sh openpolicyagent/opa latest
|
||||
tools/hack/kind-load-image.sh curlimages/curl latest
|
||||
tools/hack/kind-load-image.sh registry.cn-hangzhou.aliyuncs.com/2456868764/httpbin 1.0.2
|
||||
tools/hack/kind-load-image.sh registry.cn-hangzhou.aliyuncs.com/hinsteny/nacos-standlone-rc3 1.0.0-RC3
|
||||
|
||||
|
||||
66
README.md
66
README.md
@@ -1,3 +1,4 @@
|
||||
<a name="readme-top"></a>
|
||||
<h1 align="center">
|
||||
<img src="https://img.alicdn.com/imgextra/i2/O1CN01NwxLDd20nxfGBjxmZ_!!6000000006895-2-tps-960-290.png" alt="Higress" width="240" height="72.5">
|
||||
<br>
|
||||
@@ -8,26 +9,28 @@
|
||||
[](https://github.com/alibaba/higress/actions)
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
[**官网**](https://higress.io/) |
|
||||
[**文档**](https://higress.io/docs/latest/user/quickstart/) |
|
||||
[**博客**](https://higress.io/blog/) |
|
||||
[**开发指引**](https://higress.io/docs/latest/dev/architecture/) |
|
||||
[**AI插件**](https://higress.io/plugin/)
|
||||
[**官网**](https://higress.cn/) |
|
||||
[**文档**](https://higress.cn/docs/latest/overview/what-is-higress/) |
|
||||
[**博客**](https://higress.cn/blog/) |
|
||||
[**电子书**](https://higress.cn/docs/ebook/wasm14/) |
|
||||
[**开发指引**](https://higress.cn/docs/latest/dev/architecture/) |
|
||||
[**AI插件**](https://higress.cn/plugin/)
|
||||
|
||||
|
||||
<p>
|
||||
<a href="README_EN.md"> English <a/> | 中文
|
||||
<a href="README_EN.md"> English <a/>| 中文 | <a href="README_JP.md"> 日本語 <a/>
|
||||
</p>
|
||||
|
||||
|
||||
Higress 是基于阿里内部多年的 Envoy Gateway 实践沉淀,以开源 [Istio](https://github.com/istio/istio) 与 [Envoy](https://github.com/envoyproxy/envoy) 为核心构建的云原生 API 网关。
|
||||
Higress 是一款云原生 API 网关,内核基于 Istio 和 Envoy,可以用 Go/Rust/JS 等编写 Wasm 插件,提供了数十个现成的通用插件,以及开箱即用的控制台(demo 点[这里](http://demo.higress.io/))
|
||||
|
||||
Higress 在阿里内部作为 AI 网关,承载了通义千问 APP、百炼大模型 API、机器学习 PAI 平台等 AI 业务的流量。
|
||||
Higress 在阿里内部为解决 Tengine reload 对长连接业务有损,以及 gRPC/Dubbo 负载均衡能力不足而诞生。
|
||||
|
||||
Higress 能够用统一的协议对接国内外所有 LLM 模型厂商,同时具备丰富的 AI 可观测、多模型负载均衡/fallback、AI token 流控、AI 缓存等能力:
|
||||
阿里云基于 Higress 构建了云原生 API 网关产品,为大量企业客户提供 99.99% 的网关高可用保障服务能力。
|
||||
|
||||

|
||||
Higress 基于 AI 网关能力,支撑了通义千问 APP、百炼大模型 API、机器学习 PAI 平台等 AI 业务。同时服务国内头部的 AIGC 企业(如零一万物),以及 AI 产品(如 FastGPT)
|
||||
|
||||

|
||||
|
||||
|
||||
## Summary
|
||||
@@ -57,32 +60,45 @@ docker run -d --rm --name higress-ai -v ${PWD}:/data \
|
||||
- 8080 端口:网关 HTTP 协议入口
|
||||
- 8443 端口:网关 HTTPS 协议入口
|
||||
|
||||
**Higress 的所有 Docker 镜像都一直使用自己独享的仓库,不受 Docker Hub 境内不可访问的影响**
|
||||
**Higress 的所有 Docker 镜像都一直使用自己独享的仓库,不受 Docker Hub 境内访问受限的影响**
|
||||
|
||||
K8s 下使用 Helm 部署等其他安装方式可以参考官网 [Quick Start 文档](https://higress.io/docs/latest/user/quickstart/)。
|
||||
K8s 下使用 Helm 部署等其他安装方式可以参考官网 [Quick Start 文档](https://higress.cn/docs/latest/user/quickstart/)。
|
||||
|
||||
如果您是在云上部署,生产环境推荐使用[企业版](https://higress.io/cloud/),开发测试可以使用下面一键部署社区版:
|
||||
|
||||
[](https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=Higress社区版)
|
||||
|
||||
|
||||
## 使用场景
|
||||
|
||||
- **AI 网关**:
|
||||
|
||||
Higress 提供了一站式的 AI 插件集,可以增强依赖 AI 能力业务的稳定性、灵活性、可观测性,使得业务与 AI 的集成更加便捷和高效。
|
||||
Higress 能够用统一的协议对接国内外所有 LLM 模型厂商,同时具备丰富的 AI 可观测、多模型负载均衡/fallback、AI token 流控、AI 缓存等能力:
|
||||
|
||||

|
||||
|
||||
- **Kubernetes Ingress 网关**:
|
||||
|
||||
Higress 可以作为 K8s 集群的 Ingress 入口网关, 并且兼容了大量 K8s Nginx Ingress 的注解,可以从 K8s Nginx Ingress 快速平滑迁移到 Higress。
|
||||
|
||||
支持 [Gateway API](https://gateway-api.sigs.k8s.io/) 标准,支持用户从 Ingress API 平滑迁移到 Gateway API。
|
||||
|
||||
相比 ingress-nginx,资源开销大幅下降,路由变更生效速度有十倍提升:
|
||||
|
||||

|
||||

|
||||
|
||||
- **微服务网关**:
|
||||
|
||||
Higress 可以作为微服务网关, 能够对接多种类型的注册中心发现服务配置路由,例如 Nacos, ZooKeeper, Consul, Eureka 等。
|
||||
|
||||
并且深度集成了 [Dubbo](https://github.com/apache/dubbo), [Nacos](https://github.com/alibaba/nacos), [Sentinel](https://github.com/alibaba/Sentinel) 等微服务技术栈,基于 Envoy C++ 网关内核的出色性能,相比传统 Java 类微服务网关,可以显著降低资源使用率,减少成本。
|
||||
|
||||

|
||||
|
||||
- **安全防护网关**:
|
||||
|
||||
Higress 可以作为安全防护网关, 提供 WAF 的能力,并且支持多种认证鉴权策略,例如 key-auth, hmac-auth, jwt-auth, basic-auth, oidc 等。
|
||||
Higress 可以作为安全防护网关, 提供 WAF 的能力,并且支持多种认证鉴权策略,例如 key-auth, hmac-auth, jwt-auth, basic-auth, oidc 等。
|
||||
|
||||
## 核心优势
|
||||
|
||||
@@ -164,7 +180,7 @@ K8s 下使用 Helm 部署等其他安装方式可以参考官网 [Quick Start
|
||||
|
||||
### 交流群
|
||||
|
||||

|
||||

|
||||
|
||||
### 技术分享
|
||||
|
||||
@@ -172,3 +188,23 @@ K8s 下使用 Helm 部署等其他安装方式可以参考官网 [Quick Start
|
||||
|
||||

|
||||
|
||||
### 关联仓库
|
||||
|
||||
- Higress 控制台:https://github.com/higress-group/higress-console
|
||||
- Higress(独立运行版):https://github.com/higress-group/higress-standalone
|
||||
|
||||
### 贡献者
|
||||
|
||||
<a href="https://github.com/alibaba/higress/graphs/contributors">
|
||||
<img alt="contributors" src="https://contrib.rocks/image?repo=alibaba/higress"/>
|
||||
</a>
|
||||
|
||||
### Star History
|
||||
|
||||
[](https://star-history.com/#alibaba/higress&Date)
|
||||
|
||||
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
|
||||
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
|
||||
↑ 返回顶部 ↑
|
||||
</a>
|
||||
</p>
|
||||
|
||||
32
README_EN.md
32
README_EN.md
@@ -1,3 +1,4 @@
|
||||
<a name="readme-top"></a>
|
||||
<h1 align="center">
|
||||
<img src="https://img.alicdn.com/imgextra/i2/O1CN01NwxLDd20nxfGBjxmZ_!!6000000006895-2-tps-960-290.png" alt="Higress" width="240" height="72.5">
|
||||
<br>
|
||||
@@ -15,7 +16,7 @@
|
||||
|
||||
|
||||
<p>
|
||||
English | <a href="README.md">中文<a/>
|
||||
English | <a href="README.md">中文<a/> | <a href="README_JP.md">日本語<a/>
|
||||
</p>
|
||||
|
||||
Higress is a cloud-native api gateway based on Alibaba's internal gateway practices.
|
||||
@@ -47,7 +48,7 @@ Powered by [Istio](https://github.com/istio/istio) and [Envoy](https://github.co
|
||||
|
||||
Higress can function as a microservice gateway, which can discovery microservices from various service registries, such as Nacos, ZooKeeper, Consul, Eureka, etc.
|
||||
|
||||
It deeply integrates of [Dubbo](https://github.com/apache/dubbo), [Nacos](https://github.com/alibaba/nacos), [Sentinel](https://github.com/alibaba/Sentinel) and other microservice technology stacks.
|
||||
It deeply integrates with [Dubbo](https://github.com/apache/dubbo), [Nacos](https://github.com/alibaba/nacos), [Sentinel](https://github.com/alibaba/Sentinel) and other microservice technology stacks.
|
||||
|
||||
- **Security gateway**:
|
||||
|
||||
@@ -57,7 +58,7 @@ Powered by [Istio](https://github.com/istio/istio) and [Envoy](https://github.co
|
||||
|
||||
- **Easy to use**
|
||||
|
||||
Provide one-stop gateway solutions for traffic scheduling, service management, and security protection, support Console, K8s Ingress, and Gateway API configuration methods, and also support HTTP to Dubbo protocol conversion, and easily complete protocol mapping configuration.
|
||||
Provides one-stop gateway solutions for traffic scheduling, service management, and security protection, support Console, K8s Ingress, and Gateway API configuration methods, and also support HTTP to Dubbo protocol conversion, and easily complete protocol mapping configuration.
|
||||
|
||||
- **Easy to expand**
|
||||
|
||||
@@ -73,7 +74,7 @@ Powered by [Istio](https://github.com/istio/istio) and [Envoy](https://github.co
|
||||
|
||||
- **Security**
|
||||
|
||||
Provides JWT, OIDC, custom authentication and authentication, deeply integrates open source web application firewall.
|
||||
Provides JWT, OIDC, custom authentication and authentication, deeply integrates open-source web application firewall.
|
||||
|
||||
## Community
|
||||
|
||||
@@ -81,4 +82,25 @@ Powered by [Istio](https://github.com/istio/istio) and [Envoy](https://github.co
|
||||
|
||||
### Thanks
|
||||
|
||||
Higress would not be possible without the valuable open-source work of projects in the community. We would like to extend a special thank-you to Envoy and Istio.
|
||||
Higress would not be possible without the valuable open-source work of projects in the community. We would like to extend a special thank you to Envoy and Istio.
|
||||
|
||||
### Related Repositories
|
||||
|
||||
- Higress Console: https://github.com/higress-group/higress-console
|
||||
- Higress Standalone: https://github.com/higress-group/higress-standalone
|
||||
|
||||
### Contributors
|
||||
|
||||
<a href="https://github.com/alibaba/higress/graphs/contributors">
|
||||
<img alt="contributors" src="https://contrib.rocks/image?repo=alibaba/higress"/>
|
||||
</a>
|
||||
|
||||
### Star History
|
||||
|
||||
[](https://star-history.com/#alibaba/higress&Date)
|
||||
|
||||
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
|
||||
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
|
||||
↑ Back to Top ↑
|
||||
</a>
|
||||
</p>
|
||||
206
README_JP.md
Normal file
206
README_JP.md
Normal file
@@ -0,0 +1,206 @@
|
||||
<a name="readme-top"></a>
|
||||
<h1 align="center">
|
||||
<img src="https://img.alicdn.com/imgextra/i2/O1CN01NwxLDd20nxfGBjxmZ_!!6000000006895-2-tps-960-290.png" alt="Higress" width="240" height="72.5">
|
||||
<br>
|
||||
AIゲートウェイ
|
||||
</h1>
|
||||
<h4 align="center"> AIネイティブAPIゲートウェイ </h4>
|
||||
|
||||
[](https://github.com/alibaba/higress/actions)
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
[**公式サイト**](https://higress.cn/) |
|
||||
[**ドキュメント**](https://higress.cn/docs/latest/overview/what-is-higress/) |
|
||||
[**ブログ**](https://higress.cn/blog/) |
|
||||
[**電子書籍**](https://higress.cn/docs/ebook/wasm14/) |
|
||||
[**開発ガイド**](https://higress.cn/docs/latest/dev/architecture/) |
|
||||
[**AIプラグイン**](https://higress.cn/plugin/)
|
||||
|
||||
|
||||
<p>
|
||||
<a href="README_EN.md"> English <a/> | <a href="README.md">中文<a/> | 日本語
|
||||
</p>
|
||||
|
||||
|
||||
Higressは、IstioとEnvoyをベースにしたクラウドネイティブAPIゲートウェイで、Go/Rust/JSなどを使用してWasmプラグインを作成できます。数十の既製の汎用プラグインと、すぐに使用できるコンソールを提供しています(デモは[こちら](http://demo.higress.io/))。
|
||||
|
||||
Higressは、Tengineのリロードが長時間接続のビジネスに影響を与える問題や、gRPC/Dubboの負荷分散能力の不足を解決するために、Alibaba内部で誕生しました。
|
||||
|
||||
Alibaba Cloudは、Higressを基盤にクラウドネイティブAPIゲートウェイ製品を構築し、多くの企業顧客に99.99%のゲートウェイ高可用性保証サービスを提供しています。
|
||||
|
||||
Higressは、AIゲートウェイ機能を基盤に、Tongyi Qianwen APP、Bailian大規模モデルAPI、機械学習PAIプラットフォームなどのAIビジネスをサポートしています。また、国内の主要なAIGC企業(例:ZeroOne)やAI製品(例:FastGPT)にもサービスを提供しています。
|
||||
|
||||

|
||||
|
||||
|
||||
## 目次
|
||||
|
||||
- [**クイックスタート**](#クイックスタート)
|
||||
- [**機能紹介**](#機能紹介)
|
||||
- [**使用シナリオ**](#使用シナリオ)
|
||||
- [**主な利点**](#主な利点)
|
||||
- [**コミュニティ**](#コミュニティ)
|
||||
|
||||
## クイックスタート
|
||||
|
||||
HigressはDockerだけで起動でき、個人開発者がローカルで学習用にセットアップしたり、簡易サイトを構築するのに便利です。
|
||||
|
||||
```bash
|
||||
# 作業ディレクトリを作成
|
||||
mkdir higress; cd higress
|
||||
# Higressを起動し、設定ファイルを作業ディレクトリに書き込みます
|
||||
docker run -d --rm --name higress-ai -v ${PWD}:/data \
|
||||
-p 8001:8001 -p 8080:8080 -p 8443:8443 \
|
||||
higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:latest
|
||||
```
|
||||
|
||||
リスンポートの説明は以下の通りです:
|
||||
|
||||
- 8001ポート:Higress UIコンソールのエントリーポイント
|
||||
- 8080ポート:ゲートウェイのHTTPプロトコルエントリーポイント
|
||||
- 8443ポート:ゲートウェイのHTTPSプロトコルエントリーポイント
|
||||
|
||||
**HigressのすべてのDockerイメージは専用のリポジトリを使用しており、Docker Hubの国内アクセス不可の影響を受けません**
|
||||
|
||||
K8sでのHelmデプロイなどの他のインストール方法については、公式サイトの[クイックスタートドキュメント](https://higress.cn/docs/latest/user/quickstart/)を参照してください。
|
||||
|
||||
|
||||
## 使用シナリオ
|
||||
|
||||
- **AIゲートウェイ**:
|
||||
|
||||
Higressは、国内外のすべてのLLMモデルプロバイダーと統一されたプロトコルで接続でき、豊富なAI可観測性、多モデル負荷分散/フォールバック、AIトークンフロー制御、AIキャッシュなどの機能を備えています。
|
||||
|
||||

|
||||
|
||||
- **Kubernetes Ingressゲートウェイ**:
|
||||
|
||||
HigressはK8sクラスターのIngressエントリーポイントゲートウェイとして機能し、多くのK8s Nginx Ingressの注釈に対応しています。K8s Nginx IngressからHigressへのスムーズな移行が可能です。
|
||||
|
||||
[Gateway API](https://gateway-api.sigs.k8s.io/)標準をサポートし、ユーザーがIngress APIからGateway APIにスムーズに移行できるようにします。
|
||||
|
||||
ingress-nginxと比較して、リソースの消費が大幅に減少し、ルーティングの変更が10倍速く反映されます。
|
||||
|
||||

|
||||

|
||||
|
||||
- **マイクロサービスゲートウェイ**:
|
||||
|
||||
Higressはマイクロサービスゲートウェイとして機能し、Nacos、ZooKeeper、Consul、Eurekaなどのさまざまなサービスレジストリからサービスを発見し、ルーティングを構成できます。
|
||||
|
||||
また、[Dubbo](https://github.com/apache/dubbo)、[Nacos](https://github.com/alibaba/nacos)、[Sentinel](https://github.com/alibaba/Sentinel)などのマイクロサービス技術スタックと深く統合されています。Envoy C++ゲートウェイコアの優れたパフォーマンスに基づいて、従来のJavaベースのマイクロサービスゲートウェイと比較して、リソース使用率を大幅に削減し、コストを削減できます。
|
||||
|
||||

|
||||
|
||||
- **セキュリティゲートウェイ**:
|
||||
|
||||
Higressはセキュリティゲートウェイとして機能し、WAF機能を提供し、key-auth、hmac-auth、jwt-auth、basic-auth、oidcなどのさまざまな認証戦略をサポートします。
|
||||
|
||||
## 主な利点
|
||||
|
||||
- **プロダクションレベル**
|
||||
|
||||
Alibabaで2年以上のプロダクション検証を経た内部製品から派生し、毎秒数十万のリクエストを処理する大規模なシナリオをサポートします。
|
||||
|
||||
Nginxのリロードによるトラフィックの揺れを完全に排除し、構成変更がミリ秒単位で反映され、ビジネスに影響を与えません。AIビジネスなどの長時間接続シナリオに特に適しています。
|
||||
|
||||
- **ストリーム処理**
|
||||
|
||||
リクエスト/レスポンスボディの完全なストリーム処理をサポートし、Wasmプラグインを使用してSSE(Server-Sent Events)などのストリームプロトコルのメッセージをカスタマイズして処理できます。
|
||||
|
||||
AIビジネスなどの大帯域幅シナリオで、メモリ使用量を大幅に削減できます。
|
||||
|
||||
- **拡張性**
|
||||
|
||||
AI、トラフィック管理、セキュリティ保護などの一般的な機能をカバーする豊富な公式プラグインライブラリを提供し、90%以上のビジネスシナリオのニーズを満たします。
|
||||
|
||||
Wasmプラグイン拡張を主力とし、サンドボックス隔離を通じてメモリの安全性を確保し、複数のプログラミング言語をサポートし、プラグインバージョンの独立したアップグレードを許可し、トラフィックに影響を与えずにゲートウェイロジックをホットアップデートできます。
|
||||
|
||||
- **安全で使いやすい**
|
||||
|
||||
Ingress APIおよびGateway API標準に基づき、すぐに使用できるUIコンソールを提供し、WAF保護プラグイン、IP/Cookie CC保護プラグインをすぐに使用できます。
|
||||
|
||||
Let's Encryptの自動証明書発行および更新をサポートし、K8sを使用せずにデプロイでき、1行のDockerコマンドで起動でき、個人開発者にとって便利です。
|
||||
|
||||
|
||||
## 機能紹介
|
||||
|
||||
### AIゲートウェイデモ展示
|
||||
|
||||
[OpenAIから他の大規模モデルへの移行を30秒で完了
|
||||
](https://www.bilibili.com/video/BV1dT421a7w7/?spm_id_from=333.788.recommend_more_video.14)
|
||||
|
||||
|
||||
### Higress UIコンソール
|
||||
|
||||
- **豊富な可観測性**
|
||||
|
||||
すぐに使用できる可観測性を提供し、Grafana&Prometheusは組み込みのものを使用することも、自分で構築したものを接続することもできます。
|
||||
|
||||

|
||||
|
||||
|
||||
- **プラグイン拡張メカニズム**
|
||||
|
||||
公式にはさまざまなプラグインが提供されており、ユーザーは[独自のプラグインを開発](./plugins/wasm-go)し、Docker/OCIイメージとして構築し、コンソールで構成して、プラグインロジックをリアルタイムで変更できます。トラフィックに影響を与えずにプラグインロジックをホットアップデートできます。
|
||||
|
||||

|
||||
|
||||
|
||||
- **さまざまなサービス発見**
|
||||
|
||||
デフォルトでK8s Serviceサービス発見を提供し、構成を通じてNacos/ZooKeeperなどのレジストリに接続してサービスを発見することも、静的IPまたはDNSに基づいて発見することもできます。
|
||||
|
||||

|
||||
|
||||
|
||||
- **ドメインと証明書**
|
||||
|
||||
TLS証明書を作成および管理し、ドメインのHTTP/HTTPS動作を構成できます。ドメインポリシーでは、特定のドメインに対してプラグインを適用することができます。
|
||||
|
||||

|
||||
|
||||
|
||||
- **豊富なルーティング機能**
|
||||
|
||||
上記で定義されたサービス発見メカニズムを通じて、発見されたサービスはサービスリストに表示されます。ルーティングを作成する際に、ドメインを選択し、ルーティングマッチングメカニズムを定義し、ターゲットサービスを選択してルーティングを行います。ルーティングポリシーでは、特定のルーティングに対してプラグインを適用することができます。
|
||||
|
||||

|
||||
|
||||
|
||||
## コミュニティ
|
||||
|
||||
### 感謝
|
||||
|
||||
EnvoyとIstioのオープンソースの取り組みがなければ、Higressは実現できませんでした。これらのプロジェクトに最も誠実な敬意を表します。
|
||||
|
||||
### 交流グループ
|
||||
|
||||

|
||||
|
||||
### 技術共有
|
||||
|
||||
WeChat公式アカウント:
|
||||
|
||||

|
||||
|
||||
### 関連リポジトリ
|
||||
|
||||
- Higressコンソール:https://github.com/higress-group/higress-console
|
||||
- Higress(スタンドアロン版):https://github.com/higress-group/higress-standalone
|
||||
|
||||
### 貢献者
|
||||
|
||||
<a href="https://github.com/alibaba/higress/graphs/contributors">
|
||||
<img alt="contributors" src="https://contrib.rocks/image?repo=alibaba/higress"/>
|
||||
</a>
|
||||
|
||||
### スターの歴史
|
||||
|
||||
[](https://star-history.com/#alibaba/higress&Date)
|
||||
|
||||
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
|
||||
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
|
||||
↑ トップに戻る ↑
|
||||
</a>
|
||||
</p>
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.x.x | :white_check_mark: |
|
||||
| 1.x.x | :white_check_mark: |
|
||||
| < 1.0.0 | :x: |
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: extensions/v1alpha1/wasm.proto
|
||||
// source: extensions/v1alpha1/wasmplugin.proto
|
||||
|
||||
// $schema: higress.extensions.v1alpha1.WasmPlugin
|
||||
// $title: WasmPlugin
|
||||
@@ -84,11 +84,11 @@ func (x PluginPhase) String() string {
|
||||
}
|
||||
|
||||
func (PluginPhase) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasm_proto_enumTypes[0].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (PluginPhase) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasm_proto_enumTypes[0]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x PluginPhase) Number() protoreflect.EnumNumber {
|
||||
@@ -97,7 +97,7 @@ func (x PluginPhase) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use PluginPhase.Descriptor instead.
|
||||
func (PluginPhase) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{0}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// The pull behaviour to be applied when fetching an OCI image,
|
||||
@@ -146,11 +146,11 @@ func (x PullPolicy) String() string {
|
||||
}
|
||||
|
||||
func (PullPolicy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasm_proto_enumTypes[1].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (PullPolicy) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasm_proto_enumTypes[1]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x PullPolicy) Number() protoreflect.EnumNumber {
|
||||
@@ -159,7 +159,7 @@ func (x PullPolicy) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use PullPolicy.Descriptor instead.
|
||||
func (PullPolicy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{1}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type EnvValueSource int32
|
||||
@@ -194,11 +194,11 @@ func (x EnvValueSource) String() string {
|
||||
}
|
||||
|
||||
func (EnvValueSource) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasm_proto_enumTypes[2].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (EnvValueSource) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasm_proto_enumTypes[2]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x EnvValueSource) Number() protoreflect.EnumNumber {
|
||||
@@ -207,7 +207,7 @@ func (x EnvValueSource) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use EnvValueSource.Descriptor instead.
|
||||
func (EnvValueSource) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{2}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type FailStrategy int32
|
||||
@@ -246,11 +246,11 @@ func (x FailStrategy) String() string {
|
||||
}
|
||||
|
||||
func (FailStrategy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasm_proto_enumTypes[3].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3].Descriptor()
|
||||
}
|
||||
|
||||
func (FailStrategy) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasm_proto_enumTypes[3]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3]
|
||||
}
|
||||
|
||||
func (x FailStrategy) Number() protoreflect.EnumNumber {
|
||||
@@ -259,7 +259,7 @@ func (x FailStrategy) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use FailStrategy.Descriptor instead.
|
||||
func (FailStrategy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{3}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
// <!-- crd generation tags
|
||||
@@ -347,7 +347,7 @@ type WasmPlugin struct {
|
||||
func (x *WasmPlugin) Reset() {
|
||||
*x = WasmPlugin{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[0]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -360,7 +360,7 @@ func (x *WasmPlugin) String() string {
|
||||
func (*WasmPlugin) ProtoMessage() {}
|
||||
|
||||
func (x *WasmPlugin) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[0]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -373,7 +373,7 @@ func (x *WasmPlugin) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use WasmPlugin.ProtoReflect.Descriptor instead.
|
||||
func (*WasmPlugin) Descriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{0}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *WasmPlugin) GetUrl() string {
|
||||
@@ -490,7 +490,7 @@ type MatchRule struct {
|
||||
func (x *MatchRule) Reset() {
|
||||
*x = MatchRule{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[1]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -503,7 +503,7 @@ func (x *MatchRule) String() string {
|
||||
func (*MatchRule) ProtoMessage() {}
|
||||
|
||||
func (x *MatchRule) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[1]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -516,7 +516,7 @@ func (x *MatchRule) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use MatchRule.ProtoReflect.Descriptor instead.
|
||||
func (*MatchRule) Descriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{1}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *MatchRule) GetIngress() []string {
|
||||
@@ -569,7 +569,7 @@ type VmConfig struct {
|
||||
func (x *VmConfig) Reset() {
|
||||
*x = VmConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[2]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -582,7 +582,7 @@ func (x *VmConfig) String() string {
|
||||
func (*VmConfig) ProtoMessage() {}
|
||||
|
||||
func (x *VmConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[2]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -595,7 +595,7 @@ func (x *VmConfig) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use VmConfig.ProtoReflect.Descriptor instead.
|
||||
func (*VmConfig) Descriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{2}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *VmConfig) GetEnv() []*EnvVar {
|
||||
@@ -625,7 +625,7 @@ type EnvVar struct {
|
||||
func (x *EnvVar) Reset() {
|
||||
*x = EnvVar{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[3]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -638,7 +638,7 @@ func (x *EnvVar) String() string {
|
||||
func (*EnvVar) ProtoMessage() {}
|
||||
|
||||
func (x *EnvVar) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_v1alpha1_wasm_proto_msgTypes[3]
|
||||
mi := &file_extensions_v1alpha1_wasmplugin_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -651,7 +651,7 @@ func (x *EnvVar) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use EnvVar.ProtoReflect.Descriptor instead.
|
||||
func (*EnvVar) Descriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescGZIP(), []int{3}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *EnvVar) GetName() string {
|
||||
@@ -675,124 +675,125 @@ func (x *EnvVar) GetValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_extensions_v1alpha1_wasm_proto protoreflect.FileDescriptor
|
||||
var File_extensions_v1alpha1_wasmplugin_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_extensions_v1alpha1_wasm_proto_rawDesc = []byte{
|
||||
0x0a, 0x1e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x77, 0x61, 0x73, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x12, 0x1b, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77,
|
||||
0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73,
|
||||
0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x06, 0x0a, 0x0a,
|
||||
0x57, 0x61, 0x73, 0x6d, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,
|
||||
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68,
|
||||
0x61, 0x32, 0x35, 0x36, 0x12, 0x53, 0x0a, 0x11, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x75,
|
||||
0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x27, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x75,
|
||||
0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x50,
|
||||
0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6d, 0x61,
|
||||
0x67, 0x65, 0x5f, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x75, 0x6c, 0x6c, 0x53,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79,
|
||||
0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
|
||||
0x52, 0x0c, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f,
|
||||
0x0a, 0x0b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x3e, 0x0a, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28,
|
||||
0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c, 0x75,
|
||||
0x67, 0x69, 0x6e, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x12,
|
||||
0x37, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08,
|
||||
0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c,
|
||||
0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x29, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x61,
|
||||
0x69, 0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0c, 0x66, 0x61, 0x69, 0x6c,
|
||||
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x42, 0x0a, 0x09, 0x76, 0x6d, 0x5f, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x69,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x6d, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x08, 0x76, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, 0x0e,
|
||||
0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x65,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0d, 0x64,
|
||||
0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x47, 0x0a, 0x0b,
|
||||
0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x66, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x26, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65,
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_rawDesc = []byte{
|
||||
0x0a, 0x24, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x77, 0x61, 0x73, 0x6d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0x8d, 0x06, 0x0a, 0x0a, 0x57, 0x61, 0x73, 0x6d, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75,
|
||||
0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x53, 0x0a, 0x11, 0x69, 0x6d,
|
||||
0x61, 0x67, 0x65, 0x5f, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0f,
|
||||
0x69, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
|
||||
0x2a, 0x0a, 0x11, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x76,
|
||||
0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0c, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69,
|
||||
0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x05,
|
||||
0x70, 0x68, 0x61, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
|
||||
0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x4e,
|
||||
0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18,
|
||||
0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
|
||||
0x52, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x42,
|
||||
0x0a, 0x09, 0x76, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x25, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65,
|
||||
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
|
||||
0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18,
|
||||
0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xaf, 0x01, 0x0a, 0x09,
|
||||
0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x6e, 0x67,
|
||||
0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x69, 0x6e, 0x67, 0x72,
|
||||
0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
|
||||
0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x41, 0x0a,
|
||||
0x08, 0x56, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x03, 0x65, 0x6e, 0x76,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73,
|
||||
0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x52, 0x03, 0x65, 0x6e, 0x76,
|
||||
0x22, 0x7e, 0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4a,
|
||||
0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74,
|
||||
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
|
||||
0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x2a, 0x45, 0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12,
|
||||
0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x50,
|
||||
0x48, 0x41, 0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x4e, 0x10,
|
||||
0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x5a, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05,
|
||||
0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x50,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
|
||||
0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x10, 0x00, 0x12, 0x10, 0x0a,
|
||||
0x0c, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, 0x02, 0x2a, 0x26, 0x0a, 0x0e, 0x45,
|
||||
0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x49, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53,
|
||||
0x54, 0x10, 0x01, 0x2a, 0x2d, 0x0a, 0x0c, 0x46, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x72, 0x61, 0x74,
|
||||
0x65, 0x67, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x41, 0x49, 0x4c, 0x5f, 0x43, 0x4c, 0x4f, 0x53,
|
||||
0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x41, 0x49, 0x4c, 0x5f, 0x4f, 0x50, 0x45, 0x4e,
|
||||
0x10, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f,
|
||||
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x56, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x76, 0x6d, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x3e, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
|
||||
0x75, 0x63, 0x74, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x47, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x75, 0x6c, 0x65,
|
||||
0x73, 0x18, 0x66, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73,
|
||||
0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x52,
|
||||
0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x64,
|
||||
0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69,
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x65, 0x66,
|
||||
0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x22, 0xaf, 0x01, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
|
||||
0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x08, 0x56, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x35, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68,
|
||||
0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61,
|
||||
0x72, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x7e, 0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x72,
|
||||
0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65,
|
||||
0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x6f, 0x6d,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x45, 0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
|
||||
0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
|
||||
0x41, 0x55, 0x54, 0x48, 0x4e, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x5a,
|
||||
0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x03, 0x2a, 0x42, 0x0a,
|
||||
0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x55,
|
||||
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43,
|
||||
0x59, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x50, 0x72, 0x65, 0x73,
|
||||
0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10,
|
||||
0x02, 0x2a, 0x26, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x00, 0x12,
|
||||
0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x2a, 0x2d, 0x0a, 0x0c, 0x46, 0x61, 0x69,
|
||||
0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x10, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68,
|
||||
0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_extensions_v1alpha1_wasm_proto_rawDescOnce sync.Once
|
||||
file_extensions_v1alpha1_wasm_proto_rawDescData = file_extensions_v1alpha1_wasm_proto_rawDesc
|
||||
file_extensions_v1alpha1_wasmplugin_proto_rawDescOnce sync.Once
|
||||
file_extensions_v1alpha1_wasmplugin_proto_rawDescData = file_extensions_v1alpha1_wasmplugin_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_extensions_v1alpha1_wasm_proto_rawDescGZIP() []byte {
|
||||
file_extensions_v1alpha1_wasm_proto_rawDescOnce.Do(func() {
|
||||
file_extensions_v1alpha1_wasm_proto_rawDescData = protoimpl.X.CompressGZIP(file_extensions_v1alpha1_wasm_proto_rawDescData)
|
||||
func file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP() []byte {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_rawDescOnce.Do(func() {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_extensions_v1alpha1_wasmplugin_proto_rawDescData)
|
||||
})
|
||||
return file_extensions_v1alpha1_wasm_proto_rawDescData
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_extensions_v1alpha1_wasm_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_extensions_v1alpha1_wasm_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_extensions_v1alpha1_wasm_proto_goTypes = []interface{}{
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_goTypes = []interface{}{
|
||||
(PluginPhase)(0), // 0: higress.extensions.v1alpha1.PluginPhase
|
||||
(PullPolicy)(0), // 1: higress.extensions.v1alpha1.PullPolicy
|
||||
(EnvValueSource)(0), // 2: higress.extensions.v1alpha1.EnvValueSource
|
||||
@@ -804,7 +805,7 @@ var file_extensions_v1alpha1_wasm_proto_goTypes = []interface{}{
|
||||
(*_struct.Struct)(nil), // 8: google.protobuf.Struct
|
||||
(*wrappers.Int32Value)(nil), // 9: google.protobuf.Int32Value
|
||||
}
|
||||
var file_extensions_v1alpha1_wasm_proto_depIdxs = []int32{
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_depIdxs = []int32{
|
||||
1, // 0: higress.extensions.v1alpha1.WasmPlugin.image_pull_policy:type_name -> higress.extensions.v1alpha1.PullPolicy
|
||||
8, // 1: higress.extensions.v1alpha1.WasmPlugin.plugin_config:type_name -> google.protobuf.Struct
|
||||
0, // 2: higress.extensions.v1alpha1.WasmPlugin.phase:type_name -> higress.extensions.v1alpha1.PluginPhase
|
||||
@@ -823,13 +824,13 @@ var file_extensions_v1alpha1_wasm_proto_depIdxs = []int32{
|
||||
0, // [0:11] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_extensions_v1alpha1_wasm_proto_init() }
|
||||
func file_extensions_v1alpha1_wasm_proto_init() {
|
||||
if File_extensions_v1alpha1_wasm_proto != nil {
|
||||
func init() { file_extensions_v1alpha1_wasmplugin_proto_init() }
|
||||
func file_extensions_v1alpha1_wasmplugin_proto_init() {
|
||||
if File_extensions_v1alpha1_wasmplugin_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_extensions_v1alpha1_wasm_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*WasmPlugin); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -841,7 +842,7 @@ func file_extensions_v1alpha1_wasm_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_v1alpha1_wasm_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MatchRule); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -853,7 +854,7 @@ func file_extensions_v1alpha1_wasm_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_v1alpha1_wasm_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*VmConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -865,7 +866,7 @@ func file_extensions_v1alpha1_wasm_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_v1alpha1_wasm_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_extensions_v1alpha1_wasmplugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnvVar); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -882,19 +883,19 @@ func file_extensions_v1alpha1_wasm_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_extensions_v1alpha1_wasm_proto_rawDesc,
|
||||
RawDescriptor: file_extensions_v1alpha1_wasmplugin_proto_rawDesc,
|
||||
NumEnums: 4,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_extensions_v1alpha1_wasm_proto_goTypes,
|
||||
DependencyIndexes: file_extensions_v1alpha1_wasm_proto_depIdxs,
|
||||
EnumInfos: file_extensions_v1alpha1_wasm_proto_enumTypes,
|
||||
MessageInfos: file_extensions_v1alpha1_wasm_proto_msgTypes,
|
||||
GoTypes: file_extensions_v1alpha1_wasmplugin_proto_goTypes,
|
||||
DependencyIndexes: file_extensions_v1alpha1_wasmplugin_proto_depIdxs,
|
||||
EnumInfos: file_extensions_v1alpha1_wasmplugin_proto_enumTypes,
|
||||
MessageInfos: file_extensions_v1alpha1_wasmplugin_proto_msgTypes,
|
||||
}.Build()
|
||||
File_extensions_v1alpha1_wasm_proto = out.File
|
||||
file_extensions_v1alpha1_wasm_proto_rawDesc = nil
|
||||
file_extensions_v1alpha1_wasm_proto_goTypes = nil
|
||||
file_extensions_v1alpha1_wasm_proto_depIdxs = nil
|
||||
File_extensions_v1alpha1_wasmplugin_proto = out.File
|
||||
file_extensions_v1alpha1_wasmplugin_proto_rawDesc = nil
|
||||
file_extensions_v1alpha1_wasmplugin_proto_goTypes = nil
|
||||
file_extensions_v1alpha1_wasmplugin_proto_depIdxs = nil
|
||||
}
|
||||
@@ -8,49 +8,49 @@ import (
|
||||
|
||||
// MarshalJSON is a custom marshaler for WasmPlugin
|
||||
func (this *WasmPlugin) MarshalJSON() ([]byte, error) {
|
||||
str, err := WasmMarshaler.MarshalToString(this)
|
||||
str, err := WasmpluginMarshaler.MarshalToString(this)
|
||||
return []byte(str), err
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom unmarshaler for WasmPlugin
|
||||
func (this *WasmPlugin) UnmarshalJSON(b []byte) error {
|
||||
return WasmUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
return WasmpluginUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshaler for MatchRule
|
||||
func (this *MatchRule) MarshalJSON() ([]byte, error) {
|
||||
str, err := WasmMarshaler.MarshalToString(this)
|
||||
str, err := WasmpluginMarshaler.MarshalToString(this)
|
||||
return []byte(str), err
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom unmarshaler for MatchRule
|
||||
func (this *MatchRule) UnmarshalJSON(b []byte) error {
|
||||
return WasmUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
return WasmpluginUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshaler for VmConfig
|
||||
func (this *VmConfig) MarshalJSON() ([]byte, error) {
|
||||
str, err := WasmMarshaler.MarshalToString(this)
|
||||
str, err := WasmpluginMarshaler.MarshalToString(this)
|
||||
return []byte(str), err
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom unmarshaler for VmConfig
|
||||
func (this *VmConfig) UnmarshalJSON(b []byte) error {
|
||||
return WasmUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
return WasmpluginUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshaler for EnvVar
|
||||
func (this *EnvVar) MarshalJSON() ([]byte, error) {
|
||||
str, err := WasmMarshaler.MarshalToString(this)
|
||||
str, err := WasmpluginMarshaler.MarshalToString(this)
|
||||
return []byte(str), err
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom unmarshaler for EnvVar
|
||||
func (this *EnvVar) UnmarshalJSON(b []byte) error {
|
||||
return WasmUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
return WasmpluginUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||
}
|
||||
|
||||
var (
|
||||
WasmMarshaler = &jsonpb.Marshaler{}
|
||||
WasmUnmarshaler = &jsonpb.Unmarshaler{AllowUnknownFields: true}
|
||||
WasmpluginMarshaler = &jsonpb.Marshaler{}
|
||||
WasmpluginUnmarshaler = &jsonpb.Unmarshaler{AllowUnknownFields: true}
|
||||
)
|
||||
@@ -284,6 +284,10 @@ spec:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
protocol:
|
||||
type: string
|
||||
sni:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
zkServicesPath:
|
||||
|
||||
@@ -126,6 +126,8 @@ type RegistryConfig struct {
|
||||
ConsulServiceTag string `protobuf:"bytes,15,opt,name=consulServiceTag,proto3" json:"consulServiceTag,omitempty"`
|
||||
ConsulRefreshInterval int64 `protobuf:"varint,16,opt,name=consulRefreshInterval,proto3" json:"consulRefreshInterval,omitempty"`
|
||||
AuthSecretName string `protobuf:"bytes,17,opt,name=authSecretName,proto3" json:"authSecretName,omitempty"`
|
||||
Protocol string `protobuf:"bytes,18,opt,name=protocol,proto3" json:"protocol,omitempty"`
|
||||
Sni string `protobuf:"bytes,19,opt,name=sni,proto3" json:"sni,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RegistryConfig) Reset() {
|
||||
@@ -279,6 +281,20 @@ func (x *RegistryConfig) GetAuthSecretName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RegistryConfig) GetProtocol() string {
|
||||
if x != nil {
|
||||
return x.Protocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RegistryConfig) GetSni() string {
|
||||
if x != nil {
|
||||
return x.Sni
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_networking_v1_mcp_bridge_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_networking_v1_mcp_bridge_proto_rawDesc = []byte{
|
||||
@@ -292,7 +308,7 @@ var file_networking_v1_mcp_bridge_proto_rawDesc = []byte{
|
||||
0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x69, 0x67, 0x72,
|
||||
0x65, 0x73, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa5, 0x05, 0x0a,
|
||||
0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xd3, 0x05, 0x0a,
|
||||
0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x17, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0,
|
||||
0x41, 0x02, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
@@ -335,10 +351,13 @@ var file_networking_v1_mcp_bridge_proto_rawDesc = []byte{
|
||||
0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x26, 0x0a, 0x0e,
|
||||
0x61, 0x75, 0x74, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x11,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68, 0x69, 0x67, 0x72, 0x65,
|
||||
0x73, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e,
|
||||
0x67, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73,
|
||||
0x6e, 0x69, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2f,
|
||||
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -64,4 +64,6 @@ message RegistryConfig {
|
||||
string consulServiceTag = 15;
|
||||
int64 consulRefreshInterval = 16;
|
||||
string authSecretName = 17;
|
||||
string protocol = 18;
|
||||
string sni = 19;
|
||||
}
|
||||
|
||||
Submodule envoy/envoy updated: 8c3cc1ac25...440fb1b0f3
3
go.mod
3
go.mod
@@ -119,7 +119,6 @@ require (
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
@@ -176,13 +175,13 @@ require (
|
||||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/prometheus/prometheus v0.45.0 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/tetratelabs/wazero v1.7.3 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
|
||||
|
||||
3
go.sum
3
go.sum
@@ -1623,7 +1623,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
@@ -1705,6 +1704,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto=
|
||||
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
|
||||
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
|
||||
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
|
||||
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v2
|
||||
appVersion: 2.0.0-rc.1
|
||||
appVersion: 2.0.4
|
||||
description: Helm chart for deploying higress gateways
|
||||
icon: https://higress.io/img/higress_logo_small.png
|
||||
home: http://higress.io/
|
||||
@@ -10,4 +10,4 @@ name: higress-core
|
||||
sources:
|
||||
- http://github.com/alibaba/higress
|
||||
type: application
|
||||
version: 2.0.0-rc.1
|
||||
version: 2.0.4
|
||||
|
||||
@@ -284,6 +284,10 @@ spec:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
protocol:
|
||||
type: string
|
||||
sni:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
zkServicesPath:
|
||||
@@ -302,3 +306,4 @@ spec:
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
---
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
|
||||
@@ -101,3 +101,15 @@ higress: {{ include "controller.name" . }}
|
||||
true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.podMonitor.gvk" -}}
|
||||
{{- if eq .Values.gateway.metrics.provider "monitoring.coreos.com" -}}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PodMonitor
|
||||
{{- else if eq .Values.gateway.metrics.provider "operator.victoriametrics.com" -}}
|
||||
apiVersion: operator.victoriametrics.com/v1beta1
|
||||
kind: VMPodScrape
|
||||
{{- else -}}
|
||||
{{- fail "unexpected gateway.metrics.provider" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
319
helm/core/templates/_pod.tpl
Normal file
319
helm/core/templates/_pod.tpl
Normal file
@@ -0,0 +1,319 @@
|
||||
|
||||
{{/*
|
||||
Rendering the pod template of gateway component.
|
||||
*/}}
|
||||
{{- define "gateway.podTemplate" -}}
|
||||
{{- $o11y := .Values.global.o11y -}}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
{{- if .Values.gateway.podAnnotations }}
|
||||
{{- toYaml .Values.gateway.podAnnotations | nindent 6 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
sidecar.istio.io/inject: "false"
|
||||
{{- with .Values.gateway.revision }}
|
||||
istio.io/rev: {{ . }}
|
||||
{{- end }}
|
||||
{{- include "gateway.selectorLabels" . | nindent 6 }}
|
||||
spec:
|
||||
{{- with .Values.gateway.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gateway.serviceAccountName" . }}
|
||||
{{- if .Values.global.priorityClassName }}
|
||||
priorityClassName: "{{ .Values.global.priorityClassName }}"
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- if .Values.gateway.securityContext }}
|
||||
{{- toYaml .Values.gateway.securityContext | nindent 6 }}
|
||||
{{- else if and .Values.gateway.unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: higress-gateway
|
||||
image: "{{ .Values.gateway.hub | default .Values.global.hub }}/{{ .Values.gateway.image | default "gateway" }}:{{ .Values.gateway.tag | default .Chart.AppVersion }}"
|
||||
args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.cluster.local
|
||||
- --proxyLogLevel=warning
|
||||
- --proxyComponentLogLevel=misc:error
|
||||
- --log_output_level=all:info
|
||||
- --serviceCluster=higress-gateway
|
||||
securityContext:
|
||||
{{- if .Values.gateway.containerSecurityContext }}
|
||||
{{- toYaml .Values.gateway.containerSecurityContext | nindent 10 }}
|
||||
{{- else if and .Values.gateway.unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
# When enabling lite metrics, the configuration template files need to be replaced.
|
||||
{{- if not .Values.global.liteMetrics }}
|
||||
readOnlyRootFilesystem: true
|
||||
{{- end }}
|
||||
runAsUser: 1337
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
{{- else }}
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
runAsUser: 0
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: false
|
||||
allowPrivilegeEscalation: true
|
||||
{{- end }}
|
||||
env:
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: spec.nodeName
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.podIP
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.hostIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: PROXY_XDS_VIA_AGENT
|
||||
value: "true"
|
||||
- name: ENABLE_INGRESS_GATEWAY_SDS
|
||||
value: "false"
|
||||
- name: JWT_POLICY
|
||||
value: {{ include "controller.jwtPolicy" . }}
|
||||
- name: ISTIO_META_HTTP10
|
||||
value: "1"
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: "{{ $.Values.clusterName | default `Kubernetes` }}"
|
||||
- name: INSTANCE_NAME
|
||||
value: "higress-gateway"
|
||||
{{- if .Values.global.liteMetrics }}
|
||||
- name: LITE_METRICS
|
||||
value: "on"
|
||||
{{- end }}
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- name: ISTIO_BOOTSTRAP_OVERRIDE
|
||||
value: /etc/istio/custom-bootstrap/custom_bootstrap.json
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.networkGateway }}
|
||||
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
|
||||
value: "{{.}}"
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
protocol: TCP
|
||||
name: istio-prom
|
||||
- containerPort: 15090
|
||||
protocol: TCP
|
||||
name: http-envoy-prom
|
||||
{{- if or .Values.global.local .Values.global.kind }}
|
||||
- containerPort: {{ .Values.gateway.httpPort }}
|
||||
hostPort: {{ .Values.gateway.httpPort }}
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: {{ .Values.gateway.httpsPort }}
|
||||
hostPort: {{ .Values.gateway.httpsPort }}
|
||||
name: https
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
readinessProbe:
|
||||
failureThreshold: {{ .Values.gateway.readinessFailureThreshold }}
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.gateway.readinessInitialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gateway.readinessPeriodSeconds }}
|
||||
successThreshold: {{ .Values.gateway.readinessSuccessThreshold }}
|
||||
timeoutSeconds: {{ .Values.gateway.readinessTimeoutSeconds }}
|
||||
{{- if not (or .Values.global.local .Values.global.kind) }}
|
||||
resources:
|
||||
{{- toYaml .Values.gateway.resources | nindent 10 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
mountPath: /var/run/secrets/tokens
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: /etc/istio/config
|
||||
- name: higress-ca-root-cert
|
||||
mountPath: /var/run/secrets/istio
|
||||
- name: istio-data
|
||||
mountPath: /var/lib/istio/data
|
||||
- name: podinfo
|
||||
mountPath: /etc/istio/pod
|
||||
- name: proxy-socket
|
||||
mountPath: /etc/istio/proxy
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- mountPath: /etc/istio/custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- mountPath: /opt/plugins
|
||||
name: local-wasmplugins-volume
|
||||
{{- end }}
|
||||
{{- if $o11y.enabled }}
|
||||
- mountPath: /var/log/proxy
|
||||
name: log
|
||||
{{- end }}
|
||||
{{- if $o11y.enabled }}
|
||||
{{- $config := $o11y.promtail }}
|
||||
- name: promtail
|
||||
image: {{ $config.image.repository }}:{{ $config.image.tag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- -config.file=/etc/promtail/promtail.yaml
|
||||
env:
|
||||
- name: 'HOSTNAME'
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: 'spec.nodeName'
|
||||
ports:
|
||||
- containerPort: {{ $config.port }}
|
||||
name: http-metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: {{ $config.port }}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- name: promtail-config
|
||||
mountPath: "/etc/promtail"
|
||||
- name: log
|
||||
mountPath: /var/log/proxy
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.hostNetwork }}
|
||||
hostNetwork: {{ .Values.gateway.hostNetwork }}
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
{{- end }}
|
||||
- name: higress-ca-root-cert
|
||||
configMap:
|
||||
name: higress-ca-root-cert
|
||||
- name: config
|
||||
configMap:
|
||||
name: higress-config
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: higress-custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
- name: istio-data
|
||||
emptyDir: {}
|
||||
- name: proxy-socket
|
||||
emptyDir: {}
|
||||
{{- if $o11y.enabled }}
|
||||
- name: log
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
- name: promtail-config
|
||||
configMap:
|
||||
name: higress-promtail
|
||||
{{- end }}
|
||||
- name: podinfo
|
||||
downwardAPI:
|
||||
defaultMode: 420
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
- path: cpu-request
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: requests.cpu
|
||||
- path: cpu-limit
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: limits.cpu
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- name: local-wasmplugins-volume
|
||||
hostPath:
|
||||
path: /opt/plugins
|
||||
type: Directory
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
@@ -20,11 +20,7 @@
|
||||
# When processing a leaf namespace Istio will search for declarations in that namespace first
|
||||
# and if none are found it will search in the root namespace. Any matching declaration found in the root namespace
|
||||
# is processed as if it were declared in the leaf namespace.
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
rootNamespace: {{ .Values.meshConfig.rootNamespace | default .Values.global.istioNamespace }}
|
||||
{{- else }}
|
||||
rootNamespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
|
||||
configSources:
|
||||
- address: "xds://127.0.0.1:15051"
|
||||
@@ -85,12 +81,8 @@
|
||||
discoveryAddress: {{ printf "istiod.%s.svc" .Release.Namespace }}:15012
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
discoveryAddress: {{ printf "istiod.%s.svc" .Values.global.istioNamespace }}:15012
|
||||
{{- else }}
|
||||
discoveryAddress: {{ include "controller.name" . }}.{{.Release.Namespace}}.svc:15012
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
proxyStatsMatcher:
|
||||
inclusionRegexps:
|
||||
- ".*"
|
||||
@@ -116,6 +108,12 @@ data:
|
||||
{{- $existingData = index $existingConfig.data "higress" | default "{}" | fromYaml }}
|
||||
{{- end }}
|
||||
{{- $newData := dict }}
|
||||
{{- if hasKey .Values "upstream" }}
|
||||
{{- $_ := set $newData "upstream" .Values.upstream }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values "downstream" }}
|
||||
{{- $_ := set $newData "downstream" .Values.downstream }}
|
||||
{{- end }}
|
||||
{{- if and (hasKey .Values "tracing") .Values.tracing.enable }}
|
||||
{{- $_ := set $newData "tracing" .Values.tracing }}
|
||||
{{- end }}
|
||||
@@ -155,44 +153,12 @@ data:
|
||||
"transport_api_version": "V3",
|
||||
"grpc_service": {
|
||||
"envoy_grpc": {
|
||||
"cluster_name": "service_skywalking"
|
||||
"cluster_name": "outbound|{{ .Values.tracing.skywalking.port }}||{{ .Values.tracing.skywalking.service }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"static_resources": {
|
||||
"clusters": [
|
||||
{
|
||||
"name": "service_skywalking",
|
||||
"type": "LOGICAL_DNS",
|
||||
"connect_timeout": "5s",
|
||||
"http2_protocol_options": {
|
||||
},
|
||||
"dns_lookup_family": "V4_ONLY",
|
||||
"lb_policy": "ROUND_ROBIN",
|
||||
"load_assignment": {
|
||||
"cluster_name": "service_skywalking",
|
||||
"endpoints": [
|
||||
{
|
||||
"lb_endpoints": [
|
||||
{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socket_address": {
|
||||
"address": "{{ .Values.tracing.skywalking.service }}",
|
||||
"port_value": "{{ .Values.tracing.skywalking.port }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
---
|
||||
{{- end }}
|
||||
|
||||
@@ -129,3 +129,10 @@ rules:
|
||||
- apiGroups: ["networking.internal.knative.dev"]
|
||||
resources: ["ingresses/status"]
|
||||
verbs: ["get","patch","update"]
|
||||
# gateway api need
|
||||
- apiGroups: ["apps"]
|
||||
verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
|
||||
resources: [ "deployments" ]
|
||||
- apiGroups: [""]
|
||||
verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
|
||||
resources: [ "serviceaccounts"]
|
||||
|
||||
@@ -69,6 +69,12 @@ spec:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: DOMAIN_SUFFIX
|
||||
value: {{ .Values.global.proxy.clusterDomain }}
|
||||
- name: GATEWAY_NAME
|
||||
value: {{ include "gateway.name" . }}
|
||||
- name: PILOT_ENABLE_GATEWAY_API
|
||||
value: "{{ .Values.global.enableGatewayAPI }}"
|
||||
- name: PILOT_ENABLE_ALPHA_GATEWAY_API
|
||||
value: "{{ .Values.global.enableGatewayAPI }}"
|
||||
{{- if .Values.controller.env }}
|
||||
{{- range $key, $val := .Values.controller.env }}
|
||||
- name: {{ $key }}
|
||||
@@ -90,7 +96,6 @@ spec:
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /var/log
|
||||
{{- if not .Values.global.enableHigressIstio }}
|
||||
- name: discovery
|
||||
image: "{{ .Values.pilot.hub | default .Values.global.hub }}/{{ .Values.pilot.image | default "pilot" }}:{{ .Values.pilot.tag | default .Chart.AppVersion }}"
|
||||
{{- if .Values.global.imagePullPolicy }}
|
||||
@@ -133,6 +138,8 @@ spec:
|
||||
env:
|
||||
- name: PILOT_ENABLE_QUIC_LISTENERS
|
||||
value: "true"
|
||||
- name: VALIDATION_WEBHOOK_CONFIG_NAME
|
||||
value: ""
|
||||
- name: ISTIO_DUAL_STACK
|
||||
value: "{{ .Values.global.enableIPv6 }}"
|
||||
- name: PILOT_ENABLE_HEADLESS_SERVICE_POD_LISTENERS
|
||||
@@ -213,18 +220,16 @@ spec:
|
||||
- name: HIGRESS_ENABLE_ISTIO_API
|
||||
value: "true"
|
||||
{{- end }}
|
||||
{{- if .Values.global.enableGatewayAPI }}
|
||||
- name: PILOT_ENABLE_GATEWAY_API
|
||||
value: "true"
|
||||
value: "false"
|
||||
- name: PILOT_ENABLE_ALPHA_GATEWAY_API
|
||||
value: "false"
|
||||
- name: PILOT_ENABLE_GATEWAY_API_STATUS
|
||||
value: "true"
|
||||
value: "false"
|
||||
- name: PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER
|
||||
value: "false"
|
||||
{{- end }}
|
||||
{{- if not .Values.global.enableHigressIstio }}
|
||||
- name: CUSTOM_CA_CERT_NAME
|
||||
value: "higress-ca-root-cert"
|
||||
{{- end }}
|
||||
{{- if not (or .Values.global.local .Values.global.kind) }}
|
||||
resources:
|
||||
{{- if .Values.pilot.resources }}
|
||||
@@ -261,7 +266,6 @@ spec:
|
||||
- name: extracacerts
|
||||
mountPath: /cacerts
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
@@ -277,7 +281,6 @@ spec:
|
||||
volumes:
|
||||
- name: log
|
||||
emptyDir: {}
|
||||
{{- if not .Values.global.enableHigressIstio }}
|
||||
- name: config
|
||||
configMap:
|
||||
name: higress-config
|
||||
@@ -309,4 +312,3 @@ spec:
|
||||
configMap:
|
||||
name: pilot-jwks-extra-cacerts{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -9,7 +9,6 @@ spec:
|
||||
type: {{ .Values.controller.service.type }}
|
||||
ports:
|
||||
{{- toYaml .Values.controller.ports | nindent 4 }}
|
||||
{{- if not .Values.global.enableHigressIstio }}
|
||||
- port: 15010
|
||||
name: grpc-xds # plaintext
|
||||
protocol: TCP
|
||||
@@ -23,6 +22,5 @@ spec:
|
||||
- port: 15014
|
||||
name: http-monitoring # prometheus stats
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "controller.selectorLabels" . | nindent 4 }}
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
{{- if $kernelVersion }}
|
||||
{{- $kernelVersion = regexFind "^(\\d+\\.\\d+\\.\\d+)" $kernelVersion }}
|
||||
{{- if and $kernelVersion (semverCompare "<4.11.0" $kernelVersion) }}
|
||||
{{- $unprivilegedPortSupported = false }}
|
||||
{{- $unprivilegedPortSupported = false }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- $_ := set .Values.gateway "unprivilegedPortSupported" $unprivilegedPortSupported -}}
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
@@ -23,310 +25,5 @@ spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gateway.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
"enableHigressIstio": "true"
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.podAnnotations }}
|
||||
{{- toYaml .Values.gateway.podAnnotations | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
sidecar.istio.io/inject: "false"
|
||||
{{- with .Values.gateway.revision }}
|
||||
istio.io/rev: {{ . }}
|
||||
{{- end }}
|
||||
{{- include "gateway.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.gateway.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gateway.serviceAccountName" . }}
|
||||
{{- if .Values.global.priorityClassName }}
|
||||
priorityClassName: "{{ .Values.global.priorityClassName }}"
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- if .Values.gateway.securityContext }}
|
||||
{{- toYaml .Values.gateway.securityContext | nindent 8 }}
|
||||
{{- else if and $unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- if $o11y.enabled }}
|
||||
{{- $config := $o11y.promtail }}
|
||||
- name: promtail
|
||||
image: {{ $config.image.repository }}:{{ $config.image.tag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- -config.file=/etc/promtail/promtail.yaml
|
||||
env:
|
||||
- name: 'HOSTNAME'
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: 'spec.nodeName'
|
||||
ports:
|
||||
- containerPort: {{ $config.port }}
|
||||
name: http-metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: {{ $config.port }}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- name: promtail-config
|
||||
mountPath: "/etc/promtail"
|
||||
- name: log
|
||||
mountPath: /var/log/proxy
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- end }}
|
||||
- name: higress-gateway
|
||||
image: "{{ .Values.gateway.hub | default .Values.global.hub }}/{{ .Values.gateway.image | default "gateway" }}:{{ .Values.gateway.tag | default .Chart.AppVersion }}"
|
||||
args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.cluster.local
|
||||
- --proxyLogLevel=warning
|
||||
- --proxyComponentLogLevel=misc:error
|
||||
- --log_output_level=all:info
|
||||
- --serviceCluster=higress-gateway
|
||||
securityContext:
|
||||
{{- if .Values.gateway.containerSecurityContext }}
|
||||
{{- toYaml .Values.gateway.containerSecurityContext | nindent 12 }}
|
||||
{{- else if and $unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
# When enabling lite metrics, the configuration template files need to be replaced.
|
||||
{{- if not .Values.global.liteMetrics }}
|
||||
readOnlyRootFilesystem: true
|
||||
{{- end }}
|
||||
runAsUser: 1337
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
{{- else }}
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
runAsUser: 0
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: false
|
||||
allowPrivilegeEscalation: true
|
||||
{{- end }}
|
||||
env:
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: spec.nodeName
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.podIP
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.hostIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: PILOT_XDS_SEND_TIMEOUT
|
||||
value: 60s
|
||||
- name: PROXY_XDS_VIA_AGENT
|
||||
value: "true"
|
||||
- name: ENABLE_INGRESS_GATEWAY_SDS
|
||||
value: "false"
|
||||
- name: JWT_POLICY
|
||||
value: {{ include "controller.jwtPolicy" . }}
|
||||
- name: ISTIO_META_HTTP10
|
||||
value: "1"
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: "{{ $.Values.clusterName | default `Kubernetes` }}"
|
||||
- name: INSTANCE_NAME
|
||||
value: "higress-gateway"
|
||||
{{- if .Values.global.liteMetrics }}
|
||||
- name: LITE_METRICS
|
||||
value: "on"
|
||||
{{- end }}
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- name: ISTIO_BOOTSTRAP_OVERRIDE
|
||||
value: /etc/istio/custom-bootstrap/custom_bootstrap.json
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.networkGateway }}
|
||||
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
|
||||
value: "{{.}}"
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- containerPort: 15090
|
||||
protocol: TCP
|
||||
name: http-envoy-prom
|
||||
{{- if or .Values.global.local .Values.global.kind }}
|
||||
- containerPort: {{ .Values.gateway.httpPort }}
|
||||
hostPort: {{ .Values.gateway.httpPort }}
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: {{ .Values.gateway.httpsPort }}
|
||||
hostPort: {{ .Values.gateway.httpsPort }}
|
||||
name: https
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
readinessProbe:
|
||||
failureThreshold: {{ .Values.gateway.readinessFailureThreshold }}
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.gateway.readinessInitialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gateway.readinessPeriodSeconds }}
|
||||
successThreshold: {{ .Values.gateway.readinessSuccessThreshold }}
|
||||
timeoutSeconds: {{ .Values.gateway.readinessTimeoutSeconds }}
|
||||
{{- if not (or .Values.global.local .Values.global.kind) }}
|
||||
resources:
|
||||
{{- toYaml .Values.gateway.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
mountPath: /var/run/secrets/tokens
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: /etc/istio/config
|
||||
- name: istio-ca-root-cert
|
||||
mountPath: /var/run/secrets/istio
|
||||
- name: istio-data
|
||||
mountPath: /var/lib/istio/data
|
||||
- name: podinfo
|
||||
mountPath: /etc/istio/pod
|
||||
- name: proxy-socket
|
||||
mountPath: /etc/istio/proxy
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- mountPath: /etc/istio/custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- mountPath: /opt/plugins
|
||||
name: local-wasmplugins-volume
|
||||
{{- end }}
|
||||
{{- if $o11y.enabled }}
|
||||
- mountPath: /var/log/proxy
|
||||
name: log
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.hostNetwork }}
|
||||
hostNetwork: {{ .Values.gateway.hostNetwork }}
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
{{- end }}
|
||||
- name: istio-ca-root-cert
|
||||
configMap:
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
name: istio-ca-root-cert
|
||||
{{- else }}
|
||||
name: higress-ca-root-cert
|
||||
{{- end }}
|
||||
- name: config
|
||||
configMap:
|
||||
name: higress-config
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: higress-custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
- name: istio-data
|
||||
emptyDir: {}
|
||||
- name: proxy-socket
|
||||
emptyDir: {}
|
||||
{{- if $o11y.enabled }}
|
||||
- name: log
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
- name: promtail-config
|
||||
configMap:
|
||||
name: higress-promtail
|
||||
{{- end }}
|
||||
- name: podinfo
|
||||
downwardAPI:
|
||||
defaultMode: 420
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
- path: cpu-request
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: requests.cpu
|
||||
- path: cpu-limit
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: limits.cpu
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- name: local-wasmplugins-volume
|
||||
hostPath:
|
||||
path: /opt/plugins
|
||||
type: Directory
|
||||
{{- end }}
|
||||
{{- include "gateway.podTemplate" $ | nindent 2 -}}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{{- if eq .Values.gateway.kind "Deployment" -}}
|
||||
{{- $o11y := .Values.global.o11y }}
|
||||
{{- $unprivilegedPortSupported := true }}
|
||||
{{- range $index, $node := (lookup "v1" "Node" "default" "").items }}
|
||||
{{- $kernelVersion := $node.status.nodeInfo.kernelVersion }}
|
||||
{{- if $kernelVersion }}
|
||||
{{- $kernelVersion = regexFind "^(\\d+\\.\\d+\\.\\d+)" $kernelVersion }}
|
||||
{{- if and $kernelVersion (semverCompare "<4.11.0" $kernelVersion) }}
|
||||
{{- $unprivilegedPortSupported = false }}
|
||||
{{- $unprivilegedPortSupported = false }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- $_ := set .Values.gateway "unprivilegedPortSupported" $unprivilegedPortSupported -}}
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -38,311 +39,7 @@ spec:
|
||||
{{- else }}
|
||||
maxUnavailable: {{ .Values.gateway.rollingMaxUnavailable }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
"enableHigressIstio": "true"
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.podAnnotations }}
|
||||
{{- toYaml .Values.gateway.podAnnotations | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
sidecar.istio.io/inject: "false"
|
||||
{{- with .Values.gateway.revision }}
|
||||
istio.io/rev: {{ . }}
|
||||
{{- end }}
|
||||
{{- include "gateway.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.gateway.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gateway.serviceAccountName" . }}
|
||||
{{- if .Values.global.priorityClassName }}
|
||||
priorityClassName: "{{ .Values.global.priorityClassName }}"
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- if .Values.gateway.securityContext }}
|
||||
{{- toYaml .Values.gateway.securityContext | nindent 8 }}
|
||||
{{- else if and $unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- if $o11y.enabled }}
|
||||
{{- $config := $o11y.promtail }}
|
||||
- name: promtail
|
||||
image: {{ $config.image.repository }}:{{ $config.image.tag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- -config.file=/etc/promtail/promtail.yaml
|
||||
env:
|
||||
- name: 'HOSTNAME'
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: 'spec.nodeName'
|
||||
ports:
|
||||
- containerPort: {{ $config.port }}
|
||||
name: http-metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: {{ $config.port }}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- name: promtail-config
|
||||
mountPath: "/etc/promtail"
|
||||
- name: log
|
||||
mountPath: /var/log/proxy
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- end }}
|
||||
- name: higress-gateway
|
||||
image: "{{ .Values.gateway.hub | default .Values.global.hub }}/{{ .Values.gateway.image | default "gateway" }}:{{ .Values.gateway.tag | default .Chart.AppVersion }}"
|
||||
args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.cluster.local
|
||||
- --proxyLogLevel=warning
|
||||
- --proxyComponentLogLevel=misc:error
|
||||
- --log_output_level=all:info
|
||||
- --serviceCluster=higress-gateway
|
||||
securityContext:
|
||||
{{- if .Values.gateway.containerSecurityContext }}
|
||||
{{- toYaml .Values.gateway.containerSecurityContext | nindent 12 }}
|
||||
{{- else if and $unprivilegedPortSupported (and (not .Values.gateway.hostNetwork) (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
# Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
# When enabling lite metrics, the configuration template files need to be replaced.
|
||||
{{- if not .Values.global.liteMetrics }}
|
||||
readOnlyRootFilesystem: true
|
||||
{{- end }}
|
||||
runAsUser: 1337
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
{{- else }}
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
runAsUser: 0
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: false
|
||||
allowPrivilegeEscalation: true
|
||||
{{- end }}
|
||||
env:
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: spec.nodeName
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.podIP
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.hostIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: PROXY_XDS_VIA_AGENT
|
||||
value: "true"
|
||||
- name: ENABLE_INGRESS_GATEWAY_SDS
|
||||
value: "false"
|
||||
- name: JWT_POLICY
|
||||
value: {{ include "controller.jwtPolicy" . }}
|
||||
- name: ISTIO_META_HTTP10
|
||||
value: "1"
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: "{{ $.Values.clusterName | default `Kubernetes` }}"
|
||||
- name: INSTANCE_NAME
|
||||
value: "higress-gateway"
|
||||
{{- if .Values.global.liteMetrics }}
|
||||
- name: LITE_METRICS
|
||||
value: "on"
|
||||
{{- end }}
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- name: ISTIO_BOOTSTRAP_OVERRIDE
|
||||
value: /etc/istio/custom-bootstrap/custom_bootstrap.json
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.networkGateway }}
|
||||
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
|
||||
value: "{{.}}"
|
||||
{{- end }}
|
||||
{{- range $key, $val := .Values.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
protocol: TCP
|
||||
name: istio-prom
|
||||
- containerPort: 15090
|
||||
protocol: TCP
|
||||
name: http-envoy-prom
|
||||
{{- if or .Values.global.local .Values.global.kind }}
|
||||
- containerPort: {{ .Values.gateway.httpPort }}
|
||||
hostPort: {{ .Values.gateway.httpPort }}
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: {{ .Values.gateway.httpsPort }}
|
||||
hostPort: {{ .Values.gateway.httpsPort }}
|
||||
name: https
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
readinessProbe:
|
||||
failureThreshold: {{ .Values.gateway.readinessFailureThreshold }}
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.gateway.readinessInitialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gateway.readinessPeriodSeconds }}
|
||||
successThreshold: {{ .Values.gateway.readinessSuccessThreshold }}
|
||||
timeoutSeconds: {{ .Values.gateway.readinessTimeoutSeconds }}
|
||||
{{- if not (or .Values.global.local .Values.global.kind) }}
|
||||
resources:
|
||||
{{- toYaml .Values.gateway.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
mountPath: /var/run/secrets/tokens
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: /etc/istio/config
|
||||
- name: istio-ca-root-cert
|
||||
mountPath: /var/run/secrets/istio
|
||||
- name: istio-data
|
||||
mountPath: /var/lib/istio/data
|
||||
- name: podinfo
|
||||
mountPath: /etc/istio/pod
|
||||
- name: proxy-socket
|
||||
mountPath: /etc/istio/proxy
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- mountPath: /etc/istio/custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- mountPath: /opt/plugins
|
||||
name: local-wasmplugins-volume
|
||||
{{- end }}
|
||||
{{- if $o11y.enabled }}
|
||||
- mountPath: /var/log/proxy
|
||||
name: log
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.hostNetwork }}
|
||||
hostNetwork: {{ .Values.gateway.hostNetwork }}
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- if eq (include "controller.jwtPolicy" .) "third-party-jwt" }}
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
{{- end }}
|
||||
- name: istio-ca-root-cert
|
||||
configMap:
|
||||
{{- if .Values.global.enableHigressIstio }}
|
||||
name: istio-ca-root-cert
|
||||
{{- else }}
|
||||
name: higress-ca-root-cert
|
||||
{{- end }}
|
||||
- name: config
|
||||
configMap:
|
||||
name: higress-config
|
||||
{{- if include "skywalking.enabled" . }}
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: higress-custom-bootstrap
|
||||
name: custom-bootstrap-volume
|
||||
{{- end }}
|
||||
- name: istio-data
|
||||
emptyDir: {}
|
||||
- name: proxy-socket
|
||||
emptyDir: {}
|
||||
{{- if $o11y.enabled }}
|
||||
- name: log
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
- name: promtail-config
|
||||
configMap:
|
||||
name: higress-promtail
|
||||
{{- end }}
|
||||
- name: podinfo
|
||||
downwardAPI:
|
||||
defaultMode: 420
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
- path: cpu-request
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: requests.cpu
|
||||
- path: cpu-limit
|
||||
resourceFieldRef:
|
||||
containerName: higress-gateway
|
||||
divisor: 1m
|
||||
resource: limits.cpu
|
||||
{{- if .Values.global.volumeWasmPlugins }}
|
||||
- name: local-wasmplugins-volume
|
||||
hostPath:
|
||||
path: /opt/plugins
|
||||
type: Directory
|
||||
{{- end }}
|
||||
|
||||
{{- include "gateway.podTemplate" $ | nindent 2 -}}
|
||||
|
||||
{{- end }}
|
||||
|
||||
22
helm/core/templates/fallback-envoyfilter.yaml
Normal file
22
helm/core/templates/fallback-envoyfilter.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: EnvoyFilter
|
||||
metadata:
|
||||
name: {{ include "gateway.name" . }}-global-custom-response
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" . | nindent 4}}
|
||||
spec:
|
||||
configPatches:
|
||||
- applyTo: HTTP_FILTER
|
||||
match:
|
||||
context: GATEWAY
|
||||
listener:
|
||||
filterChain:
|
||||
filter:
|
||||
name: envoy.filters.network.http_connection_manager
|
||||
patch:
|
||||
operation: INSERT_FIRST
|
||||
value:
|
||||
name: envoy.filters.http.custom_response
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.http.custom_response.v3.CustomResponse
|
||||
@@ -1,6 +1,8 @@
|
||||
{{- if .Values.global.ingressClass }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: {{ .Values.global.ingressClass }}
|
||||
spec:
|
||||
controller: higress.io/higress-controller
|
||||
controller: higress.io/higress-controller
|
||||
{{- end }}
|
||||
|
||||
45
helm/core/templates/podmonitor.yaml
Normal file
45
helm/core/templates/podmonitor.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
{{- if .Values.gateway.metrics.enabled }}
|
||||
{{- include "gateway.podMonitor.gvk" . }}
|
||||
metadata:
|
||||
name: {{ printf "%s-metrics" (include "gateway.name" .) | trunc 63 | trimSuffix "-" }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" . | nindent 4}}
|
||||
annotations:
|
||||
{{- .Values.gateway.annotations | toYaml | nindent 4 }}
|
||||
spec:
|
||||
jobLabel: "app.kubernetes.io/name"
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gateway.selectorLabels" . | nindent 6 }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
podMetricsEndpoints:
|
||||
- port: istio-prom
|
||||
path: /stats/prometheus
|
||||
{{- if .Values.gateway.metrics.interval }}
|
||||
interval: {{ .Values.gateway.metrics.interval }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.scrapeTimeout }}
|
||||
scrapeTimeout: {{ .Values.gateway.metrics.scrapeTimeout }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.honorLabels }}
|
||||
honorLabels: {{ .Values.gateway.metrics.honorLabels }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.metricRelabelings }}
|
||||
metricRelabelings: {{ toYaml .Values.gateway.metrics.metricRelabelings | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.relabelings }}
|
||||
relabelings: {{ toYaml .Values.gateway.metrics.relabelings | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.metricRelabelConfigs }}
|
||||
metricRelabelings: {{ toYaml .Values.gateway.metrics.metricRelabelConfigs | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.gateway.metrics.relabelConfigs }}
|
||||
relabelings: {{ toYaml .Values.gateway.metrics.relabelConfigs | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if $.Values.gateway.metrics.rawSpec }}
|
||||
{{- $.Values.gateway.metrics.rawSpec | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -24,6 +24,9 @@ spec:
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.service.externalTrafficPolicy }}
|
||||
externalTrafficPolicy: "{{ . }}"
|
||||
{{- end }}
|
||||
{{- with .Values.gateway.service.loadBalancerClass}}
|
||||
loadBalancerClass: "{{ . }}"
|
||||
{{- end }}
|
||||
type: {{ .Values.gateway.service.type }}
|
||||
ports:
|
||||
|
||||
@@ -10,7 +10,7 @@ global:
|
||||
onDemandRDS: false
|
||||
hostRDSMergeSubset: false
|
||||
onlyPushRouteCluster: true
|
||||
# IngressClass filters which ingress resources the higress controller watches.
|
||||
# -- IngressClass filters which ingress resources the higress controller watches.
|
||||
# The default ingress class is higress.
|
||||
# There are some special cases for special ingress class.
|
||||
# 1. When the ingress class is set as nginx, the higress controller will watch ingress
|
||||
@@ -18,28 +18,38 @@ global:
|
||||
# 2. When the ingress class is set empty, the higress controller will watch all ingress
|
||||
# resources in the k8s cluster.
|
||||
ingressClass: "higress"
|
||||
# -- If not empty, Higress Controller will only watch resources in the specified namespace.
|
||||
# When isolating different business systems using K8s namespace,
|
||||
# if each namespace requires a standalone gateway instance,
|
||||
# this parameter can be used to confine the Ingress watching of Higress within the given namespace.
|
||||
watchNamespace: ""
|
||||
# -- Whether to disable HTTP/2 in ALPN
|
||||
disableAlpnH2: false
|
||||
# -- If true, Higress Controller will update the status field of Ingress resources.
|
||||
# When migrating from Nginx Ingress, in order to avoid status field of Ingress objects being overwritten,
|
||||
# this parameter needs to be set to false,
|
||||
# so Higress won't write the entry IP to the status field of the corresponding Ingress object.
|
||||
enableStatus: true
|
||||
# whether to use autoscaling/v2 template for HPA settings
|
||||
# -- whether to use autoscaling/v2 template for HPA settings
|
||||
# for internal usage only, not to be configured by users.
|
||||
autoscalingv2API: true
|
||||
local: false # When deploying to a local cluster (e.g.: kind cluster), set this to true.
|
||||
# -- When deploying to a local cluster (e.g.: kind cluster), set this to true.
|
||||
local: false
|
||||
kind: false # Deprecated. Please use "global.local" instead. Will be removed later.
|
||||
enableIstioAPI: false
|
||||
# -- If true, Higress Controller will monitor istio resources as well
|
||||
enableIstioAPI: true
|
||||
# -- If true, Higress Controller will monitor Gateway API resources as well
|
||||
enableGatewayAPI: false
|
||||
# Deprecated
|
||||
enableHigressIstio: false
|
||||
# Used to locate istiod.
|
||||
# -- Used to locate istiod.
|
||||
istioNamespace: istio-system
|
||||
# enable pod disruption budget for the control plane, which is used to
|
||||
# -- enable pod disruption budget for the control plane, which is used to
|
||||
# ensure Istio control plane components are gradually upgraded or recovered.
|
||||
defaultPodDisruptionBudget:
|
||||
enabled: false
|
||||
# The values aren't mutable due to a current PodDisruptionBudget limitation
|
||||
# minAvailable: 1
|
||||
|
||||
# A minimal set of requested resources to applied to all deployments so that
|
||||
# -- A minimal set of requested resources to applied to all deployments so that
|
||||
# Horizontal Pod Autoscaler will be able to function (if set).
|
||||
# Each component can overwrite these default values by adding its own resources
|
||||
# block in the relevant section below and setting the desired resources values.
|
||||
@@ -51,16 +61,16 @@ global:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
# Default hub for Istio images.
|
||||
# -- Default hub for Istio images.
|
||||
# Releases are published to docker hub under 'istio' project.
|
||||
# Dev builds from prow are on gcr.io
|
||||
hub: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress
|
||||
|
||||
# Specify image pull policy if default behavior isn't desired.
|
||||
# -- Specify image pull policy if default behavior isn't desired.
|
||||
# Default behavior: latest images will be Always else IfNotPresent.
|
||||
imagePullPolicy: ""
|
||||
|
||||
# ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace
|
||||
# -- ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace
|
||||
# to use for pulling any images in pods that reference this ServiceAccount.
|
||||
# For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing)
|
||||
# ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects.
|
||||
@@ -68,14 +78,14 @@ global:
|
||||
imagePullSecrets: []
|
||||
# - private-registry-key
|
||||
|
||||
# Enabled by default in master for maximising testing.
|
||||
# -- Enabled by default in master for maximising testing.
|
||||
istiod:
|
||||
enableAnalysis: false
|
||||
|
||||
# To output all istio components logs in json format by adding --log_as_json argument to each container argument
|
||||
# -- To output all istio components logs in json format by adding --log_as_json argument to each container argument
|
||||
logAsJson: false
|
||||
|
||||
# Comma-separated minimum per-scope logging level of messages to output, in the form of <scope>:<level>,<scope>:<level>
|
||||
# -- Comma-separated minimum per-scope logging level of messages to output, in the form of <scope>:<level>,<scope>:<level>
|
||||
# The control plane has different scopes depending on component, but can configure default log level across all components
|
||||
# If empty, default scope and level will be used as configured in code
|
||||
logging:
|
||||
@@ -83,11 +93,11 @@ global:
|
||||
|
||||
omitSidecarInjectorConfigMap: false
|
||||
|
||||
# Whether to restrict the applications namespace the controller manages;
|
||||
# -- Whether to restrict the applications namespace the controller manages;
|
||||
# If not set, controller watches all namespaces
|
||||
oneNamespace: false
|
||||
|
||||
# Configure whether Operator manages webhook configurations. The current behavior
|
||||
# -- Configure whether Operator manages webhook configurations. The current behavior
|
||||
# of Istiod is to manage its own webhook configurations.
|
||||
# When this option is set as true, Istio Operator, instead of webhooks, manages the
|
||||
# webhook configurations. When this option is set as false, webhooks manage their
|
||||
@@ -106,7 +116,7 @@ global:
|
||||
#- global
|
||||
#- "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global"
|
||||
|
||||
# Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and
|
||||
# -- Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and
|
||||
# system-node-critical, it is better to configure this in order to make sure your Istio pods
|
||||
# will not be killed because of low priority class.
|
||||
# Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
|
||||
@@ -116,18 +126,18 @@ global:
|
||||
proxy:
|
||||
image: proxyv2
|
||||
|
||||
# This controls the 'policy' in the sidecar injector.
|
||||
# -- This controls the 'policy' in the sidecar injector.
|
||||
autoInject: enabled
|
||||
|
||||
# CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value
|
||||
# -- CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value
|
||||
# cluster domain. Default value is "cluster.local".
|
||||
clusterDomain: "cluster.local"
|
||||
|
||||
# Per Component log level for proxy, applies to gateways and sidecars. If a component level is
|
||||
# -- Per Component log level for proxy, applies to gateways and sidecars. If a component level is
|
||||
# not set, then the global "logLevel" will be used.
|
||||
componentLogLevel: "misc:error"
|
||||
|
||||
# If set, newly injected sidecars will have core dumps enabled.
|
||||
# -- If set, newly injected sidecars will have core dumps enabled.
|
||||
enableCoreDump: false
|
||||
|
||||
# istio ingress capture allowlist
|
||||
@@ -136,8 +146,7 @@ global:
|
||||
excludeInboundPorts: ""
|
||||
includeInboundPorts: "*"
|
||||
|
||||
|
||||
# istio egress capture allowlist
|
||||
# -- istio egress capture allowlist
|
||||
# https://istio.io/docs/tasks/traffic-management/egress.html#calling-external-services-directly
|
||||
# example: includeIPRanges: "172.30.0.0/16,172.20.0.0/16"
|
||||
# would only capture egress traffic on those two IP Ranges, all other outbound traffic would
|
||||
@@ -147,29 +156,29 @@ global:
|
||||
includeOutboundPorts: ""
|
||||
excludeOutboundPorts: ""
|
||||
|
||||
# Log level for proxy, applies to gateways and sidecars.
|
||||
# -- Log level for proxy, applies to gateways and sidecars.
|
||||
# Expected values are: trace|debug|info|warning|error|critical|off
|
||||
logLevel: warning
|
||||
|
||||
#If set to true, istio-proxy container will have privileged securityContext
|
||||
# -- If set to true, istio-proxy container will have privileged securityContext
|
||||
privileged: false
|
||||
|
||||
# The number of successive failed probes before indicating readiness failure.
|
||||
# -- The number of successive failed probes before indicating readiness failure.
|
||||
readinessFailureThreshold: 30
|
||||
|
||||
# The number of successive successed probes before indicating readiness success.
|
||||
# -- The number of successive successed probes before indicating readiness success.
|
||||
readinessSuccessThreshold: 30
|
||||
|
||||
# The initial delay for readiness probes in seconds.
|
||||
# -- The initial delay for readiness probes in seconds.
|
||||
readinessInitialDelaySeconds: 1
|
||||
|
||||
# The period between readiness probes.
|
||||
# -- The period between readiness probes.
|
||||
readinessPeriodSeconds: 2
|
||||
|
||||
# The readiness timeout seconds
|
||||
# -- The readiness timeout seconds
|
||||
readinessTimeoutSeconds: 3
|
||||
|
||||
# Resources for the sidecar.
|
||||
# -- Resources for the sidecar.
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
@@ -178,18 +187,18 @@ global:
|
||||
cpu: 2000m
|
||||
memory: 1024Mi
|
||||
|
||||
# Default port for Pilot agent health checks. A value of 0 will disable health checking.
|
||||
# -- Default port for Pilot agent health checks. A value of 0 will disable health checking.
|
||||
statusPort: 15020
|
||||
|
||||
# Specify which tracer to use. One of: lightstep, datadog, stackdriver.
|
||||
# -- Specify which tracer to use. One of: lightstep, datadog, stackdriver.
|
||||
# If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file.
|
||||
tracer: ""
|
||||
|
||||
# Controls if sidecar is injected at the front of the container list and blocks the start of the other containers until the proxy is ready
|
||||
# -- Controls if sidecar is injected at the front of the container list and blocks the start of the other containers until the proxy is ready
|
||||
holdApplicationUntilProxyStarts: false
|
||||
|
||||
proxy_init:
|
||||
# Base name for the proxy_init container, used to configure iptables.
|
||||
# -- Base name for the proxy_init container, used to configure iptables.
|
||||
image: proxyv2
|
||||
resources:
|
||||
limits:
|
||||
@@ -199,7 +208,7 @@ global:
|
||||
cpu: 10m
|
||||
memory: 10Mi
|
||||
|
||||
# configure remote pilot and istiod service and endpoint
|
||||
# -- configure remote pilot and istiod service and endpoint
|
||||
remotePilotAddress: ""
|
||||
|
||||
##############################################################################################
|
||||
@@ -207,20 +216,20 @@ global:
|
||||
# make sure they are consistent across your Istio helm charts #
|
||||
##############################################################################################
|
||||
|
||||
# The customized CA address to retrieve certificates for the pods in the cluster.
|
||||
# -- The customized CA address to retrieve certificates for the pods in the cluster.
|
||||
# CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint.
|
||||
# If not set explicitly, default to the Istio discovery address.
|
||||
caAddress: ""
|
||||
|
||||
# Configure a remote cluster data plane controlled by an external istiod.
|
||||
# -- Configure a remote cluster data plane controlled by an external istiod.
|
||||
# When set to true, istiod is not deployed locally and only a subset of the other
|
||||
# discovery charts are enabled.
|
||||
externalIstiod: false
|
||||
|
||||
# Configure a remote cluster as the config cluster for an external istiod.
|
||||
# -- Configure a remote cluster as the config cluster for an external istiod.
|
||||
configCluster: false
|
||||
|
||||
# Configure the policy for validating JWT.
|
||||
# -- Configure the policy for validating JWT.
|
||||
# Currently, two options are supported: "third-party-jwt" and "first-party-jwt".
|
||||
jwtPolicy: "third-party-jwt"
|
||||
|
||||
@@ -242,7 +251,7 @@ global:
|
||||
# of migration TBD, and it may be a disruptive operation to change the Mesh
|
||||
# ID post-install.
|
||||
#
|
||||
# If the mesh admin does not specify a value, Istio will use the value of the
|
||||
# -- If the mesh admin does not specify a value, Istio will use the value of the
|
||||
# mesh's Trust Domain. The best practice is to select a proper Trust Domain
|
||||
# value.
|
||||
meshID: ""
|
||||
@@ -276,68 +285,69 @@ global:
|
||||
#
|
||||
meshNetworks: {}
|
||||
|
||||
# Use the user-specified, secret volume mounted key and certs for Pilot and workloads.
|
||||
# -- Use the user-specified, secret volume mounted key and certs for Pilot and workloads.
|
||||
mountMtlsCerts: false
|
||||
|
||||
multiCluster:
|
||||
# Set to true to connect two kubernetes clusters via their respective
|
||||
# -- Set to true to connect two kubernetes clusters via their respective
|
||||
# ingressgateway services when pods in each cluster cannot directly
|
||||
# talk to one another. All clusters should be using Istio mTLS and must
|
||||
# have a shared root CA for this model to work.
|
||||
enabled: true
|
||||
# Should be set to the name of the cluster this installation will run in. This is required for sidecar injection
|
||||
# -- Should be set to the name of the cluster this installation will run in. This is required for sidecar injection
|
||||
# to properly label proxies
|
||||
clusterName: ""
|
||||
|
||||
# Network defines the network this cluster belong to. This name
|
||||
# -- Network defines the network this cluster belong to. This name
|
||||
# corresponds to the networks in the map of mesh networks.
|
||||
network: ""
|
||||
|
||||
# Configure the certificate provider for control plane communication.
|
||||
# -- Configure the certificate provider for control plane communication.
|
||||
# Currently, two providers are supported: "kubernetes" and "istiod".
|
||||
# As some platforms may not have kubernetes signing APIs,
|
||||
# Istiod is the default
|
||||
pilotCertProvider: istiod
|
||||
|
||||
sds:
|
||||
# The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3.
|
||||
# -- The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3.
|
||||
# When a CSR is sent from Istio Agent to the CA (e.g. Istiod), this aud is to make sure the
|
||||
# JWT is intended for the CA.
|
||||
token:
|
||||
aud: istio-ca
|
||||
|
||||
sts:
|
||||
# The service port used by Security Token Service (STS) server to handle token exchange requests.
|
||||
# -- The service port used by Security Token Service (STS) server to handle token exchange requests.
|
||||
# Setting this port to a non-zero value enables STS server.
|
||||
servicePort: 0
|
||||
|
||||
# Configuration for each of the supported tracers
|
||||
# -- Configuration for each of the supported tracers
|
||||
tracer:
|
||||
# Configuration for envoy to send trace data to LightStep.
|
||||
# -- Configuration for envoy to send trace data to LightStep.
|
||||
# Disabled by default.
|
||||
# address: the <host>:<port> of the satellite pool
|
||||
# accessToken: required for sending data to the pool
|
||||
#
|
||||
datadog:
|
||||
# Host:Port for submitting traces to the Datadog agent.
|
||||
# -- Host:Port for submitting traces to the Datadog agent.
|
||||
address: "$(HOST_IP):8126"
|
||||
lightstep:
|
||||
address: "" # example: lightstep-satellite:443
|
||||
accessToken: "" # example: abcdefg1234567
|
||||
# -- example: lightstep-satellite:443
|
||||
address: ""
|
||||
# -- example: abcdefg1234567
|
||||
accessToken: ""
|
||||
stackdriver:
|
||||
# enables trace output to stdout.
|
||||
# -- enables trace output to stdout.
|
||||
debug: false
|
||||
# The global default max number of message events per span.
|
||||
# -- The global default max number of message events per span.
|
||||
maxNumberOfMessageEvents: 200
|
||||
# The global default max number of annotation events per span.
|
||||
# -- The global default max number of annotation events per span.
|
||||
maxNumberOfAnnotations: 200
|
||||
# The global default max number of attributes per span.
|
||||
# -- The global default max number of attributes per span.
|
||||
maxNumberOfAttributes: 200
|
||||
# Use the Mesh Control Protocol (MCP) for configuring Istiod. Requires an MCP source.
|
||||
|
||||
# -- Use the Mesh Control Protocol (MCP) for configuring Istiod. Requires an MCP source.
|
||||
useMCP: false
|
||||
|
||||
# Observability (o11y) configurations
|
||||
# -- Observability (o11y) configurations
|
||||
o11y:
|
||||
enabled: false
|
||||
promtail:
|
||||
@@ -351,7 +361,7 @@ global:
|
||||
memory: 2Gi
|
||||
securityContext: {}
|
||||
|
||||
# The name of the CA for workload certificates.
|
||||
# -- The name of the CA for workload certificates.
|
||||
# For example, when caName=GkeWorkloadCertificate, GKE workload certificates
|
||||
# will be used as the certificates for workloads.
|
||||
# The default value is "" and when caName="", the CA will be configured by other
|
||||
@@ -360,7 +370,7 @@ global:
|
||||
hub: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress
|
||||
|
||||
clusterName: ""
|
||||
# meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior
|
||||
# -- meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior
|
||||
# See https://istio.io/docs/reference/config/istio.mesh.v1alpha1/ for all available options
|
||||
meshConfig:
|
||||
enablePrometheusMerge: true
|
||||
@@ -371,14 +381,13 @@ meshConfig:
|
||||
# and gradual adoption by setting capture only on specific workloads. It also allows
|
||||
# VMs to use other DNS options, like dnsmasq or unbound.
|
||||
|
||||
# The namespace to treat as the administrative root namespace for Istio configuration.
|
||||
# -- The namespace to treat as the administrative root namespace for Istio configuration.
|
||||
# When processing a leaf namespace Istio will search for declarations in that namespace first
|
||||
# and if none are found it will search in the root namespace. Any matching declaration found in the root namespace
|
||||
# is processed as if it were declared in the leaf namespace.
|
||||
|
||||
rootNamespace:
|
||||
|
||||
# The trust domain corresponds to the trust root of a system
|
||||
# -- The trust domain corresponds to the trust root of a system
|
||||
# Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain
|
||||
trustDomain: "cluster.local"
|
||||
|
||||
@@ -392,56 +401,57 @@ meshConfig:
|
||||
|
||||
gateway:
|
||||
name: "higress-gateway"
|
||||
# -- Number of Higress Gateway pods
|
||||
replicas: 2
|
||||
image: gateway
|
||||
|
||||
# -- Use a `DaemonSet` or `Deployment`
|
||||
kind: Deployment
|
||||
|
||||
# The number of successive failed probes before indicating readiness failure.
|
||||
# -- The number of successive failed probes before indicating readiness failure.
|
||||
readinessFailureThreshold: 30
|
||||
|
||||
# The number of successive successed probes before indicating readiness success.
|
||||
# -- The number of successive successed probes before indicating readiness success.
|
||||
readinessSuccessThreshold: 1
|
||||
|
||||
# The initial delay for readiness probes in seconds.
|
||||
# -- The initial delay for readiness probes in seconds.
|
||||
readinessInitialDelaySeconds: 1
|
||||
|
||||
# The period between readiness probes.
|
||||
# -- The period between readiness probes.
|
||||
readinessPeriodSeconds: 2
|
||||
|
||||
# The readiness timeout seconds
|
||||
# -- The readiness timeout seconds
|
||||
readinessTimeoutSeconds: 3
|
||||
|
||||
hub: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress
|
||||
tag: ""
|
||||
# revision declares which revision this gateway is a part of
|
||||
# -- revision declares which revision this gateway is a part of
|
||||
revision: ""
|
||||
|
||||
rbac:
|
||||
# If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
|
||||
# -- If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
|
||||
# when using http://gateway-api.org/.
|
||||
enabled: true
|
||||
|
||||
serviceAccount:
|
||||
# If set, a service account will be created. Otherwise, the default is used
|
||||
# -- If set, a service account will be created. Otherwise, the default is used
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
# -- Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# -- The name of the service account to use.
|
||||
# If not set, the release name is used
|
||||
name: ""
|
||||
|
||||
# Pod environment variables
|
||||
# -- Pod environment variables
|
||||
env: {}
|
||||
httpPort: 80
|
||||
httpsPort: 443
|
||||
hostNetwork: false
|
||||
|
||||
# Labels to apply to all resources
|
||||
# -- Labels to apply to all resources
|
||||
labels: {}
|
||||
|
||||
# Annotations to apply to all resources
|
||||
# -- Annotations to apply to all resources
|
||||
annotations: {}
|
||||
|
||||
podAnnotations:
|
||||
@@ -449,25 +459,25 @@ gateway:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/path: "/stats/prometheus"
|
||||
sidecar.istio.io/inject: "false"
|
||||
|
||||
# Define the security context for the pod.
|
||||
|
||||
# -- Define the security context for the pod.
|
||||
# If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
|
||||
# On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
|
||||
securityContext: ~
|
||||
containerSecurityContext: ~
|
||||
|
||||
|
||||
service:
|
||||
# Type of service. Set to "None" to disable the service entirely
|
||||
# -- Type of service. Set to "None" to disable the service entirely
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- name: http2
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
- name: https
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: 443
|
||||
- name: http2
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
- name: https
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: 443
|
||||
annotations: {}
|
||||
loadBalancerIP: ""
|
||||
loadBalancerClass: ""
|
||||
@@ -476,7 +486,7 @@ gateway:
|
||||
|
||||
rollingMaxSurge: 100%
|
||||
rollingMaxUnavailable: 25%
|
||||
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 2000m
|
||||
@@ -484,24 +494,42 @@ gateway:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
|
||||
tolerations: []
|
||||
|
||||
|
||||
affinity: {}
|
||||
|
||||
# If specified, the gateway will act as a network gateway for the given network.
|
||||
|
||||
# -- If specified, the gateway will act as a network gateway for the given network.
|
||||
networkGateway: ""
|
||||
|
||||
|
||||
metrics:
|
||||
# -- If true, create PodMonitor or VMPodScrape for gateway
|
||||
enabled: false
|
||||
# -- provider group name for CustomResourceDefinition, can be monitoring.coreos.com or operator.victoriametrics.com
|
||||
provider: monitoring.coreos.com
|
||||
interval: ""
|
||||
scrapeTimeout: ""
|
||||
honorLabels: false
|
||||
# -- for monitoring.coreos.com/v1.PodMonitor
|
||||
metricRelabelings: []
|
||||
relabelings: []
|
||||
# -- for operator.victoriametrics.com/v1beta1.VMPodScrape
|
||||
metricRelabelConfigs: []
|
||||
relabelConfigs: []
|
||||
# -- some more raw podMetricsEndpoints spec
|
||||
rawSpec: {}
|
||||
|
||||
controller:
|
||||
name: "higress-controller"
|
||||
# -- Number of Higress Controller pods
|
||||
replicas: 1
|
||||
image: higress
|
||||
|
||||
@@ -510,61 +538,52 @@ controller:
|
||||
env: {}
|
||||
|
||||
labels: {}
|
||||
|
||||
probe: {
|
||||
httpGet: {
|
||||
path: /ready,
|
||||
port: 8888,
|
||||
},
|
||||
initialDelaySeconds: 1,
|
||||
periodSeconds: 3,
|
||||
timeoutSeconds: 5
|
||||
}
|
||||
|
||||
|
||||
probe:
|
||||
{
|
||||
httpGet: { path: /ready, port: 8888 },
|
||||
initialDelaySeconds: 1,
|
||||
periodSeconds: 3,
|
||||
timeoutSeconds: 5,
|
||||
}
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
rbac:
|
||||
create: true
|
||||
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
# -- Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
# -- Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
# -- The name of the service account to use.
|
||||
# -- If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
podSecurityContext:
|
||||
{}
|
||||
# fsGroup: 2000
|
||||
|
||||
ports: [
|
||||
{
|
||||
"name": "http",
|
||||
"protocol": "TCP",
|
||||
"port": 8888,
|
||||
"targetPort": 8888,
|
||||
},
|
||||
{
|
||||
"name": "http-solver",
|
||||
"protocol": "TCP",
|
||||
"port": 8889,
|
||||
"targetPort": 8889,
|
||||
},
|
||||
{
|
||||
"name": "grpc",
|
||||
"protocol": "TCP",
|
||||
"port": 15051,
|
||||
"targetPort": 15051,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
ports:
|
||||
[
|
||||
{ "name": "http", "protocol": "TCP", "port": 8888, "targetPort": 8888 },
|
||||
{
|
||||
"name": "http-solver",
|
||||
"protocol": "TCP",
|
||||
"port": 8889,
|
||||
"targetPort": 8889,
|
||||
},
|
||||
{ "name": "grpc", "protocol": "TCP", "port": 15051, "targetPort": 15051 },
|
||||
]
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
|
||||
securityContext: {}
|
||||
|
||||
securityContext:
|
||||
{}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
@@ -579,11 +598,11 @@ controller:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2048Mi
|
||||
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
|
||||
tolerations: []
|
||||
|
||||
|
||||
affinity: {}
|
||||
|
||||
autoscaling:
|
||||
@@ -594,8 +613,8 @@ controller:
|
||||
automaticHttps:
|
||||
enabled: true
|
||||
email: ""
|
||||
|
||||
## Discovery Settings
|
||||
|
||||
## -- Discovery Settings
|
||||
pilot:
|
||||
autoscaleEnabled: false
|
||||
autoscaleMin: 1
|
||||
@@ -607,11 +626,11 @@ pilot:
|
||||
hub: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress
|
||||
tag: ""
|
||||
|
||||
# Can be a full hub/image:tag
|
||||
# -- Can be a full hub/image:tag
|
||||
image: pilot
|
||||
traceSampling: 1.0
|
||||
|
||||
# Resources for a small pilot install
|
||||
# -- Resources for a small pilot install
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
@@ -626,21 +645,21 @@ pilot:
|
||||
cpu:
|
||||
targetAverageUtilization: 80
|
||||
|
||||
# if protocol sniffing is enabled for outbound
|
||||
# -- if protocol sniffing is enabled for outbound
|
||||
enableProtocolSniffingForOutbound: true
|
||||
# if protocol sniffing is enabled for inbound
|
||||
# -- if protocol sniffing is enabled for inbound
|
||||
enableProtocolSniffingForInbound: true
|
||||
|
||||
nodeSelector: {}
|
||||
podAnnotations: {}
|
||||
serviceAnnotations: {}
|
||||
|
||||
# You can use jwksResolverExtraRootCA to provide a root certificate
|
||||
# -- You can use jwksResolverExtraRootCA to provide a root certificate
|
||||
# in PEM format. This will then be trusted by pilot when resolving
|
||||
# JWKS URIs.
|
||||
jwksResolverExtraRootCA: ""
|
||||
|
||||
# This is used to set the source of configuration for
|
||||
# -- This is used to set the source of configuration for
|
||||
# the associated address in configSource, if nothing is specified
|
||||
# the default MCP is assumed.
|
||||
configSource:
|
||||
@@ -648,34 +667,48 @@ pilot:
|
||||
|
||||
plugins: []
|
||||
|
||||
# The following is used to limit how long a sidecar can be connected
|
||||
# -- The following is used to limit how long a sidecar can be connected
|
||||
# to a pilot. It balances out load across pilot instances at the cost of
|
||||
# increasing system churn.
|
||||
keepaliveMaxServerConnectionAge: 30m
|
||||
|
||||
# Additional labels to apply to the deployment.
|
||||
# -- Additional labels to apply to the deployment.
|
||||
deploymentLabels: {}
|
||||
|
||||
|
||||
## Mesh config settings
|
||||
|
||||
# Install the mesh config map, generated from values.yaml.
|
||||
# -- Install the mesh config map, generated from values.yaml.
|
||||
# If false, pilot wil use default values (by default) or user-supplied values.
|
||||
configMap: true
|
||||
|
||||
# Additional labels to apply on the pod level for monitoring and logging configuration.
|
||||
# -- Additional labels to apply on the pod level for monitoring and logging configuration.
|
||||
podLabels: {}
|
||||
|
||||
|
||||
# Tracing config settings
|
||||
tracing:
|
||||
enable: false
|
||||
sampling: 100
|
||||
timeout: 500
|
||||
skywalking:
|
||||
# access_token: ""
|
||||
service: ""
|
||||
port: 11800
|
||||
# access_token: ""
|
||||
service: ""
|
||||
port: 11800
|
||||
# zipkin:
|
||||
# service: ""
|
||||
# port: 9411
|
||||
# service: ""
|
||||
# port: 9411
|
||||
|
||||
# -- Downstream config settings
|
||||
downstream:
|
||||
idleTimeout: 180
|
||||
maxRequestHeadersKb: 60
|
||||
connectionBufferLimits: 32768
|
||||
http2:
|
||||
maxConcurrentStreams: 100
|
||||
initialStreamWindowSize: 65535
|
||||
initialConnectionWindowSize: 1048576
|
||||
routeTimeout: 0
|
||||
|
||||
# -- Upstream config settings
|
||||
upstream:
|
||||
idleTimeout: 10
|
||||
connectionBufferLimits: 10485760
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
dependencies:
|
||||
- name: higress-core
|
||||
repository: file://../core
|
||||
version: 2.0.0-rc.1
|
||||
version: 2.0.4
|
||||
- name: higress-console
|
||||
repository: https://higress.io/helm-charts/
|
||||
version: 1.4.2
|
||||
digest: sha256:10375e19aff1cc31e4d450ee5c3124ed684c8bcd2f4c019ea88abf7e3d381d76
|
||||
generated: "2024-08-15T19:39:04.526398+08:00"
|
||||
version: 1.4.6
|
||||
digest: sha256:ec570ac7ae8a6de976e7ffafaadae4a33beeabfb4b13debe63e0cfa100e2eb8c
|
||||
generated: "2024-12-06T11:34:04.628976+08:00"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v2
|
||||
appVersion: 2.0.0-rc.1
|
||||
appVersion: 2.0.4
|
||||
description: Helm chart for deploying Higress gateways
|
||||
icon: https://higress.io/img/higress_logo_small.png
|
||||
home: http://higress.io/
|
||||
@@ -12,9 +12,9 @@ sources:
|
||||
dependencies:
|
||||
- name: higress-core
|
||||
repository: "file://../core"
|
||||
version: 2.0.0-rc.1
|
||||
version: 2.0.4
|
||||
- name: higress-console
|
||||
repository: "https://higress.io/helm-charts/"
|
||||
version: 1.4.2
|
||||
version: 1.4.6
|
||||
type: application
|
||||
version: 2.0.0-rc.1
|
||||
version: 2.0.4
|
||||
|
||||
@@ -1,57 +1,275 @@
|
||||
# Higress Helm Chart
|
||||
|
||||
Installs the cloud-native gateway [Higress](http://higress.io/)
|
||||
|
||||
## Get Repo Info
|
||||
|
||||
```console
|
||||
helm repo add higress.io https://higress.io/helm-charts
|
||||
helm repo update
|
||||
```
|
||||
|
||||
_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `higress`:
|
||||
|
||||
```console
|
||||
helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes
|
||||
```
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
To uninstall/delete the higress deployment:
|
||||
|
||||
```console
|
||||
helm delete higress -n higress-system
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
## Configuration
|
||||
|
||||
| **Parameter** | **Description** | **Default** |
|
||||
|---|---|---|
|
||||
| **Global Parameters** | | |
|
||||
| global.local | Set to `true` if installing to a local K8s cluster (e.g.: Kind, Rancher Desktop, etc.) | false |
|
||||
| global.ingressClass | [IngressClass](https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#ingress-class) which is used to filter Ingress resources Higress Controller watches.<br />If there are multiple gateway instances deployed in the cluster, this parameter can be used to distinguish the scope of each gateway instance.<br />There are some special cases for special IngressClass values:<br />1. If set to "nginx", Higress Controller will watch Ingress resources with the `nginx` IngressClass or without any Ingress class.<br />2. If set to empty, Higress Controller will watch all Ingress resources in the K8s cluster. | higress |
|
||||
| global.watchNamespace | If not empty, Higress Controller will only watch resources in the specified namespace. When isolating different business systems using K8s namespace, if each namespace requires a standalone gateway instance, this parameter can be used to confine the Ingress watching of Higress within the given namespace. | "" |
|
||||
| global.disableAlpnH2 | Whether to disable HTTP/2 in ALPN | true |
|
||||
| global.enableStatus | If `true`, Higress Controller will update the `status` field of Ingress resources.<br />When migrating from Nginx Ingress, in order to avoid `status` field of Ingress objects being overwritten, this parameter needs to be set to false, so Higress won't write the entry IP to the `status` field of the corresponding Ingress object. | true |
|
||||
| global.enableIstioAPI | If `true`, Higress Controller will monitor istio resources as well | false |
|
||||
| global.enableGatewayAPI | If `true`, Higress Controller will monitor Gateway API resources as well | false |
|
||||
| global.istioNamespace | The namespace istio is installed to | istio-system |
|
||||
| **Core Paramters** | | |
|
||||
| higress-core.gateway.replicas | Number of Higress Gateway pods | 2 |
|
||||
| higress-core.controller.replicas | Number of Higress Controller pods | 1 |
|
||||
| **Console Paramters** | | |
|
||||
| higress-console.replicaCount | Number of Higress Console pods | 1 |
|
||||
| higress-console.service.type | K8s service type used by Higress Console | ClusterIP |
|
||||
| higress-console.domain | Domain used to access Higress Console | console.higress.io |
|
||||
| higress-console.tlsSecretName | Name of Secret resource used by TLS connections. | "" |
|
||||
| higress-console.web.login.prompt | Prompt message to be displayed on the login page | "" |
|
||||
| higress-console.admin.password.value | If not empty, the admin password will be configured to the specified value. | "" |
|
||||
| higress-console.admin.password.length | The length of random admin password generated during installation. Only works when `higress-console.admin.password.value` is not set. | 8 |
|
||||
| higress-console.o11y.enabled | If `true`, o11y suite (Grafana + Promethues) will be installed. | false |
|
||||
| higress-console.pvc.rwxSupported | Set to `false` when installing to a standard K8s cluster and the target cluster doesn't support the ReadWriteMany access mode of PersistentVolumeClaim. | true |
|
||||
## Higress for Kubernetes
|
||||
|
||||
Higress is a cloud-native api gateway based on Alibaba's internal gateway practices.
|
||||
|
||||
Powered by Istio and Envoy, Higress realizes the integration of the triple gateway architecture of traffic gateway, microservice gateway and security gateway, thereby greatly reducing the costs of deployment, operation and maintenance.
|
||||
|
||||
## Setup Repo Info
|
||||
|
||||
```console
|
||||
helm repo add higress.io https://higress.io/helm-charts
|
||||
helm repo update
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
To install the chart with the release name `higress`:
|
||||
|
||||
```console
|
||||
helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
|
||||
To uninstall/delete the higress deployment:
|
||||
|
||||
```console
|
||||
helm delete higress -n higress-system
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
## Parameters
|
||||
|
||||
## Values
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| clusterName | string | `""` | |
|
||||
| controller.affinity | object | `{}` | |
|
||||
| controller.automaticHttps.email | string | `""` | |
|
||||
| controller.automaticHttps.enabled | bool | `true` | |
|
||||
| controller.autoscaling.enabled | bool | `false` | |
|
||||
| controller.autoscaling.maxReplicas | int | `5` | |
|
||||
| controller.autoscaling.minReplicas | int | `1` | |
|
||||
| controller.autoscaling.targetCPUUtilizationPercentage | int | `80` | |
|
||||
| controller.env | object | `{}` | |
|
||||
| controller.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | |
|
||||
| controller.image | string | `"higress"` | |
|
||||
| controller.imagePullSecrets | list | `[]` | |
|
||||
| controller.labels | object | `{}` | |
|
||||
| controller.name | string | `"higress-controller"` | |
|
||||
| controller.nodeSelector | object | `{}` | |
|
||||
| controller.podAnnotations | object | `{}` | |
|
||||
| controller.podSecurityContext | object | `{}` | |
|
||||
| controller.ports[0].name | string | `"http"` | |
|
||||
| controller.ports[0].port | int | `8888` | |
|
||||
| controller.ports[0].protocol | string | `"TCP"` | |
|
||||
| controller.ports[0].targetPort | int | `8888` | |
|
||||
| controller.ports[1].name | string | `"http-solver"` | |
|
||||
| controller.ports[1].port | int | `8889` | |
|
||||
| controller.ports[1].protocol | string | `"TCP"` | |
|
||||
| controller.ports[1].targetPort | int | `8889` | |
|
||||
| controller.ports[2].name | string | `"grpc"` | |
|
||||
| controller.ports[2].port | int | `15051` | |
|
||||
| controller.ports[2].protocol | string | `"TCP"` | |
|
||||
| controller.ports[2].targetPort | int | `15051` | |
|
||||
| controller.probe.httpGet.path | string | `"/ready"` | |
|
||||
| controller.probe.httpGet.port | int | `8888` | |
|
||||
| controller.probe.initialDelaySeconds | int | `1` | |
|
||||
| controller.probe.periodSeconds | int | `3` | |
|
||||
| controller.probe.timeoutSeconds | int | `5` | |
|
||||
| controller.rbac.create | bool | `true` | |
|
||||
| controller.replicas | int | `1` | Number of Higress Controller pods |
|
||||
| controller.resources.limits.cpu | string | `"1000m"` | |
|
||||
| controller.resources.limits.memory | string | `"2048Mi"` | |
|
||||
| controller.resources.requests.cpu | string | `"500m"` | |
|
||||
| controller.resources.requests.memory | string | `"2048Mi"` | |
|
||||
| controller.securityContext | object | `{}` | |
|
||||
| controller.service.type | string | `"ClusterIP"` | |
|
||||
| controller.serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
|
||||
| controller.serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
|
||||
| controller.serviceAccount.name | string | `""` | If not set and create is true, a name is generated using the fullname template |
|
||||
| controller.tag | string | `""` | |
|
||||
| controller.tolerations | list | `[]` | |
|
||||
| downstream | object | `{"connectionBufferLimits":32768,"http2":{"initialConnectionWindowSize":1048576,"initialStreamWindowSize":65535,"maxConcurrentStreams":100},"idleTimeout":180,"maxRequestHeadersKb":60,"routeTimeout":0}` | Downstream config settings |
|
||||
| gateway.affinity | object | `{}` | |
|
||||
| gateway.annotations | object | `{}` | Annotations to apply to all resources |
|
||||
| gateway.autoscaling.enabled | bool | `false` | |
|
||||
| gateway.autoscaling.maxReplicas | int | `5` | |
|
||||
| gateway.autoscaling.minReplicas | int | `1` | |
|
||||
| gateway.autoscaling.targetCPUUtilizationPercentage | int | `80` | |
|
||||
| gateway.containerSecurityContext | string | `nil` | |
|
||||
| gateway.env | object | `{}` | Pod environment variables |
|
||||
| gateway.hostNetwork | bool | `false` | |
|
||||
| gateway.httpPort | int | `80` | |
|
||||
| gateway.httpsPort | int | `443` | |
|
||||
| gateway.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | |
|
||||
| gateway.image | string | `"gateway"` | |
|
||||
| gateway.kind | string | `"Deployment"` | Use a `DaemonSet` or `Deployment` |
|
||||
| gateway.labels | object | `{}` | Labels to apply to all resources |
|
||||
| gateway.metrics.enabled | bool | `false` | If true, create PodMonitor or VMPodScrape for gateway |
|
||||
| gateway.metrics.honorLabels | bool | `false` | |
|
||||
| gateway.metrics.interval | string | `""` | |
|
||||
| gateway.metrics.metricRelabelConfigs | list | `[]` | for operator.victoriametrics.com/v1beta1.VMPodScrape |
|
||||
| gateway.metrics.metricRelabelings | list | `[]` | for monitoring.coreos.com/v1.PodMonitor |
|
||||
| gateway.metrics.provider | string | `"monitoring.coreos.com"` | provider group name for CustomResourceDefinition, can be monitoring.coreos.com or operator.victoriametrics.com |
|
||||
| gateway.metrics.rawSpec | object | `{}` | some more raw podMetricsEndpoints spec |
|
||||
| gateway.metrics.relabelConfigs | list | `[]` | |
|
||||
| gateway.metrics.relabelings | list | `[]` | |
|
||||
| gateway.metrics.scrapeTimeout | string | `""` | |
|
||||
| gateway.name | string | `"higress-gateway"` | |
|
||||
| gateway.networkGateway | string | `""` | If specified, the gateway will act as a network gateway for the given network. |
|
||||
| gateway.nodeSelector | object | `{}` | |
|
||||
| gateway.podAnnotations."prometheus.io/path" | string | `"/stats/prometheus"` | |
|
||||
| gateway.podAnnotations."prometheus.io/port" | string | `"15020"` | |
|
||||
| gateway.podAnnotations."prometheus.io/scrape" | string | `"true"` | |
|
||||
| gateway.podAnnotations."sidecar.istio.io/inject" | string | `"false"` | |
|
||||
| gateway.rbac.enabled | bool | `true` | If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed when using http://gateway-api.org/. |
|
||||
| gateway.readinessFailureThreshold | int | `30` | The number of successive failed probes before indicating readiness failure. |
|
||||
| gateway.readinessInitialDelaySeconds | int | `1` | The initial delay for readiness probes in seconds. |
|
||||
| gateway.readinessPeriodSeconds | int | `2` | The period between readiness probes. |
|
||||
| gateway.readinessSuccessThreshold | int | `1` | The number of successive successed probes before indicating readiness success. |
|
||||
| gateway.readinessTimeoutSeconds | int | `3` | The readiness timeout seconds |
|
||||
| gateway.replicas | int | `2` | Number of Higress Gateway pods |
|
||||
| gateway.resources.limits.cpu | string | `"2000m"` | |
|
||||
| gateway.resources.limits.memory | string | `"2048Mi"` | |
|
||||
| gateway.resources.requests.cpu | string | `"2000m"` | |
|
||||
| gateway.resources.requests.memory | string | `"2048Mi"` | |
|
||||
| gateway.revision | string | `""` | revision declares which revision this gateway is a part of |
|
||||
| gateway.rollingMaxSurge | string | `"100%"` | |
|
||||
| gateway.rollingMaxUnavailable | string | `"25%"` | |
|
||||
| gateway.securityContext | string | `nil` | Define the security context for the pod. If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443. On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl. |
|
||||
| gateway.service.annotations | object | `{}` | |
|
||||
| gateway.service.externalTrafficPolicy | string | `""` | |
|
||||
| gateway.service.loadBalancerClass | string | `""` | |
|
||||
| gateway.service.loadBalancerIP | string | `""` | |
|
||||
| gateway.service.loadBalancerSourceRanges | list | `[]` | |
|
||||
| gateway.service.ports[0].name | string | `"http2"` | |
|
||||
| gateway.service.ports[0].port | int | `80` | |
|
||||
| gateway.service.ports[0].protocol | string | `"TCP"` | |
|
||||
| gateway.service.ports[0].targetPort | int | `80` | |
|
||||
| gateway.service.ports[1].name | string | `"https"` | |
|
||||
| gateway.service.ports[1].port | int | `443` | |
|
||||
| gateway.service.ports[1].protocol | string | `"TCP"` | |
|
||||
| gateway.service.ports[1].targetPort | int | `443` | |
|
||||
| gateway.service.type | string | `"LoadBalancer"` | Type of service. Set to "None" to disable the service entirely |
|
||||
| gateway.serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
|
||||
| gateway.serviceAccount.create | bool | `true` | If set, a service account will be created. Otherwise, the default is used |
|
||||
| gateway.serviceAccount.name | string | `""` | The name of the service account to use. If not set, the release name is used |
|
||||
| gateway.tag | string | `""` | |
|
||||
| gateway.tolerations | list | `[]` | |
|
||||
| global.autoscalingv2API | bool | `true` | whether to use autoscaling/v2 template for HPA settings for internal usage only, not to be configured by users. |
|
||||
| global.caAddress | string | `""` | The customized CA address to retrieve certificates for the pods in the cluster. CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint. If not set explicitly, default to the Istio discovery address. |
|
||||
| global.caName | string | `""` | The name of the CA for workload certificates. For example, when caName=GkeWorkloadCertificate, GKE workload certificates will be used as the certificates for workloads. The default value is "" and when caName="", the CA will be configured by other mechanisms (e.g., environmental variable CA_PROVIDER). |
|
||||
| global.configCluster | bool | `false` | Configure a remote cluster as the config cluster for an external istiod. |
|
||||
| global.defaultPodDisruptionBudget | object | `{"enabled":false}` | enable pod disruption budget for the control plane, which is used to ensure Istio control plane components are gradually upgraded or recovered. |
|
||||
| global.defaultResources | object | `{"requests":{"cpu":"10m"}}` | A minimal set of requested resources to applied to all deployments so that Horizontal Pod Autoscaler will be able to function (if set). Each component can overwrite these default values by adding its own resources block in the relevant section below and setting the desired resources values. |
|
||||
| global.defaultUpstreamConcurrencyThreshold | int | `10000` | |
|
||||
| global.disableAlpnH2 | bool | `false` | Whether to disable HTTP/2 in ALPN |
|
||||
| global.enableGatewayAPI | bool | `false` | If true, Higress Controller will monitor Gateway API resources as well |
|
||||
| global.enableH3 | bool | `false` | |
|
||||
| global.enableIPv6 | bool | `false` | |
|
||||
| global.enableIstioAPI | bool | `true` | If true, Higress Controller will monitor istio resources as well |
|
||||
| global.enableProxyProtocol | bool | `false` | |
|
||||
| global.enableSRDS | bool | `true` | |
|
||||
| global.enableStatus | bool | `true` | If true, Higress Controller will update the status field of Ingress resources. When migrating from Nginx Ingress, in order to avoid status field of Ingress objects being overwritten, this parameter needs to be set to false, so Higress won't write the entry IP to the status field of the corresponding Ingress object. |
|
||||
| global.externalIstiod | bool | `false` | Configure a remote cluster data plane controlled by an external istiod. When set to true, istiod is not deployed locally and only a subset of the other discovery charts are enabled. |
|
||||
| global.hostRDSMergeSubset | bool | `false` | |
|
||||
| global.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | Default hub for Istio images. Releases are published to docker hub under 'istio' project. Dev builds from prow are on gcr.io |
|
||||
| global.imagePullPolicy | string | `""` | Specify image pull policy if default behavior isn't desired. Default behavior: latest images will be Always else IfNotPresent. |
|
||||
| global.imagePullSecrets | list | `[]` | ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing) ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects. Must be set for any cluster configured with private docker registry. |
|
||||
| global.ingressClass | string | `"higress"` | IngressClass filters which ingress resources the higress controller watches. The default ingress class is higress. There are some special cases for special ingress class. 1. When the ingress class is set as nginx, the higress controller will watch ingress resources with the nginx ingress class or without any ingress class. 2. When the ingress class is set empty, the higress controller will watch all ingress resources in the k8s cluster. |
|
||||
| global.istioNamespace | string | `"istio-system"` | Used to locate istiod. |
|
||||
| global.istiod | object | `{"enableAnalysis":false}` | Enabled by default in master for maximising testing. |
|
||||
| global.jwtPolicy | string | `"third-party-jwt"` | Configure the policy for validating JWT. Currently, two options are supported: "third-party-jwt" and "first-party-jwt". |
|
||||
| global.kind | bool | `false` | |
|
||||
| global.liteMetrics | bool | `true` | |
|
||||
| global.local | bool | `false` | When deploying to a local cluster (e.g.: kind cluster), set this to true. |
|
||||
| global.logAsJson | bool | `false` | |
|
||||
| global.logging | object | `{"level":"default:info"}` | Comma-separated minimum per-scope logging level of messages to output, in the form of <scope>:<level>,<scope>:<level> The control plane has different scopes depending on component, but can configure default log level across all components If empty, default scope and level will be used as configured in code |
|
||||
| global.meshID | string | `""` | If the mesh admin does not specify a value, Istio will use the value of the mesh's Trust Domain. The best practice is to select a proper Trust Domain value. |
|
||||
| global.meshNetworks | object | `{}` | |
|
||||
| global.mountMtlsCerts | bool | `false` | Use the user-specified, secret volume mounted key and certs for Pilot and workloads. |
|
||||
| global.multiCluster.clusterName | string | `""` | Should be set to the name of the cluster this installation will run in. This is required for sidecar injection to properly label proxies |
|
||||
| global.multiCluster.enabled | bool | `true` | Set to true to connect two kubernetes clusters via their respective ingressgateway services when pods in each cluster cannot directly talk to one another. All clusters should be using Istio mTLS and must have a shared root CA for this model to work. |
|
||||
| global.network | string | `""` | Network defines the network this cluster belong to. This name corresponds to the networks in the map of mesh networks. |
|
||||
| global.o11y | object | `{"enabled":false,"promtail":{"image":{"repository":"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/promtail","tag":"2.9.4"},"port":3101,"resources":{"limits":{"cpu":"500m","memory":"2Gi"}},"securityContext":{}}}` | Observability (o11y) configurations |
|
||||
| global.omitSidecarInjectorConfigMap | bool | `false` | |
|
||||
| global.onDemandRDS | bool | `false` | |
|
||||
| global.oneNamespace | bool | `false` | Whether to restrict the applications namespace the controller manages; If not set, controller watches all namespaces |
|
||||
| global.onlyPushRouteCluster | bool | `true` | |
|
||||
| global.operatorManageWebhooks | bool | `false` | Configure whether Operator manages webhook configurations. The current behavior of Istiod is to manage its own webhook configurations. When this option is set as true, Istio Operator, instead of webhooks, manages the webhook configurations. When this option is set as false, webhooks manage their own webhook configurations. |
|
||||
| global.pilotCertProvider | string | `"istiod"` | Configure the certificate provider for control plane communication. Currently, two providers are supported: "kubernetes" and "istiod". As some platforms may not have kubernetes signing APIs, Istiod is the default |
|
||||
| global.priorityClassName | string | `""` | Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and system-node-critical, it is better to configure this in order to make sure your Istio pods will not be killed because of low priority class. Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass for more detail. |
|
||||
| global.proxy.autoInject | string | `"enabled"` | This controls the 'policy' in the sidecar injector. |
|
||||
| global.proxy.clusterDomain | string | `"cluster.local"` | CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value cluster domain. Default value is "cluster.local". |
|
||||
| global.proxy.componentLogLevel | string | `"misc:error"` | Per Component log level for proxy, applies to gateways and sidecars. If a component level is not set, then the global "logLevel" will be used. |
|
||||
| global.proxy.enableCoreDump | bool | `false` | If set, newly injected sidecars will have core dumps enabled. |
|
||||
| global.proxy.excludeIPRanges | string | `""` | |
|
||||
| global.proxy.excludeInboundPorts | string | `""` | |
|
||||
| global.proxy.excludeOutboundPorts | string | `""` | |
|
||||
| global.proxy.holdApplicationUntilProxyStarts | bool | `false` | Controls if sidecar is injected at the front of the container list and blocks the start of the other containers until the proxy is ready |
|
||||
| global.proxy.image | string | `"proxyv2"` | |
|
||||
| global.proxy.includeIPRanges | string | `"*"` | istio egress capture allowlist https://istio.io/docs/tasks/traffic-management/egress.html#calling-external-services-directly example: includeIPRanges: "172.30.0.0/16,172.20.0.0/16" would only capture egress traffic on those two IP Ranges, all other outbound traffic would be allowed by the sidecar |
|
||||
| global.proxy.includeInboundPorts | string | `"*"` | |
|
||||
| global.proxy.includeOutboundPorts | string | `""` | |
|
||||
| global.proxy.logLevel | string | `"warning"` | Log level for proxy, applies to gateways and sidecars. Expected values are: trace|debug|info|warning|error|critical|off |
|
||||
| global.proxy.privileged | bool | `false` | If set to true, istio-proxy container will have privileged securityContext |
|
||||
| global.proxy.readinessFailureThreshold | int | `30` | The number of successive failed probes before indicating readiness failure. |
|
||||
| global.proxy.readinessInitialDelaySeconds | int | `1` | The initial delay for readiness probes in seconds. |
|
||||
| global.proxy.readinessPeriodSeconds | int | `2` | The period between readiness probes. |
|
||||
| global.proxy.readinessSuccessThreshold | int | `30` | The number of successive successed probes before indicating readiness success. |
|
||||
| global.proxy.readinessTimeoutSeconds | int | `3` | The readiness timeout seconds |
|
||||
| global.proxy.resources | object | `{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}` | Resources for the sidecar. |
|
||||
| global.proxy.statusPort | int | `15020` | Default port for Pilot agent health checks. A value of 0 will disable health checking. |
|
||||
| global.proxy.tracer | string | `""` | Specify which tracer to use. One of: lightstep, datadog, stackdriver. If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file. |
|
||||
| global.proxy_init.image | string | `"proxyv2"` | Base name for the proxy_init container, used to configure iptables. |
|
||||
| global.proxy_init.resources.limits.cpu | string | `"2000m"` | |
|
||||
| global.proxy_init.resources.limits.memory | string | `"1024Mi"` | |
|
||||
| global.proxy_init.resources.requests.cpu | string | `"10m"` | |
|
||||
| global.proxy_init.resources.requests.memory | string | `"10Mi"` | |
|
||||
| global.remotePilotAddress | string | `""` | configure remote pilot and istiod service and endpoint |
|
||||
| global.sds.token | object | `{"aud":"istio-ca"}` | The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3. When a CSR is sent from Istio Agent to the CA (e.g. Istiod), this aud is to make sure the JWT is intended for the CA. |
|
||||
| global.sts.servicePort | int | `0` | The service port used by Security Token Service (STS) server to handle token exchange requests. Setting this port to a non-zero value enables STS server. |
|
||||
| global.tracer | object | `{"datadog":{"address":"$(HOST_IP):8126"},"lightstep":{"accessToken":"","address":""},"stackdriver":{"debug":false,"maxNumberOfAnnotations":200,"maxNumberOfAttributes":200,"maxNumberOfMessageEvents":200}}` | Configuration for each of the supported tracers |
|
||||
| global.tracer.datadog | object | `{"address":"$(HOST_IP):8126"}` | Configuration for envoy to send trace data to LightStep. Disabled by default. address: the <host>:<port> of the satellite pool accessToken: required for sending data to the pool |
|
||||
| global.tracer.datadog.address | string | `"$(HOST_IP):8126"` | Host:Port for submitting traces to the Datadog agent. |
|
||||
| global.tracer.lightstep.accessToken | string | `""` | example: abcdefg1234567 |
|
||||
| global.tracer.lightstep.address | string | `""` | example: lightstep-satellite:443 |
|
||||
| global.tracer.stackdriver.debug | bool | `false` | enables trace output to stdout. |
|
||||
| global.tracer.stackdriver.maxNumberOfAnnotations | int | `200` | The global default max number of annotation events per span. |
|
||||
| global.tracer.stackdriver.maxNumberOfAttributes | int | `200` | The global default max number of attributes per span. |
|
||||
| global.tracer.stackdriver.maxNumberOfMessageEvents | int | `200` | The global default max number of message events per span. |
|
||||
| global.useMCP | bool | `false` | Use the Mesh Control Protocol (MCP) for configuring Istiod. Requires an MCP source. |
|
||||
| global.watchNamespace | string | `""` | If not empty, Higress Controller will only watch resources in the specified namespace. When isolating different business systems using K8s namespace, if each namespace requires a standalone gateway instance, this parameter can be used to confine the Ingress watching of Higress within the given namespace. |
|
||||
| global.xdsMaxRecvMsgSize | string | `"104857600"` | |
|
||||
| hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | |
|
||||
| meshConfig | object | `{"enablePrometheusMerge":true,"rootNamespace":null,"trustDomain":"cluster.local"}` | meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior See https://istio.io/docs/reference/config/istio.mesh.v1alpha1/ for all available options |
|
||||
| meshConfig.rootNamespace | string | `nil` | The namespace to treat as the administrative root namespace for Istio configuration. When processing a leaf namespace Istio will search for declarations in that namespace first and if none are found it will search in the root namespace. Any matching declaration found in the root namespace is processed as if it were declared in the leaf namespace. |
|
||||
| meshConfig.trustDomain | string | `"cluster.local"` | The trust domain corresponds to the trust root of a system Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain |
|
||||
| pilot.autoscaleEnabled | bool | `false` | |
|
||||
| pilot.autoscaleMax | int | `5` | |
|
||||
| pilot.autoscaleMin | int | `1` | |
|
||||
| pilot.configMap | bool | `true` | Install the mesh config map, generated from values.yaml. If false, pilot wil use default values (by default) or user-supplied values. |
|
||||
| pilot.configSource | object | `{"subscribedResources":[]}` | This is used to set the source of configuration for the associated address in configSource, if nothing is specified the default MCP is assumed. |
|
||||
| pilot.cpu.targetAverageUtilization | int | `80` | |
|
||||
| pilot.deploymentLabels | object | `{}` | Additional labels to apply to the deployment. |
|
||||
| pilot.enableProtocolSniffingForInbound | bool | `true` | if protocol sniffing is enabled for inbound |
|
||||
| pilot.enableProtocolSniffingForOutbound | bool | `true` | if protocol sniffing is enabled for outbound |
|
||||
| pilot.env.PILOT_ENABLE_CROSS_CLUSTER_WORKLOAD_ENTRY | string | `"false"` | |
|
||||
| pilot.env.PILOT_ENABLE_METADATA_EXCHANGE | string | `"false"` | |
|
||||
| pilot.env.PILOT_SCOPE_GATEWAY_TO_NAMESPACE | string | `"false"` | |
|
||||
| pilot.env.VALIDATION_ENABLED | string | `"false"` | |
|
||||
| pilot.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | |
|
||||
| pilot.image | string | `"pilot"` | Can be a full hub/image:tag |
|
||||
| pilot.jwksResolverExtraRootCA | string | `""` | You can use jwksResolverExtraRootCA to provide a root certificate in PEM format. This will then be trusted by pilot when resolving JWKS URIs. |
|
||||
| pilot.keepaliveMaxServerConnectionAge | string | `"30m"` | The following is used to limit how long a sidecar can be connected to a pilot. It balances out load across pilot instances at the cost of increasing system churn. |
|
||||
| pilot.nodeSelector | object | `{}` | |
|
||||
| pilot.plugins | list | `[]` | |
|
||||
| pilot.podAnnotations | object | `{}` | |
|
||||
| pilot.podLabels | object | `{}` | Additional labels to apply on the pod level for monitoring and logging configuration. |
|
||||
| pilot.replicaCount | int | `1` | |
|
||||
| pilot.resources | object | `{"requests":{"cpu":"500m","memory":"2048Mi"}}` | Resources for a small pilot install |
|
||||
| pilot.rollingMaxSurge | string | `"100%"` | |
|
||||
| pilot.rollingMaxUnavailable | string | `"25%"` | |
|
||||
| pilot.serviceAnnotations | object | `{}` | |
|
||||
| pilot.tag | string | `""` | |
|
||||
| pilot.traceSampling | float | `1` | |
|
||||
| revision | string | `""` | |
|
||||
| tracing.enable | bool | `false` | |
|
||||
| tracing.sampling | int | `100` | |
|
||||
| tracing.skywalking.port | int | `11800` | |
|
||||
| tracing.skywalking.service | string | `""` | |
|
||||
| tracing.timeout | int | `500` | |
|
||||
| upstream | object | `{"connectionBufferLimits":10485760,"idleTimeout":10}` | Upstream config settings |
|
||||
34
helm/higress/README.md.gotmpl
Normal file
34
helm/higress/README.md.gotmpl
Normal file
@@ -0,0 +1,34 @@
|
||||
## Higress for Kubernetes
|
||||
|
||||
Higress is a cloud-native api gateway based on Alibaba's internal gateway practices.
|
||||
|
||||
Powered by Istio and Envoy, Higress realizes the integration of the triple gateway architecture of traffic gateway, microservice gateway and security gateway, thereby greatly reducing the costs of deployment, operation and maintenance.
|
||||
|
||||
## Setup Repo Info
|
||||
|
||||
```console
|
||||
helm repo add higress.io https://higress.io/helm-charts
|
||||
helm repo update
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
To install the chart with the release name `higress`:
|
||||
|
||||
```console
|
||||
helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
|
||||
To uninstall/delete the higress deployment:
|
||||
|
||||
```console
|
||||
helm delete higress -n higress-system
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
## Parameters
|
||||
|
||||
{{ template "chart.valuesSection" . }}
|
||||
@@ -114,6 +114,8 @@ static_resources:
|
||||
value: |
|
||||
{{ .JSONExample }}
|
||||
- name: envoy.filters.http.router
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
|
||||
clusters:
|
||||
- name: httpbin
|
||||
connect_timeout: 30s
|
||||
|
||||
Submodule istio/istio updated: c4fa0ca175...0fa834f7b9
Submodule istio/proxy updated: 9189360b8e...4e8eba8fc8
@@ -41,11 +41,11 @@ import (
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/keepalive"
|
||||
istiokube "istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/log"
|
||||
"istio.io/istio/pkg/security"
|
||||
"istio.io/istio/security/pkg/server/ca/authenticate"
|
||||
"istio.io/istio/security/pkg/server/ca/authenticate/kubeauth"
|
||||
"istio.io/pkg/ledger"
|
||||
"istio.io/pkg/log"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ func (s *CertMgr) Reconcile(ctx context.Context, oldConfig *Config, newConfig *C
|
||||
s.cache.Start()
|
||||
// sync domains
|
||||
s.configMgr.SetConfig(newConfig)
|
||||
CertLog.Infof("certMgr start to manageSync domains:+v%", newDomains)
|
||||
CertLog.Infof("certMgr start to manageSync domains: %+v", newDomains)
|
||||
s.manageSync(context.Background(), newDomains)
|
||||
CertLog.Infof("certMgr manageSync domains done")
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
|
||||
package cert
|
||||
|
||||
import "istio.io/pkg/log"
|
||||
import "istio.io/istio/pkg/log"
|
||||
|
||||
var CertLog = log.RegisterScope("cert", "Higress Cert process.", 0)
|
||||
var CertLog = log.RegisterScope("cert", "Higress Cert process.")
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/env"
|
||||
"istio.io/istio/pkg/keepalive"
|
||||
"istio.io/pkg/log"
|
||||
"istio.io/istio/pkg/log"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -21,7 +21,10 @@ type Protocol string
|
||||
const (
|
||||
TCP Protocol = "TCP"
|
||||
HTTP Protocol = "HTTP"
|
||||
HTTP2 Protocol = "HTTP2"
|
||||
HTTPS Protocol = "HTTPS"
|
||||
GRPC Protocol = "GRPC"
|
||||
GRPCS Protocol = "GRPCS"
|
||||
Dubbo Protocol = "Dubbo"
|
||||
Unsupported Protocol = "UnsupportedProtocol"
|
||||
)
|
||||
@@ -32,8 +35,14 @@ func ParseProtocol(s string) Protocol {
|
||||
return TCP
|
||||
case "http":
|
||||
return HTTP
|
||||
case "https":
|
||||
return HTTPS
|
||||
case "http2":
|
||||
return HTTP2
|
||||
case "grpc", "triple", "tri":
|
||||
return GRPC
|
||||
case "grpcs":
|
||||
return GRPCS
|
||||
case "dubbo":
|
||||
return Dubbo
|
||||
}
|
||||
@@ -51,7 +60,7 @@ func (p Protocol) IsTCP() bool {
|
||||
|
||||
func (p Protocol) IsHTTP() bool {
|
||||
switch p {
|
||||
case HTTP, GRPC:
|
||||
case HTTP, GRPC, GRPCS, HTTP2, HTTPS:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -60,7 +69,16 @@ func (p Protocol) IsHTTP() bool {
|
||||
|
||||
func (p Protocol) IsGRPC() bool {
|
||||
switch p {
|
||||
case GRPC:
|
||||
case GRPC, GRPCS:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (i Protocol) IsHTTPS() bool {
|
||||
switch i {
|
||||
case HTTPS, GRPCS:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -23,3 +23,7 @@ const KnativeIngressCRDName = "ingresses.networking.internal.knative.dev"
|
||||
const KnativeServicesCRDName = "services.serving.knative.dev"
|
||||
|
||||
const ManagedGatewayController = "higress.io/gateway-controller"
|
||||
|
||||
const RegistryTypeLabelKey = "higress-registry-type"
|
||||
|
||||
const RegistryNameLabelKey = "higress-registry-name"
|
||||
|
||||
@@ -19,6 +19,7 @@ import "istio.io/pkg/env"
|
||||
var (
|
||||
PodNamespace = env.RegisterStringVar("POD_NAMESPACE", "higress-system", "").Get()
|
||||
PodName = env.RegisterStringVar("POD_NAME", "", "").Get()
|
||||
GatewayName = env.RegisterStringVar("GATEWAY_NAME", "higress-gateway", "").Get()
|
||||
// Revision is the value of the Istio control plane revision, e.g. "canary",
|
||||
// and is the value used by the "istio.io/rev" label.
|
||||
Revision = env.Register("REVISION", "", "").Get()
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
extensions "istio.io/api/extensions/v1alpha1"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
istiotype "istio.io/api/type/v1beta1"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
istiomodel "istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/util/protoconv"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
@@ -53,6 +54,7 @@ import (
|
||||
extlisterv1 "github.com/alibaba/higress/client/pkg/listers/extensions/v1alpha1"
|
||||
netlisterv1 "github.com/alibaba/higress/client/pkg/listers/networking/v1"
|
||||
"github.com/alibaba/higress/pkg/cert"
|
||||
higressconst "github.com/alibaba/higress/pkg/config/constants"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/common"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/configmap"
|
||||
@@ -234,8 +236,9 @@ func (m *IngressConfig) AddLocalCluster(options common.Options) {
|
||||
ingressController = ingressv1.NewController(m.localKubeClient, m.localKubeClient, options, secretController)
|
||||
}
|
||||
m.remoteIngressControllers[options.ClusterId] = ingressController
|
||||
|
||||
m.remoteGatewayControllers[options.ClusterId] = gateway.NewController(m.localKubeClient, options)
|
||||
if features.EnableGatewayAPI {
|
||||
m.remoteGatewayControllers[options.ClusterId] = gateway.NewController(m.localKubeClient, options)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *IngressConfig) List(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
@@ -300,21 +303,21 @@ func (m *IngressConfig) listFromIngressControllers(typ config.GroupVersionKind,
|
||||
common.SortIngressByCreationTime(configs)
|
||||
wrapperConfigs := m.createWrapperConfigs(configs)
|
||||
|
||||
IngressLog.Infof("resource type %s, configs number %d", typ, len(wrapperConfigs))
|
||||
var result []config.Config
|
||||
switch typ {
|
||||
case gvk.Gateway:
|
||||
return m.convertGateways(wrapperConfigs)
|
||||
result = m.convertGateways(wrapperConfigs)
|
||||
case gvk.VirtualService:
|
||||
return m.convertVirtualService(wrapperConfigs)
|
||||
result = m.convertVirtualService(wrapperConfigs)
|
||||
case gvk.DestinationRule:
|
||||
return m.convertDestinationRule(wrapperConfigs)
|
||||
result = m.convertDestinationRule(wrapperConfigs)
|
||||
case gvk.ServiceEntry:
|
||||
return m.convertServiceEntry(wrapperConfigs)
|
||||
result = m.convertServiceEntry(wrapperConfigs)
|
||||
case gvk.WasmPlugin:
|
||||
return m.convertWasmPlugin(wrapperConfigs)
|
||||
result = m.convertWasmPlugin(wrapperConfigs)
|
||||
}
|
||||
|
||||
return nil
|
||||
IngressLog.Infof("resource type %s, ingress number %d, convert configs number %d", typ, len(configs), len(result))
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *IngressConfig) listFromGatewayControllers(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
@@ -628,8 +631,8 @@ func (m *IngressConfig) convertServiceEntry([]common.WrapperConfig) []config.Con
|
||||
if m.RegistryReconciler == nil {
|
||||
return nil
|
||||
}
|
||||
serviceEntries := m.RegistryReconciler.GetAllServiceEntryWrapper()
|
||||
IngressLog.Infof("Found http2rpc serviceEntries %s", serviceEntries)
|
||||
serviceEntries := m.RegistryReconciler.GetAllServiceWrapper()
|
||||
IngressLog.Infof("Found mcp serviceEntries %v", serviceEntries)
|
||||
out := make([]config.Config, 0, len(serviceEntries))
|
||||
for _, se := range serviceEntries {
|
||||
out = append(out, config.Config{
|
||||
@@ -638,6 +641,10 @@ func (m *IngressConfig) convertServiceEntry([]common.WrapperConfig) []config.Con
|
||||
Name: se.ServiceEntry.Hosts[0],
|
||||
Namespace: "mcp",
|
||||
CreationTimestamp: se.GetCreateTime(),
|
||||
Labels: map[string]string{
|
||||
higressconst.RegistryTypeLabelKey: se.RegistryType,
|
||||
higressconst.RegistryNameLabelKey: se.RegistryName,
|
||||
},
|
||||
},
|
||||
Spec: se.ServiceEntry,
|
||||
})
|
||||
@@ -703,6 +710,31 @@ func (m *IngressConfig) convertDestinationRule(configs []common.WrapperConfig) [
|
||||
destinationRules[serviceName] = dr
|
||||
}
|
||||
|
||||
if m.RegistryReconciler != nil {
|
||||
drws := m.RegistryReconciler.GetAllDestinationRuleWrapper()
|
||||
for _, destinationRuleWrapper := range drws {
|
||||
serviceName := destinationRuleWrapper.ServiceKey.ServiceFQDN
|
||||
dr, exist := destinationRules[serviceName]
|
||||
if !exist {
|
||||
destinationRules[serviceName] = destinationRuleWrapper
|
||||
} else if dr.DestinationRule.TrafficPolicy != nil {
|
||||
portTrafficPolicy := destinationRuleWrapper.DestinationRule.TrafficPolicy.PortLevelSettings[0]
|
||||
portUpdated := false
|
||||
for _, policy := range dr.DestinationRule.TrafficPolicy.PortLevelSettings {
|
||||
if policy.Port.Number == portTrafficPolicy.Port.Number {
|
||||
policy.Tls = portTrafficPolicy.Tls
|
||||
portUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if portUpdated {
|
||||
continue
|
||||
}
|
||||
dr.DestinationRule.TrafficPolicy.PortLevelSettings = append(dr.DestinationRule.TrafficPolicy.PortLevelSettings, portTrafficPolicy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out := make([]config.Config, 0, len(destinationRules))
|
||||
for _, dr := range destinationRules {
|
||||
sort.SliceStable(dr.DestinationRule.TrafficPolicy.PortLevelSettings, func(i, j int) bool {
|
||||
@@ -727,6 +759,7 @@ func (m *IngressConfig) convertDestinationRule(configs []common.WrapperConfig) [
|
||||
Spec: dr.DestinationRule,
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -872,6 +905,7 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
StructValue: rule.Config,
|
||||
}
|
||||
|
||||
validRule := false
|
||||
var matchItems []*_struct.Value
|
||||
// match ingress
|
||||
for _, ing := range rule.Ingress {
|
||||
@@ -882,6 +916,7 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
})
|
||||
}
|
||||
if len(matchItems) > 0 {
|
||||
validRule = true
|
||||
v.StructValue.Fields["_match_route_"] = &_struct.Value{
|
||||
Kind: &_struct.Value_ListValue{
|
||||
ListValue: &_struct.ListValue{
|
||||
@@ -889,12 +924,9 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
},
|
||||
},
|
||||
}
|
||||
ruleValues = append(ruleValues, &_struct.Value{
|
||||
Kind: v,
|
||||
})
|
||||
continue
|
||||
}
|
||||
// match service
|
||||
matchItems = nil
|
||||
for _, service := range rule.Service {
|
||||
matchItems = append(matchItems, &_struct.Value{
|
||||
Kind: &_struct.Value_StringValue{
|
||||
@@ -903,6 +935,7 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
})
|
||||
}
|
||||
if len(matchItems) > 0 {
|
||||
validRule = true
|
||||
v.StructValue.Fields["_match_service_"] = &_struct.Value{
|
||||
Kind: &_struct.Value_ListValue{
|
||||
ListValue: &_struct.ListValue{
|
||||
@@ -910,12 +943,9 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
},
|
||||
},
|
||||
}
|
||||
ruleValues = append(ruleValues, &_struct.Value{
|
||||
Kind: v,
|
||||
})
|
||||
continue
|
||||
}
|
||||
// match domain
|
||||
matchItems = nil
|
||||
for _, domain := range rule.Domain {
|
||||
matchItems = append(matchItems, &_struct.Value{
|
||||
Kind: &_struct.Value_StringValue{
|
||||
@@ -923,19 +953,23 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
},
|
||||
})
|
||||
}
|
||||
if len(matchItems) == 0 {
|
||||
if len(matchItems) > 0 {
|
||||
validRule = true
|
||||
v.StructValue.Fields["_match_domain_"] = &_struct.Value{
|
||||
Kind: &_struct.Value_ListValue{
|
||||
ListValue: &_struct.ListValue{
|
||||
Values: matchItems,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
if validRule {
|
||||
ruleValues = append(ruleValues, &_struct.Value{
|
||||
Kind: v,
|
||||
})
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid match rule has no match condition, rule:%v", rule)
|
||||
}
|
||||
v.StructValue.Fields["_match_domain_"] = &_struct.Value{
|
||||
Kind: &_struct.Value_ListValue{
|
||||
ListValue: &_struct.ListValue{
|
||||
Values: matchItems,
|
||||
},
|
||||
},
|
||||
}
|
||||
ruleValues = append(ruleValues, &_struct.Value{
|
||||
Kind: v,
|
||||
})
|
||||
}
|
||||
if len(ruleValues) > 0 {
|
||||
hasValidRule = true
|
||||
@@ -1034,16 +1068,27 @@ func (m *IngressConfig) AddOrUpdateMcpBridge(clusterNamespacedName util.ClusterN
|
||||
}
|
||||
if m.RegistryReconciler == nil {
|
||||
m.RegistryReconciler = reconcile.NewReconciler(func() {
|
||||
metadata := config.Meta{
|
||||
seMetadata := config.Meta{
|
||||
Name: "mcpbridge-serviceentry",
|
||||
Namespace: m.namespace,
|
||||
GroupVersionKind: gvk.ServiceEntry,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
drMetadata := config.Meta{
|
||||
Name: "mcpbridge-destinationrule",
|
||||
Namespace: m.namespace,
|
||||
GroupVersionKind: gvk.DestinationRule,
|
||||
// Set this label so that we do not compare configs and just push.
|
||||
Labels: map[string]string{constants.AlwaysPushLabel: "true"},
|
||||
}
|
||||
for _, f := range m.serviceEntryHandlers {
|
||||
IngressLog.Debug("McpBridge triggerd serviceEntry update")
|
||||
f(config.Config{Meta: metadata}, config.Config{Meta: metadata}, istiomodel.EventUpdate)
|
||||
f(config.Config{Meta: seMetadata}, config.Config{Meta: seMetadata}, istiomodel.EventUpdate)
|
||||
}
|
||||
for _, f := range m.destinationRuleHandlers {
|
||||
IngressLog.Debug("McpBridge triggerd destinationRule update")
|
||||
f(config.Config{Meta: drMetadata}, config.Config{Meta: drMetadata}, istiomodel.EventUpdate)
|
||||
}
|
||||
}, m.localKubeClient, m.namespace)
|
||||
}
|
||||
@@ -1489,7 +1534,7 @@ func constructBasicAuthEnvoyFilter(rules *common.BasicAuthRules, namespace strin
|
||||
}, nil
|
||||
}
|
||||
|
||||
func QueryByName(serviceEntries []*memory.ServiceEntryWrapper, serviceName string) (*memory.ServiceEntryWrapper, error) {
|
||||
func QueryByName(serviceEntries []*memory.ServiceWrapper, serviceName string) (*memory.ServiceWrapper, error) {
|
||||
IngressLog.Infof("Found http2rpc serviceEntries %s", serviceEntries)
|
||||
for _, se := range serviceEntries {
|
||||
if se.ServiceName == serviceName {
|
||||
@@ -1499,7 +1544,7 @@ func QueryByName(serviceEntries []*memory.ServiceEntryWrapper, serviceName strin
|
||||
return nil, fmt.Errorf("can't find ServiceEntry by serviceName:%v", serviceName)
|
||||
}
|
||||
|
||||
func QueryRpcServiceVersion(serviceEntry *memory.ServiceEntryWrapper, serviceName string) (string, error) {
|
||||
func QueryRpcServiceVersion(serviceEntry *memory.ServiceWrapper, serviceName string) (string, error) {
|
||||
IngressLog.Infof("Found http2rpc serviceEntry %s", serviceEntry)
|
||||
IngressLog.Infof("Found http2rpc ServiceEntry %s", serviceEntry.ServiceEntry)
|
||||
IngressLog.Infof("Found http2rpc WorkloadSelector %s", serviceEntry.ServiceEntry.WorkloadSelector)
|
||||
|
||||
@@ -493,7 +493,7 @@ func (m *KIngressConfig) HasSynced() bool {
|
||||
defer m.mutex.RUnlock()
|
||||
|
||||
for _, remoteIngressController := range m.remoteIngressControllers {
|
||||
IngressLog.Info("In Kingress Synced.", remoteIngressController)
|
||||
IngressLog.Info("In Kingress Synced.")
|
||||
if !remoteIngressController.HasSynced() {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ type Ingress struct {
|
||||
|
||||
Auth *AuthConfig
|
||||
|
||||
Mirror *MirrorConfig
|
||||
|
||||
Destination *DestinationConfig
|
||||
|
||||
IgnoreCase *IgnoreCaseConfig
|
||||
@@ -161,6 +163,7 @@ func NewAnnotationHandlerManager() AnnotationHandler {
|
||||
localRateLimit{},
|
||||
fallback{},
|
||||
auth{},
|
||||
mirror{},
|
||||
destination{},
|
||||
ignoreCaseMatching{},
|
||||
match{},
|
||||
@@ -182,6 +185,7 @@ func NewAnnotationHandlerManager() AnnotationHandler {
|
||||
retry{},
|
||||
localRateLimit{},
|
||||
fallback{},
|
||||
mirror{},
|
||||
ignoreCaseMatching{},
|
||||
match{},
|
||||
headerControl{},
|
||||
|
||||
118
pkg/ingress/kube/annotations/mirror.go
Normal file
118
pkg/ingress/kube/annotations/mirror.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2023 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 annotations
|
||||
|
||||
import (
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
wrappers "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
)
|
||||
|
||||
const (
|
||||
mirrorTargetService = "mirror-target-service"
|
||||
mirrorPercentage = "mirror-percentage"
|
||||
)
|
||||
|
||||
var (
|
||||
_ Parser = &mirror{}
|
||||
_ RouteHandler = &mirror{}
|
||||
)
|
||||
|
||||
type MirrorConfig struct {
|
||||
util.ServiceInfo
|
||||
Percentage *wrappers.DoubleValue
|
||||
}
|
||||
|
||||
type mirror struct{}
|
||||
|
||||
func (m mirror) Parse(annotations Annotations, config *Ingress, globalContext *GlobalContext) error {
|
||||
if !needMirror(annotations) {
|
||||
return nil
|
||||
}
|
||||
|
||||
target, err := annotations.ParseStringASAP(mirrorTargetService)
|
||||
if err != nil {
|
||||
IngressLog.Errorf("Get mirror target service fail, err: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
serviceInfo, err := util.ParseServiceInfo(target, config.Namespace)
|
||||
if err != nil {
|
||||
IngressLog.Errorf("Get mirror target service fail, err: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
serviceLister, exist := globalContext.ClusterServiceList[config.ClusterId]
|
||||
if !exist {
|
||||
IngressLog.Errorf("service lister of cluster %s doesn't exist", config.ClusterId)
|
||||
return nil
|
||||
}
|
||||
|
||||
service, err := serviceLister.Services(serviceInfo.Namespace).Get(serviceInfo.Name)
|
||||
if err != nil {
|
||||
IngressLog.Errorf("Mirror service %s/%s within ingress %s/%s is not found, with err: %v",
|
||||
serviceInfo.Namespace, serviceInfo.Name, config.Namespace, config.Name, err)
|
||||
return nil
|
||||
}
|
||||
if service == nil {
|
||||
IngressLog.Errorf("service %s/%s within ingress %s/%s is empty value",
|
||||
serviceInfo.Namespace, serviceInfo.Name, config.Namespace, config.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
if serviceInfo.Port == 0 {
|
||||
// Use the first port
|
||||
serviceInfo.Port = uint32(service.Spec.Ports[0].Port)
|
||||
}
|
||||
|
||||
var percentage *wrappers.DoubleValue
|
||||
if value, err := annotations.ParseIntASAP(mirrorPercentage); err == nil {
|
||||
if value < 100 {
|
||||
percentage = &wrappers.DoubleValue{
|
||||
Value: float64(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.Mirror = &MirrorConfig{
|
||||
ServiceInfo: serviceInfo,
|
||||
Percentage: percentage,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m mirror) ApplyRoute(route *networking.HTTPRoute, config *Ingress) {
|
||||
if config.Mirror == nil {
|
||||
return
|
||||
}
|
||||
|
||||
route.Mirror = &networking.Destination{
|
||||
Host: util.CreateServiceFQDN(config.Mirror.Namespace, config.Mirror.Name),
|
||||
Port: &networking.PortSelector{
|
||||
Number: config.Mirror.Port,
|
||||
},
|
||||
}
|
||||
|
||||
if config.Mirror.Percentage != nil {
|
||||
route.MirrorPercentage = &networking.Percent{
|
||||
Value: config.Mirror.Percentage.GetValue(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func needMirror(annotations Annotations) bool {
|
||||
return annotations.HasASAP(mirrorTargetService)
|
||||
}
|
||||
163
pkg/ingress/kube/annotations/mirror_test.go
Normal file
163
pkg/ingress/kube/annotations/mirror_test.go
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed 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 annotations
|
||||
|
||||
import (
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
"github.com/golang/protobuf/proto"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseMirror(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input []map[string]string
|
||||
expect *MirrorConfig
|
||||
}{
|
||||
{},
|
||||
{
|
||||
input: []map[string]string{
|
||||
{buildHigressAnnotationKey(mirrorTargetService): "test/app"},
|
||||
{buildNginxAnnotationKey(mirrorTargetService): "test/app"},
|
||||
},
|
||||
expect: &MirrorConfig{
|
||||
ServiceInfo: util.ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Namespace: "test",
|
||||
Name: "app",
|
||||
},
|
||||
Port: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: []map[string]string{
|
||||
{buildHigressAnnotationKey(mirrorTargetService): "test/app:8080"},
|
||||
{buildNginxAnnotationKey(mirrorTargetService): "test/app:8080"},
|
||||
},
|
||||
expect: &MirrorConfig{
|
||||
ServiceInfo: util.ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Namespace: "test",
|
||||
Name: "app",
|
||||
},
|
||||
Port: 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: []map[string]string{
|
||||
{buildHigressAnnotationKey(mirrorTargetService): "test/app:hi"},
|
||||
{buildNginxAnnotationKey(mirrorTargetService): "test/app:hi"},
|
||||
},
|
||||
expect: &MirrorConfig{
|
||||
ServiceInfo: util.ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Namespace: "test",
|
||||
Name: "app",
|
||||
},
|
||||
Port: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: []map[string]string{
|
||||
{buildHigressAnnotationKey(mirrorTargetService): "test/app"},
|
||||
{buildNginxAnnotationKey(mirrorTargetService): "test/app"},
|
||||
},
|
||||
expect: &MirrorConfig{
|
||||
ServiceInfo: util.ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Namespace: "test",
|
||||
Name: "app",
|
||||
},
|
||||
Port: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mirror := mirror{}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run("", func(t *testing.T) {
|
||||
config := &Ingress{
|
||||
Meta: Meta{
|
||||
Namespace: "test",
|
||||
ClusterId: "cluster",
|
||||
},
|
||||
}
|
||||
globalContext, cancel := initGlobalContextForService()
|
||||
defer cancel()
|
||||
|
||||
for _, in := range testCase.input {
|
||||
_ = mirror.Parse(in, config, globalContext)
|
||||
if !reflect.DeepEqual(testCase.expect, config.Mirror) {
|
||||
t.Log("expect:", *testCase.expect)
|
||||
t.Log("actual:", *config.Mirror)
|
||||
t.Fatal("Should be equal")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMirror_ApplyRoute(t *testing.T) {
|
||||
testCases := []struct {
|
||||
config *Ingress
|
||||
input *networking.HTTPRoute
|
||||
expect *networking.HTTPRoute
|
||||
}{
|
||||
{
|
||||
config: &Ingress{},
|
||||
input: &networking.HTTPRoute{},
|
||||
expect: &networking.HTTPRoute{},
|
||||
},
|
||||
{
|
||||
config: &Ingress{
|
||||
Mirror: &MirrorConfig{
|
||||
ServiceInfo: util.ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Port: 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
input: &networking.HTTPRoute{},
|
||||
expect: &networking.HTTPRoute{
|
||||
Mirror: &networking.Destination{
|
||||
Host: "test.default.svc.cluster.local",
|
||||
Port: &networking.PortSelector{
|
||||
Number: 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mirror := mirror{}
|
||||
for _, testCase := range testCases {
|
||||
t.Run("", func(t *testing.T) {
|
||||
mirror.ApplyRoute(testCase.input, testCase.config)
|
||||
if !proto.Equal(testCase.input, testCase.expect) {
|
||||
t.Fatal("Must be equal.")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,15 @@ type WrapperGateway struct {
|
||||
Host string
|
||||
}
|
||||
|
||||
func CreateMcpServiceKey(host string, portNumber int32) ServiceKey {
|
||||
return ServiceKey{
|
||||
Namespace: "mcp",
|
||||
Name: host,
|
||||
ServiceFQDN: host,
|
||||
Port: portNumber,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WrapperGateway) IsHTTPS() bool {
|
||||
if w.Gateway == nil || len(w.Gateway.Servers) == 0 {
|
||||
return false
|
||||
|
||||
@@ -255,6 +255,59 @@ func (t *TracingController) ConstructEnvoyFilters() ([]*config.Config, error) {
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
configPatches := []*networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||
{
|
||||
ApplyTo: networking.EnvoyFilter_NETWORK_FILTER,
|
||||
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||
Context: networking.EnvoyFilter_GATEWAY,
|
||||
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||
Name: "envoy.filters.network.http_connection_manager",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||
Value: util.BuildPatchStruct(tracingConfig),
|
||||
},
|
||||
},
|
||||
{
|
||||
ApplyTo: networking.EnvoyFilter_HTTP_FILTER,
|
||||
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||
Context: networking.EnvoyFilter_GATEWAY,
|
||||
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||
Name: "envoy.filters.network.http_connection_manager",
|
||||
SubFilter: &networking.EnvoyFilter_ListenerMatch_SubFilterMatch{
|
||||
Name: "envoy.filters.http.router",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||
Value: util.BuildPatchStruct(`{
|
||||
"name":"envoy.filters.http.router",
|
||||
"typed_config":{
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||
"start_child_span": true
|
||||
}
|
||||
}`),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
patches := t.constructTracingExtendPatches(tracing)
|
||||
configPatches = append(configPatches, patches...)
|
||||
|
||||
config := &config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.EnvoyFilter,
|
||||
@@ -262,55 +315,7 @@ func (t *TracingController) ConstructEnvoyFilters() ([]*config.Config, error) {
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: &networking.EnvoyFilter{
|
||||
ConfigPatches: []*networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||
{
|
||||
ApplyTo: networking.EnvoyFilter_NETWORK_FILTER,
|
||||
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||
Context: networking.EnvoyFilter_GATEWAY,
|
||||
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||
Name: "envoy.filters.network.http_connection_manager",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||
Value: util.BuildPatchStruct(tracingConfig),
|
||||
},
|
||||
},
|
||||
{
|
||||
ApplyTo: networking.EnvoyFilter_HTTP_FILTER,
|
||||
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||
Context: networking.EnvoyFilter_GATEWAY,
|
||||
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||
Name: "envoy.filters.network.http_connection_manager",
|
||||
SubFilter: &networking.EnvoyFilter_ListenerMatch_SubFilterMatch{
|
||||
Name: "envoy.filters.http.router",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||
Value: util.BuildPatchStruct(`{
|
||||
"name":"envoy.filters.http.router",
|
||||
"typed_config":{
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||
"start_child_span": true
|
||||
}
|
||||
}`),
|
||||
},
|
||||
},
|
||||
},
|
||||
ConfigPatches: configPatches,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -318,6 +323,52 @@ func (t *TracingController) ConstructEnvoyFilters() ([]*config.Config, error) {
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
func tracingClusterName(port, service string) string {
|
||||
return fmt.Sprintf("outbound|%s||%s", port, service)
|
||||
}
|
||||
|
||||
func (t *TracingController) constructHTTP2ProtocolOptionsPatch(port, service string) *networking.EnvoyFilter_EnvoyConfigObjectPatch {
|
||||
http2ProtocolOptions := `{"typed_extension_protocol_options": {
|
||||
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
|
||||
"explicit_http_config": {
|
||||
"http2_protocol_options": {}
|
||||
}
|
||||
}
|
||||
}}`
|
||||
|
||||
return &networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||
ApplyTo: networking.EnvoyFilter_CLUSTER,
|
||||
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||
Context: networking.EnvoyFilter_GATEWAY,
|
||||
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Cluster{
|
||||
Cluster: &networking.EnvoyFilter_ClusterMatch{
|
||||
Name: tracingClusterName(port, service),
|
||||
},
|
||||
},
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||
Value: util.BuildPatchStruct(http2ProtocolOptions),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TracingController) constructTracingExtendPatches(tracing *Tracing) []*networking.EnvoyFilter_EnvoyConfigObjectPatch {
|
||||
if tracing == nil {
|
||||
return nil
|
||||
}
|
||||
var patches []*networking.EnvoyFilter_EnvoyConfigObjectPatch
|
||||
if skywalking := tracing.Skywalking; skywalking != nil {
|
||||
patches = append(patches, t.constructHTTP2ProtocolOptionsPatch(skywalking.Port, skywalking.Service))
|
||||
}
|
||||
if otel := tracing.OpenTelemetry; otel != nil {
|
||||
patches = append(patches, t.constructHTTP2ProtocolOptionsPatch(otel.Port, otel.Service))
|
||||
}
|
||||
|
||||
return patches
|
||||
}
|
||||
|
||||
func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace string) string {
|
||||
tracingConfig := ""
|
||||
timeout := float32(tracing.Timeout) / 1000
|
||||
@@ -338,7 +389,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
},
|
||||
"grpc_service": {
|
||||
"envoy_grpc": {
|
||||
"cluster_name": "outbound|%s||%s"
|
||||
"cluster_name": "%s"
|
||||
},
|
||||
"timeout": "%.3fs"
|
||||
}
|
||||
@@ -349,7 +400,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, namespace, skywalking.AccessToken, skywalking.Port, skywalking.Service, timeout, tracing.Sampling)
|
||||
}`, namespace, skywalking.AccessToken, tracingClusterName(skywalking.Port, skywalking.Service), timeout, tracing.Sampling)
|
||||
}
|
||||
|
||||
if tracing.Zipkin != nil {
|
||||
@@ -363,7 +414,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
"name": "envoy.tracers.zipkin",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
|
||||
"collector_cluster": "outbound|%s||%s",
|
||||
"collector_cluster": "%s",
|
||||
"collector_endpoint": "/api/v2/spans",
|
||||
"collector_hostname": "higress-gateway",
|
||||
"collector_endpoint_version": "HTTP_JSON",
|
||||
@@ -375,7 +426,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, zipkin.Port, zipkin.Service, tracing.Sampling)
|
||||
}`, tracingClusterName(zipkin.Port, zipkin.Service), tracing.Sampling)
|
||||
}
|
||||
|
||||
if tracing.OpenTelemetry != nil {
|
||||
@@ -392,7 +443,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
"service_name": "higress-gateway.%s",
|
||||
"grpc_service": {
|
||||
"envoy_grpc": {
|
||||
"cluster_name": "outbound|%s||%s"
|
||||
"cluster_name": "%s"
|
||||
},
|
||||
"timeout": "%.3fs"
|
||||
}
|
||||
@@ -403,7 +454,7 @@ func (t *TracingController) constructTracingTracer(tracing *Tracing, namespace s
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, namespace, opentelemetry.Port, opentelemetry.Service, timeout, tracing.Sampling)
|
||||
}`, namespace, tracingClusterName(opentelemetry.Port, opentelemetry.Service), timeout, tracing.Sampling)
|
||||
}
|
||||
return tracingConfig
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
kubecredentials "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
kubecontroller "istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
@@ -48,6 +49,7 @@ type gatewayController struct {
|
||||
store model.ConfigStoreController
|
||||
credsController credentials.MulticlusterController
|
||||
istioController *istiogateway.Controller
|
||||
statusManager *status.Manager
|
||||
|
||||
resourceUpToDate atomic.Bool
|
||||
}
|
||||
@@ -76,9 +78,10 @@ func NewController(client kube.Client, options common.Options) common.GatewayCon
|
||||
istioController.DefaultGatewaySelector = map[string]string{options.GatewaySelectorKey: options.GatewaySelectorValue}
|
||||
}
|
||||
|
||||
var statusManager *status.Manager = nil
|
||||
if options.EnableStatus {
|
||||
// TODO: Add status sync support
|
||||
//istioController.SetStatusWrite(true,)
|
||||
statusManager = status.NewManager(store)
|
||||
istioController.SetStatusWrite(true, statusManager)
|
||||
} else {
|
||||
IngressLog.Infof("Disable status update for cluster %s", clusterId)
|
||||
}
|
||||
@@ -87,6 +90,7 @@ func NewController(client kube.Client, options common.Options) common.GatewayCon
|
||||
store: store,
|
||||
credsController: credsController,
|
||||
istioController: istioController,
|
||||
statusManager: statusManager,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +152,9 @@ func (g *gatewayController) Run(stop <-chan struct{}) {
|
||||
})
|
||||
go g.store.Run(stop)
|
||||
go g.istioController.Run(stop)
|
||||
if g.statusManager != nil {
|
||||
g.statusManager.Start(stop)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gatewayController) SetWatchErrorHandler(f func(r *cache.Reflector, err error)) error {
|
||||
|
||||
@@ -15,26 +15,37 @@
|
||||
package istio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
serviceRegistryKube "istio.io/istio/pilot/pkg/serviceregistry/kube"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config/host"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// GatewayContext contains a minimal subset of push context functionality to be exposed to GatewayAPIControllers
|
||||
type GatewayContext struct {
|
||||
ps *model.PushContext
|
||||
// Start - Updated by Higress
|
||||
client kube.Client
|
||||
domainSuffix string
|
||||
clusterID cluster.ID
|
||||
// End - Updated by Higress
|
||||
}
|
||||
|
||||
func NewGatewayContext(ps *model.PushContext) GatewayContext {
|
||||
return GatewayContext{ps}
|
||||
// Start - Updated by Higress
|
||||
|
||||
func NewGatewayContext(ps *model.PushContext, client kube.Client, domainSuffix string, clusterID cluster.ID) GatewayContext {
|
||||
return GatewayContext{ps, client, domainSuffix, clusterID}
|
||||
}
|
||||
|
||||
// ResolveGatewayInstances attempts to resolve all instances that a gateway will be exposed on.
|
||||
@@ -59,26 +70,20 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
foundExternal := sets.New[string]()
|
||||
foundPending := sets.New[string]()
|
||||
warnings := []string{}
|
||||
|
||||
// Cache endpoints to reduce redundant queries
|
||||
endpointsCache := make(map[string]*corev1.Endpoints)
|
||||
|
||||
for _, g := range gwsvcs {
|
||||
svc, f := gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(g)][namespace]
|
||||
if !f {
|
||||
otherNamespaces := []string{}
|
||||
for ns := range gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(g)] {
|
||||
otherNamespaces = append(otherNamespaces, `"`+ns+`"`) // Wrap in quotes for output
|
||||
}
|
||||
if len(otherNamespaces) > 0 {
|
||||
sort.Strings(otherNamespaces)
|
||||
warnings = append(warnings, fmt.Sprintf("hostname %q not found in namespace %q, but it was found in namespace(s) %v",
|
||||
g, namespace, strings.Join(otherNamespaces, ", ")))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("hostname %q not found", g))
|
||||
}
|
||||
svc := gc.GetService(g, namespace, gvk.Service.Kind)
|
||||
if svc == nil {
|
||||
warnings = append(warnings, fmt.Sprintf("hostname %q not found", g))
|
||||
continue
|
||||
}
|
||||
svcKey := svc.Key()
|
||||
|
||||
for port := range ports {
|
||||
instances := gc.ps.ServiceInstancesByPort(svc, port, nil)
|
||||
if len(instances) > 0 {
|
||||
exists := checkServicePortExists(svc, port)
|
||||
if exists {
|
||||
foundInternal.Insert(fmt.Sprintf("%s:%d", g, port))
|
||||
if svc.Attributes.ClusterExternalAddresses.Len() > 0 {
|
||||
// Fetch external IPs from all clusters
|
||||
@@ -92,22 +97,30 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
instancesByPort := gc.ps.ServiceInstances(svcKey)
|
||||
if instancesEmpty(instancesByPort) {
|
||||
endpoints, ok := endpointsCache[g]
|
||||
if !ok {
|
||||
endpoints = gc.GetEndpoints(g, namespace)
|
||||
endpointsCache[g] = endpoints
|
||||
}
|
||||
|
||||
if endpoints == nil {
|
||||
warnings = append(warnings, fmt.Sprintf("no instances found for hostname %q", g))
|
||||
} else {
|
||||
hintPort := sets.New[string]()
|
||||
for _, instances := range instancesByPort {
|
||||
for _, i := range instances {
|
||||
if i.Endpoint.EndpointPort == uint32(port) {
|
||||
hintPort.Insert(strconv.Itoa(i.ServicePort.Port))
|
||||
hintWorkloadPort := false
|
||||
for _, subset := range endpoints.Subsets {
|
||||
for _, subSetPort := range subset.Ports {
|
||||
if subSetPort.Port == int32(port) {
|
||||
hintWorkloadPort = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hintWorkloadPort {
|
||||
break
|
||||
}
|
||||
}
|
||||
if hintPort.Len() > 0 {
|
||||
if hintWorkloadPort {
|
||||
warnings = append(warnings, fmt.Sprintf(
|
||||
"port %d not found for hostname %q (hint: the service port should be specified, not the workload port. Did you mean one of these ports: %v?)",
|
||||
port, g, sets.SortedList(hintPort)))
|
||||
"port %d not found for hostname %q (hint: the service port should be specified, not the workload port", port, g))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("port %d not found for hostname %q", port, g))
|
||||
}
|
||||
@@ -119,15 +132,60 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
return sets.SortedList(foundInternal), sets.SortedList(foundExternal), sets.SortedList(foundPending), warnings
|
||||
}
|
||||
|
||||
func (gc GatewayContext) GetService(hostname, namespace string) *model.Service {
|
||||
return gc.ps.ServiceIndex.HostnameAndNamespace[host.Name(hostname)][namespace]
|
||||
func (gc GatewayContext) GetService(hostname, namespace, kind string) *model.Service {
|
||||
// Currently only supports type Kubernetes Service
|
||||
if kind != gvk.Service.Kind {
|
||||
log.Warnf("Unsupported kind: expected 'Service', but got '%s'", kind)
|
||||
return nil
|
||||
}
|
||||
serviceName := extractServiceName(hostname)
|
||||
|
||||
svc, err := gc.client.Kube().CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
log.Errorf("failed to get service (serviceName: %s, namespace: %s): %v", serviceName, namespace, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return serviceRegistryKube.ConvertService(*svc, gc.domainSuffix, gc.clusterID)
|
||||
}
|
||||
|
||||
func instancesEmpty(m map[int][]*model.ServiceInstance) bool {
|
||||
for _, instances := range m {
|
||||
if len(instances) > 0 {
|
||||
return false
|
||||
func (gc GatewayContext) GetEndpoints(hostname, namespace string) *corev1.Endpoints {
|
||||
serviceName := extractServiceName(hostname)
|
||||
|
||||
endpoints, err := gc.client.Kube().CoreV1().Endpoints(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
log.Errorf("failed to get endpoints (serviceName: %s, namespace: %s): %v", serviceName, namespace, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
func checkServicePortExists(svc *model.Service, port int) bool {
|
||||
if svc == nil {
|
||||
return false
|
||||
}
|
||||
for _, svcPort := range svc.Ports {
|
||||
if port == svcPort.Port {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func extractServiceName(hostName string) string {
|
||||
parts := strings.Split(hostName, ".")
|
||||
if len(parts) >= 4 {
|
||||
return parts[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// End - Updated by Higress
|
||||
|
||||
@@ -201,7 +201,9 @@ func (c *Controller) Reconcile(ps *model.PushContext) error {
|
||||
ReferenceGrant: referenceGrant,
|
||||
DefaultGatewaySelector: c.DefaultGatewaySelector,
|
||||
Domain: c.domain,
|
||||
Context: NewGatewayContext(ps),
|
||||
// Start - Updated by Higress
|
||||
Context: NewGatewayContext(ps, c.client, c.domain, c.cluster),
|
||||
// End - Updated by Higress
|
||||
}
|
||||
|
||||
if !input.hasResources() {
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"strings"
|
||||
|
||||
higressconfig "github.com/alibaba/higress/pkg/config"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
istio "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
@@ -1168,7 +1169,7 @@ func buildDestination(ctx configContext, to k8s.BackendRef, ns string, enforceRe
|
||||
return nil, &ConfigError{Reason: InvalidDestination, Message: "serviceName invalid; the name of the Service must be used, not the hostname."}
|
||||
}
|
||||
hostname := fmt.Sprintf("%s.%s.svc.%s", to.Name, namespace, ctx.Domain)
|
||||
if ctx.Context.GetService(hostname, namespace) == nil {
|
||||
if ctx.Context.GetService(hostname, namespace, gvk.Service.Kind) == nil {
|
||||
invalidBackendErr = &ConfigError{Reason: InvalidDestinationNotFound, Message: fmt.Sprintf("backend(%s) not found", hostname)}
|
||||
}
|
||||
return &istio.Destination{
|
||||
@@ -1192,7 +1193,7 @@ func buildDestination(ctx configContext, to k8s.BackendRef, ns string, enforceRe
|
||||
if strings.Contains(string(to.Name), ".") {
|
||||
return nil, &ConfigError{Reason: InvalidDestination, Message: "serviceName invalid; the name of the Service must be used, not the hostname."}
|
||||
}
|
||||
if ctx.Context.GetService(hostname, namespace) == nil {
|
||||
if ctx.Context.GetService(hostname, namespace, "ServiceImport") == nil {
|
||||
invalidBackendErr = &ConfigError{Reason: InvalidDestinationNotFound, Message: fmt.Sprintf("backend(%s) not found", hostname)}
|
||||
}
|
||||
return &istio.Destination{
|
||||
@@ -1210,7 +1211,7 @@ func buildDestination(ctx configContext, to k8s.BackendRef, ns string, enforceRe
|
||||
return nil, &ConfigError{Reason: InvalidDestination, Message: "namespace may not be set with Hostname type"}
|
||||
}
|
||||
hostname := string(to.Name)
|
||||
if ctx.Context.GetService(hostname, namespace) == nil {
|
||||
if ctx.Context.GetService(hostname, namespace, "Hostname") == nil {
|
||||
invalidBackendErr = &ConfigError{Reason: InvalidDestinationNotFound, Message: fmt.Sprintf("backend(%s) not found", hostname)}
|
||||
}
|
||||
return &istio.Destination{
|
||||
@@ -1880,7 +1881,7 @@ func extractGatewayServices(r GatewayResources, kgw *k8s.GatewaySpec, obj config
|
||||
if len(name) > 0 {
|
||||
return []string{fmt.Sprintf("%s.%s.svc.%v", name, obj.Namespace, r.Domain)}, false, nil
|
||||
}
|
||||
return []string{}, true, nil
|
||||
return []string{fmt.Sprintf("%s.%s.svc.%s", higressconfig.GatewayName, higressconfig.PodNamespace, util.GetDomainSuffix())}, true, nil
|
||||
}
|
||||
gatewayServices := []string{}
|
||||
skippedAddresses := []string{}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package istio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
@@ -25,6 +26,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"istio.io/istio/pilot/pkg/config/kube/crd"
|
||||
credentials "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
@@ -47,7 +49,8 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var ports = []*model.Port{
|
||||
// Start - Updated by Higress
|
||||
var ports = []corev1.ServicePort{
|
||||
{
|
||||
Name: "http",
|
||||
Port: 80,
|
||||
@@ -64,232 +67,291 @@ var defaultGatewaySelector = map[string]string{
|
||||
"higress": "higress-system-higress-gateway",
|
||||
}
|
||||
|
||||
var services = []*model.Service{
|
||||
var services = []corev1.Service{
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "higress-gateway",
|
||||
Namespace: "higress-system",
|
||||
ClusterExternalAddresses: &model.AddressMap{
|
||||
Addresses: map[cluster.ID][]string{
|
||||
"Kubernetes": {"1.2.3.4"},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
ExternalIPs: []string{"1.2.3.4"},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "example.com",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-apple",
|
||||
Namespace: "apple",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-banana",
|
||||
Namespace: "banana",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-second",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-wildcard",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo-svc",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-other",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "example",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "echo",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin",
|
||||
Namespace: "cert",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-svc",
|
||||
Namespace: "service",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "google.com",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc2",
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc2",
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc1",
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc3",
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc4",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin",
|
||||
Namespace: "group-namespace1",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin",
|
||||
Namespace: "group-namespace2",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-zero",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-mirror",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-alt",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "higress-controller",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "echo",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httpbin-bad",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var endpoints = []corev1.Endpoints{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "higress-gateway",
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Subsets: []corev1.EndpointSubset{
|
||||
{
|
||||
Ports: []corev1.EndpointPort{
|
||||
{
|
||||
Port: 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-gateway.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "example.com",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "apple",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-apple.apple.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "banana",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-banana.banana.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-second.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-wildcard.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "foo-svc.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-other.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "example.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "cert",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.cert.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "service",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "my-svc.service.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "google.com",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc2.allowed-1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc2.allowed-2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc1.allowed-1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "allowed-2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc3.allowed-2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "svc4.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "group-namespace1",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.group-namespace1.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "group-namespace2",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.group-namespace2.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-zero.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-mirror.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-foo.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-alt.default.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-controller.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "higress-controller.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "higress-system",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "echo.higress-system.svc.domain.suffix",
|
||||
},
|
||||
{
|
||||
Attributes: model.ServiceAttributes{
|
||||
Namespace: "default",
|
||||
},
|
||||
Ports: ports,
|
||||
Hostname: "httpbin-bad.default.svc.domain.suffix",
|
||||
},
|
||||
}
|
||||
|
||||
// End - Updated by Higress
|
||||
|
||||
var (
|
||||
// https://github.com/kubernetes/kubernetes/blob/v1.25.4/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_tls_test.go#L31
|
||||
rsaCertPEM = `-----BEGIN CERTIFICATE-----
|
||||
@@ -364,6 +426,21 @@ func init() {
|
||||
|
||||
func TestConvertResources(t *testing.T) {
|
||||
validator := crdvalidation.NewIstioValidator(t)
|
||||
|
||||
// Start - Updated by Higress
|
||||
client := kube.NewFakeClient()
|
||||
for _, svc := range services {
|
||||
if _, err := client.Kube().CoreV1().Services(svc.Namespace).Create(context.TODO(), &svc, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
for _, endpoint := range endpoints {
|
||||
if _, err := client.Kube().CoreV1().Endpoints(endpoint.Namespace).Create(context.TODO(), &endpoint, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
// End - Updated by Higress
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
}{
|
||||
@@ -374,38 +451,23 @@ func TestConvertResources(t *testing.T) {
|
||||
{"weighted"},
|
||||
{"zero"},
|
||||
{"invalid"},
|
||||
{"multi-gateway"},
|
||||
// 目前仅支持 type 为 Hostname 和 ServiceImport
|
||||
//{"multi-gateway"},
|
||||
{"delegated"},
|
||||
{"route-binding"},
|
||||
{"reference-policy-tls"},
|
||||
{"reference-policy-service"},
|
||||
{"serviceentry"},
|
||||
//{"serviceentry"},
|
||||
{"alias"},
|
||||
{"mcs"},
|
||||
//{"mcs"},
|
||||
{"route-precedence"},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
input := readConfig(t, fmt.Sprintf("testdata/%s.yaml", tt.name), validator)
|
||||
// Setup a few preconfigured services
|
||||
instances := []*model.ServiceInstance{}
|
||||
for _, svc := range services {
|
||||
instances = append(instances, &model.ServiceInstance{
|
||||
Service: svc,
|
||||
ServicePort: ports[0],
|
||||
Endpoint: &model.IstioEndpoint{EndpointPort: 8080},
|
||||
}, &model.ServiceInstance{
|
||||
Service: svc,
|
||||
ServicePort: ports[1],
|
||||
Endpoint: &model.IstioEndpoint{},
|
||||
})
|
||||
}
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{
|
||||
Services: services,
|
||||
Instances: instances,
|
||||
})
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
|
||||
kr := splitInput(t, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
kr.Context = NewGatewayContext(cg.PushContext(), client, "domain.suffix", "")
|
||||
output := convertResources(kr)
|
||||
output.AllowedReferences = AllowedReferences{} // Not tested here
|
||||
output.ReferencedNamespaceKeys = nil // Not tested here
|
||||
@@ -427,20 +489,20 @@ func TestConvertResources(t *testing.T) {
|
||||
|
||||
assert.Equal(t, golden, output)
|
||||
|
||||
//outputStatus := getStatus(t, kr.GatewayClass, kr.Gateway, kr.HTTPRoute, kr.TLSRoute, kr.TCPRoute)
|
||||
//goldenStatusFile := fmt.Sprintf("testdata/%s.status.yaml.golden", tt.name)
|
||||
//if util.Refresh() {
|
||||
// if err := os.WriteFile(goldenStatusFile, outputStatus, 0o644); err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
//}
|
||||
//goldenStatus, err := os.ReadFile(goldenStatusFile)
|
||||
//if err != nil {
|
||||
// t.Fatal(err)
|
||||
//}
|
||||
//if diff := cmp.Diff(string(goldenStatus), string(outputStatus)); diff != "" {
|
||||
// t.Fatalf("Diff:\n%s", diff)
|
||||
//}
|
||||
outputStatus := getStatus(t, kr.GatewayClass, kr.Gateway, kr.HTTPRoute, kr.TLSRoute, kr.TCPRoute)
|
||||
goldenStatusFile := fmt.Sprintf("testdata/%s.status.yaml.golden", tt.name)
|
||||
if util.Refresh() {
|
||||
if err := os.WriteFile(goldenStatusFile, outputStatus, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
goldenStatus, err := os.ReadFile(goldenStatusFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff(string(goldenStatus), string(outputStatus)); diff != "" {
|
||||
t.Fatalf("Diff:\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -593,7 +655,7 @@ spec:
|
||||
input := readConfigString(t, tt.config, validator)
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
|
||||
kr := splitInput(t, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
kr.Context = NewGatewayContext(cg.PushContext(), nil, "", "")
|
||||
output := convertResources(kr)
|
||||
c := &Controller{
|
||||
state: output,
|
||||
@@ -814,7 +876,7 @@ func BenchmarkBuildHTTPVirtualServices(b *testing.B) {
|
||||
validator := crdvalidation.NewIstioValidator(b)
|
||||
input := readConfig(b, "testdata/benchmark-httproute.yaml", validator)
|
||||
kr := splitInput(b, input)
|
||||
kr.Context = NewGatewayContext(cg.PushContext())
|
||||
kr.Context = NewGatewayContext(cg.PushContext(), nil, "", "")
|
||||
ctx := configContext{
|
||||
GatewayResources: kr,
|
||||
AllowedReferences: convertReferencePolicies(kr),
|
||||
@@ -857,7 +919,7 @@ func TestExtractGatewayServices(t *testing.T) {
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{},
|
||||
gatewayServices: []string{"higress-gateway.higress-system.svc.cluster.local"},
|
||||
useDefaultService: true,
|
||||
},
|
||||
{
|
||||
@@ -977,7 +1039,7 @@ func TestExtractGatewayServices(t *testing.T) {
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
gatewayServices: []string{},
|
||||
gatewayServices: []string{"higress-gateway.higress-system.svc.cluster.local"},
|
||||
useDefaultService: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -128,8 +128,7 @@ status:
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: port 8080 not found for
|
||||
hostname "higress-gateway.higress-system.svc.domain.suffix" (hint: the service
|
||||
port should be specified, not the workload port. Did you mean one of these ports:
|
||||
[80]?)'
|
||||
port should be specified, not the workload port'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Programmed
|
||||
@@ -163,26 +162,6 @@ status:
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-gateway-address
|
||||
namespace: invalid-gateway-address
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: only Hostname is supported, ignoring [1.2.3.4]
|
||||
reason: UnsupportedAddress
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: Failed to assign to any requested addresses
|
||||
reason: UnsupportedAddress
|
||||
status: "False"
|
||||
type: Programmed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid-cert-kind
|
||||
@@ -477,4 +456,29 @@ status:
|
||||
namespace: higress-system
|
||||
sectionName: fake
|
||||
---
|
||||
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: no-backend
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
parentRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin
|
||||
---
|
||||
|
||||
@@ -55,22 +55,23 @@ spec:
|
||||
hostname: "*.example"
|
||||
port: 8080 # Test service has port 80 with targetPort 8080
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid-gateway-address
|
||||
namespace: invalid-gateway-address
|
||||
spec:
|
||||
gatewayClassName: higress
|
||||
addresses:
|
||||
- value: 1.2.3.4
|
||||
type: istio.io/FakeType
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
#---
|
||||
# Higress 仅支持 addresses type 为 Hostname
|
||||
#apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
#kind: Gateway
|
||||
#metadata:
|
||||
# name: invalid-gateway-address
|
||||
# namespace: invalid-gateway-address
|
||||
#spec:
|
||||
# gatewayClassName: higress
|
||||
# addresses:
|
||||
# - value: 1.2.3.4
|
||||
# type: istio.io/FakeType
|
||||
# listeners:
|
||||
# - name: default
|
||||
# hostname: "*.domain.example"
|
||||
# port: 80
|
||||
# protocol: HTTP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
|
||||
@@ -53,25 +53,6 @@ spec:
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: Gateway/invalid-gateway-address/default.invalid-gateway-address
|
||||
creationTimestamp: null
|
||||
name: invalid-gateway-address-istio-autogenerated-k8s-gateway-default
|
||||
namespace: invalid-gateway-address
|
||||
spec:
|
||||
selector:
|
||||
higress: higress-system-higress-gateway
|
||||
servers:
|
||||
- hosts:
|
||||
- invalid-gateway-address/*.domain.example
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
|
||||
@@ -920,12 +920,7 @@ func (c *controller) storeBackendTrafficPolicy(wrapper *common.WrapperConfig, ba
|
||||
if common.ValidateBackendResource(backend.Resource) && wrapper.AnnotationsConfig.Destination != nil {
|
||||
for _, dest := range wrapper.AnnotationsConfig.Destination.McpDestination {
|
||||
portNumber := dest.Destination.GetPort().GetNumber()
|
||||
serviceKey := common.ServiceKey{
|
||||
Namespace: "mcp",
|
||||
Name: dest.Destination.Host,
|
||||
Port: int32(portNumber),
|
||||
ServiceFQDN: dest.Destination.Host,
|
||||
}
|
||||
serviceKey := common.CreateMcpServiceKey(dest.Destination.Host, int32(portNumber))
|
||||
if _, exist := store[serviceKey]; !exist {
|
||||
if serviceKey.Port != 0 {
|
||||
store[serviceKey] = &common.WrapperTrafficPolicy{
|
||||
|
||||
@@ -81,8 +81,6 @@ func (s *statusSyncer) runUpdateStatus() error {
|
||||
return err
|
||||
}
|
||||
|
||||
IngressLog.Debugf("found number %d of svc", len(svcList))
|
||||
|
||||
lbStatusList := common.GetLbStatusListV1Beta1(svcList)
|
||||
if len(lbStatusList) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -162,6 +162,7 @@ func (c *controller) onEvent(namespacedName types.NamespacedName) error {
|
||||
delete(c.ingresses, namespacedName.String())
|
||||
c.mutex.Unlock()
|
||||
} else {
|
||||
IngressLog.Warnf("ingressLister Get failed, ingress: %s, err: %v", namespacedName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -171,7 +172,7 @@ func (c *controller) onEvent(namespacedName types.NamespacedName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
IngressLog.Debugf("ingress: %s, event: %s", namespacedName, event)
|
||||
IngressLog.Infof("ingress: %s, event: %s", namespacedName, event)
|
||||
|
||||
// we should check need process only when event is not delete,
|
||||
// if it is delete event, and previously processed, we need to process too.
|
||||
@@ -181,7 +182,7 @@ func (c *controller) onEvent(namespacedName types.NamespacedName) error {
|
||||
return err
|
||||
}
|
||||
if !shouldProcess {
|
||||
IngressLog.Infof("no need process, ingress %s", namespacedName)
|
||||
IngressLog.Infof("no need process, ingress: %s", namespacedName)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -279,10 +280,17 @@ func (c *controller) List() []config.Config {
|
||||
for _, raw := range c.ingressInformer.Informer.GetStore().List() {
|
||||
ing, ok := raw.(*ingress.Ingress)
|
||||
if !ok {
|
||||
IngressLog.Warnf("get ingress from informer failed: %v", raw)
|
||||
continue
|
||||
}
|
||||
|
||||
if should, err := c.shouldProcessIngress(ing); !should || err != nil {
|
||||
should, err := c.shouldProcessIngress(ing)
|
||||
if err != nil {
|
||||
IngressLog.Warnf("check should process ingress failed: %v", err)
|
||||
continue
|
||||
}
|
||||
if !should {
|
||||
IngressLog.Debugf("no need process ingress: %s/%s", ing.Namespace, ing.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -900,12 +908,7 @@ func (c *controller) storeBackendTrafficPolicy(wrapper *common.WrapperConfig, ba
|
||||
if common.ValidateBackendResource(backend.Resource) && wrapper.AnnotationsConfig.Destination != nil {
|
||||
for _, dest := range wrapper.AnnotationsConfig.Destination.McpDestination {
|
||||
portNumber := dest.Destination.GetPort().GetNumber()
|
||||
serviceKey := common.ServiceKey{
|
||||
Namespace: "mcp",
|
||||
Name: dest.Destination.Host,
|
||||
Port: int32(portNumber),
|
||||
ServiceFQDN: dest.Destination.Host,
|
||||
}
|
||||
serviceKey := common.CreateMcpServiceKey(dest.Destination.Host, int32(portNumber))
|
||||
if _, exist := store[serviceKey]; !exist {
|
||||
if serviceKey.Port != 0 {
|
||||
store[serviceKey] = &common.WrapperTrafficPolicy{
|
||||
|
||||
@@ -81,8 +81,6 @@ func (s *statusSyncer) runUpdateStatus() error {
|
||||
return err
|
||||
}
|
||||
|
||||
IngressLog.Debugf("found number %d of svc", len(svcList))
|
||||
|
||||
lbStatusList := common.GetLbStatusListV1(svcList)
|
||||
if len(lbStatusList) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -77,7 +77,6 @@ func (s *statusSyncer) runUpdateStatus() error {
|
||||
return err
|
||||
}
|
||||
|
||||
IngressLog.Debugf("found number %d of svc", len(svcList))
|
||||
lbStatusList := common2.GetLbStatusList(svcList)
|
||||
return s.updateStatus(lbStatusList)
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
@@ -113,3 +115,44 @@ func BuildPatchStruct(config string) *_struct.Struct {
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
type ServiceInfo struct {
|
||||
model.NamespacedName
|
||||
Port uint32
|
||||
}
|
||||
|
||||
// convertToPort converts a port string to a uint32.
|
||||
func convertToPort(v string) (uint32, error) {
|
||||
p, err := strconv.ParseUint(v, 10, 32)
|
||||
if err != nil || p > 65535 {
|
||||
return 0, fmt.Errorf("invalid port %s: %v", v, err)
|
||||
}
|
||||
return uint32(p), nil
|
||||
}
|
||||
|
||||
func ParseServiceInfo(service string, ingressNamespace string) (ServiceInfo, error) {
|
||||
parts := strings.Split(service, ":")
|
||||
namespacedName := SplitNamespacedName(parts[0])
|
||||
|
||||
if namespacedName.Name == "" {
|
||||
return ServiceInfo{}, errors.New("service name can not be empty")
|
||||
}
|
||||
|
||||
if namespacedName.Namespace == "" {
|
||||
namespacedName.Namespace = ingressNamespace
|
||||
}
|
||||
|
||||
var port uint32
|
||||
if len(parts) == 2 {
|
||||
// If port parse fail, we ignore port and pick the first one.
|
||||
port, _ = convertToPort(parts[1])
|
||||
}
|
||||
|
||||
return ServiceInfo{
|
||||
NamespacedName: model.NamespacedName{
|
||||
Name: namespacedName.Name,
|
||||
Namespace: namespacedName.Namespace,
|
||||
},
|
||||
Port: port,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
|
||||
package log
|
||||
|
||||
import "istio.io/pkg/log"
|
||||
import "istio.io/istio/pkg/log"
|
||||
|
||||
var IngressLog = log.RegisterScope("ingress", "Higress Ingress process.", 0)
|
||||
var IngressLog = log.RegisterScope("ingress", "Higress Ingress process.")
|
||||
|
||||
@@ -64,7 +64,7 @@ func (c ServiceEntryGenerator) Generate(proxy *model.Proxy, w *model.WatchedReso
|
||||
return serviceEntries[i].CreationTimestamp.Before(serviceEntries[j].CreationTimestamp)
|
||||
})
|
||||
}
|
||||
return generate(proxy, serviceEntries, w, updates, false, false)
|
||||
return generate(proxy, serviceEntries, w, updates, c.GeneratorOptions.KeepConfigLabels, c.GeneratorOptions.KeepConfigAnnotations)
|
||||
}
|
||||
|
||||
func (c ServiceEntryGenerator) GenerateDeltas(proxy *model.Proxy, updates *model.PushRequest,
|
||||
@@ -82,7 +82,7 @@ type VirtualServiceGenerator struct {
|
||||
func (c VirtualServiceGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource,
|
||||
updates *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
|
||||
virtualServices := c.Environment.List(gvk.VirtualService, model.NamespaceAll)
|
||||
return generate(proxy, virtualServices, w, updates, false, false)
|
||||
return generate(proxy, virtualServices, w, updates, c.GeneratorOptions.KeepConfigLabels, c.GeneratorOptions.KeepConfigAnnotations)
|
||||
}
|
||||
|
||||
func (c VirtualServiceGenerator) GenerateDeltas(proxy *model.Proxy, updates *model.PushRequest,
|
||||
@@ -100,7 +100,7 @@ type DestinationRuleGenerator struct {
|
||||
func (c DestinationRuleGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource,
|
||||
updates *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
|
||||
rules := c.Environment.List(gvk.DestinationRule, model.NamespaceAll)
|
||||
return generate(proxy, rules, w, updates, false, false)
|
||||
return generate(proxy, rules, w, updates, c.GeneratorOptions.KeepConfigLabels, c.GeneratorOptions.KeepConfigAnnotations)
|
||||
}
|
||||
|
||||
func (c DestinationRuleGenerator) GenerateDeltas(proxy *model.Proxy, updates *model.PushRequest,
|
||||
@@ -118,7 +118,7 @@ type EnvoyFilterGenerator struct {
|
||||
func (c EnvoyFilterGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource,
|
||||
updates *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
|
||||
filters := c.Environment.List(gvk.EnvoyFilter, model.NamespaceAll)
|
||||
return generate(proxy, filters, w, updates, false, false)
|
||||
return generate(proxy, filters, w, updates, c.GeneratorOptions.KeepConfigLabels, c.GeneratorOptions.KeepConfigAnnotations)
|
||||
}
|
||||
|
||||
func (c EnvoyFilterGenerator) GenerateDeltas(proxy *model.Proxy, updates *model.PushRequest,
|
||||
@@ -154,7 +154,7 @@ type WasmPluginGenerator struct {
|
||||
func (c WasmPluginGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource,
|
||||
updates *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
|
||||
wasmPlugins := c.Environment.List(gvk.WasmPlugin, model.NamespaceAll)
|
||||
return generate(proxy, wasmPlugins, w, updates, false, false)
|
||||
return generate(proxy, wasmPlugins, w, updates, c.GeneratorOptions.KeepConfigLabels, c.GeneratorOptions.KeepConfigAnnotations)
|
||||
}
|
||||
|
||||
func (c WasmPluginGenerator) GenerateDeltas(proxy *model.Proxy, push *model.PushContext, updates *model.PushRequest,
|
||||
|
||||
@@ -187,10 +187,9 @@ func (m *IngressTranslation) List(typ config.GroupVersionKind, namespace string)
|
||||
higressConfig = append(higressConfig, ingressConfig...)
|
||||
if m.kingressConfig != nil {
|
||||
kingressConfig := m.kingressConfig.List(typ, namespace)
|
||||
if kingressConfig == nil {
|
||||
return nil
|
||||
if kingressConfig != nil {
|
||||
higressConfig = append(higressConfig, kingressConfig...)
|
||||
}
|
||||
higressConfig = append(higressConfig, kingressConfig...)
|
||||
}
|
||||
return higressConfig
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
## Wasm 插件
|
||||
|
||||
|
||||
目前 Higress 提供了 c++ 和 golang 两种 Wasm 插件开发框架,支持 Wasm 插件路由&域名级匹配生效。
|
||||
|
||||
同时提供了多个内置插件,用户可以基于 Higress 提供的官方镜像仓库直接使用这些插件(以 c++ 版本举例):
|
||||
|
||||
@@ -16,24 +16,28 @@ load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")
|
||||
|
||||
container_deps()
|
||||
|
||||
PROXY_WASM_CPP_SDK_SHA = "fd0be8405db25de0264bdb78fae3a82668c03782"
|
||||
PROXY_WASM_CPP_SDK_SHA = "eaec483b5b3c7bcb89fd208b5a1fa5d79d626f61"
|
||||
|
||||
PROXY_WASM_CPP_SDK_SHA256 = "c57de2425b5c61d7f630c5061e319b4557ae1f1c7526e5a51c33dc1299471b08"
|
||||
PROXY_WASM_CPP_SDK_SHA256 = "1140bc8114d75db56a6ca6b18423d4df50d988d40b4cec929a1eb246cf5a4a3d"
|
||||
|
||||
http_archive(
|
||||
name = "proxy_wasm_cpp_sdk",
|
||||
sha256 = PROXY_WASM_CPP_SDK_SHA256,
|
||||
strip_prefix = "proxy-wasm-cpp-sdk-" + PROXY_WASM_CPP_SDK_SHA,
|
||||
url = "https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/archive/" + PROXY_WASM_CPP_SDK_SHA + ".tar.gz",
|
||||
url = "https://github.com/higress-group/proxy-wasm-cpp-sdk/archive/" + PROXY_WASM_CPP_SDK_SHA + ".tar.gz",
|
||||
)
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/dep:deps.bzl", "wasm_dependencies")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:repositories.bzl", "proxy_wasm_cpp_sdk_repositories")
|
||||
|
||||
wasm_dependencies()
|
||||
proxy_wasm_cpp_sdk_repositories()
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/dep:deps_extra.bzl", "wasm_dependencies_extra")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:dependencies.bzl", "proxy_wasm_cpp_sdk_dependencies")
|
||||
|
||||
wasm_dependencies_extra()
|
||||
proxy_wasm_cpp_sdk_dependencies()
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel:dependencies_extra.bzl", "proxy_wasm_cpp_sdk_dependencies_extra")
|
||||
|
||||
proxy_wasm_cpp_sdk_dependencies_extra()
|
||||
|
||||
load("@istio_ecosystem_wasm_extensions//bazel:wasm.bzl", "wasm_libraries")
|
||||
|
||||
|
||||
@@ -2,16 +2,16 @@ diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/interna
|
||||
index d8cb047..0c5f182 100644
|
||||
--- a/absl/time/internal/cctz/src/time_zone_format.cc
|
||||
+++ b/absl/time/internal/cctz/src/time_zone_format.cc
|
||||
@@ -18,6 +18,8 @@
|
||||
#endif
|
||||
#endif
|
||||
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
+#define HAS_STRPTIME 0
|
||||
+
|
||||
#if defined(HAS_STRPTIME) && HAS_STRPTIME
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE // Definedness suffices for strptime.
|
||||
@@ -58,7 +60,7 @@ namespace {
|
||||
#if !defined(HAS_STRPTIME)
|
||||
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||
#define HAS_STRPTIME 1 // assume everyone has strptime() except windows
|
||||
@@ -58,7 +60,7 @@
|
||||
|
||||
#if !HAS_STRPTIME
|
||||
// Build a strptime() using C++11's std::get_time().
|
||||
@@ -20,7 +20,7 @@ index d8cb047..0c5f182 100644
|
||||
std::istringstream input(s);
|
||||
input >> std::get_time(tm, fmt);
|
||||
if (input.fail()) return nullptr;
|
||||
@@ -648,7 +650,7 @@ const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) {
|
||||
@@ -648,7 +650,7 @@
|
||||
// Parses a string into a std::tm using strptime(3).
|
||||
const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
|
||||
if (dp != nullptr) {
|
||||
|
||||
@@ -9,9 +9,9 @@ load(
|
||||
def wasm_libraries():
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
sha256 = "ec8ef47335310cc3382bdc0d0cc1097a001e67dc83fcba807845aa5696e7e1e4",
|
||||
strip_prefix = "abseil-cpp-302b250e1d917ede77b5ff00a6fd9f28430f1563",
|
||||
url = "https://github.com/abseil/abseil-cpp/archive/302b250e1d917ede77b5ff00a6fd9f28430f1563.tar.gz",
|
||||
sha256 = "3a0bb3d2e6f53352526a8d1a7e7b5749c68cd07f2401766a404fb00d2853fa49",
|
||||
strip_prefix = "abseil-cpp-4bbdb026899fea9f882a95cbd7d6a4adaf49b2dd",
|
||||
url = "https://github.com/abseil/abseil-cpp/archive/4bbdb026899fea9f882a95cbd7d6a4adaf49b2dd.tar.gz",
|
||||
patch_args = ["-p1"],
|
||||
patches = ["//bazel:absl.patch"],
|
||||
)
|
||||
@@ -33,14 +33,14 @@ def wasm_libraries():
|
||||
urls = ["https://github.com/google/googletest/archive/release-1.10.0.tar.gz"],
|
||||
)
|
||||
|
||||
PROXY_WASM_CPP_HOST_SHA = "f38347360feaaf5b2a733f219c4d8c9660d626f0"
|
||||
PROXY_WASM_CPP_HOST_SHA256 = "bf10de946eb5785813895c2bf16504afc0cd590b9655d9ee52fb1074d0825ea3"
|
||||
PROXY_WASM_CPP_HOST_SHA = "ecf42a27fcf78f42e64037d4eff1a0ca5a61e403"
|
||||
PROXY_WASM_CPP_HOST_SHA256 = "9748156731e9521837686923321bf12725c32c9fa8355218209831cc3ee87080"
|
||||
|
||||
http_archive(
|
||||
name = "proxy_wasm_cpp_host",
|
||||
sha256 = PROXY_WASM_CPP_HOST_SHA256,
|
||||
strip_prefix = "proxy-wasm-cpp-host-" + PROXY_WASM_CPP_HOST_SHA,
|
||||
url = "https://github.com/proxy-wasm/proxy-wasm-cpp-host/archive/" + PROXY_WASM_CPP_HOST_SHA +".tar.gz",
|
||||
url = "https://github.com/higress-group/proxy-wasm-cpp-host/archive/" + PROXY_WASM_CPP_HOST_SHA +".tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
|
||||
#include "common/common_util.h"
|
||||
|
||||
namespace Wasm::Common::Http {
|
||||
@@ -190,7 +189,8 @@ std::vector<std::string> getAllOfHeader(std::string_view key) {
|
||||
std::vector<std::string> result;
|
||||
auto headers = getRequestHeaderPairs()->pairs();
|
||||
for (auto& header : headers) {
|
||||
if (absl::EqualsIgnoreCase(Wasm::Common::stdToAbsl(header.first), Wasm::Common::stdToAbsl(key))) {
|
||||
if (absl::EqualsIgnoreCase(Wasm::Common::stdToAbsl(header.first),
|
||||
Wasm::Common::stdToAbsl(key))) {
|
||||
result.push_back(std::string(header.second));
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,8 @@ void forEachCookie(
|
||||
v = v.substr(1, v.size() - 2);
|
||||
}
|
||||
|
||||
if (!cookie_consumer(Wasm::Common::abslToStd(k), Wasm::Common::abslToStd(v))) {
|
||||
if (!cookie_consumer(Wasm::Common::abslToStd(k),
|
||||
Wasm::Common::abslToStd(v))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -265,7 +266,63 @@ std::string buildOriginalUri(std::optional<uint32_t> max_path_length) {
|
||||
auto scheme = scheme_ptr->view();
|
||||
auto host_ptr = getRequestHeader(Header::Host);
|
||||
auto host = host_ptr->view();
|
||||
return absl::StrCat(Wasm::Common::stdToAbsl(scheme), "://", Wasm::Common::stdToAbsl(host), Wasm::Common::stdToAbsl(final_path));
|
||||
return absl::StrCat(Wasm::Common::stdToAbsl(scheme), "://",
|
||||
Wasm::Common::stdToAbsl(host),
|
||||
Wasm::Common::stdToAbsl(final_path));
|
||||
}
|
||||
|
||||
void extractHostPathFromUri(const absl::string_view& uri,
|
||||
absl::string_view& host, absl::string_view& path) {
|
||||
/**
|
||||
* URI RFC: https://www.ietf.org/rfc/rfc2396.txt
|
||||
*
|
||||
* Example:
|
||||
* uri = "https://example.com:8443/certs"
|
||||
* pos: ^
|
||||
* host_pos: ^
|
||||
* path_pos: ^
|
||||
* host = "example.com:8443"
|
||||
* path = "/certs"
|
||||
*/
|
||||
const auto pos = uri.find("://");
|
||||
// Start position of the host
|
||||
const auto host_pos = (pos == std::string::npos) ? 0 : pos + 3;
|
||||
// Start position of the path
|
||||
const auto path_pos = uri.find('/', host_pos);
|
||||
if (path_pos == std::string::npos) {
|
||||
// If uri doesn't have "/", the whole string is treated as host.
|
||||
host = uri.substr(host_pos);
|
||||
path = "/";
|
||||
} else {
|
||||
host = uri.substr(host_pos, path_pos - host_pos);
|
||||
path = uri.substr(path_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void extractPathWithoutArgsFromUri(const std::string_view& uri,
|
||||
std::string_view& path_without_args) {
|
||||
auto params_pos = uri.find('?');
|
||||
size_t uri_end;
|
||||
if (params_pos == std::string::npos) {
|
||||
uri_end = uri.size();
|
||||
} else {
|
||||
uri_end = params_pos;
|
||||
}
|
||||
path_without_args = uri.substr(0, uri_end);
|
||||
}
|
||||
|
||||
bool hasRequestBody() {
|
||||
auto contentType = getRequestHeader("content-type")->toString();
|
||||
auto contentLengthStr = getRequestHeader("content-length")->toString();
|
||||
auto transferEncoding = getRequestHeader("transfer-encoding")->toString();
|
||||
|
||||
if (!contentType.empty()) {
|
||||
return true;
|
||||
}
|
||||
if (!contentLengthStr.empty()) {
|
||||
return true;
|
||||
}
|
||||
return transferEncoding.find("chunked") != std::string::npos;
|
||||
}
|
||||
|
||||
} // namespace Wasm::Common::Http
|
||||
|
||||
@@ -42,6 +42,12 @@ namespace Wasm::Common::Http {
|
||||
using QueryParams = std::map<std::string, std::string>;
|
||||
using SystemTime = std::chrono::time_point<std::chrono::system_clock>;
|
||||
|
||||
namespace Status {
|
||||
constexpr int OK = 200;
|
||||
constexpr int InternalServerError = 500;
|
||||
constexpr int Unauthorized = 401;
|
||||
} // namespace Status
|
||||
|
||||
namespace Header {
|
||||
constexpr std::string_view Scheme(":scheme");
|
||||
constexpr std::string_view Method(":method");
|
||||
@@ -52,14 +58,17 @@ constexpr std::string_view Accept("accept");
|
||||
constexpr std::string_view ContentMD5("content-md5");
|
||||
constexpr std::string_view ContentType("content-type");
|
||||
constexpr std::string_view ContentLength("content-length");
|
||||
constexpr std::string_view TransferEncoding("transfer-encoding");
|
||||
constexpr std::string_view UserAgent("user-agent");
|
||||
constexpr std::string_view Date("date");
|
||||
constexpr std::string_view Cookie("cookie");
|
||||
constexpr std::string_view StrictTransportSecurity("strict-transport-security");
|
||||
} // namespace Header
|
||||
|
||||
namespace ContentTypeValues {
|
||||
constexpr std::string_view Grpc{"application/grpc"};
|
||||
}
|
||||
constexpr std::string_view Json{"application/json"};
|
||||
} // namespace ContentTypeValues
|
||||
|
||||
class PercentEncoding {
|
||||
public:
|
||||
@@ -142,4 +151,10 @@ std::unordered_map<std::string, std::string> parseCookies(
|
||||
|
||||
std::string buildOriginalUri(std::optional<uint32_t> max_path_length);
|
||||
|
||||
void extractHostPathFromUri(const absl::string_view& uri,
|
||||
absl::string_view& host, absl::string_view& path);
|
||||
|
||||
void extractPathWithoutArgsFromUri(const std::string_view& uri,
|
||||
std::string_view& path_without_args);
|
||||
bool hasRequestBody();
|
||||
} // namespace Wasm::Common::Http
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
<p>
|
||||
<a href="README_EN.md">English</a> | 中文
|
||||
</p>
|
||||
---
|
||||
title: Basic 认证
|
||||
keywords: [higress,basic auth]
|
||||
description: Basic 认证插件配置参考
|
||||
---
|
||||
|
||||
# 功能说明
|
||||
## 功能说明
|
||||
`basic-auth`插件实现了基于 HTTP Basic Auth 标准进行认证鉴权的功能
|
||||
|
||||
# 配置字段
|
||||
## 运行属性
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | -------- | ------ | ---------------------------------------------------- |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
| `_rules_` | array of object | 选填 | - | 配置特定路由或域名的访问权限列表,用于对请求进行鉴权 |
|
||||
插件执行阶段:`认证阶段`
|
||||
插件执行优先级:`320`
|
||||
|
||||
## 配置字段
|
||||
|
||||
**注意:**
|
||||
|
||||
- 在一个规则里,鉴权配置和认证配置不可同时存在
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
### 认证配置
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | -------- | ------ | ---------------------------------------------------- |
|
||||
| `global_auth` | bool | 选填(**仅实例级别配置**) | - | 只能在实例级别配置,若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制,若不配置则仅当没有域名和路由配置时全局生效(兼容老用户使用习惯)。 |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
|
||||
`consumers`中每一项的配置字段说明如下:
|
||||
|
||||
@@ -19,51 +33,49 @@
|
||||
| `credential` | string | 必填 | - | 配置该consumer的访问凭证 |
|
||||
| `name` | string | 必填 | - | 配置该consumer的名称 |
|
||||
|
||||
`_rules_` 中每一项的配置字段说明如下:
|
||||
### 鉴权配置(非必需)
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ------ | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的路由名称 |
|
||||
| `_match_domain_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的域名 |
|
||||
| `allow` | array of string | 必填 | - | 对于符合匹配条件的请求,配置允许访问的consumer名称 |
|
||||
|
||||
**注意:**
|
||||
- 若不配置`_rules_`字段,则默认对当前网关实例的所有路由开启认证;
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
## 配置示例
|
||||
|
||||
# 配置示例
|
||||
|
||||
## 对特定路由或域名开启认证和鉴权
|
||||
### 全局配置认证和路由粒度进行鉴权
|
||||
|
||||
以下配置将对网关特定路由或域名开启 Basic Auth 认证和鉴权,注意凭证信息中的用户名和密码之间使用":"分隔,`credential`字段不能重复
|
||||
|
||||
|
||||
在实例级别做如下插件配置:
|
||||
|
||||
```yaml
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
consumers:
|
||||
- credential: 'admin:123456'
|
||||
name: consumer1
|
||||
- credential: 'guest:abc'
|
||||
name: consumer2
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer1
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer2
|
||||
global_auth: false
|
||||
```
|
||||
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许`name`为`consumer1`的调用者访问,其他调用者不允许访问;
|
||||
对 route-a 和 route-b 这两个路由做如下配置:
|
||||
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将允许`name`为`consumer2`的调用者访问,其他调用者不允许访问。
|
||||
```yaml
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
|
||||
### 根据该配置,下列请求可以允许访问:
|
||||
对 *.example.com 和 test.com 在这两个域名做如下配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
若是在控制台进行配置,此例指定的 `route-a` 和 `route-b` 即在控制台创建路由时填写的路由名称,当匹配到这两个路由时,将允许`name`为`consumer1`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
此例指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将允许`name`为`consumer2`的调用者访问,其他调用者不允许访问。
|
||||
|
||||
根据该配置,下列请求可以允许访问:
|
||||
|
||||
**请求指定用户名密码**
|
||||
|
||||
@@ -77,7 +89,7 @@ curl -H 'Authorization: Basic YWRtaW46MTIzNDU2' http://xxx.hello.com/test
|
||||
|
||||
认证鉴权通过后,请求的header中会被添加一个`X-Mse-Consumer`字段,在此例中其值为`consumer1`,用以标识调用方的名称
|
||||
|
||||
### 下列请求将拒绝访问:
|
||||
下列请求将拒绝访问:
|
||||
|
||||
**请求未提供用户名密码,返回401**
|
||||
```bash
|
||||
@@ -93,22 +105,10 @@ curl -u admin:abc http://xxx.hello.com/test
|
||||
curl -u guest:abc http://xxx.hello.com/test
|
||||
```
|
||||
|
||||
## 网关实例级别开启
|
||||
## 相关错误码
|
||||
|
||||
以下配置未指定`_rules_`字段,因此将对网关实例级别开启 Basic Auth 认证
|
||||
|
||||
```yaml
|
||||
consumers:
|
||||
- credential: 'admin:123456'
|
||||
name: consumer1
|
||||
- credential: 'guest:abc'
|
||||
name: consumer2
|
||||
```
|
||||
|
||||
# 相关错误码
|
||||
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- | ------------------------------------------------------------------------------ | ---------------------- |
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- |--------------------------------------------------------------------------------| ---------------------- |
|
||||
| 401 | Request denied by Basic Auth check. No Basic Authentication information found. | 请求未提供凭证 |
|
||||
| 401 | Request denied by Basic Auth check. Invalid username and/or password | 请求凭证无效 |
|
||||
| 403 | Request denied by Basic Auth check. Unauthorized consumer | 请求的调用方无访问权限 |
|
||||
| 401 | Request denied by Basic Auth check. Invalid username and/or password. | 请求凭证无效 |
|
||||
| 403 | Request denied by Basic Auth check. Unauthorized consumer. | 请求的调用方无访问权限 |
|
||||
|
||||
@@ -1,117 +1,99 @@
|
||||
<p>
|
||||
English | <a href="README.md">中文</a>
|
||||
</p>
|
||||
---
|
||||
title: Basic Authentication
|
||||
keywords: [higress,basic auth]
|
||||
description: Basic authentication plugin configuration reference
|
||||
---
|
||||
## Function Description
|
||||
The `basic-auth` plugin implements authentication and authorization based on the HTTP Basic Auth standard.
|
||||
|
||||
# Description
|
||||
`basic-auth` plugin implements the function of authentication based on the HTTP Basic Auth standard.
|
||||
|
||||
# Configuration Fields
|
||||
|
||||
| Name | Type | Requirement | Default Value | Description |
|
||||
| ----------- | --------------- | -------- | ------ | ---------------------------------------------------- |
|
||||
| `consumers` | array of object | Required | - | Caller of the service for authentication of requests |
|
||||
| `_rules_` | array of object | Optional | - | Configure access permission list for specific routes or domains to authenticate requests |
|
||||
|
||||
Filed descriptions of `consumers` items:
|
||||
|
||||
| Name | Type | Requirement | Default Value | Description |
|
||||
| ------------ | ------ | ----------- | ------------- | ------------------------------------- |
|
||||
| `credential` | string | Required | - | Credential for this consumer's access |
|
||||
| `name` | string | Required | - | Name of this consumer |
|
||||
|
||||
Configuration field descriptions for each item in `_rules_` are as follows:
|
||||
|
||||
| Field Name | Data Type | Requirement | Default | Description |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ------ | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | One of `_match_route_` or `_match_domain_` | - | Configure the routes to match for request authorization |
|
||||
| `_match_domain_` | array of string | One of `_match_route_` , `_match_domain_` | - | Configure the domains to match for request authorization |
|
||||
| `allow` | array of string | Required | - | Configure the consumer names allowed to access requests that match the match condition |
|
||||
## Operation Attributes
|
||||
Plugin execution stage: `Authentication Phase`
|
||||
Plugin execution priority: `320`
|
||||
|
||||
## Configuration Fields
|
||||
**Note:**
|
||||
- In one rule, authentication configurations and authorization configurations cannot coexist.
|
||||
- For requests that pass authentication, the request header will include an `X-Mse-Consumer` field to identify the caller's name.
|
||||
|
||||
- If the `_rules_` field is not configured, authentication is enabled for all routes of the current gateway instance by default;
|
||||
- For authenticated requests, `X-Mse-Consumer` field will be added to the request header to identify the name of the caller.
|
||||
### Authentication Configuration
|
||||
| Name | Data Type | Requirements | Default Value | Description |
|
||||
| ------------- | ---------------- | ------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `global_auth` | bool | Optional (**instance-level only**) | - | Can only be configured at the instance level. If set to true, the authentication mechanism will take effect globally; if set to false, it will only take effect for the configured domains and routes. If not configured, it will only take effect globally when there are no domain and route configurations (compatible with old user habits). |
|
||||
| `consumers` | array of object | Required | - | Configures the service callers for request authentication. |
|
||||
|
||||
# Configuration Samples
|
||||
|
||||
## Enable Authentication and Authorization for specific routes or domains
|
||||
|
||||
The following configuration will enable Basic Auth authentication and authorization for specific routes or domains of the gateway. Note that the username and password in the credential information are separated by a ":", and the `credential` field cannot be repeated.
|
||||
Each configuration field in `consumers` is described as follows:
|
||||
| Name | Data Type | Requirements | Default Value | Description |
|
||||
| ------------ | --------- | ------------ | ------------- | ------------------------------- |
|
||||
| `credential` | string | Required | - | Configures the access credentials for this consumer. |
|
||||
| `name` | string | Required | - | Configures the name of this consumer. |
|
||||
|
||||
### Authorization Configuration (Optional)
|
||||
| Name | Data Type | Requirements | Default Value | Description |
|
||||
| ---------------- | ---------------- | ---------------------------------------------------- | -------------- | -------------------------------------------------------- |
|
||||
| `allow` | array of string | Required | - | Configures the consumer names allowed to access for matching requests. |
|
||||
|
||||
## Configuration Example
|
||||
### Global Authentication and Route Granularity Authorization
|
||||
The following configuration will enable Basic Auth authentication and authorization for specific routes or domains of the gateway. Note that the username and password in the credential information are separated by ":", and the `credential` field cannot be duplicated.
|
||||
|
||||
Make the following plugin configuration at the instance level:
|
||||
```yaml
|
||||
# use the _rules_ field for fine-grained rule configuration.
|
||||
consumers:
|
||||
- credential: 'admin:123456'
|
||||
name: consumer1
|
||||
- credential: 'guest:abc'
|
||||
name: consumer2
|
||||
_rules_:
|
||||
# rule 1: match by the route name.
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer1
|
||||
# rule 2: match by the domain.
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer2
|
||||
global_auth: false
|
||||
```
|
||||
In this sample, `route-a` and `route-b` specified in `_match_route_` are the route names filled in when creating gateway routes. When these two routes are matched, the caller with `name` as `consumer1` is allowed to access, and other callers are not allowed to access.
|
||||
|
||||
The `*.example.com` and `test.com` specified in `_match_domain_` are used to match the domain name of the request. When the domain name is matched, the caller with `name` as `consumer2` is allowed to access, and other callers are not allowed to access.
|
||||
For routes `route-a` and `route-b`, configure as follows:
|
||||
```yaml
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
|
||||
For the domains `*.example.com` and `test.com`, configure as follows:
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
### According to this configuration, the following requests are allowed:
|
||||
If configured in the console, the specified `route-a` and `route-b` refer to the route names filled in when creating the routes in the console. When matching these two routes, callers with the name `consumer1` will be allowed access, while other callers will not.
|
||||
|
||||
**Requests with specified username and password**
|
||||
The specified `*.example.com` and `test.com` are used to match the request domain. When a match is found, callers with the name `consumer2` will be allowed access, while other callers will not.
|
||||
|
||||
Based on this configuration, the following requests may be allowed access:
|
||||
**Request with specified username and password**
|
||||
```bash
|
||||
# Assuming the following request will match with route-a
|
||||
# Use -u option of curl to specify the credentials
|
||||
# Assuming the following request matches the route-a route
|
||||
# Using curl's -u parameter to specify
|
||||
curl -u admin:123456 http://xxx.hello.com/test
|
||||
# Or specify the Authorization request header directly with the credentials in base64 encoding
|
||||
# Or directly specify the Authorization request header with the username and password encoded in base64
|
||||
curl -H 'Authorization: Basic YWRtaW46MTIzNDU2' http://xxx.hello.com/test
|
||||
```
|
||||
|
||||
A `X-Mse-Consumer` field will be added to the headers of the request, and its value in this example is `consumer1`, used to identify the name of the caller when passed authentication and authorization.
|
||||
After successful authentication, the request header will have an added `X-Mse-Consumer` field, which in this case is `consumer1` to identify the caller's name.
|
||||
|
||||
### The following requests will be denied:
|
||||
|
||||
**Requests without providing username and password, returning 401**
|
||||
The following requests will be denied access:
|
||||
**Request without username and password, returns 401**
|
||||
```bash
|
||||
curl http://xxx.hello.com/test
|
||||
```
|
||||
**Requests with incorrect username or password, returning 401**
|
||||
|
||||
**Request with incorrect username and password, returns 401**
|
||||
```bash
|
||||
curl -u admin:abc http://xxx.hello.com/test
|
||||
```
|
||||
**Requests matched with a caller who has no access permission, returning 403**
|
||||
|
||||
**Caller matched by username and password has no access, returns 403**
|
||||
```bash
|
||||
# consumer2 is not in the allow list of route-a
|
||||
# consumer2 is not in the allow list for route-a
|
||||
curl -u guest:abc http://xxx.hello.com/test
|
||||
```
|
||||
|
||||
## Enable basic auth for gateway instance
|
||||
|
||||
The following configuration does not specify the `_rules_` field, so Basic Auth authentication will be effective for the whole gateway instance.
|
||||
|
||||
```yaml
|
||||
consumers:
|
||||
- credential: 'admin:123456'
|
||||
name: consumer1
|
||||
- credential: 'guest:abc'
|
||||
name: consumer2
|
||||
```
|
||||
|
||||
# Error Codes
|
||||
|
||||
| HTTP Status Code | Error Info | Reason |
|
||||
| ----------- | ------------------------------------------------------------------------------ | ---------------------- |
|
||||
| 401 | Request denied by Basic Auth check. No Basic Authentication information found. | Credentials not provided in the request |
|
||||
| 401 | Request denied by Basic Auth check. Invalid username and/or password | Invalid username and/or password |
|
||||
| 403 | Request denied by Basic Auth check. Unauthorized consumer | Unauthorized consumer |
|
||||
## Related Error Codes
|
||||
| HTTP Status Code | Error Message | Reason Description |
|
||||
| ---------------- | ------------------------------------------------------------------------------------- | -------------------------------- |
|
||||
| 401 | Request denied by Basic Auth check. No Basic Authentication information found. | Request did not provide credentials. |
|
||||
| 401 | Request denied by Basic Auth check. Invalid username and/or password. | Request credentials are invalid. |
|
||||
| 403 | Request denied by Basic Auth check. Unauthorized consumer. | The caller making the request does not have access. |
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:defs.bzl", "proxy_wasm_cc_binary")
|
||||
load("//bazel:wasm.bzl", "declare_wasm_image_targets")
|
||||
|
||||
wasm_cc_binary(
|
||||
proxy_wasm_cc_binary(
|
||||
name = "bot_detect.wasm",
|
||||
srcs = [
|
||||
"plugin.cc",
|
||||
@@ -28,7 +28,6 @@ wasm_cc_binary(
|
||||
"//common:http_util",
|
||||
"//common:regex_util",
|
||||
"//common:rule_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
<p>
|
||||
<a href="README_EN.md"> English </a> | 中文
|
||||
</p>
|
||||
---
|
||||
title: Bot 拦截
|
||||
keywords: [higress,bot detect]
|
||||
description: Bot 拦截插件配置参考
|
||||
---
|
||||
|
||||
|
||||
## 功能说明
|
||||
|
||||
# 功能说明
|
||||
`bot-detect`插件可以用于识别并阻止互联网爬虫对站点资源的爬取
|
||||
|
||||
# 配置字段
|
||||
## 运行属性
|
||||
|
||||
插件执行阶段:`授权阶段`
|
||||
插件执行优先级:`310`
|
||||
|
||||
|
||||
## 配置字段
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
@@ -33,9 +43,9 @@
|
||||
(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\/\$BotVersion|123metaspider-Bot|1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\b\w{0,30}favicon\w{0,30}\b|\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+)|)|)|)
|
||||
```
|
||||
|
||||
# 配置示例
|
||||
## 配置示例
|
||||
|
||||
## 放行原本命中爬虫规则的请求
|
||||
### 放行原本命中爬虫规则的请求
|
||||
```yaml
|
||||
allow:
|
||||
- ".*Go-http-client.*"
|
||||
@@ -44,7 +54,7 @@ allow:
|
||||
若不作该配置,默认的 Golang 网络库请求会被视做爬虫,被禁止访问
|
||||
|
||||
|
||||
## 增加爬虫判断
|
||||
### 增加爬虫判断
|
||||
```yaml
|
||||
deny:
|
||||
- "spd-tools.*"
|
||||
@@ -56,24 +66,3 @@ deny:
|
||||
curl http://example.com -H 'User-Agent: spd-tools/1.1'
|
||||
curl http://exmaple.com -H 'User-Agent: spd-tools'
|
||||
```
|
||||
|
||||
## 对特定路由或域名开启
|
||||
```yaml
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- ".*Go-http-client.*"
|
||||
```
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置;
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将使用此段配置;
|
||||
配置的匹配生效顺序,将按照 `_rules_` 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略。
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
<p>
|
||||
English | <a href="README.md">中文</a>
|
||||
</p>
|
||||
---
|
||||
title: Bot Detect
|
||||
keywords: [higress, bot detect]
|
||||
description: Bot detect plugin configuration reference
|
||||
---
|
||||
## Function Description
|
||||
The `bot-detect` plugin can be used to identify and block internet crawlers from accessing site resources.
|
||||
|
||||
# Description
|
||||
`bot-detect` plugin can be used to identify and prevent web crawlers from crawling websites.
|
||||
## Running Properties
|
||||
Plugin Execution Phase: `Authorization Phase`
|
||||
Plugin Execution Priority: `310`
|
||||
|
||||
# Configuration Fields
|
||||
## Configuration Fields
|
||||
| Name | Data Type | Required | Default Value | Description |
|
||||
| ----------------- | ------------------- | --------------| --------------| ---------------------------------------------------------- |
|
||||
| allow | array of string | Optional | - | Regular expressions to match the User-Agent request header; requests matching will be allowed to access. |
|
||||
| deny | array of string | Optional | - | Regular expressions to match the User-Agent request header; requests matching will be blocked. |
|
||||
| blocked_code | number | Optional | 403 | HTTP status code returned when a request is blocked. |
|
||||
| blocked_message | string | Optional | - | HTTP response body returned when a request is blocked. |
|
||||
|
||||
| Name | Type | Requirement | Default Value | Description |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
| allow | array of string | Optional | - | A regular expression to match the User-Agent request header and will allow access if the match hits |
|
||||
| deny | array of string | Optional | - | A regular expression to match the User-Agent request header and will block the request if the match hits |
|
||||
| blocked_code | number | Optional | 403 | The HTTP status code returned when a request is blocked |
|
||||
| blocked_message | string | Optional | - | The HTTP response Body returned when a request is blocked |
|
||||
The `allow` and `deny` fields can both be left unconfigured, in which case the default crawler identification logic will be executed. Configuring the `allow` field can allow requests that would otherwise hit the default crawler identification logic. Configuring the `deny` field can add additional crawler identification logic.
|
||||
|
||||
If field `allow` and field `deny` are not configured at the same time, the default logic to identify crawlers will be executed. By configuring the `allow` field, requests that would otherwise hit the default logic can be allowed. The judgement can be extended by configuring the `deny` field
|
||||
|
||||
The default set of crawler judgment regular expressions is as follows:
|
||||
The default crawler identification regular expression set is as follows:
|
||||
|
||||
```bash
|
||||
# Bots General matcher 'name/0.0'
|
||||
@@ -33,45 +37,23 @@ The default set of crawler judgment regular expressions is as follows:
|
||||
(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\/\$BotVersion|123metaspider-Bot|1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\b\w{0,30}favicon\w{0,30}\b|\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+)|)|)|)
|
||||
```
|
||||
|
||||
# Configuration Samples
|
||||
|
||||
## Release Requests that would otherwise Hit the Crawler Rules
|
||||
## Configuration Example
|
||||
### Allowing Requests That Hit the Crawler Rules
|
||||
```yaml
|
||||
allow:
|
||||
- ".*Go-http-client.*"
|
||||
```
|
||||
|
||||
Without this configuration, the default Golang web library request will be treated as a crawler and access will be denied.
|
||||
If this configuration is not made, requests from the default Golang network library will be treated as crawlers and blocked.
|
||||
|
||||
|
||||
## Add Crawler Judgement
|
||||
### Adding Crawler Identification
|
||||
```yaml
|
||||
deny:
|
||||
- "spd-tools.*"
|
||||
```
|
||||
|
||||
According to this configuration, the following requests will be denied:
|
||||
|
||||
With this configuration, the following requests will be blocked:
|
||||
```bash
|
||||
curl http://example.com -H 'User-Agent: spd-tools/1.1'
|
||||
curl http://exmaple.com -H 'User-Agent: spd-tools'
|
||||
```
|
||||
|
||||
## Only Enabled for Specific Routes or Domains
|
||||
```yaml
|
||||
# Use _rules_ field for fine-grained rule configurations
|
||||
_rules_:
|
||||
# Rule 1: Match by route name
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
# Rule 2: Match by domain
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- ".*Go-http-client.*"
|
||||
```
|
||||
In the rule sample of `_match_route_`, `route-a` and `route-b` are the route names provided when creating a new gateway route. When the current route names matches the configuration, the rule following shall be applied.
|
||||
In the rule sample of `_match_domain_`, `*.example.com` and `test.com` are the domain names used for request matching. When the current domain name matches the configuration, the rule following shall be applied.
|
||||
All rules shall be checked following the order of items in the `_rules_` field, The first matched rule will be applied. All remained will be ignored.
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:defs.bzl", "proxy_wasm_cc_binary")
|
||||
load("//bazel:wasm.bzl", "declare_wasm_image_targets")
|
||||
|
||||
wasm_cc_binary(
|
||||
proxy_wasm_cc_binary(
|
||||
name = "custom_response.wasm",
|
||||
srcs = [
|
||||
"plugin.cc",
|
||||
@@ -27,7 +27,6 @@ wasm_cc_binary(
|
||||
"//common:json_util",
|
||||
"//common:http_util",
|
||||
"//common:rule_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
<p>
|
||||
<a href="README_EN.md"> English </a> | 中文
|
||||
</p>
|
||||
---
|
||||
title: 自定义应答
|
||||
keywords: [higress,customn response]
|
||||
description: 自定义应答插件配置参考
|
||||
---
|
||||
|
||||
# 功能说明
|
||||
|
||||
## 功能说明
|
||||
`custom-response`插件支持配置自定义的响应,包括自定义 HTTP 应答状态码、HTTP 应答头,以及 HTTP 应答 Body。可以用于 Mock 响应,也可以用于判断特定状态码后给出自定义应答,例如在触发网关限流策略时实现自定义响应。
|
||||
|
||||
# 配置字段
|
||||
## 运行属性
|
||||
|
||||
插件执行阶段:`认证阶段`
|
||||
插件执行优先级:`910`
|
||||
|
||||
## 配置字段
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
@@ -14,9 +22,9 @@
|
||||
| body | string | 选填 | - | 自定义 HTTP 应答 Body |
|
||||
| enable_on_status | array of number | 选填 | - | 匹配原始状态码,生成自定义响应,不填写时,不判断原始状态码 |
|
||||
|
||||
# 配置示例
|
||||
## 配置示例
|
||||
|
||||
## Mock 应答场景
|
||||
### Mock 应答场景
|
||||
|
||||
```yaml
|
||||
status_code: 200
|
||||
@@ -38,7 +46,7 @@ Content-Length: 17
|
||||
{"hello":"world"}
|
||||
```
|
||||
|
||||
## 触发限流时自定义响应
|
||||
### 触发限流时自定义响应
|
||||
|
||||
```yaml
|
||||
enable_on_status:
|
||||
@@ -58,27 +66,3 @@ Location: https://example.com
|
||||
从而实现基于浏览器 302 重定向机制,将限流后的用户引导到其他页面,比如可以是一个 CDN 上的静态页面。
|
||||
|
||||
如果希望触发限流时,正常返回其他应答,参考 Mock 应答场景配置相应的字段即可。
|
||||
|
||||
## 对特定路由或域名开启
|
||||
```yaml
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
body: "{\"hello\":\"world\"}"
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
enable_on_status:
|
||||
- 429
|
||||
status_code: 200
|
||||
headers:
|
||||
- Content-Type=application/json
|
||||
body: "{\"errmsg\": \"rate limited\"}"
|
||||
```
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置;
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将使用此段配置;
|
||||
配置的匹配生效顺序,将按照 `_rules_` 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略。
|
||||
|
||||
@@ -1,84 +1,54 @@
|
||||
<p>
|
||||
English | <a href="README.md">中文</a>
|
||||
</p>
|
||||
---
|
||||
title: Custom Response
|
||||
keywords: [higress, custom response]
|
||||
description: Custom response plugin configuration reference
|
||||
---
|
||||
## Function Description
|
||||
The `custom-response` plugin supports the configuration of custom responses, including custom HTTP response status codes, HTTP response headers, and HTTP response bodies. It can be used for Mock responses or for providing custom responses based on specific status codes, such as implementing custom responses when triggering the gateway rate-limiting policy.
|
||||
|
||||
# Description
|
||||
`custom-response` plugin implements a function of sending custom responses, including custom HTTP response status codes, HTTP response headers and HTTP response body, which can be used in the scenarios of response mocking and sending a custom response for specific status codes, such as customizing the response for rate-limited requests.
|
||||
## Running Attributes
|
||||
Plugin Execution Phase: `Authentication Phase`
|
||||
|
||||
# Configuration Fields
|
||||
Plugin Execution Priority: `910`
|
||||
|
||||
| Name | Type | Requirement | Default Value | Description |
|
||||
## Configuration Fields
|
||||
| Name | Data Type | Requirements | Default Value | Description |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
| status_code | number | Optional | 200 | Custom HTTP response status code |
|
||||
| headers | array of string | Optional | - | Custom HTTP response header. Key and value shall be separated using `=`. |
|
||||
| headers | array of string | Optional | - | Custom HTTP response headers, keys and values separated by `=` |
|
||||
| body | string | Optional | - | Custom HTTP response body |
|
||||
| enable_on_status | array of number | Optional | - | The original response status code to match. Generate the custom response only the actual status code matches the configuration. Ignore the status code match if left unconfigured. |
|
||||
|
||||
# Configuration Samples
|
||||
|
||||
## Mock Responses
|
||||
| enable_on_status | array of number | Optional | - | Match original status codes to generate custom responses; if not specified, the original status code is not checked |
|
||||
|
||||
## Configuration Example
|
||||
### Mock Response Scenario
|
||||
```yaml
|
||||
status_code: 200
|
||||
headers:
|
||||
- Content-Type=application/json
|
||||
- Hello=World
|
||||
body: "{\"hello\":\"world\"}"
|
||||
|
||||
```
|
||||
|
||||
According to the configuration above, all the requests will get the following custom response:
|
||||
|
||||
With this configuration, the request will return the following custom response:
|
||||
```text
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
Hello: World
|
||||
Content-Length: 17
|
||||
|
||||
{"hello":"world"}
|
||||
```
|
||||
|
||||
## Send a Custom Response when Rate-Limited
|
||||
|
||||
### Custom Response on Rate Limiting
|
||||
```yaml
|
||||
enable_on_status:
|
||||
enable_on_status:
|
||||
- 429
|
||||
status_code: 302
|
||||
headers:
|
||||
- Location=https://example.com
|
||||
```
|
||||
|
||||
When rate-limited, normally gateway will return a status code of `429` . Now, rate-limited requests will get the following custom response:
|
||||
|
||||
When the gateway rate limiting is triggered, it generally returns the `429` status code, and the request will return the following custom response:
|
||||
```text
|
||||
HTTP/1.1 302 Found
|
||||
Location: https://example.com
|
||||
```
|
||||
This achieves the goal of redirecting users who have been rate-limited to another page based on the browser's 302 redirect mechanism, which could be a static page on a CDN.
|
||||
|
||||
So based on the 302 redirecting mechanism provided by browsers, this can redirect rate-limited users to other pages, for example, a static page hosted on CDN.
|
||||
|
||||
If you'd like to send other responses when rate-limited, please add other fields into the configuration, referring to the Mock Responses scenario.
|
||||
|
||||
## Only Enabled for Specific Routes or Domains
|
||||
```yaml
|
||||
# Use _rules_ field for fine-grained rule configurations
|
||||
_rules_:
|
||||
# Rule 1: Match by route name
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
body: "{\"hello\":\"world\"}"
|
||||
# Rule 2: Match by domain
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
enable_on_status:
|
||||
- 429
|
||||
status_code: 200
|
||||
headers:
|
||||
- Content-Type=application/json
|
||||
body: "{\"errmsg\": \"rate limited\"}"
|
||||
```
|
||||
In the rule sample of `_match_route_`, `route-a` and `route-b` are the route names provided when creating a new gateway route. When the current route names matches the configuration, the rule following shall be applied.
|
||||
In the rule sample of `_match_domain_`, `*.example.com` and `test.com` are the domain names used for request matching. When the current domain name matches the configuration, the rule following shall be applied.
|
||||
All rules shall be checked following the order of items in the `_rules_` field, The first matched rule will be applied. All remained will be ignored.
|
||||
If you wish to return other responses normally when rate limiting is triggered, just refer to the Mock response scenario to configure the relevant fields accordingly.
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:defs.bzl", "proxy_wasm_cc_binary")
|
||||
load("//bazel:wasm.bzl", "declare_wasm_image_targets")
|
||||
|
||||
wasm_cc_binary(
|
||||
proxy_wasm_cc_binary(
|
||||
name = "hmac_auth.wasm",
|
||||
srcs = [
|
||||
"plugin.cc",
|
||||
@@ -30,7 +30,6 @@ wasm_cc_binary(
|
||||
"//common:crypto_util",
|
||||
"//common:http_util",
|
||||
"//common:rule_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
# 功能说明
|
||||
---
|
||||
title: HMAC 认证
|
||||
keywords: [higress,hmac auth]
|
||||
description: HMAC 认证插件配置参考
|
||||
---
|
||||
|
||||
## 功能说明
|
||||
`hmac-auth`插件实现了基于 HMAC 算法为 HTTP 请求生成不可伪造的签名,并基于签名实现身份认证和鉴权
|
||||
|
||||
# 配置字段
|
||||
## 运行属性
|
||||
|
||||
插件执行阶段:`认证阶段`
|
||||
插件执行优先级:`330`
|
||||
|
||||
## 配置字段
|
||||
|
||||
**注意:**
|
||||
|
||||
- 在一个规则里,鉴权配置和认证配置不可同时存在
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
### 认证配置
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ------------- | --------------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `global_auth` | bool | 选填(**仅实例级别配置**) | - | 只能在实例级别配置,若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制,若不配置则仅当没有域名和路由配置时全局生效(兼容老用户使用习惯)。 |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
| `date_offset` | number | 选填 | - | 配置允许的客户端最大时间偏移,单位为秒,根据请求头`Date`解析客户端 UTC 时间,可用于避免请求重放;未配置时,不做校验 |
|
||||
| `_rules_` | array of object | 选填 | - | 配置特定路由或域名的访问权限列表,用于对请求进行鉴权 |
|
||||
|
||||
|
||||
`consumers`中每一项的配置字段说明如下:
|
||||
|
||||
@@ -17,24 +36,21 @@
|
||||
| `secret` | string | 必填 | - | 配置用于生成签名的secret |
|
||||
| `name` | string | 必填 | - | 配置该consumer的名称 |
|
||||
|
||||
`_rules_` 中每一项的配置字段说明如下:
|
||||
### 鉴权配置(非必需)
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ------ | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的路由名称 |
|
||||
| `_match_domain_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的域名 |
|
||||
| `allow` | array of string | 必填 | - | 对于符合匹配条件的请求,配置允许访问的consumer名称 |
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | ------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| `allow` | array of string | 选填(**非实例级别配置**) | - | 只能在路由或域名等细粒度规则上配置,对于符合匹配条件的请求,配置允许访问的 consumer,从而实现细粒度的权限控制 |
|
||||
|
||||
**注意:**
|
||||
- 若不配置`_rules_`字段,则默认对当前网关实例的所有路由开启认证;
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
# 配置示例
|
||||
## 配置示例
|
||||
|
||||
以下配置将对网关特定路由或域名开启 Hmac Auth 认证和鉴权,注意`key`字段不能重复
|
||||
### 全局配置认证和路由粒度进行鉴权
|
||||
|
||||
在实例级别做如下插件配置, 注意`key`字段不能重复:
|
||||
|
||||
## 对特定路由或域名开启
|
||||
```yaml
|
||||
global_auth: false
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
@@ -42,34 +58,33 @@ consumers:
|
||||
- key: appKey-example-2
|
||||
secret: appSecret-example-2
|
||||
name: consumer-2
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer-1
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer-2
|
||||
```
|
||||
每条匹配规则下的`allow`字段用于指定该匹配条件下允许访问的调用者列表;
|
||||
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许`name`为`consumer-1`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将允许`name`为`consumer-2`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
认证成功后,请求的header中会被添加一个`X-Mse-Consumer`字段,其值为调用方的名称,例如`consumer-1`。
|
||||
|
||||
## 网关实例级别开启
|
||||
|
||||
以下配置将对网关实例级别开启 Hamc Auth 认证
|
||||
route-a和route-b两个路由做如下插件配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
|
||||
在*.example.com和test.com两个域名做如下插件配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
若是在控制台进行配置,此例指定的route-a和route-b即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许name为consumer1的调用者访问,其他调用者不允许访问。
|
||||
|
||||
此例指定的*.example.com和test.com用于匹配请求的域名,当发现域名匹配时,将允许name为consumer2的调用者访问,其他调用者不被允许访问。
|
||||
|
||||
|
||||
### 网关实例级别开启
|
||||
|
||||
以下配置将对网关实例级别开启 Hamc Auth 认证,所有请求均需要经过认证后才能访问。
|
||||
|
||||
```yaml
|
||||
global_auth: true
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
@@ -80,18 +95,18 @@ consumers:
|
||||
```
|
||||
|
||||
|
||||
# 签名机制说明
|
||||
## 签名机制说明
|
||||
|
||||
## 配置准备
|
||||
### 配置准备
|
||||
|
||||
如上指引,在插件配置中配置生成和验证签名需要用的凭证配置
|
||||
|
||||
- key: 用于请求头 `x-ca-key` 中设置
|
||||
- secret: 用于生成请求签名
|
||||
|
||||
## 客户端签名生成方式
|
||||
### 客户端签名生成方式
|
||||
|
||||
### 流程简介
|
||||
#### 流程简介
|
||||
|
||||
客户端生成签名一共分三步处理:
|
||||
|
||||
@@ -104,7 +119,7 @@ consumers:
|
||||
如下图所示:
|
||||

|
||||
|
||||
### 签名串提取流程
|
||||
#### 签名串提取流程
|
||||
|
||||
客户端需要从Http请求中提取出关键数据,组合成一个签名串,生成的签名串的格式如下:
|
||||
|
||||
@@ -160,7 +175,7 @@ Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN +
|
||||
|
||||
4. Query和Form存在数组参数时(key相同,value不同的参数) ,取第一个Value参与签名计算
|
||||
|
||||
### 签名串提取示例
|
||||
#### 签名串提取示例
|
||||
|
||||
初始的HTTP请求:
|
||||
```text
|
||||
@@ -190,7 +205,7 @@ x-ca-timestamp:1525872629832
|
||||
/http2test/test?param1=test&password=123456789&username=xiaoming
|
||||
```
|
||||
|
||||
### 签名计算流程
|
||||
#### 签名计算流程
|
||||
|
||||
客户端从HTTP请求中提取出关键数据组装成签名串后,需要对签名串进行加密及编码处理,形成最终的签名
|
||||
|
||||
@@ -206,7 +221,7 @@ String sign = Base64.encodeBase64String(result);
|
||||
|
||||
总结一下,就是将 `stringToSign` 使用UTF-8解码后得到Byte数组,然后使用加密算法对Byte数组进行加密,然后使用Base64算法进行编码,形成最终的签名。
|
||||
|
||||
### 添加签名流程
|
||||
#### 添加签名流程
|
||||
|
||||
客户端需要将以下四个Header放在HTTP请求中传输给API网关,进行签名校验:
|
||||
|
||||
@@ -238,9 +253,9 @@ content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
## 服务端签名验证方式
|
||||
### 服务端签名验证方式
|
||||
|
||||
### 流程简介
|
||||
#### 流程简介
|
||||
|
||||
服务器验证客户端签名一共分四步处理:
|
||||
|
||||
@@ -256,7 +271,7 @@ username=xiaoming&password=123456789
|
||||

|
||||
|
||||
|
||||
## 签名排错方法
|
||||
### 签名排错方法
|
||||
|
||||
网关签名校验失败时,会将服务端的签名串(StringToSign)放到HTTP Response的Header中返回到客户端,Key为:X-Ca-Error-Message,用户只需要将本地计算的签名串(StringToSign)与服务端返回的签名串进行对比即可找到问题;
|
||||
|
||||
@@ -269,7 +284,7 @@ X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json
|
||||
|
||||
```
|
||||
|
||||
# 相关错误码
|
||||
## 相关错误码
|
||||
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
@@ -281,5 +296,3 @@ X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json
|
||||
| 413 | Request Body Too Large | 请求 Body 超过限制大小:32 MB |
|
||||
| 413 | Payload Too Large | 请求 Body 超过全局配置 DownstreamConnectionBufferLimits |
|
||||
| 403 | Unauthorized Consumer | 请求的调用方无访问权限 |
|
||||
|
||||
|
||||
|
||||
@@ -1,76 +1,71 @@
|
||||
# Function Description
|
||||
The `hmac-auth` plugin implements the generation of tamper-proof signatures for HTTP requests based on HMAC algorithm, and uses the signature for identity authentication and authorization.
|
||||
---
|
||||
title: HMAC Authentication
|
||||
keywords: [higress,hmac auth]
|
||||
description: HMAC Authentication plugin configuration reference
|
||||
---
|
||||
## Function Description
|
||||
The `hmac-auth` plugin implements the generation of tamper-proof signatures for HTTP requests based on the HMAC algorithm, and performs authentication and authorization based on the signature.
|
||||
|
||||
# Configuration Fields
|
||||
## Running Attributes
|
||||
Plugin execution phase: `Authentication phase`
|
||||
Plugin execution priority: `330`
|
||||
|
||||
| Name | Data Type | Required | Default | Description |
|
||||
| ------------- | --------------- | -------------| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `consumers` | array of object | Required | - | Configures the caller of the service to authenticate the request. |
|
||||
| `date_offset` | number | Optional | - | Configures the maximum allowed time deviation of the client, in seconds. It is used to parse the client's UTC time from `the Date` header of the request, and can be used to prevent replay attacks. If not configured, no validation is performed. |
|
||||
| `_rules_` | array of object | Optional | - | Configures the access control list for specific routes or domains, used for authorization of requests. |
|
||||
## Configuration Fields
|
||||
**Note:**
|
||||
- In a rule, authentication and authorization configurations cannot coexist.
|
||||
- For requests that pass authentication and authorization, the request header will be added with an `X-Mse-Consumer` field to identify the caller's name.
|
||||
|
||||
The configuration fields for each item in `consumers` are as follows :
|
||||
### Authentication Configuration
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| ------------- | ---------------- | ------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `global_auth` | bool | Optional (**Instance level configuration only**) | - | Can only be configured at the instance level. If set to true, it acts globally; if false, only applies to configured domains and routes. If not configured, it will apply globally only when there are no domain and route configurations (to accommodate old user habits). |
|
||||
| `consumers` | array of object | Mandatory | - | Configures the callers of the service for request authentication. |
|
||||
| `date_offset` | number | Optional | - | Configures the maximum allowed client time offset, in seconds; parsed based on the request header `Date`; can be used to prevent request replay; no validation is performed if not configured. |
|
||||
|
||||
| Name | Data Type| Required | Default| Description |
|
||||
| -------- | -------- | ------------ | ------ | ----------------------------------------------------------------------- |
|
||||
| `key` | string | Required | - | Configures the key extracted from the `x-ca-key` header of the request. |
|
||||
| `secret` | string | Required | - | Configures the secret used to generate the signature. |
|
||||
| `name` | string | Required | - | Configures the name of the consumer. |
|
||||
The configuration fields for each item in `consumers` are as follows:
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| -------- | --------- | ----------- | ------------- | ------------------------------------------- |
|
||||
| `key` | string | Mandatory | - | Configures the key extracted from the `x-ca-key` header of the request. |
|
||||
| `secret` | string | Mandatory | - | Configures the secret used to generate the signature. |
|
||||
| `name` | string | Mandatory | - | Configures the name of the consumer. |
|
||||
|
||||
The configuration fields for each item in `_rules_` are as follows:
|
||||
### Authorization Configuration (Optional)
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| ----------- | ---------------- | --------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `allow` | array of string | Optional (**Non-instance level configuration**) | - | Can only be configured on granular rules such as routes or domains. For requests that match the conditions, configure the allowed consumers to achieve fine-grained permission control. |
|
||||
|
||||
| Name | Data Type | Required | Default | Description |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ---------------------------- | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | Optional, either `_match_route_` or `_match_domain_` must be provided | - | Configures the name of the route to match. |
|
||||
| `_match_domain_` | array of string | Optional, either `_match_route_` or `_match_domain_` must be provided | - | Configures the name of the domain to match. |
|
||||
| `allow` | array of string | Required | - | Configures the name of the consumer to allow for requests that match the specified route or domain. |
|
||||
|
||||
**Note:**
|
||||
- If `_rules_` is not configured, authentication is enabled for all routes on the current gateway instance by default ;
|
||||
- For requests that pass authentication and authorization, a `X-Mse-Consumer` header will be added to the request headers to identify the name of the consumer.
|
||||
|
||||
# Configuration Example
|
||||
|
||||
The following configuration enables Hmac Auth authentication and authorization for specific routes or domains on the gateway. Note that the `key` field should not be duplicated.
|
||||
|
||||
## Enabling for specific routes or domains
|
||||
## Configuration Example
|
||||
### Global Configuration Authentication and Route Granular Authorization
|
||||
Configure the following plugin settings at the instance level. Note that the `key` field cannot be duplicated:
|
||||
```yaml
|
||||
consumers:
|
||||
global_auth: false
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
name: consumer-1
|
||||
- key: appKey-example-2
|
||||
secret: appSecret-example-2
|
||||
name: consumer-2
|
||||
# Configuring Fine-Grained Rules using _rules_ Field
|
||||
_rules_:
|
||||
# Rule 1: Matching by route name.
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer-1
|
||||
# Rule 2: Applies based on domain name matching.
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer-2
|
||||
```
|
||||
The `allow` field under each matching rule specifies the list of callers allowed to access under that matching condition;
|
||||
|
||||
In this example, `route-a` and `route-b` specified in `_match_route_` are the route names filled in when creating the gateway route. When either of these routes is matched, it will allow access to the caller named `consumer-1`, while denying access to other callers;
|
||||
|
||||
In` _match_domain_`, `*.example.com` and `test.com` are used to match the requested domain name. When a match is found, it will allow access to the caller named `consumer-2`, while denying access to other callers;
|
||||
|
||||
Upon successful authentication, the `X-Mse-Consumer` field will be added to the request header with the value set to the caller's name, such as `consumer-1`.。
|
||||
|
||||
## Enable at the Gateway Instance Level
|
||||
|
||||
The following configuration enables HMAC authentication at the gateway instance level.
|
||||
|
||||
For route-a and route-b, configure the plugin as follows:
|
||||
```yaml
|
||||
consumers:
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
For the two domains *.example.com and test.com, configure as follows:
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
If configured in the console, the specified route names route-a and route-b correspond to the route names filled in when creating the gateway routes. When matched to these two routes, access will be allowed for the caller named consumer1, while other callers will not be allowed access.
|
||||
|
||||
The specified *.example.com and test.com are used to match the domains of the requests. When a domain match is found, access will be allowed for the caller named consumer2, while other callers will not be allowed access.
|
||||
|
||||
### Gateway Instance Level Activation
|
||||
The following configuration will enable HMAC Auth authentication at the gateway instance level, requiring all requests to undergo authentication before access.
|
||||
```yaml
|
||||
global_auth: true
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
name: consumer-1
|
||||
@@ -79,34 +74,24 @@ consumers:
|
||||
name: consumer-2
|
||||
```
|
||||
|
||||
## Signature Mechanism Description
|
||||
### Configuration Preparation
|
||||
As mentioned above, configure the credentials required for generating and verifying signatures in the plugin settings.
|
||||
- key: to be set in the request header `x-ca-key`.
|
||||
- secret: used for generating request signatures.
|
||||
|
||||
# Description of Signing Mechanism
|
||||
### Client Signature Generation Process
|
||||
#### Overview
|
||||
The client generates a signature through three main steps:
|
||||
1. Extract key data from the original request to create a string for signing.
|
||||
2. Encrypt the key data signing string using the algorithm and the configured `secret` to obtain the signature.
|
||||
3. Include all relevant headers for the signature into the original HTTP request to form the final HTTP request.
|
||||
|
||||
## Configuration Preparation
|
||||
|
||||
As mentioned in the guide above, configure the credential settings required for generating and validating signatures in the plugin configuration.
|
||||
|
||||
- key: Used for setting in the request header `x-ca-key`.
|
||||
- secret: Used for generating the request signature.
|
||||
|
||||
## Client Signature Generation Method
|
||||
### Overview of the Process
|
||||
|
||||
The process for generating a signature on the client side consists of three steps:
|
||||
|
||||
1. Extracting key data from the original request to obtain a string to be signed.
|
||||
|
||||
2. Using encryption algorithms and the configured `secret` to encrypt the key data signing string and obtain a signature.
|
||||
|
||||
3. Adding all headers related to the signature to the original HTTP request to obtain the final HTTP request.
|
||||
|
||||
As shown below :
|
||||
As shown in the figure below:
|
||||

|
||||
|
||||
### Process for Extracting Signing String
|
||||
|
||||
To generate a signature, the client needs to extract key data from the HTTP request and combine it into a signing string. The format of the generated signing string is as follows:
|
||||
|
||||
#### Signing String Extraction Process
|
||||
The client needs to extract key data from the HTTP request, combine it into a signing string, which has the following format:
|
||||
```text
|
||||
HTTPMethod
|
||||
Accept
|
||||
@@ -116,54 +101,38 @@ Date
|
||||
Headers
|
||||
PathAndParameters
|
||||
```
|
||||
|
||||
The signing string consists of the above 7 fields separated by \n. If Headers is empty, no \n is needed. If other fields are empty, the \n should still be retained. The signature is case-sensitive. Below are the rules for extracting each field:
|
||||
|
||||
- HTTPMethod: The HTTP method used in the request, in all capital letters, such as POST.
|
||||
|
||||
- Accept: The value of the Accept header in the request, which can be empty. It is recommended to explicitly set the Accept header. When Accept is empty, some HTTP clients will set the default value of `*/*`, which may cause signature verification to fail.
|
||||
|
||||
- Content-MD5: The value of the Content-MD5 header in the request, which can be empty. It is only calculated when there is a non-form body in the request. The following is a reference calculation method for Content-MD5 values in :
|
||||
|
||||
|
||||
The seven fields above constitute the entire signing string, separated by newline characters `\n`. If Headers is empty, no newline is needed; other fields should retain `\n` if empty. The signature is case-sensitive. Below are the extraction rules for each field:
|
||||
- HTTPMethod: The HTTP method, all uppercase (e.g., POST).
|
||||
- Accept: The value of the Accept header in the request, can be empty. It is recommended to explicitly set the Accept Header. When Accept is empty, some HTTP clients may set a default value of `*/*`, resulting in a signature verification failure.
|
||||
- Content-MD5: The value of the Content-MD5 header in the request, can be empty. It is calculated only if there is a Body in the request and it is not in Form format. Here’s a reference calculation method for the Content-MD5 value in Java:
|
||||
```java
|
||||
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));
|
||||
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getBytes("UTF-8")));
|
||||
```
|
||||
|
||||
- Content-Type: The value of the Content-Type header in the request, which can be empty.
|
||||
|
||||
- Date: The value of the Date header in the request. When the` date_offset` configuration is not enabled, it can be empty. Otherwise, it will be used for time offset verification.
|
||||
|
||||
- Headers: Users can select specific headers to participate in the signature. There are the following rules for concatenating the signature string with headers:
|
||||
- The keys of the headers participating in the signature calculation are sorted in alphabetical order and concatenated as follows:
|
||||
- Content-Type: The value of the Content-Type header in the request, can be empty.
|
||||
- Date: The value of the Date header in the request. If the `date_offset` configuration is not turned on, it can be empty; otherwise, it will be used for time offset verification.
|
||||
- Headers: Users can select specific headers to participate in the signature. The rules for concatenating the signing header string are as follows:
|
||||
- The Keys of the headers participating in the signature calculation are concatenated after being sorted lexicographically, as follows:
|
||||
```text
|
||||
HeaderKey1 + ":" + HeaderValue1 + "\n"\+
|
||||
HeaderKey2 + ":" + HeaderValue2 + "\n"\+
|
||||
HeaderKey1 + ":" + HeaderValue1 + "\n" +
|
||||
HeaderKey2 + ":" + HeaderValue2 + "\n" +
|
||||
...
|
||||
HeaderKeyN + ":" + HeaderValueN + "\n"
|
||||
```
|
||||
- If the value of a header is empty, it will participate in the signature with the `HeaderKey+":"+"\n"` only, and the key and english colon should be retained.
|
||||
- The set of keys for all headers participating in the signature is separated by a comma and placed in the `X-Ca-Signature-Headers header`.
|
||||
- If the Value of a certain header is empty, use HeaderKey + ":" + "\n" to participate in the signature, retaining the Key and the colon.
|
||||
- The collection of all participating header Keys is placed in the Header with the key X-Ca-Signature-Headers, separated by commas.
|
||||
- The following headers are not included in the header signature calculation: X-Ca-Signature, X-Ca-Signature-Headers, Accept, Content-MD5, Content-Type, Date.
|
||||
|
||||
- PathAndParameters: This field contains all parameters in the path, query, and form. The specific format is as follows:
|
||||
|
||||
- PathAndParameters: This field includes Path, Query, and all parameters in Form, specifically organized as follows:
|
||||
```text
|
||||
Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
|
||||
```
|
||||
Note:
|
||||
1. The Key of Query and Form parameters should be sorted lexicographically before being concatenated as above.
|
||||
2. If Query and Form parameters are empty, just use Path without adding `?`.
|
||||
3. If the Value of parameters is empty, only the Key should be retained in the signature, the equal sign does not need to be added.
|
||||
4. In the case of array parameters (parameters with the same key but different values), only the first Value should be used for signature calculation.
|
||||
|
||||
Notes:
|
||||
1. The keys of the query and form parameter pairs are sorted alphabetically, and the same format as above is used for concatenation.
|
||||
|
||||
2. If there are no query and form parameters, use the path directly without adding `?` .
|
||||
|
||||
3. If the value of a parameter is empty, only the key will be included in the signature. The equal sign should not be included in the signature.
|
||||
|
||||
4. If there are array parameters in the query or form (parameters with the same key but different values), only the first value should be included in the signature calculation.
|
||||
|
||||
### Example of Extracting Signing String
|
||||
|
||||
The initial HTTP request :
|
||||
#### Signing String Extraction Example
|
||||
Initial HTTP request:
|
||||
```text
|
||||
POST /http2test/test?param1=test HTTP/1.1
|
||||
host:api.aliyun.com
|
||||
@@ -177,8 +146,7 @@ x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
|
||||
content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
The correct generated signature string is :
|
||||
The generated correct signing string is:
|
||||
```text
|
||||
POST
|
||||
application/json; charset=utf-8
|
||||
@@ -190,13 +158,10 @@ x-ca-signature-method:HmacSHA256
|
||||
x-ca-timestamp:1525872629832
|
||||
/http2test/test?param1=test&password=123456789&username=xiaoming
|
||||
```
|
||||
#### Signature Calculation Process
|
||||
After the client assembles the key data extracted from the HTTP request into a signing string, it needs to encrypt the signing string and encode it to form the final signature.
|
||||
|
||||
### Signature Calculation Process
|
||||
|
||||
After extracting the key data from the HTTP request and assembling it into a signature string, the client needs to encrypt and encode the signature string to form the final signature.
|
||||
|
||||
The specific encryption format is as follows, where `stringToSign` is the extracted signature string, `secret` is the one filled in the plugin configuration, and `sign` is the final generated signature:
|
||||
|
||||
The specific encryption form is as follows, where `stringToSign` is the extracted signing string, `secret` is the one filled in the plugin configuration, and `sign` is the final generated signature:
|
||||
```java
|
||||
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
|
||||
byte[] secretBytes = secret.getBytes("UTF-8");
|
||||
@@ -204,23 +169,16 @@ hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA25
|
||||
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
|
||||
String sign = Base64.encodeBase64String(result);
|
||||
```
|
||||
To summarize, the `stringToSign` is decoded using UTF-8 to obtain a Byte array, then the encryption algorithm is applied to the Byte array, and finally, the Base64 algorithm is used for encoding, forming the final signature.
|
||||
|
||||
In summary, the `stringToSign` is decoded using UTF-8 to obtain a Byte array. Then, an encryption algorithm is used to encrypt the Byte array, and finally, the Base64 algorithm is used to encode the encrypted data, resulting in the final signature.
|
||||
|
||||
### The Process of Adding a Signature
|
||||
|
||||
The client needs to include the following four headers in the HTTP request to be transmitted to the API gateway for signature verification:
|
||||
|
||||
- x-ca-key: The value is the APP Key and is required.
|
||||
|
||||
- x-ca-signature-method: The signature algorithm, the value can be HmacSHA256 or HmacSHA1, optional. The default value is HmacSHA256.
|
||||
|
||||
- x-ca-signature-headers: The collection of keys for all signature headers, separated by commas. Optional.
|
||||
|
||||
- x-ca-signature: The signature and it is required.
|
||||
|
||||
Here is an example of a complete HTTP request with a signature :
|
||||
#### Adding the Signature Process
|
||||
The client needs to include the following four headers in the HTTP request to transmit to the API gateway for signature verification:
|
||||
- x-ca-key: The APP Key, mandatory.
|
||||
- x-ca-signature-method: The signature algorithm, can be HmacSHA256 or HmacSHA1, optional, default is HmacSHA256.
|
||||
- x-ca-signature-headers: The collection of all signature header Keys, separated by commas, optional.
|
||||
- x-ca-signature: The signature, mandatory.
|
||||
|
||||
Below is an example of the entire HTTP request carrying the signature:
|
||||
```text
|
||||
POST /http2test/test?param1=test HTTP/1.1
|
||||
host:api.aliyun.com
|
||||
@@ -239,48 +197,35 @@ content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
## Server-side Signature Verification Method
|
||||
### Server-side Signature Verification Method
|
||||
#### Overview
|
||||
The server verifies the client signature through four main steps:
|
||||
1. Extract key data from the received request to create a signing string.
|
||||
2. Read the `key` from the received request and query the corresponding `secret`.
|
||||
3. Encrypt the key data signing string using the algorithm and the `secret` to obtain the signature.
|
||||
4. Read the client signature from the received request and compare the server-side signature with the client-side signature for consistency.
|
||||
|
||||
### Overview of the Process
|
||||
|
||||
The server-side signature verification of the client's request involves four steps :
|
||||
|
||||
1. Extract crucial data from the received request to obtain a string for signing.
|
||||
|
||||
2. Retrieve the `key` from the received request and use it to query its corresponding `secret`.
|
||||
|
||||
3. Encrypt the string for signing using the encryption algorithm and `secret`.
|
||||
|
||||
4. Retrieve the client's signature from the received request, and compare the consistency of the server-side signature with the client's signature.
|
||||
|
||||
As shown below :
|
||||
As shown in the figure below:
|
||||

|
||||
|
||||
### Signature Troubleshooting Method
|
||||
When the gateway signature verification fails, the server's signing string (StringToSign) will be returned in the HTTP Response header to the client, with the key: X-Ca-Error-Message. The user only needs to compare the locally computed signing string (StringToSign) with the signing string returned by the server to find the issue.
|
||||
|
||||
## Troubleshooting Signature Errors
|
||||
|
||||
When the gateway signature verification fails, the server-side signing string (StringToSign) will be returned to the client in the HTTP Response Header. The key is X-Ca-Error-Message. Users only need to compare the locally calculated signing string with the server-side signing string returned to locate the problem;
|
||||
|
||||
If the StringToSign on the server side is consistent with that on the client side, please check whether the APP Secret used for signature calculation is correct;
|
||||
|
||||
Because line breaks cannot be represented in HTTP headers, all line breaks in the StringToSign are replaced with #, as shown below:
|
||||
If the StringToSign from the server and the client are consistent, please check whether the APP Secret used for signature calculation is correct.
|
||||
|
||||
Since HTTP headers cannot express line breaks, the line breaks in the StringToSign have been replaced with `#`, as shown below:
|
||||
```text
|
||||
X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`
|
||||
|
||||
```
|
||||
|
||||
# Related Error Codes
|
||||
|
||||
| HTTP Status Code | Error Message | Reason |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
| 401 | Invalid Key | The x-ca-key request header is not provided or is invalid. |
|
||||
| 401 | Empty Signature | The x-ca-signature request header does not contain a signature. |
|
||||
| 400 | Invalid Signature | The x-ca-signature request header contains a signature that does not match the server-calculated signature. |
|
||||
| 400 | Invalid Content-MD5 | The content-md5 request header is incorrect. |
|
||||
| 400 | Invalid Date | The time offset calculated based on the date request header exceeds the configured date_offset. |
|
||||
| 413 | Request Body Too Large | The request body exceeds the size limit of 32 MB. |
|
||||
| 413 | Payload Too Large | The request body exceeds the DownstreamConnectionBufferLimits global configuration. |
|
||||
| 403 | Unauthorized Consumer | The requesting party does not have access permission. |
|
||||
|
||||
|
||||
## Related Error Codes
|
||||
| HTTP Status Code | Error Message | Reasoning |
|
||||
| ---------------- | --------------------- | --------------------------------------------- |
|
||||
| 401 | Invalid Key | The request header did not provide x-ca-key, or x-ca-key is invalid. |
|
||||
| 401 | Empty Signature | The request header did not provide the x-ca-signature signing string. |
|
||||
| 400 | Invalid Signature | The x-ca-signature signing string in the request header does not match the signature calculated by the server. |
|
||||
| 400 | Invalid Content-MD5 | The Content-MD5 header in the request is incorrect. |
|
||||
| 400 | Invalid Date | The time offset calculated based on the Date header in the request exceeds the configured date_offset. |
|
||||
| 413 | Request Body Too Large| The request Body exceeds the maximum size of 32 MB. |
|
||||
| 413 | Payload Too Large | The request Body exceeds the global configured DownstreamConnectionBufferLimits. |
|
||||
| 403 | Unauthorized Consumer | The calling party does not have access permissions for the request. |
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
|
||||
load("@proxy_wasm_cpp_sdk//bazel:defs.bzl", "proxy_wasm_cc_binary")
|
||||
load("//bazel:wasm.bzl", "declare_wasm_image_targets")
|
||||
|
||||
wasm_cc_binary(
|
||||
@@ -33,7 +33,6 @@ wasm_cc_binary(
|
||||
"//common:json_util",
|
||||
"//common:http_util",
|
||||
"//common:rule_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,17 +1,216 @@
|
||||
# 功能说明
|
||||
---
|
||||
title: JWT 认证
|
||||
keywords: [higress,jwt auth]
|
||||
description: JWT 认证插件配置参考
|
||||
---
|
||||
|
||||
## 功能说明
|
||||
`jwt-auth`插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能,支持从HTTP请求的URL参数、请求头、Cookie字段解析JWT,同时验证该Token是否有权限访问。
|
||||
|
||||
本插件和`安全能力->认证鉴权`中JWT认证的区别是,额外提供了调用方身份识别的能力,支持对不同调用方配置不同的JWT凭证。
|
||||
|
||||
# 详细说明
|
||||
## 运行属性
|
||||
|
||||
## 1、基于token的认证
|
||||
插件执行阶段:`认证阶段`
|
||||
插件执行优先级:`340`
|
||||
|
||||
### 1.1 简介
|
||||
## 配置字段
|
||||
|
||||
**注意:**
|
||||
|
||||
- 在一个规则里,鉴权配置和认证配置不可同时存在
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
### 认证配置
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | ------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| `global_auth` | bool | 选填(**仅实例级别配置**) | - | 只能在实例级别配置,若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制,若不配置则仅当没有域名和路由配置时全局生效(兼容老用户使用习惯)。 |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
|
||||
`consumers`中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------------------- | ----------------- | -------- | ------------------------------------------------- | ------------------------ |
|
||||
| `name` | string | 必填 | - | 配置该consumer的名称 |
|
||||
| `jwks` | string | 必填 | - | https://www.rfc-editor.org/rfc/rfc7517 指定的json格式字符串,是由验证JWT中签名的公钥(或对称密钥)组成的Json Web Key Set |
|
||||
| `issuer` | string | 必填 | - | JWT的签发者,需要和payload中的iss字段保持一致 |
|
||||
| `claims_to_headers` | array of object | 选填 | - | 抽取JWT的payload中指定字段,设置到指定的请求头中转发给后端 |
|
||||
| `from_headers` | array of object | 选填 | {"name":"Authorization","value_prefix":"Bearer "} | 从指定的请求头中抽取JWT |
|
||||
| `from_params` | array of string | 选填 | access_token | 从指定的URL参数中抽取JWT |
|
||||
| `from_cookies` | array of string | 选填 | - | 从指定的cookie中抽取JWT |
|
||||
| `clock_skew_seconds` | number | 选填 | 60 | 校验JWT的exp和iat字段时允许的时钟偏移量,单位为秒 |
|
||||
| `keep_token` | bool | 选填 | ture | 转发给后端时是否保留JWT |
|
||||
|
||||
**注意:**
|
||||
- 只有当`from_headers`,`from_params`,`from_cookies`均未配置时,才会使用默认值
|
||||
|
||||
`from_headers` 中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求| 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------- | ------ | --------------------------------------------------------- |
|
||||
| `name` | string | 必填 | - | 抽取JWT的请求header |
|
||||
| `value_prefix` | string | 必填 | - | 对请求header的value去除此前缀,剩余部分作为JWT |
|
||||
|
||||
`claims_to_headers` 中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求| 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------- | ------ | --------------------------------------------------------- |
|
||||
| `claim` | string | 必填 | - | JWT payload中的指定字段,要求必须是字符串或无符号整数类型 |
|
||||
| `header` | string | 必填 | - | 从payload取出字段的值设置到这个请求头中,转发给后端 |
|
||||
| `override` | bool | 选填 | true | true时,存在同名请求头会进行覆盖;false时,追加同名请求头 |
|
||||
|
||||
|
||||
### 鉴权配置(非必需)
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | ------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| `allow` | array of string | 选填(**非实例级别配置**) | - | 只能在路由或域名等细粒度规则上配置,对于符合匹配条件的请求,配置允许访问的 consumer,从而实现细粒度的权限控制 |
|
||||
|
||||
## 配置示例
|
||||
|
||||
### 全局配置认证和路由粒度进行鉴权
|
||||
|
||||
注意如果一个JWT能匹配多个`jwks`,则按照配置顺序命中第一个匹配的`consumer`
|
||||
|
||||
在实例级别做如下插件配置:
|
||||
|
||||
```yaml
|
||||
global_auth: false
|
||||
consumers:
|
||||
- name: consumer1
|
||||
issuer: abcd
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "oct",
|
||||
"kid": "123",
|
||||
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
|
||||
"alg": "HS256"
|
||||
}
|
||||
]
|
||||
}
|
||||
- name: consumer2
|
||||
issuer: abc
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "RSA",
|
||||
"e": "AQAB",
|
||||
"use": "sig",
|
||||
"kid": "123",
|
||||
"alg": "RS256",
|
||||
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
对 route-a 和 route-b 这两个路由做如下配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
|
||||
对 *.example.com 和 test.com 在这两个域名做如下配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
**说明:**
|
||||
|
||||
此例指定的route-a和route-b即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许name为consumer1的调用者访问,其他调用者不允许访问。
|
||||
|
||||
此例指定的*.example.com和test.com用于匹配请求的域名,当发现域名匹配时,将允许name为consumer2的调用者访问,其他调用者不被允许访问。
|
||||
|
||||
根据该配置,下列请求可以允许访问:
|
||||
|
||||
假设以下请求会匹配到route-a这条路由
|
||||
|
||||
**将 JWT 设置在 url 参数中**
|
||||
```bash
|
||||
curl 'http://xxx.hello.com/test?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
**将 JWT 设置在 http 请求头中**
|
||||
```bash
|
||||
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
|
||||
认证鉴权通过后,请求的header中会被添加一个`X-Mse-Consumer`字段,在此例中其值为`consumer1`,用以标识调用方的名称
|
||||
|
||||
下列请求将拒绝访问:
|
||||
|
||||
**请求未提供JWT,返回401**
|
||||
```bash
|
||||
curl http://xxx.hello.com/test
|
||||
```
|
||||
|
||||
**根据请求提供的JWT匹配到的调用者无访问权限,返回403**
|
||||
```bash
|
||||
# consumer1不在*.example.com的allow列表里
|
||||
curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
|
||||
#### 网关实例级别开启
|
||||
|
||||
以下配置将对网关实例级别开启 JWT Auth 认证,所有请求均需要经过认证后才能访问。
|
||||
|
||||
```yaml
|
||||
global_auth: true
|
||||
consumers:
|
||||
- name: consumer1
|
||||
issuer: abcd
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "oct",
|
||||
"kid": "123",
|
||||
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
|
||||
"alg": "HS256"
|
||||
}
|
||||
]
|
||||
}
|
||||
- name: consumer2
|
||||
issuer: abc
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "RSA",
|
||||
"e": "AQAB",
|
||||
"use": "sig",
|
||||
"kid": "123",
|
||||
"alg": "RS256",
|
||||
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 常见错误码说明
|
||||
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
| 401 | Jwt missing | 请求头未提供JWT |
|
||||
| 401 | Jwt expired | JWT已经过期 |
|
||||
| 401 | Jwt verification fails | JWT payload校验失败,如iss不匹配 |
|
||||
| 403 | Access Denied | 无权限访问当前路由 |
|
||||
|
||||
## 详细说明
|
||||
|
||||
### 1、基于token的认证
|
||||
|
||||
#### 1.1 简介
|
||||
|
||||
很多对外开放的API需要识别请求者的身份,并据此判断所请求的资源是否可以返回给请求者。token就是一种用于身份验证的机制,基于这种机制,应用不需要在服务端保留用户的认证信息或者会话信息,可实现无状态、分布式的Web应用授权,为应用的扩展提供了便利。
|
||||
|
||||
### 1.2 流程描述
|
||||
#### 1.2 流程描述
|
||||
|
||||

|
||||
|
||||
@@ -35,13 +234,13 @@
|
||||
|
||||
在这个整个过程中, 网关利用token认证机制,实现了用户使用自己的用户体系对自己API进行授权的能力。下面我们就要介绍网关实现token认证所使用的结构化令牌Json Web Token(JWT)。
|
||||
|
||||
### 1.3 JWT
|
||||
#### 1.3 JWT
|
||||
|
||||
#### 1.3.1 简介
|
||||
##### 1.3.1 简介
|
||||
|
||||
Json Web Toke(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准RFC7519。JWT一般可以用作独立的身份验证令牌,可以包含用户标识、用户角色和权限等信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,特别适用于分布式站点的登录场景。
|
||||
|
||||
#### 1.3.2 JWT的构成
|
||||
##### 1.3.2 JWT的构成
|
||||
|
||||
`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ`
|
||||
|
||||
@@ -119,11 +318,11 @@ var signature = HMACSHA256(encodedString, '$secret');
|
||||
将这三部分用 . 连接成一个完整的字符串,就构成了 1.3.2 节最开始的JWT示例。
|
||||
|
||||
|
||||
#### 1.3.3 时效
|
||||
##### 1.3.3 时效
|
||||
|
||||
网关会验证token中的exp字段,一旦这个字段过期了,网关会认为这个token无效而将请求直接打回。过期时间这个值必须设置。
|
||||
|
||||
#### 1.3.4 JWT的几个特点
|
||||
##### 1.3.4 JWT的几个特点
|
||||
|
||||
1. JWT 默认是不加密,不能将秘密数据写入 JWT。
|
||||
2. JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
|
||||
@@ -131,9 +330,9 @@ var signature = HMACSHA256(encodedString, '$secret');
|
||||
4. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
|
||||
5. 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用HTTPS 协议传输。
|
||||
|
||||
## 2、用户系统如何应用JWT插件保护API
|
||||
### 2、用户系统如何应用JWT插件保护API
|
||||
|
||||
### 2.1 生成一对JWK(JSON Web 密钥)
|
||||
#### 2.1 生成一对JWK(JSON Web 密钥)
|
||||
|
||||
**方法一、在线生成:**
|
||||
|
||||
@@ -162,7 +361,7 @@ final String publicKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLeve
|
||||
final String privateKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
|
||||
```
|
||||
|
||||
### 2.2 使用JWK中的私钥实现颁发token 的认证服务
|
||||
#### 2.2 使用JWK中的私钥实现颁发token 的认证服务
|
||||
|
||||
需要使用2.1节中在线生成的 Keypair JSON字符串(三个方框内的第一个)或者本地生成的 privateKeyString JSON字符串作为私钥来颁发token,用于授权可信的用户访问受保护的API,具体实现可以参考下方示例。 向客户颁发token的形式由用户根据具体的业务场景决定,可以将颁发token的功能部署到生产环境,配置成普通API后由访问者通过用户名密码获得,也可以直接在本地环境生成token 后,直接拷贝给指定用户使用。
|
||||
|
||||
@@ -216,187 +415,3 @@ public class GenerateJwtDemo {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# 插件配置说明
|
||||
|
||||
## 配置字段
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | ------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
| `_rules_` | array of object | 选填 | - | 配置特定路由或域名的访问权限列表,用于对请求进行鉴权 |
|
||||
|
||||
`consumers`中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------------------- | ----------------- | -------- | ------------------------------------------------- | ------------------------ |
|
||||
| `name` | string | 必填 | - | 配置该consumer的名称 |
|
||||
| `jwks` | string | 必填 | - | https://www.rfc-editor.org/rfc/rfc7517 指定的json格式字符串,是由验证JWT中签名的公钥(或对称密钥)组成的Json Web Key Set |
|
||||
| `issuer` | string | 必填 | - | JWT的签发者,需要和payload中的iss字段保持一致 |
|
||||
| `claims_to_headers` | array of object | 选填 | - | 抽取JWT的payload中指定字段,设置到指定的请求头中转发给后端 |
|
||||
| `from_headers` | array of object | 选填 | {"name":"Authorization","value_prefix":"Bearer "} | 从指定的请求头中抽取JWT |
|
||||
| `from_params` | array of string | 选填 | access_token | 从指定的URL参数中抽取JWT |
|
||||
| `from_cookies` | array of string | 选填 | - | 从指定的cookie中抽取JWT |
|
||||
| `clock_skew_seconds` | number | 选填 | 60 | 校验JWT的exp和iat字段时允许的时钟偏移量,单位为秒 |
|
||||
| `keep_token` | bool | 选填 | ture | 转发给后端时是否保留JWT |
|
||||
|
||||
**注意:**
|
||||
- 只有当`from_headers`,`from_params`,`from_cookies`均未配置时,才会使用默认值
|
||||
|
||||
`from_headers` 中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求| 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------- | ------ | --------------------------------------------------------- |
|
||||
| `name` | string | 必填 | - | 抽取JWT的请求header |
|
||||
| `value_prefix` | string | 必填 | - | 对请求header的value去除此前缀,剩余部分作为JWT |
|
||||
|
||||
`claims_to_headers` 中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求| 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------- | ------ | --------------------------------------------------------- |
|
||||
| `claim` | string | 必填 | - | JWT payload中的指定字段,要求必须是字符串或无符号整数类型 |
|
||||
| `header` | string | 必填 | - | 从payload取出字段的值设置到这个请求头中,转发给后端 |
|
||||
| `override` | bool | 选填 | true | true时,存在同名请求头会进行覆盖;false时,追加同名请求头 |
|
||||
|
||||
|
||||
`_rules_` 中每一项的配置字段说明如下:
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ------ | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的路由名称 |
|
||||
| `_match_domain_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的域名 |
|
||||
| `allow` | array of string | 必填 | - | 对于符合匹配条件的请求,配置允许访问的consumer名称 |
|
||||
|
||||
**注意:**
|
||||
- 若不配置`_rules_`字段,则默认对当前网关实例的所有路由开启认证;
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
## 配置示例
|
||||
|
||||
### 对特定路由或域名开启
|
||||
|
||||
以下配置将对网关特定路由或域名开启 Jwt Auth 认证和鉴权,注意如果一个JWT能匹配多个`jwks`,则按照配置顺序命中第一个匹配的`consumer`
|
||||
|
||||
```yaml
|
||||
consumers:
|
||||
- name: consumer1
|
||||
issuer: abcd
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "oct",
|
||||
"kid": "123",
|
||||
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
|
||||
"alg": "HS256"
|
||||
}
|
||||
]
|
||||
}
|
||||
- name: consumer2
|
||||
issuer: abc
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "RSA",
|
||||
"e": "AQAB",
|
||||
"use": "sig",
|
||||
"kid": "123",
|
||||
"alg": "RS256",
|
||||
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
|
||||
}
|
||||
]
|
||||
}
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer1
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许`name`为`consumer1`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将允许`name`为`consumer2`的调用者访问,其他调用者不允许访问。
|
||||
|
||||
#### 根据该配置,下列请求可以允许访问:
|
||||
|
||||
假设以下请求会匹配到route-a这条路由
|
||||
|
||||
**将 JWT 设置在 url 参数中**
|
||||
```bash
|
||||
curl 'http://xxx.hello.com/test?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
**将 JWT 设置在 http 请求头中**
|
||||
```bash
|
||||
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
|
||||
认证鉴权通过后,请求的header中会被添加一个`X-Mse-Consumer`字段,在此例中其值为`consumer1`,用以标识调用方的名称
|
||||
|
||||
#### 下列请求将拒绝访问:
|
||||
|
||||
**请求未提供JWT,返回401**
|
||||
```bash
|
||||
curl http://xxx.hello.com/test
|
||||
```
|
||||
|
||||
**根据请求提供的JWT匹配到的调用者无访问权限,返回403**
|
||||
```bash
|
||||
# consumer1不在*.example.com的allow列表里
|
||||
curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
|
||||
```
|
||||
|
||||
### 网关实例级别开启
|
||||
|
||||
以下配置未指定`_rules_`字段,因此将对网关实例级别开启 JWT Auth 认证
|
||||
|
||||
```yaml
|
||||
consumers:
|
||||
- name: consumer1
|
||||
issuer: abcd
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "oct",
|
||||
"kid": "123",
|
||||
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
|
||||
"alg": "HS256"
|
||||
}
|
||||
]
|
||||
}
|
||||
- name: consumer2
|
||||
issuer: abc
|
||||
jwks: |
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"kty": "RSA",
|
||||
"e": "AQAB",
|
||||
"use": "sig",
|
||||
"kid": "123",
|
||||
"alg": "RS256",
|
||||
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
# 常见错误码说明
|
||||
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
| 401 | Jwt missing | 请求头未提供JWT |
|
||||
| 401 | Jwt expired | JWT已经过期 |
|
||||
| 401 | Jwt verification fails | JWT payload校验失败,如iss不匹配 |
|
||||
| 403 | Access Denied | 无权限访问当前路由 |
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user