mirror of https://github.com/istio/proxy.git
Compare commits
475 Commits
Author | SHA1 | Date |
---|---|---|
|
85c28434c3 | |
|
dd3d9baa45 | |
|
28bd02a1b9 | |
|
51074d7979 | |
|
2cb036959c | |
|
3ae982ec4e | |
|
fbe1167e87 | |
|
fba14d9f67 | |
|
38b94dff3e | |
|
fb3df4ebd1 | |
|
9ca562874b | |
|
884980ae61 | |
|
715e9950d3 | |
|
85878351b6 | |
|
b80b90e891 | |
|
a568c3561a | |
|
b2f733524a | |
|
a04f0159fd | |
|
9414c10b56 | |
|
8ffb10eef0 | |
|
465dfe27b8 | |
|
eac6a8ea28 | |
|
c51abd662d | |
|
491c23b5b2 | |
|
17926fc432 | |
|
8243b8a544 | |
|
866870fac0 | |
|
3a3d5c5eeb | |
|
f1a368d5fe | |
|
1409b2e78f | |
|
cbc8bcc988 | |
|
3c9dbf2756 | |
|
aea95c7140 | |
|
4e8d8ea338 | |
|
e477738647 | |
|
44e40b801e | |
|
72326c50df | |
|
28c94ac20d | |
|
7230983027 | |
|
8fd34bd127 | |
|
5f58981e6f | |
|
0507e331dd | |
|
16fad2b5d9 | |
|
5d4727241d | |
|
024957f198 | |
|
d023cdd5f0 | |
|
cb2c0289b1 | |
|
e5dc651d35 | |
|
3941fec91b | |
|
1fae178953 | |
|
f3c11540b0 | |
|
cfde121e25 | |
|
f7d8213fb6 | |
|
68585389c4 | |
|
1834fcc306 | |
|
aab89e829d | |
|
1b16ce6423 | |
|
7b20907635 | |
|
65c34ec654 | |
|
06e3ead9db | |
|
63942621de | |
|
f3131949e4 | |
|
87dd28dfaf | |
|
633531a5bc | |
|
85c932f655 | |
|
f0842aa465 | |
|
0e1ff29aa8 | |
|
8d28fdd081 | |
|
d12108e0db | |
|
9445f5937f | |
|
1ca15b8ba6 | |
|
6aaacdd054 | |
|
1dbc6e9794 | |
|
9064710ab4 | |
|
2c605ad6f5 | |
|
14537f0863 | |
|
e6d9841a4f | |
|
66388d0181 | |
|
72630c019f | |
|
b52e33a823 | |
|
c5d3627199 | |
|
5cecd24136 | |
|
c4fcc92e44 | |
|
85d93e0013 | |
|
44c82b7b9c | |
|
5df4291d78 | |
|
9950dd1ee8 | |
|
097f8c563c | |
|
de9edf0b67 | |
|
43f7e312ff | |
|
1e6beeaa55 | |
|
88df19ee23 | |
|
7bafbf2268 | |
|
b17690c0e3 | |
|
47efd7a031 | |
|
4e48433cd0 | |
|
6d266652c8 | |
|
9d176df1db | |
|
115b0eb036 | |
|
216b9ef9fb | |
|
4e641e0bb8 | |
|
4ba4edc9e6 | |
|
e6e2ed4f4f | |
|
514a644781 | |
|
e0fd35acbd | |
|
a8dc181482 | |
|
d36a211276 | |
|
5a62959ebf | |
|
b0d4ae0c83 | |
|
b6258b5d41 | |
|
a16c86c7b2 | |
|
ebe9ed11ed | |
|
c00934a851 | |
|
8358a38f0a | |
|
e2782afa20 | |
|
e7a3438021 | |
|
c271a2a361 | |
|
aca940e1ae | |
|
f5f75fccad | |
|
43e7bea767 | |
|
e211657be9 | |
|
b25f1c6363 | |
|
4a2d8f7541 | |
|
405c75a8fd | |
|
a096eab649 | |
|
29a1faa60c | |
|
350f6d5c01 | |
|
f3d9265744 | |
|
b2f49ea7c0 | |
|
832185f524 | |
|
52cd9c1e00 | |
|
0708949e77 | |
|
187ef6426b | |
|
8572e6de6a | |
|
2240686201 | |
|
12c92748ed | |
|
147cc9af7b | |
|
dfae03070b | |
|
a757555db3 | |
|
e80703132d | |
|
4b4991300c | |
|
2d9c9eb1da | |
|
f08201e7c7 | |
|
b3920fcf56 | |
|
7152aa80e7 | |
|
854c889f4c | |
|
1aa0851ed5 | |
|
9963cb6e79 | |
|
7e21bf29d9 | |
|
dc8bf846a0 | |
|
a3b20fbf0d | |
|
b1a30a228b | |
|
630838deca | |
|
bbdabac40a | |
|
09b8e0419e | |
|
285284dcd8 | |
|
00ca866cb9 | |
|
ea517cadc8 | |
|
0954debc61 | |
|
72a567fb4c | |
|
c81d1c7910 | |
|
c299ef8332 | |
|
0e24cfb9ec | |
|
ddc87ca613 | |
|
70d182b019 | |
|
44133ea459 | |
|
d72a525881 | |
|
7bce06d301 | |
|
9dacc003f0 | |
|
ad794e899c | |
|
e6b4dc405b | |
|
b9c8138326 | |
|
5d5edd4817 | |
|
f777f1f75f | |
|
dd13c6784a | |
|
3944d5c584 | |
|
12794c7725 | |
|
450bbc9559 | |
|
d5285a06d5 | |
|
b2eb9e6de2 | |
|
87f21076d0 | |
|
5dd1d365e4 | |
|
09bbb30113 | |
|
3300cfebf5 | |
|
277287076f | |
|
3ee8889e31 | |
|
9d289678ba | |
|
2c1a278182 | |
|
ad2deb3f81 | |
|
9ca2524d6c | |
|
cfdde45e96 | |
|
089e781c2e | |
|
526aeb10d3 | |
|
a9f18ad30a | |
|
896077d9f4 | |
|
0e5ee833b5 | |
|
f7cc614dc1 | |
|
e425bfecd5 | |
|
519448b6d8 | |
|
b1237fd9f2 | |
|
1dc69a1c9e | |
|
43adfed2e0 | |
|
f3b3ab2f73 | |
|
068793d292 | |
|
a895327df8 | |
|
cbd898add0 | |
|
6b493c7aca | |
|
549d3bbb86 | |
|
ce668311b7 | |
|
35e62e2c29 | |
|
c138703eee | |
|
91b5e5d46a | |
|
96bb942e84 | |
|
04b6075e14 | |
|
4100b590bb | |
|
30bf0d6a46 | |
|
1db3ffd955 | |
|
0c0386455b | |
|
6b385ab792 | |
|
84caaba23a | |
|
0471d24373 | |
|
6b837d5dd8 | |
|
1ebefd0ea0 | |
|
0cc7022f53 | |
|
081e87a37b | |
|
4003e06aa8 | |
|
cd9f9e69b7 | |
|
2b17fbbead | |
|
8f1a4189e8 | |
|
b8cc914c8f | |
|
0149de9855 | |
|
8948e13f48 | |
|
bf2163d9eb | |
|
a83a8b718a | |
|
e12e71e769 | |
|
4bdf258a3f | |
|
7c1428643f | |
|
56b4d5caec | |
|
bf82f0c322 | |
|
a5f9c4e06f | |
|
8e4c54e6d2 | |
|
5cef8c326e | |
|
c98bc5b067 | |
|
9385ad46e7 | |
|
afcfa7519c | |
|
2821208112 | |
|
75315e65c5 | |
|
777579cc6f | |
|
584d399c25 | |
|
cfbefc9cb1 | |
|
b0f5c6e40e | |
|
2070827719 | |
|
911737b96b | |
|
1e9d92a616 | |
|
1450780f36 | |
|
289151ac12 | |
|
5e3d334582 | |
|
93aad69a6c | |
|
5d72fdac48 | |
|
5280e55dac | |
|
cf1ff87ebb | |
|
871d23e6bd | |
|
73396379b4 | |
|
6d5d324009 | |
|
5f336d92df | |
|
2e561cd539 | |
|
33e229a1a4 | |
|
bc9a03cd86 | |
|
61f031f010 | |
|
2d0b426070 | |
|
131fb41236 | |
|
dff3c5eaea | |
|
70049a6c89 | |
|
c5df3135b4 | |
|
cee476c96f | |
|
9b5152057e | |
|
608d683460 | |
|
b175ff3c4e | |
|
21aa6a5fa1 | |
|
e17dfe800f | |
|
da3f3f8122 | |
|
493c490cbf | |
|
6ef4d417d0 | |
|
803f9a71ee | |
|
bbbf5dc561 | |
|
8fc6b12b4d | |
|
4c198c0739 | |
|
5f80bc103d | |
|
c834fac2f6 | |
|
7f6e22aa5b | |
|
196be6aab9 | |
|
879300a40c | |
|
ff43dec5cd | |
|
01b8fd5b11 | |
|
e4fafdc06a | |
|
8164fd671b | |
|
94437650db | |
|
f5fb004f30 | |
|
7725c1c986 | |
|
225979a62a | |
|
04ba57ef85 | |
|
ff0b57fc20 | |
|
1320648113 | |
|
491e261847 | |
|
31b603f46e | |
|
f6e8766f0b | |
|
99c27a9bb0 | |
|
a2fc3f7a78 | |
|
f30adb60de | |
|
7f4961784f | |
|
ea251d9027 | |
|
42ab5848de | |
|
5800040e3a | |
|
ec7c4d555e | |
|
1ceb165669 | |
|
ebc43dd8e8 | |
|
c8bfbf6439 | |
|
698faa778c | |
|
e498583f62 | |
|
daadd7371a | |
|
fdb55fe680 | |
|
450b33ddf3 | |
|
f124d0e092 | |
|
ba8893c737 | |
|
4a4f8885dd | |
|
e86741054f | |
|
9734540ba3 | |
|
3ff69b49ba | |
|
e0d4ce52e3 | |
|
d4b933c0b9 | |
|
cf09bab953 | |
|
b53d450663 | |
|
467eae0d7a | |
|
fba4c67cf6 | |
|
3790ec743b | |
|
b641be303d | |
|
0df62073b0 | |
|
b34faf3ec2 | |
|
cec2166722 | |
|
48238cfe62 | |
|
ba9135cfbd | |
|
96cbb48e14 | |
|
b23760cf29 | |
|
94d6398e8a | |
|
a0129815ff | |
|
ad5609d5f5 | |
|
b61546a054 | |
|
b155d715a8 | |
|
27a7461581 | |
|
c955d82537 | |
|
b6fc5b58d9 | |
|
cf6bb6b2d6 | |
|
3005ce3fe1 | |
|
32b266f1c9 | |
|
eb920e9e6f | |
|
ddae7098b8 | |
|
1a8e8d40ff | |
|
9fb55b8c33 | |
|
f5a53daf0d | |
|
b5771ab520 | |
|
db5107d018 | |
|
e11c37aeca | |
|
332c542aa5 | |
|
c59a38d143 | |
|
fc942e4295 | |
|
006527e964 | |
|
44fe838efc | |
|
430338d16e | |
|
ff75792665 | |
|
6a4e70feef | |
|
9f66492f0f | |
|
0840b5ca18 | |
|
3b82953e0e | |
|
bee898357e | |
|
535ce95086 | |
|
7ace483f40 | |
|
75004b8bd4 | |
|
24a4847dcf | |
|
bd3177ba7a | |
|
53d0d548e5 | |
|
b6591a9999 | |
|
4e37264f7c | |
|
1211b219d5 | |
|
2111f1a3fc | |
|
f204be73bd | |
|
9d9dc7d9c8 | |
|
0850bd6625 | |
|
989a8cbcae | |
|
180dcc50d1 | |
|
b9a56ed5f7 | |
|
94a9e192d4 | |
|
db8d49dcaf | |
|
3634966d32 | |
|
4187a10812 | |
|
e8a7218486 | |
|
9285105258 | |
|
afbd9e264a | |
|
628088d580 | |
|
56490c48a5 | |
|
0c71d1f824 | |
|
e61e6f97c6 | |
|
4195ae840b | |
|
023e10a7fc | |
|
b4abf6ae06 | |
|
3e285c1c77 | |
|
c53a6ed438 | |
|
122cdba413 | |
|
adfb08fe49 | |
|
9dfefce0ae | |
|
62e93ff050 | |
|
c04da862b8 | |
|
3e2ee68c64 | |
|
be9ed1dcbb | |
|
1b4b7499b5 | |
|
57e863b743 | |
|
033cbd1ef4 | |
|
812f11396d | |
|
ff08598396 | |
|
fb0f97b8dd | |
|
1e5b6e37c8 | |
|
cd1ff0473f | |
|
77a9a2bda1 | |
|
5643d90bd3 | |
|
2d9173b3b4 | |
|
4bb7691fff | |
|
28487117a4 | |
|
31dc68618f | |
|
dc4f975ef3 | |
|
7d3cb6e416 | |
|
5bba4704fd | |
|
098fa0cf40 | |
|
20355fc368 | |
|
4363d1c647 | |
|
42191ac9c2 | |
|
4a2e408ea7 | |
|
967f36f0e9 | |
|
456db56c0b | |
|
4aa2c2c7a7 | |
|
f22b7930b6 | |
|
35e33dc9aa | |
|
04f1317f79 | |
|
1db7091d04 | |
|
e9d7dffccb | |
|
598886d6b1 | |
|
b3a92a55c6 | |
|
80963e8ad9 | |
|
5e81a5e524 | |
|
3696d225cb | |
|
dd502f0fde | |
|
1532a7e3d3 | |
|
40e715ca76 | |
|
cbdfba7250 | |
|
95d14f4877 | |
|
4d0d59d3c7 | |
|
a846053d57 | |
|
492b0eba15 | |
|
c9b8ac3ec5 | |
|
50d4818704 | |
|
da29cb909f | |
|
b727aaaefa | |
|
b5e8707925 | |
|
8a5e5744ac | |
|
7124ecc710 | |
|
c3eaebe647 | |
|
15edf9d9d6 | |
|
3acfd468c6 | |
|
39a751f982 | |
|
63827a9d24 | |
|
e02f8bc49f | |
|
c109cf08fc | |
|
91ab35a32b | |
|
f940250e29 | |
|
5e5e097ee8 | |
|
4c4e2e0c42 | |
|
0dfd5193c7 |
12
.bazelrc
12
.bazelrc
|
@ -14,7 +14,10 @@ build:remote --remote_timeout=7200
|
|||
# ========================================
|
||||
|
||||
# Enable libc++ and C++20 by default.
|
||||
build:linux --config=libc++20
|
||||
build:linux --config=clang
|
||||
|
||||
# put /usr/local/bin before /usr/bin to avoid picking up wrong python3.6 when building envoy.tls.key_providers.cryptomb
|
||||
build:linux --action_env=PATH=/usr/lib/llvm/bin:/usr/local/bin:/bin:/usr/bin
|
||||
|
||||
# Need for CI image to pickup docker-credential-gcloud, PATH is fixed in rbe-toolchain-* configs.
|
||||
build:remote-ci --action_env=PATH=/usr/local/google-cloud-sdk/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
|
||||
|
@ -47,20 +50,17 @@ build:debug -c dbg
|
|||
build --cxxopt -Wformat
|
||||
build --cxxopt -Wformat-security
|
||||
|
||||
# Link pthread for flatbuffers
|
||||
build --host_linkopt=-pthread
|
||||
|
||||
build:clang --host_action_env=CC=
|
||||
build:clang --host_action_env=CXX=
|
||||
|
||||
# CI sanitizer configuration
|
||||
#
|
||||
build:clang-asan-ci --config=clang-asan
|
||||
build:clang-asan-ci --config=asan
|
||||
build:clang-asan-ci --linkopt='-L/usr/lib/llvm/lib/x86_64-unknown-linux-gnu'
|
||||
build:clang-asan-ci --linkopt='-Wl,-rpath,/usr/lib/llvm/lib/x86_64-unknown-linux-gnu'
|
||||
build:clang-asan-ci --linkopt='-L/usr/lib/llvm/lib/clang/14.0.0/lib/x86_64-unknown-linux-gnu'
|
||||
|
||||
build:clang-tsan-ci --config=clang-tsan
|
||||
build:clang-tsan-ci --config=tsan
|
||||
build:clang-tsan-ci --linkopt=-L/opt/libcxx_tsan/lib
|
||||
build:clang-tsan-ci --linkopt=-Wl,-rpath,/opt/libcxx_tsan/lib
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
6.5.0
|
||||
7.6.0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "istio build-tools",
|
||||
"image": "gcr.io/istio-testing/build-tools:master-3a1982fd09c72f345f85d394d5cce906b5484b76",
|
||||
"image": "gcr.io/istio-testing/build-tools-proxy:master-8e6480403f5cf4c9a4cd9d65174d01850e632e1a",
|
||||
"privileged": true,
|
||||
"remoteEnv": {
|
||||
"USE_GKE_GCLOUD_AUTH_PLUGIN": "True",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# Configures Depdendabot to PR go security updates only
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# Go configuration for master branch
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
# Limit number of open PRs to 0 so that we only get security updates
|
||||
# See https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates
|
||||
open-pull-requests-limit: 0
|
||||
labels:
|
||||
- "release-notes-none"
|
|
@ -12,10 +12,5 @@ test/envoye2e/tcp_metadata_exchange/testoutput
|
|||
test/envoye2e/http_metadata_exchange/testoutput
|
||||
*.wasm
|
||||
.vscode
|
||||
/extensions/common/flatbuffers
|
||||
/extensions/common/node_info_generated.h
|
||||
/extensions/common/node_info_bfbs_generated.h
|
||||
/extensions/common/proxy_expr.h
|
||||
/extensions/common/nlohmann_json.hpp
|
||||
out/
|
||||
.cache
|
||||
|
|
2
Makefile
2
Makefile
|
@ -19,7 +19,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SHELL := /bin/bash
|
||||
SHELL := /usr/bin/env bash
|
||||
|
||||
# allow optional per-repo overrides
|
||||
-include Makefile.overrides.mk
|
||||
|
|
|
@ -89,7 +89,7 @@ test:
|
|||
bazel $(BAZEL_STARTUP_ARGS) test $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) -- $(BAZEL_TEST_TARGETS); \
|
||||
fi
|
||||
if [ -n "$(E2E_TEST_TARGETS)" ]; then \
|
||||
env ENVOY_DEBUG=$(TEST_ENVOY_DEBUG) ENVOY_PATH=$(shell bazel info $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) bazel-bin)/envoy $(E2E_TEST_ENVS) GO111MODULE=on go test -timeout 30m $(E2E_TEST_FLAGS) $(E2E_TEST_TARGETS); \
|
||||
env ENVOY_DEBUG=$(TEST_ENVOY_DEBUG) ENVOY_PATH=$(shell bazel $(BAZEL_STARTUP_ARGS) info $(BAZEL_BUILD_ARGS) $(BAZEL_CONFIG_CURRENT) bazel-bin)/envoy $(E2E_TEST_ENVS) GO111MODULE=on go test -timeout 30m $(E2E_TEST_FLAGS) $(E2E_TEST_TARGETS); \
|
||||
fi
|
||||
|
||||
test_asan: BAZEL_CONFIG_CURRENT = $(BAZEL_CONFIG_ASAN)
|
||||
|
@ -108,30 +108,6 @@ check:
|
|||
lint: lint-copyright-banner format-go lint-go tidy-go lint-scripts gen-extensions-doc
|
||||
@scripts/check-repository.sh
|
||||
@scripts/check-style.sh
|
||||
@scripts/verify-last-flag-matches-upstream.sh
|
||||
|
||||
protoc = protoc -I common-protos -I extensions
|
||||
protoc_gen_docs_plugin := --docs_out=camel_case_fields=false,warnings=true,per_file=true,mode=html_fragment_with_front_matter:$(repo_dir)/
|
||||
|
||||
metadata_exchange_path := extensions/metadata_exchange
|
||||
metadata_exchange_protos := $(wildcard $(metadata_exchange_path)/*.proto)
|
||||
metadata_exchange_docs := $(metadata_exchange_protos:.proto=.pb.html)
|
||||
$(metadata_exchange_docs): $(metadata_exchange_protos)
|
||||
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(metadata_exchange_path) $^
|
||||
|
||||
stackdriver_path := extensions/stackdriver/config/v1alpha1
|
||||
stackdriver_protos := $(wildcard $(stackdriver_path)/*.proto)
|
||||
stackdriver_docs := $(stackdriver_protos:.proto=.pb.html)
|
||||
$(stackdriver_docs): $(stackdriver_protos)
|
||||
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(stackdriver_path) $^
|
||||
|
||||
accesslog_policy_path := extensions/access_log_policy/config/v1alpha1
|
||||
accesslog_policy_protos := $(wildcard $(accesslog_policy_path)/*.proto)
|
||||
accesslog_policy_docs := $(accesslog_policy_protos:.proto=.pb.html)
|
||||
$(accesslog_policy_docs): $(accesslog_policy_protos)
|
||||
@$(protoc) -I ./extensions $(protoc_gen_docs_plugin)$(accesslog_policy_path) $^
|
||||
|
||||
extensions-docs: $(metadata_exchange_docs) $(stackdriver_docs) $(accesslog_policy_docs)
|
||||
|
||||
test_release:
|
||||
ifeq "$(shell uname -m)" "x86_64"
|
||||
|
|
|
@ -22,10 +22,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||
# 1. Determine SHA256 `wget https://github.com/envoyproxy/envoy/archive/$COMMIT.tar.gz && sha256sum $COMMIT.tar.gz`
|
||||
# 2. Update .bazelversion, envoy.bazelrc and .bazelrc if needed.
|
||||
#
|
||||
# Commit date: 2024-07-15
|
||||
ENVOY_SHA = "c29e205efaf43f5dc683082368f4cab229b8c049"
|
||||
# Commit date: 2025-07-10
|
||||
ENVOY_SHA = "46bb6bc3dc41a684671fd4811eddfe82207a6d21"
|
||||
|
||||
ENVOY_SHA256 = "1ded00803edf3b4a397950cc5ab4f86e391a911b33bb6d03fe8a11973a7ff043"
|
||||
ENVOY_SHA256 = "e3ca4967f3cfd343cbf9983c7ec85eb1845c5d3b219e045cf008e730e9c06b61"
|
||||
|
||||
ENVOY_ORG = "envoyproxy"
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ ENVOY_EXTENSIONS = {
|
|||
#
|
||||
|
||||
"envoy.grpc_credentials.file_based_metadata": "//source/extensions/grpc_credentials/file_based_metadata:config",
|
||||
"envoy.grpc_credentials.aws_iam": "//source/extensions/grpc_credentials/aws_iam:config",
|
||||
|
||||
#
|
||||
# WASM
|
||||
|
@ -146,6 +145,7 @@ ENVOY_EXTENSIONS = {
|
|||
"envoy.filters.http.on_demand": "//source/extensions/filters/http/on_demand:config",
|
||||
"envoy.filters.http.original_src": "//source/extensions/filters/http/original_src:config",
|
||||
"envoy.filters.http.ratelimit": "//source/extensions/filters/http/ratelimit:config",
|
||||
"envoy.filters.http.rate_limit_quota": "//source/extensions/filters/http/rate_limit_quota:config",
|
||||
"envoy.filters.http.rbac": "//source/extensions/filters/http/rbac:config",
|
||||
"envoy.filters.http.router": "//source/extensions/filters/http/router:config",
|
||||
"envoy.filters.http.set_filter_state": "//source/extensions/filters/http/set_filter_state:config",
|
||||
|
@ -202,6 +202,7 @@ ENVOY_EXTENSIONS = {
|
|||
# Resource monitors
|
||||
#
|
||||
|
||||
"envoy.resource_monitors.cpu_utilization": "//source/extensions/resource_monitors/cpu_utilization:config",
|
||||
"envoy.resource_monitors.fixed_heap": "//source/extensions/resource_monitors/fixed_heap:config",
|
||||
"envoy.resource_monitors.injected_resource": "//source/extensions/resource_monitors/injected_resource:config",
|
||||
"envoy.resource_monitors.downstream_connections": "//source/extensions/resource_monitors/downstream_connections:config",
|
||||
|
@ -230,7 +231,6 @@ ENVOY_EXTENSIONS = {
|
|||
# Tracers
|
||||
#
|
||||
|
||||
"envoy.tracers.dynamic_ot": "//source/extensions/tracers/dynamic_ot:config",
|
||||
"envoy.tracers.datadog": "//source/extensions/tracers/datadog:config",
|
||||
"envoy.tracers.zipkin": "//source/extensions/tracers/zipkin:config",
|
||||
"envoy.tracers.xray": "//source/extensions/tracers/xray:config",
|
||||
|
@ -357,7 +357,7 @@ ENVOY_EXTENSIONS = {
|
|||
# QUIC extensions
|
||||
#
|
||||
|
||||
"envoy.quic.deterministic_connection_id_generator": "//source/extensions/quic/connection_id_generator:envoy_deterministic_connection_id_generator_config",
|
||||
"envoy.quic.deterministic_connection_id_generator": "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config",
|
||||
"envoy.quic.crypto_stream.server.quiche": "//source/extensions/quic/crypto_stream:envoy_quic_default_crypto_server_stream",
|
||||
"envoy.quic.proof_source.filter_chain": "//source/extensions/quic/proof_source:envoy_quic_default_proof_source",
|
||||
|
||||
|
@ -418,6 +418,7 @@ ENVOY_EXTENSIONS = {
|
|||
"envoy.load_balancing_policies.ring_hash": "//source/extensions/load_balancing_policies/ring_hash:config",
|
||||
"envoy.load_balancing_policies.subset": "//source/extensions/load_balancing_policies/subset:config",
|
||||
"envoy.load_balancing_policies.cluster_provided": "//source/extensions/load_balancing_policies/cluster_provided:config",
|
||||
"envoy.load_balancing_policies.override_host": "//source/extensions/load_balancing_policies/override_host:config",
|
||||
|
||||
#
|
||||
# HTTP Early Header Mutation
|
||||
|
|
|
@ -1 +1 @@
|
|||
cbe0f69e442f6d1d19c702d931b39048abd833c2
|
||||
d46067e1a8ba3db4abe2635af5807f00ba1981e6
|
||||
|
|
|
@ -106,13 +106,11 @@ update-common:
|
|||
@if [ "$(CONTRIB_OVERRIDE)" != "CONTRIBUTING.md" ]; then\
|
||||
rm $(TMP)/common-files/files/CONTRIBUTING.md;\
|
||||
fi
|
||||
# istio/istio.io uses the Creative Commons Attribution 4.0 license. Don't update LICENSE with the common Apache license.
|
||||
@LICENSE_OVERRIDE=$(shell grep -l "Creative Commons Attribution 4.0 International Public License" LICENSE)
|
||||
@if [ "$(LICENSE_OVERRIDE)" != "LICENSE" ]; then\
|
||||
rm $(TMP)/common-files/files/LICENSE;\
|
||||
fi
|
||||
@cp -a $(TMP)/common-files/files/* $(TMP)/common-files/files/.devcontainer $(TMP)/common-files/files/.gitattributes $(shell pwd)
|
||||
@rm -fr $(TMP)/common-files
|
||||
@if [ "$(AUTOMATOR_REPO)" == "proxy" ]; then\
|
||||
sed -i -e 's/build-tools:/build-tools-proxy:/g' .devcontainer/devcontainer.json;\
|
||||
fi
|
||||
@$(or $(COMMONFILES_POSTPROCESS), true)
|
||||
|
||||
check-clean-repo:
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
|
||||
#
|
||||
# The original version of this file is located in the https://github.com/istio/common-files repo.
|
||||
# If you're looking at this file in a different repo and want to make a change, please go to the
|
||||
# common-files repo, make the change there and check it in. Then come back to this repo and run
|
||||
# "make update-common".
|
||||
|
||||
run:
|
||||
# Timeout for analysis, e.g. 30s, 5m.
|
||||
# Default: 1m
|
||||
timeout: 20m
|
||||
build-tags:
|
||||
- integ
|
||||
- integfuzz
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- goimports
|
||||
- gofumpt
|
||||
- gci
|
||||
fast: false
|
||||
linters-settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard # Captures all standard packages if they do not match another section.
|
||||
- default # Contains all imports that could not be matched to another section type.
|
||||
- prefix(istio.io/) # Groups all imports with the specified Prefix.
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: istio.io/
|
||||
issues:
|
||||
# Which dirs to exclude: issues from them won't be reported.
|
||||
# Can use regexp here: `generated.*`, regexp is applied on full path,
|
||||
# including the path prefix if one is set.
|
||||
# Default dirs are skipped independently of this option's value (see exclude-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work on Windows.
|
||||
# Default: []
|
||||
exclude-dirs:
|
||||
- genfiles$
|
||||
- vendor$
|
||||
# Which files to exclude: they will be analyzed, but issues from them won't be reported.
|
||||
# There is no need to include all autogenerated files,
|
||||
# we confidently recognize autogenerated files.
|
||||
# If it's not, please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work on Windows.
|
||||
# Default: []
|
||||
exclude-files:
|
||||
- ".*\\.pb\\.go"
|
||||
- ".*\\.gen\\.go"
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
|
@ -1,262 +1,221 @@
|
|||
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
|
||||
#
|
||||
# The original version of this file is located in the https://github.com/istio/common-files repo.
|
||||
# If you're looking at this file in a different repo and want to make a change, please go to the
|
||||
# common-files repo, make the change there and check it in. Then come back to this repo and run
|
||||
# "make update-common".
|
||||
|
||||
version: "2"
|
||||
run:
|
||||
# Timeout for analysis, e.g. 30s, 5m.
|
||||
# Default: 1m
|
||||
timeout: 20m
|
||||
build-tags:
|
||||
- integ
|
||||
- integfuzz
|
||||
linters:
|
||||
disable-all: true
|
||||
default: none
|
||||
enable:
|
||||
- errcheck
|
||||
- exportloopref
|
||||
- copyloopvar
|
||||
- depguard
|
||||
- errcheck
|
||||
- gocritic
|
||||
- gofumpt
|
||||
- goimports
|
||||
- revive
|
||||
- gosimple
|
||||
- gosec
|
||||
- govet
|
||||
- ineffassign
|
||||
- lll
|
||||
- misspell
|
||||
- revive
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- gci
|
||||
- gosec
|
||||
fast: false
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
govet:
|
||||
disable:
|
||||
# report about shadowed variables
|
||||
- shadow
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: istio.io/
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||
locale: US
|
||||
ignore-words:
|
||||
- cancelled
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 160
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
revive:
|
||||
ignore-generated-header: false
|
||||
severity: "warning"
|
||||
confidence: 0.0
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
DenyGogoProtobuf:
|
||||
files:
|
||||
- $all
|
||||
deny:
|
||||
- pkg: github.com/gogo/protobuf
|
||||
desc: gogo/protobuf is deprecated, use golang/protobuf
|
||||
errcheck:
|
||||
check-type-assertions: false
|
||||
check-blank: false
|
||||
gocritic:
|
||||
disable-all: true
|
||||
enabled-checks:
|
||||
- appendCombine
|
||||
- argOrder
|
||||
- assignOp
|
||||
- badCond
|
||||
- boolExprSimplify
|
||||
- builtinShadow
|
||||
- captLocal
|
||||
- caseOrder
|
||||
- codegenComment
|
||||
- commentedOutCode
|
||||
- commentedOutImport
|
||||
- defaultCaseOrder
|
||||
- deprecatedComment
|
||||
- docStub
|
||||
- dupArg
|
||||
- dupBranchBody
|
||||
- dupCase
|
||||
- dupSubExpr
|
||||
- elseif
|
||||
- emptyFallthrough
|
||||
- equalFold
|
||||
- flagDeref
|
||||
- flagName
|
||||
- hexLiteral
|
||||
- indexAlloc
|
||||
- initClause
|
||||
- methodExprCall
|
||||
- nilValReturn
|
||||
- octalLiteral
|
||||
- offBy1
|
||||
- rangeExprCopy
|
||||
- regexpMust
|
||||
- sloppyLen
|
||||
- stringXbytes
|
||||
- switchTrue
|
||||
- typeAssertChain
|
||||
- typeSwitchVar
|
||||
- typeUnparen
|
||||
- underef
|
||||
- unlambda
|
||||
- unnecessaryBlock
|
||||
- unslice
|
||||
- valSwap
|
||||
- weakCond
|
||||
gosec:
|
||||
includes:
|
||||
- G401
|
||||
- G402
|
||||
- G404
|
||||
govet:
|
||||
disable:
|
||||
- shadow
|
||||
lll:
|
||||
line-length: 160
|
||||
tab-width: 1
|
||||
misspell:
|
||||
locale: US
|
||||
ignore-rules:
|
||||
- cancelled
|
||||
revive:
|
||||
confidence: 0
|
||||
severity: warning
|
||||
rules:
|
||||
- name: blank-imports
|
||||
- name: context-keys-type
|
||||
- name: time-naming
|
||||
- name: var-declaration
|
||||
- name: unexported-return
|
||||
- name: errorf
|
||||
- name: context-as-argument
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: indent-error-flow
|
||||
- name: superfluous-else
|
||||
- name: modifies-parameter
|
||||
- name: unreachable-code
|
||||
- name: struct-tag
|
||||
- name: constant-logical-expr
|
||||
- name: bool-literal-in-expr
|
||||
- name: redefines-builtin-id
|
||||
- name: imports-blocklist
|
||||
- name: range-val-in-closure
|
||||
- name: range-val-address
|
||||
- name: waitgroup-by-value
|
||||
- name: atomic
|
||||
- name: call-to-gc
|
||||
- name: duplicated-imports
|
||||
- name: string-of-int
|
||||
- name: defer
|
||||
arguments:
|
||||
- - call-chain
|
||||
- name: unconditional-recursion
|
||||
- name: identical-branches
|
||||
unparam:
|
||||
check-exported: false
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- name: blank-imports
|
||||
- name: context-keys-type
|
||||
- name: time-naming
|
||||
- name: var-declaration
|
||||
- name: unexported-return
|
||||
- name: errorf
|
||||
- name: context-as-argument
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: indent-error-flow
|
||||
- name: superfluous-else
|
||||
- name: modifies-parameter
|
||||
- name: unreachable-code
|
||||
- name: struct-tag
|
||||
- name: constant-logical-expr
|
||||
- name: bool-literal-in-expr
|
||||
- name: redefines-builtin-id
|
||||
- name: imports-blacklist
|
||||
- name: range-val-in-closure
|
||||
- name: range-val-address
|
||||
- name: waitgroup-by-value
|
||||
- name: atomic
|
||||
- name: call-to-gc
|
||||
- name: duplicated-imports
|
||||
- name: string-of-int
|
||||
- name: defer
|
||||
arguments:
|
||||
- - "call-chain"
|
||||
- name: unconditional-recursion
|
||||
- name: identical-branches
|
||||
# the following rules can be enabled in the future
|
||||
# - name: empty-lines
|
||||
# - name: confusing-results
|
||||
# - name: empty-block
|
||||
# - name: get-return
|
||||
# - name: confusing-naming
|
||||
# - name: unexported-naming
|
||||
# - name: early-return
|
||||
# - name: unused-parameter
|
||||
# - name: unnecessary-stmt
|
||||
# - name: deep-exit
|
||||
# - name: import-shadowing
|
||||
# - name: modifies-value-receiver
|
||||
# - name: unused-receiver
|
||||
# - name: bare-return
|
||||
# - name: flag-parameter
|
||||
# - name: unhandled-error
|
||||
# - name: if-return
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
gci:
|
||||
sections:
|
||||
- standard # Captures all standard packages if they do not match another section.
|
||||
- default # Contains all imports that could not be matched to another section type.
|
||||
- prefix(istio.io/) # Groups all imports with the specified Prefix.
|
||||
gocritic:
|
||||
# Disable all checks.
|
||||
# Default: false
|
||||
disable-all: true
|
||||
# Which checks should be enabled in addition to default checks. Since we don't want
|
||||
# all of the default checks, we do the disable-all first.
|
||||
enabled-checks:
|
||||
- appendCombine
|
||||
- argOrder
|
||||
- assignOp
|
||||
- badCond
|
||||
- boolExprSimplify
|
||||
- builtinShadow
|
||||
- captLocal
|
||||
- caseOrder
|
||||
- codegenComment
|
||||
- commentedOutCode
|
||||
- commentedOutImport
|
||||
- defaultCaseOrder
|
||||
- deprecatedComment
|
||||
- docStub
|
||||
- dupArg
|
||||
- dupBranchBody
|
||||
- dupCase
|
||||
- dupSubExpr
|
||||
- elseif
|
||||
- emptyFallthrough
|
||||
- equalFold
|
||||
- flagDeref
|
||||
- flagName
|
||||
- hexLiteral
|
||||
- indexAlloc
|
||||
- initClause
|
||||
- methodExprCall
|
||||
- nilValReturn
|
||||
- octalLiteral
|
||||
- offBy1
|
||||
- rangeExprCopy
|
||||
- regexpMust
|
||||
- sloppyLen
|
||||
- stringXbytes
|
||||
- switchTrue
|
||||
- typeAssertChain
|
||||
- typeSwitchVar
|
||||
- typeUnparen
|
||||
- underef
|
||||
- unlambda
|
||||
- unnecessaryBlock
|
||||
- unslice
|
||||
- valSwap
|
||||
- weakCond
|
||||
depguard:
|
||||
rules:
|
||||
DenyGogoProtobuf:
|
||||
files:
|
||||
- $all
|
||||
deny:
|
||||
- pkg: github.com/gogo/protobuf
|
||||
desc: "gogo/protobuf is deprecated, use golang/protobuf"
|
||||
gosec:
|
||||
includes:
|
||||
- G401
|
||||
- G402
|
||||
- G404
|
||||
- linters:
|
||||
- errcheck
|
||||
- maligned
|
||||
path: _test\.go$|tests/|samples/
|
||||
- path: _test\.go$
|
||||
text: 'dot-imports: should not use dot imports'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: package github.com/golang/protobuf/jsonpb'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: "github.com/golang/protobuf/jsonpb"'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: grpc.Dial is deprecated: use NewClient instead'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: grpc.DialContext is deprecated: use NewClient instead'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: grpc.WithBlock is deprecated'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: grpc.FailOnNonTempDialError'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'SA1019: grpc.WithReturnConnectionError'
|
||||
- path: (.+)\.go$
|
||||
text: composite literal uses unkeyed fields
|
||||
# TODO: remove following rule in the future
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'QF'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'ST1005'
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: 'S1007'
|
||||
paths:
|
||||
- .*\.pb\.go
|
||||
- .*\.gen\.go
|
||||
- genfiles$
|
||||
- vendor$
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
exclude:
|
||||
- composite literal uses unkeyed fields
|
||||
# Which dirs to exclude: issues from them won't be reported.
|
||||
# Can use regexp here: `generated.*`, regexp is applied on full path,
|
||||
# including the path prefix if one is set.
|
||||
# Default dirs are skipped independently of this option's value (see exclude-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work on Windows.
|
||||
# Default: []
|
||||
exclude-dirs:
|
||||
- genfiles$
|
||||
- vendor$
|
||||
# Which files to exclude: they will be analyzed, but issues from them won't be reported.
|
||||
# There is no need to include all autogenerated files,
|
||||
# we confidently recognize autogenerated files.
|
||||
# If it's not, please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work on Windows.
|
||||
# Default: []
|
||||
exclude-files:
|
||||
- ".*\\.pb\\.go"
|
||||
- ".*\\.gen\\.go"
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on test files.
|
||||
- path: _test\.go$|^tests/|^samples/
|
||||
linters:
|
||||
- errcheck
|
||||
- maligned
|
||||
- path: _test\.go$
|
||||
text: "dot-imports: should not use dot imports"
|
||||
# We need to use the deprecated module since the jsonpb replacement is not backwards compatible.
|
||||
- linters: [staticcheck]
|
||||
text: "SA1019: package github.com/golang/protobuf/jsonpb"
|
||||
- linters: [staticcheck]
|
||||
text: 'SA1019: "github.com/golang/protobuf/jsonpb"'
|
||||
# This is not helpful. The new function is not very usable and the current function will not be removed
|
||||
- linters: [staticcheck]
|
||||
text: 'SA1019: grpc.Dial is deprecated: use NewClient instead'
|
||||
- linters: [staticcheck]
|
||||
text: 'SA1019: grpc.DialContext is deprecated: use NewClient instead'
|
||||
- linters: [staticcheck]
|
||||
text: "SA1019: grpc.WithBlock is deprecated"
|
||||
- linters: [staticcheck]
|
||||
text: "SA1019: grpc.FailOnNonTempDialError"
|
||||
- linters: [staticcheck]
|
||||
text: "SA1019: grpc.WithReturnConnectionError"
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: true
|
||||
# Maximum issues count per one linter.
|
||||
# Set to 0 to disable.
|
||||
# Default: 50
|
||||
max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofumpt
|
||||
- goimports
|
||||
settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(istio.io/)
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- istio.io/
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- .*\.pb\.go
|
||||
- .*\.gen\.go
|
||||
- genfiles$
|
||||
- vendor$
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
|
|
@ -125,4 +125,21 @@ allowlisted_modules:
|
|||
|
||||
# Simplified BSD (BSD-2-Clause): https://github.com/russross/blackfriday/blob/master/LICENSE.txt
|
||||
- github.com/russross/blackfriday
|
||||
- github.com/russross/blackfriday/v2
|
||||
- github.com/russross/blackfriday/v2
|
||||
|
||||
# W3C Test Suite License, W3C 3-clause BSD License
|
||||
# gonum uses this for its some of its test files
|
||||
# gonum.org/v1/gonum/graph/formats/rdf/testdata/LICENSE.md
|
||||
- gonum.org/v1/gonum
|
||||
|
||||
# BSD 3-clause: https://github.com/go-inf/inf/blob/v0.9.1/LICENSE
|
||||
- gopkg.in/inf.v0
|
||||
|
||||
# BSD 3-clause: https://github.com/go-git/gcfg/blob/main/LICENSE
|
||||
- github.com/go-git/gcfg
|
||||
|
||||
# Apache 2.0
|
||||
- github.com/aws/smithy-go
|
||||
|
||||
# Simplified BSD License: https://github.com/gomarkdown/markdown/blob/master/LICENSE.txt
|
||||
- github.com/gomarkdown/markdown
|
||||
|
|
|
@ -21,4 +21,4 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
golangci-lint run --fix -c ./common/config/.golangci-format.yml
|
||||
golangci-lint run --fix -c ./common/config/.golangci.yml
|
||||
|
|
|
@ -32,7 +32,10 @@ set -x
|
|||
####################################################################
|
||||
|
||||
# DEFAULT_KIND_IMAGE is used to set the Kubernetes version for KinD unless overridden in params to setup_kind_cluster(s)
|
||||
DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.28.4"
|
||||
DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.33.1"
|
||||
|
||||
# the default kind cluster should be ipv4 if not otherwise specified
|
||||
KIND_IP_FAMILY="${KIND_IP_FAMILY:-ipv4}"
|
||||
|
||||
# COMMON_SCRIPTS contains the directory this file is in.
|
||||
COMMON_SCRIPTS=$(dirname "${BASH_SOURCE:-$0}")
|
||||
|
@ -144,7 +147,7 @@ function setup_kind_cluster_retry() {
|
|||
# 1. NAME: Name of the Kind cluster (optional)
|
||||
# 2. IMAGE: Node image used by KinD (optional)
|
||||
# 3. CONFIG: KinD cluster configuration YAML file. If not specified then DEFAULT_CLUSTER_YAML is used
|
||||
# 4. NOMETALBINSTALL: Dont install matllb if set.
|
||||
# 4. NOMETALBINSTALL: Dont install metalb if set.
|
||||
# This function returns 0 when everything goes well, or 1 otherwise
|
||||
# If Kind cluster was already created then it would be cleaned up in case of errors
|
||||
function setup_kind_cluster() {
|
||||
|
@ -174,11 +177,6 @@ function setup_kind_cluster() {
|
|||
CONFIG=${DEFAULT_CLUSTER_YAML}
|
||||
fi
|
||||
|
||||
# Configure the ipFamily of the cluster
|
||||
if [ -n "${IP_FAMILY}" ]; then
|
||||
yq eval ".networking.ipFamily = \"${IP_FAMILY}\"" -i "${CONFIG}"
|
||||
fi
|
||||
|
||||
KIND_WAIT_FLAG="--wait=180s"
|
||||
KIND_DISABLE_CNI="false"
|
||||
if [[ -n "${KUBERNETES_CNI:-}" ]]; then
|
||||
|
@ -187,16 +185,26 @@ function setup_kind_cluster() {
|
|||
fi
|
||||
|
||||
# Create KinD cluster
|
||||
if ! (yq eval "${CONFIG}" --expression ".networking.disableDefaultCNI = ${KIND_DISABLE_CNI}" | \
|
||||
if ! (yq eval "${CONFIG}" --expression ".networking.disableDefaultCNI = ${KIND_DISABLE_CNI}" \
|
||||
--expression ".networking.ipFamily = \"${KIND_IP_FAMILY}\"" | \
|
||||
kind create cluster --name="${NAME}" -v4 --retain --image "${IMAGE}" ${KIND_WAIT_FLAG:+"$KIND_WAIT_FLAG"} --config -); then
|
||||
echo "Could not setup KinD environment. Something wrong with KinD setup. Exporting logs."
|
||||
return 9
|
||||
# kubectl config set clusters.kind-istio-testing.server https://istio-testing-control-plane:6443
|
||||
fi
|
||||
|
||||
if [[ -n "${DEVCONTAINER:-}" ]]; then
|
||||
# identify our docker container id using proc and regex
|
||||
containerid=$(grep 'resolv.conf' /proc/self/mountinfo | sed 's/.*\/docker\/containers\/\([0-9a-f]*\).*/\1/')
|
||||
docker network connect kind "$containerid"
|
||||
kind export kubeconfig --name="${NAME}" --internal
|
||||
fi
|
||||
|
||||
# Workaround kind issue causing taints to not be removed in 1.24
|
||||
kubectl taint nodes "${NAME}"-control-plane node-role.kubernetes.io/control-plane- 2>/dev/null || true
|
||||
|
||||
# Determine what CNI to install
|
||||
case "${KUBERNETES_CNI:-}" in
|
||||
case "${KUBERNETES_CNI:-}" in
|
||||
|
||||
"calico")
|
||||
echo "Installing Calico CNI"
|
||||
|
@ -231,7 +239,7 @@ function setup_kind_cluster() {
|
|||
# https://github.com/coredns/coredns/issues/2494#issuecomment-457215452
|
||||
# CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL
|
||||
# otherwise pods stops trying to resolve the domain.
|
||||
if [ "${IP_FAMILY}" = "ipv6" ] || [ "${IP_FAMILY}" = "dual" ]; then
|
||||
if [ "${KIND_IP_FAMILY}" = "ipv6" ] || [ "${KIND_IP_FAMILY}" = "dual" ]; then
|
||||
# Get the current config
|
||||
original_coredns=$(kubectl get -oyaml -n=kube-system configmap/coredns)
|
||||
echo "Original CoreDNS config:"
|
||||
|
@ -268,14 +276,14 @@ function cleanup_kind_clusters() {
|
|||
# setup_kind_clusters sets up a given number of kind clusters with given topology
|
||||
# as specified in cluster topology configuration file.
|
||||
# 1. IMAGE = docker image used as node by KinD
|
||||
# 2. IP_FAMILY = either ipv4 or ipv6
|
||||
# 2. KIND_IP_FAMILY = either ipv4 or ipv6 or dual
|
||||
#
|
||||
# NOTE: Please call load_cluster_topology before calling this method as it expects
|
||||
# cluster topology information to be loaded in advance
|
||||
function setup_kind_clusters() {
|
||||
IMAGE="${1:-"${DEFAULT_KIND_IMAGE}"}"
|
||||
KUBECONFIG_DIR="${ARTIFACTS:-$(mktemp -d)}/kubeconfig"
|
||||
IP_FAMILY="${2:-ipv4}"
|
||||
KIND_IP_FAMILY="${2:-ipv4}"
|
||||
|
||||
check_default_cluster_yaml
|
||||
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
GOLANGCILINT_RUN_ARGS=(--output.text.path stdout --output.junit-xml.path "${ARTIFACTS}"/junit-lint.xml)
|
||||
|
||||
if [[ "${ARTIFACTS}" != "" ]]; then
|
||||
golangci-lint run -v -c ./common/config/.golangci.yml --out-format colored-line-number,junit-xml:"${ARTIFACTS}"/junit-lint.xml
|
||||
golangci-lint run -v -c ./common/config/.golangci.yml "${GOLANGCILINT_RUN_ARGS[@]}"
|
||||
else
|
||||
golangci-lint run -v -c ./common/config/.golangci.yml
|
||||
fi
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
|
||||
#
|
||||
|
@ -36,7 +36,7 @@ MOUNT_DEST="${MOUNT_DEST:-/work}"
|
|||
|
||||
read -ra DOCKER_RUN_OPTIONS <<< "${DOCKER_RUN_OPTIONS:-}"
|
||||
|
||||
[[ -t 1 ]] && DOCKER_RUN_OPTIONS+=("-it")
|
||||
[[ -t 0 ]] && DOCKER_RUN_OPTIONS+=("-it")
|
||||
[[ ${UID} -ne 0 ]] && DOCKER_RUN_OPTIONS+=(-u "${UID}:${DOCKER_GID}")
|
||||
|
||||
# $CONTAINER_OPTIONS becomes an empty arg when quoted, so SC2086 is disabled for the
|
||||
|
@ -47,7 +47,9 @@ read -ra DOCKER_RUN_OPTIONS <<< "${DOCKER_RUN_OPTIONS:-}"
|
|||
"${DOCKER_RUN_OPTIONS[@]}" \
|
||||
--init \
|
||||
--sig-proxy=true \
|
||||
--cap-add=SYS_ADMIN \
|
||||
${DOCKER_SOCKET_MOUNT:--v /var/run/docker.sock:/var/run/docker.sock} \
|
||||
-e DOCKER_HOST=${DOCKER_SOCKET_HOST:-unix:///var/run/docker.sock} \
|
||||
$CONTAINER_OPTIONS \
|
||||
--env-file <(env | grep -v ${ENV_BLOCKLIST}) \
|
||||
-e IN_BUILD_CONTAINER=1 \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2034
|
||||
|
||||
# WARNING: DO NOT EDIT, THIS FILE IS PROBABLY A COPY
|
||||
|
@ -75,7 +75,7 @@ fi
|
|||
TOOLS_REGISTRY_PROVIDER=${TOOLS_REGISTRY_PROVIDER:-gcr.io}
|
||||
PROJECT_ID=${PROJECT_ID:-istio-testing}
|
||||
if [[ "${IMAGE_VERSION:-}" == "" ]]; then
|
||||
IMAGE_VERSION=master-3a1982fd09c72f345f85d394d5cce906b5484b76
|
||||
IMAGE_VERSION=master-8e6480403f5cf4c9a4cd9d65174d01850e632e1a
|
||||
fi
|
||||
if [[ "${IMAGE_NAME:-}" == "" ]]; then
|
||||
IMAGE_NAME=build-tools
|
||||
|
|
351
envoy.bazelrc
351
envoy.bazelrc
|
@ -8,8 +8,11 @@
|
|||
# leave room for compiler/linker.
|
||||
# The number 3G is chosen heuristically to both support large VM and small VM with RBE.
|
||||
# Startup options cannot be selected via config.
|
||||
# TODO: Adding just to test android
|
||||
startup --host_jvm_args=-Xmx3g
|
||||
|
||||
common --noenable_bzlmod
|
||||
|
||||
fetch --color=yes
|
||||
run --color=yes
|
||||
|
||||
|
@ -19,12 +22,20 @@ build --workspace_status_command="bash bazel/get_workspace_status"
|
|||
build --incompatible_strict_action_env
|
||||
build --java_runtime_version=remotejdk_11
|
||||
build --tool_java_runtime_version=remotejdk_11
|
||||
build --java_language_version=11
|
||||
build --tool_java_language_version=11
|
||||
build --platform_mappings=bazel/platform_mappings
|
||||
# silence absl logspam.
|
||||
build --copt=-DABSL_MIN_LOG_LEVEL=4
|
||||
# Global C++ standard and common warning suppressions
|
||||
build --cxxopt=-std=c++20 --host_cxxopt=-std=c++20
|
||||
build --copt=-Wno-deprecated-declarations
|
||||
build --define envoy_mobile_listener=enabled
|
||||
build --experimental_repository_downloader_retries=2
|
||||
build --enable_platform_specific_config
|
||||
build --incompatible_merge_fixed_and_default_shell_env
|
||||
# A workaround for slow ICU download.
|
||||
build --http_timeout_scaling=6.0
|
||||
|
||||
# Pass CC, CXX and LLVM_CONFIG variables from the environment.
|
||||
# We assume they have stable values, so this won't cause action cache misses.
|
||||
|
@ -42,10 +53,6 @@ build:windows --action_env=PATH --host_action_env=PATH
|
|||
# Requires setting `BAZEL_VOLATILE_DIRTY` in the env.
|
||||
build --action_env=BAZEL_VOLATILE_DIRTY --host_action_env=BAZEL_VOLATILE_DIRTY
|
||||
|
||||
# Prevent stamped caches from busting (eg in PRs)
|
||||
# Requires setting `BAZEL_FAKE_SCM_REVISION` in the env.
|
||||
build --action_env=BAZEL_FAKE_SCM_REVISION --host_action_env=BAZEL_FAKE_SCM_REVISION
|
||||
|
||||
build --test_summary=terse
|
||||
|
||||
build:docs-ci --action_env=DOCS_RST_CHECK=1 --host_action_env=DOCS_RST_CHECK=1
|
||||
|
@ -60,18 +67,16 @@ test --experimental_ui_max_stdouterr_bytes=11712829 #default 1048576
|
|||
# Allow tags to influence execution requirements
|
||||
common --experimental_allow_tags_propagation
|
||||
|
||||
build:linux --copt=-fdebug-types-section
|
||||
# Enable position independent code (this is the default on macOS and Windows)
|
||||
# (Workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/421)
|
||||
build:linux --copt=-fdebug-types-section
|
||||
build:linux --copt=-fPIC
|
||||
build:linux --copt=-Wno-deprecated-declarations
|
||||
build:linux --cxxopt=-std=c++20 --host_cxxopt=-std=c++20
|
||||
build:linux --cxxopt=-fsized-deallocation --host_cxxopt=-fsized-deallocation
|
||||
build:linux --conlyopt=-fexceptions
|
||||
build:linux --fission=dbg,opt
|
||||
build:linux --features=per_object_debug_info
|
||||
build:linux --action_env=BAZEL_LINKLIBS=-l%:libstdc++.a
|
||||
build:linux --action_env=BAZEL_LINKOPTS=-lm
|
||||
build:linux --action_env=BAZEL_LINKOPTS=-lm:-fuse-ld=gold
|
||||
|
||||
# We already have absl in the build, define absl=1 to tell googletest to use absl for backtrace.
|
||||
build --define absl=1
|
||||
|
@ -83,21 +88,46 @@ build --@com_googlesource_googleurl//build_config:system_icu=0
|
|||
build:sanitizer --define tcmalloc=disabled
|
||||
build:sanitizer --linkopt -ldl
|
||||
|
||||
# Common flags for Clang
|
||||
build:clang --action_env=BAZEL_COMPILER=clang
|
||||
build:clang --linkopt=-fuse-ld=lld
|
||||
build:clang --action_env=CC=clang --host_action_env=CC=clang
|
||||
build:clang --action_env=CXX=clang++ --host_action_env=CXX=clang++
|
||||
# Common flags for Clang (shared between all clang variants)
|
||||
build:clang-common --action_env=BAZEL_COMPILER=clang
|
||||
build:clang-common --linkopt=-fuse-ld=lld
|
||||
build:clang-common --action_env=CC=clang --host_action_env=CC=clang
|
||||
build:clang-common --action_env=CXX=clang++ --host_action_env=CXX=clang++
|
||||
build:clang-common --incompatible_enable_cc_toolchain_resolution=false
|
||||
|
||||
# Clang with libc++ (default)
|
||||
build:clang --config=clang-common
|
||||
build:clang --config=libc++
|
||||
|
||||
build:arm64-clang --config=clang
|
||||
|
||||
# Flags for Clang + PCH
|
||||
build:clang-pch --spawn_strategy=local
|
||||
build:clang-pch --define=ENVOY_CLANG_PCH=1
|
||||
|
||||
# libstdc++ - currently only used for gcc
|
||||
build:libstdc++ --@envoy//bazel:libc++=false
|
||||
build:libstdc++ --@envoy//bazel:libstdc++=true
|
||||
|
||||
# Use gold linker for gcc compiler.
|
||||
build:gcc --linkopt=-fuse-ld=gold
|
||||
build:gcc --config=libstdc++
|
||||
build:gcc --test_env=HEAPCHECK=
|
||||
build:gcc --action_env=BAZEL_COMPILER=gcc
|
||||
build:gcc --action_env=CC=gcc --action_env=CXX=g++
|
||||
# This is to work around a bug in GCC that makes debug-types-section
|
||||
# option not play well with fission:
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110885
|
||||
build:gcc --copt=-fno-debug-types-section
|
||||
# These trigger errors in multiple places both in Envoy dependecies
|
||||
# and in Envoy code itself when using GCC.
|
||||
# And in all cases the reports appear to be clear false positives.
|
||||
build:gcc --copt=-Wno-error=restrict
|
||||
build:gcc --copt=-Wno-error=uninitialized
|
||||
build:gcc --cxxopt=-Wno-missing-requires
|
||||
build:gcc --cxxopt=-Wno-dangling-reference
|
||||
build:gcc --cxxopt=-Wno-nonnull-compare
|
||||
build:gcc --incompatible_enable_cc_toolchain_resolution=false
|
||||
build:gcc --linkopt=-fuse-ld=gold --host_linkopt=-fuse-ld=gold
|
||||
|
||||
# Clang-tidy
|
||||
# TODO(phlax): enable this, its throwing some errors as well as finding more issues
|
||||
|
@ -107,44 +137,40 @@ build:clang-tidy --aspects @envoy_toolshed//format/clang_tidy:clang_tidy.bzl%cla
|
|||
build:clang-tidy --output_groups=report
|
||||
build:clang-tidy --build_tag_filters=-notidy
|
||||
|
||||
# Basic ASAN/UBSAN that works for gcc
|
||||
build:asan --config=sanitizer
|
||||
# Basic ASAN/UBSAN that works for gcc or llvm
|
||||
build:asan-common --config=sanitizer
|
||||
# ASAN install its signal handler, disable ours so the stacktrace will be printed by ASAN
|
||||
build:asan --define signal_trace=disabled
|
||||
build:asan --define ENVOY_CONFIG_ASAN=1
|
||||
build:asan --build_tag_filters=-no_san
|
||||
build:asan --test_tag_filters=-no_san
|
||||
build:asan --copt -fsanitize=address,undefined
|
||||
build:asan --linkopt -fsanitize=address,undefined
|
||||
# vptr and function sanitizer are enabled in clang-asan if it is set up via bazel/setup_clang.sh.
|
||||
build:asan --copt -fno-sanitize=vptr,function
|
||||
build:asan --linkopt -fno-sanitize=vptr,function
|
||||
build:asan --copt -DADDRESS_SANITIZER=1
|
||||
build:asan --copt -DUNDEFINED_SANITIZER=1
|
||||
build:asan --copt -D__SANITIZE_ADDRESS__
|
||||
build:asan --test_env=ASAN_OPTIONS=handle_abort=1:allow_addr2line=true:check_initialization_order=true:strict_init_order=true:detect_odr_violation=1
|
||||
build:asan --test_env=UBSAN_OPTIONS=halt_on_error=true:print_stacktrace=1
|
||||
build:asan --test_env=ASAN_SYMBOLIZER_PATH
|
||||
build:asan-common --define signal_trace=disabled
|
||||
build:asan-common --define ENVOY_CONFIG_ASAN=1
|
||||
build:asan-common --build_tag_filters=-no_san
|
||||
build:asan-common --test_tag_filters=-no_san
|
||||
build:asan-common --copt -fsanitize=address,undefined
|
||||
build:asan-common --linkopt -fsanitize=address,undefined
|
||||
# vptr and function sanitizer are enabled in asan if it is set up via bazel/setup_clang.sh.
|
||||
build:asan-common --copt -fno-sanitize=vptr,function
|
||||
build:asan-common --linkopt -fno-sanitize=vptr,function
|
||||
build:asan-common --copt -DADDRESS_SANITIZER=1
|
||||
build:asan-common --copt -DUNDEFINED_SANITIZER=1
|
||||
build:asan-common --copt -D__SANITIZE_ADDRESS__
|
||||
build:asan-common --test_env=ASAN_OPTIONS=handle_abort=1:allow_addr2line=true:check_initialization_order=true:strict_init_order=true:detect_odr_violation=1
|
||||
build:asan-common --test_env=UBSAN_OPTIONS=halt_on_error=true:print_stacktrace=1
|
||||
build:asan-common --test_env=ASAN_SYMBOLIZER_PATH
|
||||
# ASAN needs -O1 to get reasonable performance.
|
||||
build:asan --copt -O1
|
||||
build:asan --copt -fno-optimize-sibling-calls
|
||||
build:asan-common --copt -O1
|
||||
build:asan-common --copt -fno-optimize-sibling-calls
|
||||
|
||||
# Clang ASAN/UBSAN
|
||||
build:clang-asan-common --config=clang
|
||||
build:clang-asan-common --config=asan
|
||||
build:clang-asan-common --linkopt -fuse-ld=lld
|
||||
build:clang-asan-common --linkopt --rtlib=compiler-rt
|
||||
build:clang-asan-common --linkopt --unwindlib=libgcc
|
||||
|
||||
build:clang-asan --config=clang-asan-common
|
||||
build:clang-asan --linkopt=-l:libclang_rt.ubsan_standalone.a
|
||||
build:clang-asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
|
||||
build:clang-asan --action_env=ENVOY_UBSAN_VPTR=1
|
||||
build:clang-asan --copt=-fsanitize=vptr,function
|
||||
build:clang-asan --linkopt=-fsanitize=vptr,function
|
||||
# ASAN config with clang runtime
|
||||
build:asan --config=asan-common
|
||||
build:asan --linkopt --rtlib=compiler-rt
|
||||
build:asan --linkopt --unwindlib=libgcc
|
||||
build:asan --linkopt=-l:libclang_rt.ubsan_standalone.a
|
||||
build:asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
|
||||
build:asan --action_env=ENVOY_UBSAN_VPTR=1
|
||||
build:asan --copt=-fsanitize=vptr,function
|
||||
build:asan --linkopt=-fsanitize=vptr,function
|
||||
build:asan --linkopt='-L/opt/llvm/lib/clang/18/lib/x86_64-unknown-linux-gnu'
|
||||
|
||||
# macOS
|
||||
build:macos --cxxopt=-std=c++20 --host_cxxopt=-std=c++20
|
||||
build:macos --action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin
|
||||
build:macos --host_action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin
|
||||
build:macos --define tcmalloc=disabled
|
||||
|
@ -159,54 +185,47 @@ build:macos-asan --copt -DGRPC_BAZEL_BUILD
|
|||
# Dynamic link cause issues like: `dyld: malformed mach-o: load commands size (59272) > 32768`
|
||||
build:macos-asan --dynamic_mode=off
|
||||
|
||||
# Clang TSAN
|
||||
build:clang-tsan --action_env=ENVOY_TSAN=1
|
||||
build:clang-tsan --config=sanitizer
|
||||
build:clang-tsan --define ENVOY_CONFIG_TSAN=1
|
||||
build:clang-tsan --copt -fsanitize=thread
|
||||
build:clang-tsan --linkopt -fsanitize=thread
|
||||
build:clang-tsan --linkopt -fuse-ld=lld
|
||||
build:clang-tsan --copt -DTHREAD_SANITIZER=1
|
||||
build:clang-tsan --build_tag_filters=-no_san,-no_tsan
|
||||
build:clang-tsan --test_tag_filters=-no_san,-no_tsan
|
||||
# Base TSAN config
|
||||
build:tsan --action_env=ENVOY_TSAN=1
|
||||
build:tsan --config=sanitizer
|
||||
build:tsan --define ENVOY_CONFIG_TSAN=1
|
||||
build:tsan --copt -fsanitize=thread
|
||||
build:tsan --linkopt -fsanitize=thread
|
||||
build:tsan --copt -DTHREAD_SANITIZER=1
|
||||
build:tsan --build_tag_filters=-no_san,-no_tsan
|
||||
build:tsan --test_tag_filters=-no_san,-no_tsan
|
||||
# Needed due to https://github.com/libevent/libevent/issues/777
|
||||
build:clang-tsan --copt -DEVENT__DISABLE_DEBUG_MODE
|
||||
build:tsan --copt -DEVENT__DISABLE_DEBUG_MODE
|
||||
# https://github.com/abseil/abseil-cpp/issues/760
|
||||
# https://github.com/google/sanitizers/issues/953
|
||||
build:clang-tsan --test_env="TSAN_OPTIONS=report_atomic_races=0"
|
||||
build:clang-tsan --test_timeout=120,600,1500,4800
|
||||
build:tsan --test_env="TSAN_OPTIONS=report_atomic_races=0"
|
||||
build:tsan --test_timeout=120,600,1500,4800
|
||||
|
||||
# Clang MSAN - this is the base config for remote-msan and docker-msan. To run this config without
|
||||
# our build image, follow https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo
|
||||
# with libc++ instruction and provide corresponding `--copt` and `--linkopt` as well.
|
||||
build:clang-msan --action_env=ENVOY_MSAN=1
|
||||
build:clang-msan --config=sanitizer
|
||||
build:clang-msan --build_tag_filters=-no_san
|
||||
build:clang-msan --test_tag_filters=-no_san
|
||||
build:clang-msan --define ENVOY_CONFIG_MSAN=1
|
||||
build:clang-msan --copt -fsanitize=memory
|
||||
build:clang-msan --linkopt -fsanitize=memory
|
||||
build:clang-msan --linkopt -fuse-ld=lld
|
||||
build:clang-msan --copt -fsanitize-memory-track-origins=2
|
||||
build:clang-msan --copt -DMEMORY_SANITIZER=1
|
||||
build:clang-msan --test_env=MSAN_SYMBOLIZER_PATH
|
||||
# Base MSAN config
|
||||
build:msan --action_env=ENVOY_MSAN=1
|
||||
build:msan --config=sanitizer
|
||||
build:msan --build_tag_filters=-no_san
|
||||
build:msan --test_tag_filters=-no_san
|
||||
build:msan --define ENVOY_CONFIG_MSAN=1
|
||||
build:msan --copt -fsanitize=memory
|
||||
build:msan --linkopt -fsanitize=memory
|
||||
build:msan --copt -fsanitize-memory-track-origins=2
|
||||
build:msan --copt -DMEMORY_SANITIZER=1
|
||||
build:msan --test_env=MSAN_SYMBOLIZER_PATH
|
||||
# MSAN needs -O1 to get reasonable performance.
|
||||
build:clang-msan --copt -O1
|
||||
build:clang-msan --copt -fno-optimize-sibling-calls
|
||||
build:msan --copt -O1
|
||||
build:msan --copt -fno-optimize-sibling-calls
|
||||
|
||||
# Clang with libc++
|
||||
build:libc++ --config=clang
|
||||
build:libc++ --action_env=CXXFLAGS=-stdlib=libc++
|
||||
build:libc++ --action_env=LDFLAGS=-stdlib=libc++
|
||||
build:libc++ --action_env=BAZEL_CXXOPTS=-stdlib=libc++
|
||||
build:libc++ --action_env=BAZEL_LINKLIBS=-l%:libc++.a:-l%:libc++abi.a
|
||||
build:libc++ --action_env=BAZEL_LINKOPTS=-lm:-pthread
|
||||
build:libc++ --define force_libcpp=enabled
|
||||
build:clang-libc++ --config=libc++
|
||||
build:libc++ --@envoy//bazel:libc++=true
|
||||
|
||||
|
||||
|
||||
build:libc++20 --config=libc++
|
||||
# gRPC has a lot of deprecated-enum-enum-conversion warning. Remove once it is addressed
|
||||
build:libc++20 --copt=-Wno-error=deprecated-enum-enum-conversion
|
||||
|
||||
# Optimize build for binary size reduction.
|
||||
build:sizeopt -c opt --copt -Os
|
||||
|
@ -223,7 +242,6 @@ build:coverage --action_env=GCOV=llvm-profdata
|
|||
build:coverage --copt=-DNDEBUG
|
||||
# 1.5x original timeout + 300s for trace merger in all categories
|
||||
build:coverage --test_timeout=390,750,1500,5700
|
||||
build:coverage --define=dynamic_link_tests=true
|
||||
build:coverage --define=ENVOY_CONFIG_COVERAGE=1
|
||||
build:coverage --cxxopt="-DENVOY_CONFIG_COVERAGE=1"
|
||||
build:coverage --test_env=HEAPCHECK=
|
||||
|
@ -242,6 +260,9 @@ build:coverage --define=no_debug_info=1
|
|||
# `--no-relax` is required for coverage to not err with `relocation R_X86_64_REX_GOTPCRELX`
|
||||
build:coverage --linkopt=-Wl,-s,--no-relax
|
||||
build:coverage --test_env=ENVOY_IP_TEST_VERSIONS=v4only
|
||||
build:coverage --define=dynamic_link_tests=false
|
||||
# Use custom report generator that also generates HTML
|
||||
build:coverage --coverage_report_generator=@envoy//tools/coverage:report_generator
|
||||
|
||||
build:test-coverage --test_arg="-l trace"
|
||||
build:test-coverage --test_arg="--log-path /dev/null"
|
||||
|
@ -249,62 +270,45 @@ build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target
|
|||
build:fuzz-coverage --config=plain-fuzzer
|
||||
build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh
|
||||
build:fuzz-coverage --test_tag_filters=-nocoverage
|
||||
# Existing fuzz tests don't need a full WASM runtime and in generally we don't really want to
|
||||
# fuzz dependencies anyways. On the other hand, disabling WASM reduces the build time and
|
||||
# resources required to build and run the tests.
|
||||
build:fuzz-coverage --define=wasm=disabled
|
||||
build:fuzz-coverage --config=fuzz-coverage-config
|
||||
build:fuzz-coverage-config --//tools/coverage:config=//test:fuzz_coverage_config
|
||||
|
||||
build:cache-local --remote_cache=grpc://localhost:9092
|
||||
|
||||
# Remote execution: https://docs.bazel.build/versions/master/remote-execution.html
|
||||
build:rbe-toolchain --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
|
||||
build:rbe-toolchain --incompatible_enable_cc_toolchain_resolution=false
|
||||
|
||||
build:rbe-toolchain-clang --config=rbe-toolchain
|
||||
build:rbe-toolchain-clang --platforms=@envoy_build_tools//toolchains:rbe_linux_clang_platform
|
||||
build:rbe-toolchain-clang --host_platform=@envoy_build_tools//toolchains:rbe_linux_clang_platform
|
||||
build:rbe-toolchain-clang --crosstool_top=@envoy_build_tools//toolchains/configs/linux/clang/cc:toolchain
|
||||
build:rbe-toolchain-clang --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/clang/config:cc-toolchain
|
||||
build:rbe-toolchain-clang --action_env=CC=clang --action_env=CXX=clang++ --action_env=PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
|
||||
build:rbe-toolchain-clang --config=clang
|
||||
build:rbe-toolchain-clang --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_clang_platform
|
||||
build:rbe-toolchain-clang --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_clang_platform
|
||||
build:rbe-toolchain-clang --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/clang/cc:toolchain
|
||||
build:rbe-toolchain-clang --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/clang/config:cc-toolchain
|
||||
build:rbe-toolchain-clang --action_env=CC=clang --action_env=CXX=clang++
|
||||
|
||||
build:rbe-toolchain-clang-libc++ --config=rbe-toolchain
|
||||
build:rbe-toolchain-clang-libc++ --platforms=@envoy_build_tools//toolchains:rbe_linux_clang_libcxx_platform
|
||||
build:rbe-toolchain-clang-libc++ --host_platform=@envoy_build_tools//toolchains:rbe_linux_clang_libcxx_platform
|
||||
build:rbe-toolchain-clang-libc++ --crosstool_top=@envoy_build_tools//toolchains/configs/linux/clang_libcxx/cc:toolchain
|
||||
build:rbe-toolchain-clang-libc++ --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/clang_libcxx/config:cc-toolchain
|
||||
build:rbe-toolchain-clang-libc++ --action_env=CC=clang --action_env=CXX=clang++ --action_env=PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/llvm/bin
|
||||
build:rbe-toolchain-clang-libc++ --action_env=CXXFLAGS=-stdlib=libc++
|
||||
build:rbe-toolchain-clang-libc++ --action_env=LDFLAGS=-stdlib=libc++
|
||||
build:rbe-toolchain-clang-libc++ --define force_libcpp=enabled
|
||||
|
||||
# Do not inherit from "clang-asan" to avoid picking up flags from local clang.bazelrc.
|
||||
build:rbe-toolchain-asan --config=asan
|
||||
build:rbe-toolchain-asan --linkopt -fuse-ld=lld
|
||||
build:rbe-toolchain-asan --action_env=ENVOY_UBSAN_VPTR=1
|
||||
build:rbe-toolchain-asan --copt=-fsanitize=vptr,function
|
||||
build:rbe-toolchain-asan --linkopt=-fsanitize=vptr,function
|
||||
build:rbe-toolchain-asan --linkopt='-L/opt/llvm/lib/clang/14.0.0/lib/x86_64-unknown-linux-gnu'
|
||||
build:rbe-toolchain-asan --linkopt=-l:libclang_rt.ubsan_standalone.a
|
||||
build:rbe-toolchain-asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a
|
||||
build:rbe-toolchain-arm64-clang --config=rbe-toolchain
|
||||
build:rbe-toolchain-arm64-clang --config=clang
|
||||
build:rbe-toolchain-arm64-clang --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_arm64_clang_platform
|
||||
build:rbe-toolchain-arm64-clang --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_arm64_clang_platform
|
||||
build:rbe-toolchain-arm64-clang --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/clang/cc:toolchain
|
||||
build:rbe-toolchain-arm64-clang --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/clang/config:cc-toolchain-arm64
|
||||
build:rbe-toolchain-arm64-clang --action_env=CC=clang --action_env=CXX=clang++
|
||||
|
||||
build:rbe-toolchain-msan --linkopt=-L/opt/libcxx_msan/lib
|
||||
build:rbe-toolchain-msan --linkopt=-Wl,-rpath,/opt/libcxx_msan/lib
|
||||
build:rbe-toolchain-msan --config=clang-msan
|
||||
|
||||
build:rbe-toolchain-tsan --linkopt=-L/opt/libcxx_tsan/lib
|
||||
build:rbe-toolchain-tsan --linkopt=-Wl,-rpath,/opt/libcxx_tsan/lib
|
||||
build:rbe-toolchain-tsan --config=clang-tsan
|
||||
# Sanitizer configs - CI uses the *-common configs directly
|
||||
# Note: clang config comes from rbe-toolchain-clang to avoid duplication
|
||||
|
||||
build:rbe-toolchain-gcc --config=rbe-toolchain
|
||||
build:rbe-toolchain-gcc --platforms=@envoy_build_tools//toolchains:rbe_linux_gcc_platform
|
||||
build:rbe-toolchain-gcc --host_platform=@envoy_build_tools//toolchains:rbe_linux_gcc_platform
|
||||
build:rbe-toolchain-gcc --crosstool_top=@envoy_build_tools//toolchains/configs/linux/gcc/cc:toolchain
|
||||
build:rbe-toolchain-gcc --extra_toolchains=@envoy_build_tools//toolchains/configs/linux/gcc/config:cc-toolchain
|
||||
|
||||
build:rbe-toolchain-msvc-cl --host_platform=@envoy_build_tools//toolchains:rbe_windows_msvc_cl_platform
|
||||
build:rbe-toolchain-msvc-cl --platforms=@envoy_build_tools//toolchains:rbe_windows_msvc_cl_platform
|
||||
build:rbe-toolchain-msvc-cl --crosstool_top=@envoy_build_tools//toolchains/configs/windows/msvc-cl/cc:toolchain
|
||||
build:rbe-toolchain-msvc-cl --extra_toolchains=@envoy_build_tools//toolchains/configs/windows/msvc-cl/config:cc-toolchain
|
||||
|
||||
build:rbe-toolchain-clang-cl --host_platform=@envoy_build_tools//toolchains:rbe_windows_clang_cl_platform
|
||||
build:rbe-toolchain-clang-cl --platforms=@envoy_build_tools//toolchains:rbe_windows_clang_cl_platform
|
||||
build:rbe-toolchain-clang-cl --crosstool_top=@envoy_build_tools//toolchains/configs/windows/clang-cl/cc:toolchain
|
||||
build:rbe-toolchain-clang-cl --extra_toolchains=@envoy_build_tools//toolchains/configs/windows/clang-cl/config:cc-toolchain
|
||||
build:rbe-toolchain-gcc --platforms=@envoy//bazel/rbe/toolchains:rbe_linux_gcc_platform
|
||||
build:rbe-toolchain-gcc --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_gcc_platform
|
||||
build:rbe-toolchain-gcc --crosstool_top=@envoy//bazel/rbe/toolchains/configs/linux/gcc/cc:toolchain
|
||||
build:rbe-toolchain-gcc --extra_toolchains=@envoy//bazel/rbe/toolchains/configs/linux/gcc/config:cc-toolchain
|
||||
|
||||
build:remote --spawn_strategy=remote,sandboxed,local
|
||||
build:remote --strategy=Javac=remote,sandboxed,local
|
||||
|
@ -324,24 +328,26 @@ build:remote-windows --remote_download_toplevel
|
|||
build:remote-clang --config=remote
|
||||
build:remote-clang --config=rbe-toolchain-clang
|
||||
|
||||
build:remote-clang-libc++ --config=remote
|
||||
build:remote-clang-libc++ --config=rbe-toolchain-clang-libc++
|
||||
|
||||
build:remote-arm64-clang --config=remote
|
||||
build:remote-arm64-clang --config=rbe-toolchain-arm64-clang
|
||||
|
||||
|
||||
build:remote-gcc --config=remote
|
||||
build:remote-gcc --config=gcc
|
||||
build:remote-gcc --config=rbe-toolchain-gcc
|
||||
|
||||
build:remote-asan --config=remote
|
||||
build:remote-asan --config=rbe-toolchain-clang-libc++
|
||||
build:remote-asan --config=rbe-toolchain-asan
|
||||
build:remote-asan --config=rbe-toolchain-clang
|
||||
build:remote-asan --config=asan
|
||||
|
||||
build:remote-msan --config=remote
|
||||
build:remote-msan --config=rbe-toolchain-clang-libc++
|
||||
build:remote-msan --config=rbe-toolchain-msan
|
||||
build:remote-msan --config=rbe-toolchain-clang
|
||||
build:remote-msan --config=msan
|
||||
|
||||
build:remote-tsan --config=remote
|
||||
build:remote-tsan --config=rbe-toolchain-clang-libc++
|
||||
build:remote-tsan --config=rbe-toolchain-tsan
|
||||
build:remote-tsan --config=rbe-toolchain-clang
|
||||
build:remote-tsan --config=tsan
|
||||
|
||||
build:remote-msvc-cl --config=remote-windows
|
||||
build:remote-msvc-cl --config=msvc-cl
|
||||
|
@ -365,14 +371,15 @@ build:compile-time-options --define=deprecated_features=disabled
|
|||
build:compile-time-options --define=tcmalloc=gperftools
|
||||
build:compile-time-options --define=zlib=ng
|
||||
build:compile-time-options --define=uhv=enabled
|
||||
build:compile-time-options --config=libc++20
|
||||
# gRPC has a lot of deprecated-enum-enum-conversion warnings with C++20
|
||||
build:compile-time-options --copt=-Wno-error=deprecated-enum-enum-conversion
|
||||
build:compile-time-options --test_env=ENVOY_HAS_EXTRA_EXTENSIONS=true
|
||||
build:compile-time-options --@envoy//bazel:http3=False
|
||||
build:compile-time-options --@envoy//source/extensions/filters/http/kill_request:enabled
|
||||
|
||||
# Docker sandbox
|
||||
# NOTE: Update this from https://github.com/envoyproxy/envoy-build-tools/blob/main/toolchains/rbe_toolchains_config.bzl#L8
|
||||
build:docker-sandbox --experimental_docker_image=envoyproxy/envoy-build-ubuntu:f94a38f62220a2b017878b790b6ea98a0f6c5f9c@sha256:2dd96b6f43c08ccabd5f4747fce5854f5f96af509b32e5cf6493f136e9833649
|
||||
build:docker-sandbox --experimental_docker_image=envoyproxy/envoy-build-ubuntu:f4a881a1205e8e6db1a57162faf3df7aed88eae8@sha256:b10346fe2eee41733dbab0e02322c47a538bf3938d093a5daebad9699860b814
|
||||
build:docker-sandbox --spawn_strategy=docker
|
||||
build:docker-sandbox --strategy=Javac=docker
|
||||
build:docker-sandbox --strategy=Closure=docker
|
||||
|
@ -384,39 +391,37 @@ build:docker-sandbox --experimental_enable_docker_sandbox
|
|||
build:docker-clang --config=docker-sandbox
|
||||
build:docker-clang --config=rbe-toolchain-clang
|
||||
|
||||
build:docker-clang-libc++ --config=docker-sandbox
|
||||
build:docker-clang-libc++ --config=rbe-toolchain-clang-libc++
|
||||
|
||||
build:docker-gcc --config=docker-sandbox
|
||||
build:docker-gcc --config=gcc
|
||||
build:docker-gcc --config=rbe-toolchain-gcc
|
||||
|
||||
build:docker-asan --config=docker-sandbox
|
||||
build:docker-asan --config=rbe-toolchain-clang-libc++
|
||||
build:docker-asan --config=rbe-toolchain-asan
|
||||
build:docker-asan --config=rbe-toolchain-clang
|
||||
build:docker-asan --config=asan
|
||||
|
||||
build:docker-msan --config=docker-sandbox
|
||||
build:docker-msan --config=rbe-toolchain-clang-libc++
|
||||
build:docker-msan --config=rbe-toolchain-msan
|
||||
build:docker-msan --config=rbe-toolchain-clang
|
||||
build:docker-msan --config=msan
|
||||
|
||||
build:docker-tsan --config=docker-sandbox
|
||||
build:docker-tsan --config=rbe-toolchain-clang-libc++
|
||||
build:docker-tsan --config=rbe-toolchain-tsan
|
||||
build:docker-tsan --config=rbe-toolchain-clang
|
||||
build:docker-tsan --config=tsan
|
||||
|
||||
# CI configurations
|
||||
build:remote-ci --config=ci
|
||||
build:remote-ci --remote_download_minimal
|
||||
|
||||
# Note this config is used by mobile CI also.
|
||||
build:ci --noshow_progress
|
||||
build:ci --noshow_loading_progress
|
||||
build:ci --test_output=errors
|
||||
common:ci --noshow_progress
|
||||
common:ci --noshow_loading_progress
|
||||
common:ci --test_output=errors
|
||||
|
||||
# Fuzz builds
|
||||
|
||||
# Shared fuzzing configuration.
|
||||
build:fuzzing --define=ENVOY_CONFIG_ASAN=1
|
||||
build:fuzzing --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
build:fuzzing --config=libc++
|
||||
|
||||
# Fuzzing without ASAN. This is useful for profiling fuzzers without any ASAN artifacts.
|
||||
build:plain-fuzzer --config=fuzzing
|
||||
|
@ -427,13 +432,16 @@ build:plain-fuzzer --define=FUZZING_ENGINE=libfuzzer
|
|||
build:plain-fuzzer --copt=-fsanitize=fuzzer-no-link
|
||||
build:plain-fuzzer --linkopt=-fsanitize=fuzzer-no-link
|
||||
|
||||
# ASAN fuzzer
|
||||
build:asan-fuzzer --config=plain-fuzzer
|
||||
build:asan-fuzzer --config=clang-asan
|
||||
build:asan-fuzzer --config=asan
|
||||
build:asan-fuzzer --copt=-fno-omit-frame-pointer
|
||||
# Remove UBSAN halt_on_error to avoid crashing on protobuf errors.
|
||||
build:asan-fuzzer --test_env=UBSAN_OPTIONS=print_stacktrace=1
|
||||
build:asan-fuzzer --linkopt=-lc++
|
||||
|
||||
build:oss-fuzz --config=fuzzing
|
||||
build:oss-fuzz --config=libc++
|
||||
build:oss-fuzz --define=FUZZING_ENGINE=oss-fuzz
|
||||
build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=oss-fuzz
|
||||
build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
|
||||
|
@ -519,25 +527,41 @@ build:rbe-engflow --remote_executor=grpcs://envoy.cluster.engflow.com
|
|||
build:rbe-engflow --bes_backend=grpcs://envoy.cluster.engflow.com/
|
||||
build:rbe-engflow --bes_results_url=https://envoy.cluster.engflow.com/invocation/
|
||||
build:rbe-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
|
||||
build:rbe-engflow --grpc_keepalive_time=30s
|
||||
build:rbe-engflow --grpc_keepalive_time=60s
|
||||
build:rbe-engflow --grpc_keepalive_timeout=30s
|
||||
build:rbe-engflow --remote_timeout=3600s
|
||||
build:rbe-engflow --bes_timeout=3600s
|
||||
build:rbe-engflow --bes_upload_mode=fully_async
|
||||
build:rbe-engflow --nolegacy_important_outputs
|
||||
|
||||
build:cache-envoy-engflow --google_default_credentials=false
|
||||
build:cache-envoy-engflow --remote_cache=grpcs://morganite.cluster.engflow.com
|
||||
build:cache-envoy-engflow --remote_timeout=3600s
|
||||
build:cache-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
|
||||
build:cache-envoy-engflow --grpc_keepalive_time=30s
|
||||
build:bes-envoy-engflow --bes_backend=grpcs://morganite.cluster.engflow.com/
|
||||
build:bes-envoy-engflow --bes_results_url=https://morganite.cluster.engflow.com/invocation/
|
||||
build:bes-envoy-engflow --bes_timeout=3600s
|
||||
build:bes-envoy-engflow --bes_upload_mode=fully_async
|
||||
build:rbe-envoy-engflow --config=cache-envoy-engflow
|
||||
build:rbe-envoy-engflow --config=bes-envoy-engflow
|
||||
build:rbe-envoy-engflow --remote_executor=grpcs://morganite.cluster.engflow.com
|
||||
build:rbe-envoy-engflow --remote_default_exec_properties=container-image=docker://docker.io/envoyproxy/envoy-build-ubuntu:f94a38f62220a2b017878b790b6ea98a0f6c5f9c@sha256:2dd96b6f43c08ccabd5f4747fce5854f5f96af509b32e5cf6493f136e9833649
|
||||
# RBE (Engflow Envoy)
|
||||
common:common-envoy-engflow --google_default_credentials=false
|
||||
common:common-envoy-engflow --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh
|
||||
common:common-envoy-engflow --grpc_keepalive_time=60s
|
||||
common:common-envoy-engflow --grpc_keepalive_timeout=30s
|
||||
|
||||
common:cache-envoy-engflow --remote_cache=grpcs://mordenite.cluster.engflow.com
|
||||
common:cache-envoy-engflow --remote_timeout=3600s
|
||||
# common:cache-envoy-engflow --remote_instance_name=llvm-18
|
||||
common:bes-envoy-engflow --bes_backend=grpcs://mordenite.cluster.engflow.com/
|
||||
common:bes-envoy-engflow --bes_results_url=https://mordenite.cluster.engflow.com/invocation/
|
||||
common:bes-envoy-engflow --bes_timeout=3600s
|
||||
common:bes-envoy-engflow --bes_upload_mode=fully_async
|
||||
common:bes-envoy-engflow --nolegacy_important_outputs
|
||||
common:rbe-envoy-engflow --remote_executor=grpcs://mordenite.cluster.engflow.com
|
||||
common:rbe-envoy-engflow --remote_default_exec_properties=container-image=docker://gcr.io/envoy-ci/envoy-build@sha256:95d7afdea0f0f8881e88fa5e581db4f50907d0745ac8d90e00357ac1a316abe5
|
||||
common:rbe-envoy-engflow --jobs=200
|
||||
common:rbe-envoy-engflow --define=engflow_rbe=true
|
||||
|
||||
common:remote-envoy-engflow --config=common-envoy-engflow
|
||||
common:remote-envoy-engflow --config=cache-envoy-engflow
|
||||
common:remote-envoy-engflow --config=rbe-envoy-engflow
|
||||
|
||||
common:remote-cache-envoy-engflow --config=common-envoy-engflow
|
||||
common:remote-cache-envoy-engflow --config=cache-envoy-engflow
|
||||
|
||||
# Specifies the rustfmt.toml for all rustfmt_test targets.
|
||||
build --@rules_rust//rust/settings:rustfmt.toml=//:rustfmt.toml
|
||||
|
||||
#############################################################################
|
||||
# debug: Various Bazel debugging flags
|
||||
|
@ -561,6 +585,7 @@ common:debug --config=debug-sandbox
|
|||
common:debug --config=debug-coverage
|
||||
common:debug --config=debug-tests
|
||||
|
||||
try-import %workspace%/repo.bazelrc
|
||||
try-import %workspace%/clang.bazelrc
|
||||
try-import %workspace%/user.bazelrc
|
||||
try-import %workspace%/local_tsan.bazelrc
|
||||
|
|
|
@ -20,135 +20,21 @@ load(
|
|||
"envoy_cc_library",
|
||||
"envoy_cc_test",
|
||||
)
|
||||
load(
|
||||
"@com_github_google_flatbuffers//:build_defs.bzl",
|
||||
"DEFAULT_FLATC_ARGS",
|
||||
"flatbuffer_library_public",
|
||||
)
|
||||
load(
|
||||
"@envoy//test/extensions:extensions_build_system.bzl",
|
||||
"envoy_extension_cc_benchmark_binary",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
envoy_cc_library(
|
||||
name = "proto_util",
|
||||
srcs = [
|
||||
"proto_util.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"proto_util.h",
|
||||
],
|
||||
repository = "@envoy",
|
||||
deps = [
|
||||
":metadata_object_lib",
|
||||
":node_info_fb_cc",
|
||||
":util",
|
||||
"@com_google_protobuf//:protobuf",
|
||||
"@proxy_wasm_cpp_host//:null_lib",
|
||||
],
|
||||
)
|
||||
|
||||
envoy_cc_library(
|
||||
name = "util",
|
||||
srcs = [
|
||||
"util.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"util.h",
|
||||
],
|
||||
repository = "@envoy",
|
||||
deps = [
|
||||
"@proxy_wasm_cpp_host//:null_lib",
|
||||
],
|
||||
)
|
||||
|
||||
envoy_cc_test(
|
||||
name = "proto_util_test",
|
||||
size = "small",
|
||||
srcs = ["proto_util_test.cc"],
|
||||
repository = "@envoy",
|
||||
deps = [
|
||||
":node_info_fb_cc",
|
||||
":proto_util",
|
||||
"@com_google_protobuf//:protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
envoy_cc_test(
|
||||
name = "util_test",
|
||||
size = "small",
|
||||
srcs = ["util_test.cc"],
|
||||
repository = "@envoy",
|
||||
deps = [
|
||||
":util",
|
||||
],
|
||||
)
|
||||
|
||||
# TODO: fix this build on mac m1?
|
||||
envoy_extension_cc_benchmark_binary(
|
||||
name = "proto_util_speed_test",
|
||||
srcs = select({
|
||||
"@envoy//bazel:linux": ["proto_util_speed_test.cc"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
extension_names = ["envoy.wasm.runtime.null"],
|
||||
external_deps = [
|
||||
"benchmark",
|
||||
],
|
||||
repository = "@envoy",
|
||||
deps = select({
|
||||
"@envoy//bazel:linux": [
|
||||
":metadata_object_lib",
|
||||
":node_info_fb_cc",
|
||||
":proto_util",
|
||||
"@envoy//source/common/stream_info:filter_state_lib",
|
||||
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
|
||||
"@envoy//test/test_common:status_utility_lib",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
flatbuffer_library_public(
|
||||
name = "node_info_fbs",
|
||||
srcs = ["node_info.fbs"],
|
||||
outs = [
|
||||
"node_info_bfbs_generated.h",
|
||||
"node_info_generated.h",
|
||||
],
|
||||
flatc_args = DEFAULT_FLATC_ARGS + ["--bfbs-gen-embed"],
|
||||
language_flag = "-c",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "node_info_fb_cc",
|
||||
srcs = [":node_info_fbs"],
|
||||
hdrs = [":node_info_fbs"],
|
||||
features = ["-parse_headers"],
|
||||
linkstatic = True,
|
||||
deps = [
|
||||
"@com_github_google_flatbuffers//:flatbuffers",
|
||||
"@com_github_google_flatbuffers//:runtime_cc",
|
||||
],
|
||||
)
|
||||
|
||||
envoy_cc_library(
|
||||
name = "metadata_object_lib",
|
||||
srcs = ["metadata_object.cc"],
|
||||
hdrs = ["metadata_object.h"],
|
||||
repository = "@envoy",
|
||||
deps = [
|
||||
":node_info_fb_cc",
|
||||
"@com_github_google_flatbuffers//:flatbuffers",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@envoy//envoy/common:hashable_interface",
|
||||
"@envoy//envoy/network:filter_interface",
|
||||
"@envoy//envoy/ssl:connection_interface",
|
||||
"@envoy//envoy/registry",
|
||||
"@envoy//envoy/stream_info:filter_state_interface",
|
||||
"@envoy//source/common/common:hash_lib",
|
||||
],
|
||||
|
@ -160,6 +46,6 @@ envoy_cc_test(
|
|||
repository = "@envoy",
|
||||
deps = [
|
||||
":metadata_object_lib",
|
||||
"@envoy//test/mocks/ssl:ssl_mocks",
|
||||
"@envoy//envoy/registry",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -14,25 +14,26 @@
|
|||
|
||||
#include "extensions/common/metadata_object.h"
|
||||
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "extensions/common/node_info_bfbs_generated.h"
|
||||
#include "envoy/registry/registry.h"
|
||||
#include "source/common/common/hash.h"
|
||||
#include "source/common/protobuf/utility.h"
|
||||
|
||||
#include "absl/strings/str_join.h"
|
||||
|
||||
namespace Istio {
|
||||
namespace Common {
|
||||
|
||||
namespace {
|
||||
static absl::flat_hash_map<absl::string_view, BaggageToken> ALL_BAGGAGE_TOKENS = {
|
||||
{NamespaceNameToken, BaggageToken::NamespaceName},
|
||||
{ClusterNameToken, BaggageToken::ClusterName},
|
||||
{ServiceNameToken, BaggageToken::ServiceName},
|
||||
{ServiceVersionToken, BaggageToken::ServiceVersion},
|
||||
{PodNameToken, BaggageToken::PodName},
|
||||
{DeploymentNameToken, BaggageToken::DeploymentName},
|
||||
{JobNameToken, BaggageToken::JobName},
|
||||
{CronJobNameToken, BaggageToken::CronJobName},
|
||||
{AppNameToken, BaggageToken::AppName},
|
||||
{AppVersionToken, BaggageToken::AppVersion},
|
||||
{WorkloadNameToken, BaggageToken::WorkloadName},
|
||||
{WorkloadTypeToken, BaggageToken::WorkloadType},
|
||||
{InstanceNameToken, BaggageToken::InstanceName},
|
||||
};
|
||||
|
||||
static absl::flat_hash_map<absl::string_view, WorkloadType> ALL_WORKLOAD_TOKENS = {
|
||||
|
@ -42,9 +43,283 @@ static absl::flat_hash_map<absl::string_view, WorkloadType> ALL_WORKLOAD_TOKENS
|
|||
{CronJobSuffix, WorkloadType::CronJob},
|
||||
};
|
||||
|
||||
WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view baggage_header_value) {
|
||||
// TODO: check for well-formed-ness of the baggage string: duplication,
|
||||
// inconsistency
|
||||
absl::optional<absl::string_view> toSuffix(WorkloadType workload_type) {
|
||||
switch (workload_type) {
|
||||
case WorkloadType::Deployment:
|
||||
return DeploymentSuffix;
|
||||
case WorkloadType::CronJob:
|
||||
return CronJobSuffix;
|
||||
case WorkloadType::Job:
|
||||
return JobSuffix;
|
||||
case WorkloadType::Pod:
|
||||
return PodSuffix;
|
||||
case WorkloadType::Unknown:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Envoy::ProtobufTypes::MessagePtr WorkloadMetadataObject::serializeAsProto() const {
|
||||
auto message = std::make_unique<Envoy::ProtobufWkt::Struct>();
|
||||
const auto suffix = toSuffix(workload_type_);
|
||||
if (suffix) {
|
||||
(*message->mutable_fields())[WorkloadTypeToken].set_string_value(*suffix);
|
||||
}
|
||||
if (!workload_name_.empty()) {
|
||||
(*message->mutable_fields())[WorkloadNameToken].set_string_value(workload_name_);
|
||||
}
|
||||
if (!cluster_name_.empty()) {
|
||||
(*message->mutable_fields())[InstanceNameToken].set_string_value(instance_name_);
|
||||
}
|
||||
if (!cluster_name_.empty()) {
|
||||
(*message->mutable_fields())[ClusterNameToken].set_string_value(cluster_name_);
|
||||
}
|
||||
if (!namespace_name_.empty()) {
|
||||
(*message->mutable_fields())[NamespaceNameToken].set_string_value(namespace_name_);
|
||||
}
|
||||
if (!canonical_name_.empty()) {
|
||||
(*message->mutable_fields())[ServiceNameToken].set_string_value(canonical_name_);
|
||||
}
|
||||
if (!canonical_revision_.empty()) {
|
||||
(*message->mutable_fields())[ServiceVersionToken].set_string_value(canonical_revision_);
|
||||
}
|
||||
if (!app_name_.empty()) {
|
||||
(*message->mutable_fields())[AppNameToken].set_string_value(app_name_);
|
||||
}
|
||||
if (!app_version_.empty()) {
|
||||
(*message->mutable_fields())[AppVersionToken].set_string_value(app_version_);
|
||||
}
|
||||
if (!identity_.empty()) {
|
||||
(*message->mutable_fields())[IdentityToken].set_string_value(identity_);
|
||||
}
|
||||
|
||||
if (!labels_.empty()) {
|
||||
auto* labels = (*message->mutable_fields())[LabelsToken].mutable_struct_value();
|
||||
for (const auto& l : labels_) {
|
||||
(*labels->mutable_fields())[std::string(l.first)].set_string_value(std::string(l.second));
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
std::vector<std::pair<absl::string_view, absl::string_view>>
|
||||
WorkloadMetadataObject::serializeAsPairs() const {
|
||||
std::vector<std::pair<absl::string_view, absl::string_view>> parts;
|
||||
const auto suffix = toSuffix(workload_type_);
|
||||
if (suffix) {
|
||||
parts.push_back({WorkloadTypeToken, *suffix});
|
||||
}
|
||||
if (!workload_name_.empty()) {
|
||||
parts.push_back({WorkloadNameToken, workload_name_});
|
||||
}
|
||||
if (!instance_name_.empty()) {
|
||||
parts.push_back({InstanceNameToken, instance_name_});
|
||||
}
|
||||
if (!cluster_name_.empty()) {
|
||||
parts.push_back({ClusterNameToken, cluster_name_});
|
||||
}
|
||||
if (!namespace_name_.empty()) {
|
||||
parts.push_back({NamespaceNameToken, namespace_name_});
|
||||
}
|
||||
if (!canonical_name_.empty()) {
|
||||
parts.push_back({ServiceNameToken, canonical_name_});
|
||||
}
|
||||
if (!canonical_revision_.empty()) {
|
||||
parts.push_back({ServiceVersionToken, canonical_revision_});
|
||||
}
|
||||
if (!app_name_.empty()) {
|
||||
parts.push_back({AppNameToken, app_name_});
|
||||
}
|
||||
if (!app_version_.empty()) {
|
||||
parts.push_back({AppVersionToken, app_version_});
|
||||
}
|
||||
if (!labels_.empty()) {
|
||||
for (const auto& l : labels_) {
|
||||
parts.push_back({absl::StrCat("labels[]", l.first), absl::string_view(l.second)});
|
||||
}
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
absl::optional<std::string> WorkloadMetadataObject::serializeAsString() const {
|
||||
const auto parts = serializeAsPairs();
|
||||
return absl::StrJoin(parts, ",", absl::PairFormatter("="));
|
||||
}
|
||||
|
||||
absl::optional<uint64_t> WorkloadMetadataObject::hash() const {
|
||||
return Envoy::HashUtil::xxHash64(*serializeAsString());
|
||||
}
|
||||
|
||||
absl::optional<std::string> WorkloadMetadataObject::owner() const {
|
||||
const auto suffix = toSuffix(workload_type_);
|
||||
if (suffix) {
|
||||
return absl::StrCat(OwnerPrefix, namespace_name_, "/", *suffix, "s/", workload_name_);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
WorkloadType fromSuffix(absl::string_view suffix) {
|
||||
const auto it = ALL_WORKLOAD_TOKENS.find(suffix);
|
||||
if (it != ALL_WORKLOAD_TOKENS.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return WorkloadType::Unknown;
|
||||
}
|
||||
|
||||
WorkloadType parseOwner(absl::string_view owner, absl::string_view workload) {
|
||||
// Strip "s/workload_name" and check for workload type.
|
||||
if (owner.size() > workload.size() + 2) {
|
||||
owner.remove_suffix(workload.size() + 2);
|
||||
size_t last = owner.rfind('/');
|
||||
if (last != absl::string_view::npos) {
|
||||
return fromSuffix(owner.substr(last + 1));
|
||||
}
|
||||
}
|
||||
return WorkloadType::Unknown;
|
||||
}
|
||||
|
||||
google::protobuf::Struct convertWorkloadMetadataToStruct(const WorkloadMetadataObject& obj) {
|
||||
google::protobuf::Struct metadata;
|
||||
if (!obj.instance_name_.empty()) {
|
||||
(*metadata.mutable_fields())[InstanceMetadataField].set_string_value(obj.instance_name_);
|
||||
}
|
||||
if (!obj.namespace_name_.empty()) {
|
||||
(*metadata.mutable_fields())[NamespaceMetadataField].set_string_value(obj.namespace_name_);
|
||||
}
|
||||
if (!obj.workload_name_.empty()) {
|
||||
(*metadata.mutable_fields())[WorkloadMetadataField].set_string_value(obj.workload_name_);
|
||||
}
|
||||
if (!obj.cluster_name_.empty()) {
|
||||
(*metadata.mutable_fields())[ClusterMetadataField].set_string_value(obj.cluster_name_);
|
||||
}
|
||||
auto* labels = (*metadata.mutable_fields())[LabelsMetadataField].mutable_struct_value();
|
||||
if (!obj.canonical_name_.empty()) {
|
||||
(*labels->mutable_fields())[CanonicalNameLabel].set_string_value(obj.canonical_name_);
|
||||
}
|
||||
if (!obj.canonical_revision_.empty()) {
|
||||
(*labels->mutable_fields())[CanonicalRevisionLabel].set_string_value(obj.canonical_revision_);
|
||||
}
|
||||
if (!obj.app_name_.empty()) {
|
||||
(*labels->mutable_fields())[AppNameLabel].set_string_value(obj.app_name_);
|
||||
}
|
||||
if (!obj.app_version_.empty()) {
|
||||
(*labels->mutable_fields())[AppVersionLabel].set_string_value(obj.app_version_);
|
||||
}
|
||||
if (!obj.getLabels().empty()) {
|
||||
for (const auto& lbl : obj.getLabels()) {
|
||||
(*labels->mutable_fields())[std::string(lbl.first)].set_string_value(std::string(lbl.second));
|
||||
}
|
||||
}
|
||||
if (const auto owner = obj.owner(); owner.has_value()) {
|
||||
(*metadata.mutable_fields())[OwnerMetadataField].set_string_value(*owner);
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
// Convert struct to a metadata object.
|
||||
std::unique_ptr<WorkloadMetadataObject>
|
||||
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata) {
|
||||
return convertStructToWorkloadMetadata(metadata, {});
|
||||
}
|
||||
|
||||
std::unique_ptr<WorkloadMetadataObject>
|
||||
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata,
|
||||
const absl::flat_hash_set<std::string>& additional_labels) {
|
||||
absl::string_view instance, namespace_name, owner, workload, cluster, canonical_name,
|
||||
canonical_revision, app_name, app_version;
|
||||
std::vector<std::pair<std::string, std::string>> labels;
|
||||
for (const auto& it : metadata.fields()) {
|
||||
if (it.first == InstanceMetadataField) {
|
||||
instance = it.second.string_value();
|
||||
} else if (it.first == NamespaceMetadataField) {
|
||||
namespace_name = it.second.string_value();
|
||||
} else if (it.first == OwnerMetadataField) {
|
||||
owner = it.second.string_value();
|
||||
} else if (it.first == WorkloadMetadataField) {
|
||||
workload = it.second.string_value();
|
||||
} else if (it.first == ClusterMetadataField) {
|
||||
cluster = it.second.string_value();
|
||||
} else if (it.first == LabelsMetadataField) {
|
||||
for (const auto& labels_it : it.second.struct_value().fields()) {
|
||||
if (labels_it.first == CanonicalNameLabel) {
|
||||
canonical_name = labels_it.second.string_value();
|
||||
} else if (labels_it.first == CanonicalRevisionLabel) {
|
||||
canonical_revision = labels_it.second.string_value();
|
||||
} else if (labels_it.first == AppNameLabel) {
|
||||
app_name = labels_it.second.string_value();
|
||||
} else if (labels_it.first == AppVersionLabel) {
|
||||
app_version = labels_it.second.string_value();
|
||||
} else if (!additional_labels.empty() &&
|
||||
additional_labels.contains(std::string(labels_it.first))) {
|
||||
labels.push_back(
|
||||
{std::string(labels_it.first), std::string(labels_it.second.string_value())});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto obj = std::make_unique<WorkloadMetadataObject>(instance, cluster, namespace_name, workload,
|
||||
canonical_name, canonical_revision, app_name,
|
||||
app_version, parseOwner(owner, workload), "");
|
||||
obj->setLabels(labels);
|
||||
return obj;
|
||||
}
|
||||
|
||||
absl::optional<WorkloadMetadataObject>
|
||||
convertEndpointMetadata(const std::string& endpoint_encoding) {
|
||||
std::vector<absl::string_view> parts = absl::StrSplit(endpoint_encoding, ';');
|
||||
if (parts.size() < 5) {
|
||||
return {};
|
||||
}
|
||||
return absl::make_optional<WorkloadMetadataObject>("", parts[4], parts[1], parts[0], parts[2],
|
||||
parts[3], "", "", WorkloadType::Unknown, "");
|
||||
}
|
||||
|
||||
std::string serializeToStringDeterministic(const google::protobuf::Struct& metadata) {
|
||||
std::string out;
|
||||
{
|
||||
google::protobuf::io::StringOutputStream md(&out);
|
||||
google::protobuf::io::CodedOutputStream mcs(&md);
|
||||
mcs.SetSerializationDeterministic(true);
|
||||
if (!metadata.SerializeToCodedStream(&mcs)) {
|
||||
out.clear();
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
WorkloadMetadataObject::FieldType
|
||||
WorkloadMetadataObject::getField(absl::string_view field_name) const {
|
||||
const auto it = ALL_BAGGAGE_TOKENS.find(field_name);
|
||||
if (it != ALL_BAGGAGE_TOKENS.end()) {
|
||||
switch (it->second) {
|
||||
case BaggageToken::NamespaceName:
|
||||
return namespace_name_;
|
||||
case BaggageToken::ClusterName:
|
||||
return cluster_name_;
|
||||
case BaggageToken::ServiceName:
|
||||
return canonical_name_;
|
||||
case BaggageToken::ServiceVersion:
|
||||
return canonical_revision_;
|
||||
case BaggageToken::AppName:
|
||||
return app_name_;
|
||||
case BaggageToken::AppVersion:
|
||||
return app_version_;
|
||||
case BaggageToken::WorkloadName:
|
||||
return workload_name_;
|
||||
case BaggageToken::WorkloadType:
|
||||
if (const auto value = toSuffix(workload_type_); value.has_value()) {
|
||||
return *value;
|
||||
}
|
||||
case BaggageToken::InstanceName:
|
||||
return instance_name_;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<WorkloadMetadataObject> convertBaggageToWorkloadMetadata(absl::string_view data) {
|
||||
absl::string_view instance;
|
||||
absl::string_view cluster;
|
||||
absl::string_view workload;
|
||||
|
@ -53,11 +328,10 @@ WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view bag
|
|||
absl::string_view canonical_revision;
|
||||
absl::string_view app_name;
|
||||
absl::string_view app_version;
|
||||
WorkloadType workload_type = WorkloadType::Pod;
|
||||
|
||||
std::vector<absl::string_view> properties = absl::StrSplit(baggage_header_value, ',');
|
||||
WorkloadType workload_type = WorkloadType::Unknown;
|
||||
std::vector<absl::string_view> properties = absl::StrSplit(data, ',');
|
||||
for (absl::string_view property : properties) {
|
||||
std::pair<absl::string_view, absl::string_view> parts = absl::StrSplit(property, "=");
|
||||
std::pair<absl::string_view, absl::string_view> parts = absl::StrSplit(property, '=');
|
||||
const auto it = ALL_BAGGAGE_TOKENS.find(parts.first);
|
||||
if (it != ALL_BAGGAGE_TOKENS.end()) {
|
||||
switch (it->second) {
|
||||
|
@ -73,249 +347,27 @@ WorkloadMetadataObject WorkloadMetadataObject::fromBaggage(absl::string_view bag
|
|||
case BaggageToken::ServiceVersion:
|
||||
canonical_revision = parts.second;
|
||||
break;
|
||||
case BaggageToken::PodName:
|
||||
workload_type = WorkloadType::Pod;
|
||||
instance = parts.second;
|
||||
workload = parts.second;
|
||||
break;
|
||||
case BaggageToken::DeploymentName:
|
||||
workload_type = WorkloadType::Deployment;
|
||||
workload = parts.second;
|
||||
break;
|
||||
case BaggageToken::JobName:
|
||||
workload_type = WorkloadType::Job;
|
||||
instance = parts.second;
|
||||
workload = parts.second;
|
||||
break;
|
||||
case BaggageToken::CronJobName:
|
||||
workload_type = WorkloadType::CronJob;
|
||||
workload = parts.second;
|
||||
break;
|
||||
case BaggageToken::AppName:
|
||||
app_name = parts.second;
|
||||
break;
|
||||
case BaggageToken::AppVersion:
|
||||
app_version = parts.second;
|
||||
break;
|
||||
case BaggageToken::WorkloadName:
|
||||
workload = parts.second;
|
||||
break;
|
||||
case BaggageToken::WorkloadType:
|
||||
workload_type = fromSuffix(parts.second);
|
||||
break;
|
||||
case BaggageToken::InstanceName:
|
||||
instance = parts.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return WorkloadMetadataObject(instance, cluster, namespace_name, workload, canonical_name,
|
||||
canonical_revision, app_name, app_version, workload_type, "");
|
||||
}
|
||||
|
||||
std::string WorkloadMetadataObject::baggage() const {
|
||||
absl::string_view workload_type = PodSuffix;
|
||||
switch (workload_type_) {
|
||||
case WorkloadType::Deployment:
|
||||
workload_type = DeploymentSuffix;
|
||||
break;
|
||||
case WorkloadType::CronJob:
|
||||
workload_type = CronJobSuffix;
|
||||
break;
|
||||
case WorkloadType::Job:
|
||||
workload_type = JobSuffix;
|
||||
break;
|
||||
case WorkloadType::Pod:
|
||||
workload_type = PodSuffix;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
std::vector<absl::string_view> parts;
|
||||
parts.push_back("k8s.");
|
||||
parts.push_back(workload_type);
|
||||
parts.push_back(".name=");
|
||||
parts.push_back(workload_name_);
|
||||
if (!cluster_name_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(ClusterNameToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(cluster_name_);
|
||||
}
|
||||
if (!namespace_name_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(NamespaceNameToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(namespace_name_);
|
||||
}
|
||||
if (!canonical_name_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(ServiceNameToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(canonical_name_);
|
||||
}
|
||||
if (!canonical_revision_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(ServiceVersionToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(canonical_revision_);
|
||||
}
|
||||
if (!app_name_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(AppNameToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(app_name_);
|
||||
}
|
||||
if (!app_version_.empty()) {
|
||||
parts.push_back(",");
|
||||
parts.push_back(AppVersionToken);
|
||||
parts.push_back("=");
|
||||
parts.push_back(app_version_);
|
||||
}
|
||||
return absl::StrJoin(parts, "");
|
||||
}
|
||||
|
||||
absl::optional<uint64_t> WorkloadMetadataObject::hash() const {
|
||||
return Envoy::HashUtil::xxHash64(absl::StrCat(instance_name_, "/", namespace_name_));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Returns a string view stored in a flatbuffers string.
|
||||
absl::string_view toAbslStringView(const flatbuffers::String* str) {
|
||||
return str ? absl::string_view(str->c_str(), str->size()) : absl::string_view();
|
||||
}
|
||||
|
||||
std::string_view toStdStringView(absl::string_view view) {
|
||||
return std::string_view(view.data(), view.size());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string convertWorkloadMetadataToFlatNode(const WorkloadMetadataObject& obj) {
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
|
||||
flatbuffers::Offset<flatbuffers::String> name, cluster, namespace_, workload_name, owner,
|
||||
identity;
|
||||
std::vector<flatbuffers::Offset<Wasm::Common::KeyVal>> labels;
|
||||
|
||||
name = fbb.CreateString(toStdStringView(obj.instance_name_));
|
||||
namespace_ = fbb.CreateString(toStdStringView(obj.namespace_name_));
|
||||
cluster = fbb.CreateString(toStdStringView(obj.cluster_name_));
|
||||
workload_name = fbb.CreateString(toStdStringView(obj.workload_name_));
|
||||
identity = fbb.CreateString(toStdStringView(obj.identity_));
|
||||
|
||||
switch (obj.workload_type_) {
|
||||
case WorkloadType::Deployment:
|
||||
owner = fbb.CreateString(absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", DeploymentSuffix,
|
||||
"s/", obj.workload_name_));
|
||||
break;
|
||||
case WorkloadType::Job:
|
||||
owner = fbb.CreateString(
|
||||
absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", JobSuffix, "s/", obj.workload_name_));
|
||||
break;
|
||||
case WorkloadType::CronJob:
|
||||
owner = fbb.CreateString(absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", CronJobSuffix,
|
||||
"s/", obj.workload_name_));
|
||||
break;
|
||||
case WorkloadType::Pod:
|
||||
owner = fbb.CreateString(
|
||||
absl::StrCat(OwnerPrefix, obj.namespace_name_, "/", PodSuffix, "s/", obj.workload_name_));
|
||||
break;
|
||||
}
|
||||
|
||||
labels.push_back(
|
||||
Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(CanonicalNameLabel),
|
||||
fbb.CreateString(toStdStringView(obj.canonical_name_))));
|
||||
labels.push_back(
|
||||
Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(CanonicalRevisionLabel),
|
||||
fbb.CreateString(toStdStringView(obj.canonical_revision_))));
|
||||
labels.push_back(Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(AppLabel),
|
||||
fbb.CreateString(toStdStringView(obj.app_name_))));
|
||||
labels.push_back(Wasm::Common::CreateKeyVal(fbb, fbb.CreateString(VersionLabel),
|
||||
fbb.CreateString(toStdStringView(obj.app_version_))));
|
||||
|
||||
auto labels_offset = fbb.CreateVectorOfSortedTables(&labels);
|
||||
Wasm::Common::FlatNodeBuilder node(fbb);
|
||||
node.add_name(name);
|
||||
node.add_cluster_id(cluster);
|
||||
node.add_namespace_(namespace_);
|
||||
node.add_workload_name(workload_name);
|
||||
node.add_owner(owner);
|
||||
node.add_labels(labels_offset);
|
||||
node.add_identity(identity);
|
||||
auto data = node.Finish();
|
||||
fbb.Finish(data);
|
||||
auto fb = fbb.Release();
|
||||
return std::string(reinterpret_cast<const char*>(fb.data()), fb.size());
|
||||
}
|
||||
|
||||
WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::FlatNode& node) {
|
||||
const absl::string_view instance = toAbslStringView(node.name());
|
||||
const absl::string_view cluster = toAbslStringView(node.cluster_id());
|
||||
const absl::string_view workload = toAbslStringView(node.workload_name());
|
||||
const absl::string_view namespace_name = toAbslStringView(node.namespace_());
|
||||
const absl::string_view identity = toAbslStringView(node.identity());
|
||||
const auto* labels = node.labels();
|
||||
|
||||
absl::string_view canonical_name;
|
||||
absl::string_view canonical_revision;
|
||||
absl::string_view app_name;
|
||||
absl::string_view app_version;
|
||||
if (labels) {
|
||||
const auto* name_iter = labels->LookupByKey(CanonicalNameLabel);
|
||||
const auto* name = name_iter ? name_iter->value() : nullptr;
|
||||
canonical_name = toAbslStringView(name);
|
||||
|
||||
const auto* revision_iter = labels->LookupByKey(CanonicalRevisionLabel);
|
||||
const auto* revision = revision_iter ? revision_iter->value() : nullptr;
|
||||
canonical_revision = toAbslStringView(revision);
|
||||
|
||||
const auto* app_iter = labels->LookupByKey(AppLabel);
|
||||
const auto* app = app_iter ? app_iter->value() : nullptr;
|
||||
app_name = toAbslStringView(app);
|
||||
|
||||
const auto* version_iter = labels->LookupByKey(VersionLabel);
|
||||
const auto* version = version_iter ? version_iter->value() : nullptr;
|
||||
app_version = toAbslStringView(version);
|
||||
}
|
||||
|
||||
WorkloadType workload_type = WorkloadType::Pod;
|
||||
// Strip "s/workload_name" and check for workload type.
|
||||
absl::string_view owner = toAbslStringView(node.owner());
|
||||
if (owner.size() > workload.size() + 2) {
|
||||
owner.remove_suffix(workload.size() + 2);
|
||||
size_t last = owner.rfind('/');
|
||||
if (last != absl::string_view::npos) {
|
||||
const auto it = ALL_WORKLOAD_TOKENS.find(owner.substr(last + 1));
|
||||
if (it != ALL_WORKLOAD_TOKENS.end()) {
|
||||
switch (it->second) {
|
||||
case WorkloadType::Deployment:
|
||||
workload_type = WorkloadType::Deployment;
|
||||
break;
|
||||
case WorkloadType::CronJob:
|
||||
workload_type = WorkloadType::CronJob;
|
||||
break;
|
||||
case WorkloadType::Job:
|
||||
workload_type = WorkloadType::Job;
|
||||
break;
|
||||
case WorkloadType::Pod:
|
||||
workload_type = WorkloadType::Pod;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WorkloadMetadataObject(instance, cluster, namespace_name, workload, canonical_name,
|
||||
canonical_revision, app_name, app_version, workload_type, identity);
|
||||
}
|
||||
|
||||
absl::optional<WorkloadMetadataObject>
|
||||
convertEndpointMetadata(const std::string& endpoint_encoding) {
|
||||
std::vector<absl::string_view> parts = absl::StrSplit(endpoint_encoding, ';');
|
||||
if (parts.size() < 5) {
|
||||
return {};
|
||||
}
|
||||
// TODO: we cannot determine workload type from the encoding.
|
||||
return absl::make_optional<WorkloadMetadataObject>("", parts[4], parts[1], parts[0], parts[2],
|
||||
parts[3], "", "", WorkloadType::Pod, "");
|
||||
}
|
||||
|
||||
std::string_view nodeInfoSchema() {
|
||||
return std::string_view(reinterpret_cast<const char*>(Wasm::Common::FlatNodeBinarySchema::data()),
|
||||
Wasm::Common::FlatNodeBinarySchema::size());
|
||||
return std::make_unique<WorkloadMetadataObject>(instance, cluster, namespace_name, workload,
|
||||
canonical_name, canonical_revision, app_name,
|
||||
app_version, workload_type, "");
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
|
|
@ -14,27 +14,34 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "envoy/common/hashable.h"
|
||||
#include "envoy/ssl/connection.h"
|
||||
#include "envoy/stream_info/filter_state.h"
|
||||
#include "extensions/common/node_info_generated.h"
|
||||
|
||||
#include "source/common/protobuf/protobuf.h"
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include "google/protobuf/struct.pb.h"
|
||||
|
||||
namespace Istio {
|
||||
namespace Common {
|
||||
|
||||
constexpr absl::string_view WasmDownstreamPeer = "wasm.downstream_peer";
|
||||
constexpr absl::string_view WasmDownstreamPeerID = "wasm.downstream_peer_id";
|
||||
constexpr absl::string_view WasmUpstreamPeer = "wasm.upstream_peer";
|
||||
constexpr absl::string_view WasmUpstreamPeerID = "wasm.upstream_peer_id";
|
||||
// Filter state key to store the peer metadata under.
|
||||
constexpr absl::string_view DownstreamPeer = "downstream_peer";
|
||||
constexpr absl::string_view UpstreamPeer = "upstream_peer";
|
||||
|
||||
// Special filter state key to indicate the filter is done looking for peer metadata.
|
||||
// This is used by network metadata exchange on failure.
|
||||
constexpr absl::string_view NoPeer = "peer_not_found";
|
||||
|
||||
// Special labels used in the peer metadata.
|
||||
constexpr absl::string_view CanonicalNameLabel = "service.istio.io/canonical-name";
|
||||
constexpr absl::string_view CanonicalRevisionLabel = "service.istio.io/canonical-revision";
|
||||
constexpr absl::string_view AppLabel = "app";
|
||||
constexpr absl::string_view VersionLabel = "version";
|
||||
constexpr absl::string_view AppNameLabel = "app";
|
||||
constexpr absl::string_view AppVersionLabel = "version";
|
||||
|
||||
enum class WorkloadType {
|
||||
Unknown,
|
||||
Pod,
|
||||
Deployment,
|
||||
Job,
|
||||
|
@ -42,6 +49,7 @@ enum class WorkloadType {
|
|||
};
|
||||
|
||||
constexpr absl::string_view OwnerPrefix = "kubernetes://apis/apps/v1/namespaces/";
|
||||
|
||||
constexpr absl::string_view PodSuffix = "pod";
|
||||
constexpr absl::string_view DeploymentSuffix = "deployment";
|
||||
constexpr absl::string_view JobSuffix = "job";
|
||||
|
@ -52,45 +60,56 @@ enum class BaggageToken {
|
|||
ClusterName,
|
||||
ServiceName,
|
||||
ServiceVersion,
|
||||
PodName,
|
||||
DeploymentName,
|
||||
JobName,
|
||||
CronJobName,
|
||||
AppName,
|
||||
AppVersion,
|
||||
WorkloadName,
|
||||
WorkloadType,
|
||||
InstanceName,
|
||||
};
|
||||
|
||||
constexpr absl::string_view NamespaceNameToken = "k8s.namespace.name";
|
||||
constexpr absl::string_view ClusterNameToken = "k8s.cluster.name";
|
||||
constexpr absl::string_view ServiceNameToken = "service.name";
|
||||
constexpr absl::string_view ServiceVersionToken = "service.version";
|
||||
constexpr absl::string_view PodNameToken = "k8s.pod.name";
|
||||
constexpr absl::string_view DeploymentNameToken = "k8s.deployment.name";
|
||||
constexpr absl::string_view JobNameToken = "k8s.job.name";
|
||||
constexpr absl::string_view CronJobNameToken = "k8s.cronjob.name";
|
||||
constexpr absl::string_view AppNameToken = "app.name";
|
||||
constexpr absl::string_view AppVersionToken = "app.version";
|
||||
constexpr absl::string_view NamespaceNameToken = "namespace";
|
||||
constexpr absl::string_view ClusterNameToken = "cluster";
|
||||
constexpr absl::string_view ServiceNameToken = "service";
|
||||
constexpr absl::string_view ServiceVersionToken = "revision";
|
||||
constexpr absl::string_view AppNameToken = "app";
|
||||
constexpr absl::string_view AppVersionToken = "version";
|
||||
constexpr absl::string_view WorkloadNameToken = "workload";
|
||||
constexpr absl::string_view WorkloadTypeToken = "type";
|
||||
constexpr absl::string_view InstanceNameToken = "name";
|
||||
constexpr absl::string_view LabelsToken = "labels";
|
||||
constexpr absl::string_view IdentityToken = "identity";
|
||||
|
||||
struct WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
|
||||
public Envoy::Hashable {
|
||||
constexpr absl::string_view InstanceMetadataField = "NAME";
|
||||
constexpr absl::string_view NamespaceMetadataField = "NAMESPACE";
|
||||
constexpr absl::string_view ClusterMetadataField = "CLUSTER_ID";
|
||||
constexpr absl::string_view OwnerMetadataField = "OWNER";
|
||||
constexpr absl::string_view WorkloadMetadataField = "WORKLOAD_NAME";
|
||||
constexpr absl::string_view LabelsMetadataField = "LABELS";
|
||||
|
||||
class WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
|
||||
public Envoy::Hashable {
|
||||
public:
|
||||
explicit WorkloadMetadataObject(absl::string_view instance_name, absl::string_view cluster_name,
|
||||
absl::string_view namespace_name, absl::string_view workload_name,
|
||||
absl::string_view canonical_name,
|
||||
absl::string_view canonical_revision, absl::string_view app_name,
|
||||
absl::string_view app_version, const WorkloadType workload_type,
|
||||
absl::string_view app_version, WorkloadType workload_type,
|
||||
absl::string_view identity)
|
||||
: instance_name_(instance_name), cluster_name_(cluster_name), namespace_name_(namespace_name),
|
||||
workload_name_(workload_name), canonical_name_(canonical_name),
|
||||
canonical_revision_(canonical_revision), app_name_(app_name), app_version_(app_version),
|
||||
workload_type_(workload_type), identity_(identity) {}
|
||||
|
||||
static WorkloadMetadataObject fromBaggage(absl::string_view baggage_header_value);
|
||||
|
||||
std::string baggage() const;
|
||||
|
||||
absl::optional<uint64_t> hash() const override;
|
||||
|
||||
absl::optional<std::string> serializeAsString() const override { return baggage(); }
|
||||
Envoy::ProtobufTypes::MessagePtr serializeAsProto() const override;
|
||||
std::vector<std::pair<absl::string_view, absl::string_view>> serializeAsPairs() const;
|
||||
absl::optional<std::string> serializeAsString() const override;
|
||||
absl::optional<std::string> owner() const;
|
||||
bool hasFieldSupport() const override { return true; }
|
||||
using Envoy::StreamInfo::FilterState::Object::FieldType;
|
||||
FieldType getField(absl::string_view) const override;
|
||||
void setLabels(std::vector<std::pair<std::string, std::string>> labels) { labels_ = labels; }
|
||||
std::vector<std::pair<std::string, std::string>> getLabels() const { return labels_; }
|
||||
|
||||
const std::string instance_name_;
|
||||
const std::string cluster_name_;
|
||||
|
@ -102,13 +121,25 @@ struct WorkloadMetadataObject : public Envoy::StreamInfo::FilterState::Object,
|
|||
const std::string app_version_;
|
||||
const WorkloadType workload_type_;
|
||||
const std::string identity_;
|
||||
std::vector<std::pair<std::string, std::string>> labels_;
|
||||
};
|
||||
|
||||
// Convert metadata object to flatbuffer.
|
||||
std::string convertWorkloadMetadataToFlatNode(const WorkloadMetadataObject& obj);
|
||||
// Parse string workload type.
|
||||
WorkloadType fromSuffix(absl::string_view suffix);
|
||||
|
||||
// Convert flatbuffer to metadata object.
|
||||
WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::FlatNode& node);
|
||||
// Parse owner field from kubernetes to detect the workload type.
|
||||
WorkloadType parseOwner(absl::string_view owner, absl::string_view workload);
|
||||
|
||||
// Convert a metadata object to a struct.
|
||||
google::protobuf::Struct convertWorkloadMetadataToStruct(const WorkloadMetadataObject& obj);
|
||||
|
||||
// Convert struct to a metadata object.
|
||||
std::unique_ptr<WorkloadMetadataObject>
|
||||
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata);
|
||||
|
||||
std::unique_ptr<WorkloadMetadataObject>
|
||||
convertStructToWorkloadMetadata(const google::protobuf::Struct& metadata,
|
||||
const absl::flat_hash_set<std::string>& additional_labels);
|
||||
|
||||
// Convert endpoint metadata string to a metadata object.
|
||||
// Telemetry metadata is compressed into a semicolon separated string:
|
||||
|
@ -118,8 +149,10 @@ WorkloadMetadataObject convertFlatNodeToWorkloadMetadata(const Wasm::Common::Fla
|
|||
absl::optional<WorkloadMetadataObject>
|
||||
convertEndpointMetadata(const std::string& endpoint_encoding);
|
||||
|
||||
// Returns flatbuffer schema for node info.
|
||||
std::string_view nodeInfoSchema();
|
||||
std::string serializeToStringDeterministic(const google::protobuf::Struct& metadata);
|
||||
|
||||
// Convert from baggage encoding.
|
||||
std::unique_ptr<WorkloadMetadataObject> convertBaggageToWorkloadMetadata(absl::string_view data);
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Istio
|
||||
|
|
|
@ -14,154 +14,156 @@
|
|||
|
||||
#include "extensions/common/metadata_object.h"
|
||||
|
||||
#include "envoy/registry/registry.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace Istio {
|
||||
namespace Common {
|
||||
|
||||
using Envoy::Protobuf::util::MessageDifferencer;
|
||||
using ::testing::NiceMock;
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, Hash) {
|
||||
WorkloadMetadataObject obj1("foo-pod-12345", "my-cluster", "default", "foo", "foo", "latest",
|
||||
"foo-app", "v1", WorkloadType::Deployment, "");
|
||||
WorkloadMetadataObject obj2("foo-pod-12345", "my-cluster", "default", "bar", "baz", "first",
|
||||
"foo-app", "v1", WorkloadType::Job, "");
|
||||
|
||||
EXPECT_EQ(obj1.hash().value(), obj2.hash().value());
|
||||
}
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, Baggage) {
|
||||
WorkloadMetadataObject deploy("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", WorkloadType::Deployment, "");
|
||||
"v1alpha3", "", "", WorkloadType::Deployment, "");
|
||||
|
||||
WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", WorkloadType::Pod, "");
|
||||
"v1alpha3", "", "", WorkloadType::Pod, "");
|
||||
|
||||
WorkloadMetadataObject cronjob("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", WorkloadType::CronJob, "");
|
||||
|
||||
WorkloadMetadataObject job("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", WorkloadType::Job, "");
|
||||
"v1alpha3", "", "", WorkloadType::Job, "");
|
||||
|
||||
EXPECT_EQ(deploy.baggage(), absl::StrCat("k8s.deployment.name=foo,k8s.cluster.name=my-cluster,",
|
||||
"k8s.namespace.name=default,",
|
||||
"service.name=foo-service,service.version=v1alpha3,",
|
||||
"app.name=foo-app,app.version=v1"));
|
||||
EXPECT_EQ(deploy.serializeAsString(),
|
||||
absl::StrCat("type=deployment,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
|
||||
"namespace=default,service=foo-service,revision=v1alpha3"));
|
||||
|
||||
EXPECT_EQ(pod.baggage(), absl::StrCat("k8s.pod.name=foo,k8s.cluster.name=my-cluster,",
|
||||
"k8s.namespace.name=default,",
|
||||
"service.name=foo-service,service.version=v1alpha3,",
|
||||
"app.name=foo-app,app.version=v1"));
|
||||
EXPECT_EQ(pod.serializeAsString(),
|
||||
absl::StrCat("type=pod,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
|
||||
"namespace=default,service=foo-service,revision=v1alpha3"));
|
||||
|
||||
EXPECT_EQ(cronjob.baggage(), absl::StrCat("k8s.cronjob.name=foo,k8s.cluster.name=my-cluster,",
|
||||
"k8s.namespace.name=default,"
|
||||
"service.name=foo-service,service.version=v1alpha3,",
|
||||
"app.name=foo-app,app.version=v1"));
|
||||
EXPECT_EQ(cronjob.serializeAsString(),
|
||||
absl::StrCat("type=cronjob,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
|
||||
"namespace=default,service=foo-service,revision=v1alpha3,",
|
||||
"app=foo-app,version=v1"));
|
||||
|
||||
EXPECT_EQ(job.baggage(), absl::StrCat("k8s.job.name=foo,k8s.cluster.name=my-cluster,",
|
||||
"k8s.namespace.name=default,",
|
||||
"service.name=foo-service,service.version=v1alpha3,",
|
||||
"app.name=foo-app,app.version=v1"));
|
||||
EXPECT_EQ(job.serializeAsString(),
|
||||
absl::StrCat("type=job,workload=foo,name=pod-foo-1234,cluster=my-cluster,",
|
||||
"namespace=default,service=foo-service,revision=v1alpha3"));
|
||||
}
|
||||
|
||||
void checkFlatNodeConversion(const WorkloadMetadataObject& obj) {
|
||||
auto buffer = convertWorkloadMetadataToFlatNode(obj);
|
||||
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(buffer.data());
|
||||
auto obj2 = convertFlatNodeToWorkloadMetadata(node);
|
||||
EXPECT_EQ(obj2.baggage(), obj.baggage());
|
||||
void checkStructConversion(const Envoy::StreamInfo::FilterState::Object& data) {
|
||||
const auto& obj = dynamic_cast<const WorkloadMetadataObject&>(data);
|
||||
auto pb = convertWorkloadMetadataToStruct(obj);
|
||||
auto obj2 = convertStructToWorkloadMetadata(pb);
|
||||
EXPECT_EQ(obj2->serializeAsString(), obj.serializeAsString());
|
||||
MessageDifferencer::Equals(*(obj2->serializeAsProto()), *(obj.serializeAsProto()));
|
||||
EXPECT_EQ(obj2->hash(), obj.hash());
|
||||
}
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, FromBaggage) {
|
||||
TEST(WorkloadMetadataObjectTest, ConversionWithLabels) {
|
||||
WorkloadMetadataObject deploy("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "", "", WorkloadType::Deployment, "");
|
||||
deploy.setLabels({{"label1", "value1"}, {"label2", "value2"}});
|
||||
auto pb = convertWorkloadMetadataToStruct(deploy);
|
||||
auto obj1 = convertStructToWorkloadMetadata(pb, {"label1", "label2"});
|
||||
EXPECT_EQ(obj1->getLabels().size(), 2);
|
||||
auto obj2 = convertStructToWorkloadMetadata(pb, {"label1"});
|
||||
EXPECT_EQ(obj2->getLabels().size(), 1);
|
||||
absl::flat_hash_set<std::string> empty;
|
||||
auto obj3 = convertStructToWorkloadMetadata(pb, empty);
|
||||
EXPECT_EQ(obj3->getLabels().size(), 0);
|
||||
}
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, Conversion) {
|
||||
{
|
||||
auto obj = WorkloadMetadataObject::fromBaggage(
|
||||
absl::StrCat("k8s.deployment.name=foo,k8s.cluster.name=my-cluster,k8s."
|
||||
"namespace.name=default,",
|
||||
"service.name=foo-service,", "service.version=v1alpha3"));
|
||||
EXPECT_EQ(obj.canonical_name_, "foo-service");
|
||||
EXPECT_EQ(obj.canonical_revision_, "v1alpha3");
|
||||
EXPECT_EQ(obj.workload_type_, WorkloadType::Deployment);
|
||||
EXPECT_EQ(obj.workload_name_, "foo");
|
||||
EXPECT_EQ(obj.namespace_name_, "default");
|
||||
EXPECT_EQ(obj.cluster_name_, "my-cluster");
|
||||
checkFlatNodeConversion(obj);
|
||||
const auto r = convertBaggageToWorkloadMetadata(
|
||||
"type=deployment,workload=foo,cluster=my-cluster,"
|
||||
"namespace=default,service=foo-service,revision=v1alpha3,app=foo-app,version=latest");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1alpha3");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), DeploymentSuffix);
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("app")), "foo-app");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("version")), "latest");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
|
||||
{
|
||||
auto obj = WorkloadMetadataObject::fromBaggage(
|
||||
absl::StrCat("k8s.pod.name=foo-pod-435,k8s.cluster.name=my-cluster,k8s."
|
||||
"namespace.name=test,"
|
||||
"service.name=foo-service,service.version=v1beta2"));
|
||||
|
||||
EXPECT_EQ(obj.canonical_name_, "foo-service");
|
||||
EXPECT_EQ(obj.canonical_revision_, "v1beta2");
|
||||
EXPECT_EQ(obj.workload_type_, WorkloadType::Pod);
|
||||
EXPECT_EQ(obj.workload_name_, "foo-pod-435");
|
||||
EXPECT_EQ(obj.instance_name_, "foo-pod-435");
|
||||
EXPECT_EQ(obj.namespace_name_, "test");
|
||||
EXPECT_EQ(obj.cluster_name_, "my-cluster");
|
||||
checkFlatNodeConversion(obj);
|
||||
const auto r =
|
||||
convertBaggageToWorkloadMetadata("type=pod,name=foo-pod-435,cluster=my-cluster,namespace="
|
||||
"test,service=foo-service,revision=v1beta2");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta2");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), PodSuffix);
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "foo-pod-435");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("app")), "");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("version")), "");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
|
||||
{
|
||||
auto obj = WorkloadMetadataObject::fromBaggage(
|
||||
absl::StrCat("k8s.job.name=foo-job-435,k8s.cluster.name=my-cluster,k8s."
|
||||
"namespace.name=test,",
|
||||
"service.name=foo-service,", "service.version=v1beta4"));
|
||||
|
||||
EXPECT_EQ(obj.canonical_name_, "foo-service");
|
||||
EXPECT_EQ(obj.canonical_revision_, "v1beta4");
|
||||
EXPECT_EQ(obj.workload_type_, WorkloadType::Job);
|
||||
EXPECT_EQ(obj.workload_name_, "foo-job-435");
|
||||
EXPECT_EQ(obj.instance_name_, "foo-job-435");
|
||||
EXPECT_EQ(obj.namespace_name_, "test");
|
||||
EXPECT_EQ(obj.cluster_name_, "my-cluster");
|
||||
checkFlatNodeConversion(obj);
|
||||
const auto r =
|
||||
convertBaggageToWorkloadMetadata("type=job,name=foo-job-435,cluster=my-cluster,namespace="
|
||||
"test,service=foo-service,revision=v1beta4");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta4");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), JobSuffix);
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "foo-job-435");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
|
||||
{
|
||||
auto obj = WorkloadMetadataObject::fromBaggage(
|
||||
absl::StrCat("k8s.cronjob.name=foo-cronjob,k8s.cluster.name=my-cluster,"
|
||||
"k8s.namespace.name=test,",
|
||||
"service.name=foo-service,", "service.version=v1beta4"));
|
||||
|
||||
EXPECT_EQ(obj.canonical_name_, "foo-service");
|
||||
EXPECT_EQ(obj.canonical_revision_, "v1beta4");
|
||||
EXPECT_EQ(obj.workload_type_, WorkloadType::CronJob);
|
||||
EXPECT_EQ(obj.workload_name_, "foo-cronjob");
|
||||
EXPECT_EQ(obj.namespace_name_, "test");
|
||||
EXPECT_EQ(obj.cluster_name_, "my-cluster");
|
||||
EXPECT_EQ(obj.app_name_, "");
|
||||
EXPECT_EQ(obj.app_version_, "");
|
||||
checkFlatNodeConversion(obj);
|
||||
const auto r =
|
||||
convertBaggageToWorkloadMetadata("type=cronjob,workload=foo-cronjob,cluster=my-cluster,"
|
||||
"namespace=test,service=foo-service,revision=v1beta4");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1beta4");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), CronJobSuffix);
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo-cronjob");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("name")), "");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "test");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "my-cluster");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
|
||||
{
|
||||
auto obj = WorkloadMetadataObject::fromBaggage(absl::StrCat(
|
||||
"k8s.deployment.name=foo,k8s.namespace.name=default,", "service.name=foo-service,",
|
||||
"service.version=v1alpha3,app.name=foo-app,app.version=v1"));
|
||||
const auto r = convertBaggageToWorkloadMetadata(
|
||||
"type=deployment,workload=foo,namespace=default,service=foo-service,revision=v1alpha3");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("service")), "foo-service");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("revision")), "v1alpha3");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("type")), DeploymentSuffix);
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("workload")), "foo");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("cluster")), "");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
|
||||
EXPECT_EQ(obj.canonical_name_, "foo-service");
|
||||
EXPECT_EQ(obj.canonical_revision_, "v1alpha3");
|
||||
EXPECT_EQ(obj.workload_type_, WorkloadType::Deployment);
|
||||
EXPECT_EQ(obj.workload_name_, "foo");
|
||||
EXPECT_EQ(obj.namespace_name_, "default");
|
||||
EXPECT_EQ(obj.cluster_name_, "");
|
||||
EXPECT_EQ(obj.app_name_, "foo-app");
|
||||
EXPECT_EQ(obj.app_version_, "v1");
|
||||
checkFlatNodeConversion(obj);
|
||||
{
|
||||
const auto r = convertBaggageToWorkloadMetadata("namespace=default");
|
||||
EXPECT_EQ(absl::get<absl::string_view>(r->getField("namespace")), "default");
|
||||
checkStructConversion(*r);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, ConvertFromFlatNode) {
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
Wasm::Common::FlatNodeBuilder builder(fbb);
|
||||
auto data = builder.Finish();
|
||||
fbb.Finish(data);
|
||||
auto buffer = fbb.Release();
|
||||
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(buffer.data());
|
||||
auto obj = convertFlatNodeToWorkloadMetadata(node);
|
||||
EXPECT_EQ(obj.baggage(), "k8s.pod.name=");
|
||||
TEST(WorkloadMetadataObjectTest, ConvertFromEmpty) {
|
||||
google::protobuf::Struct node;
|
||||
auto obj = convertStructToWorkloadMetadata(node);
|
||||
EXPECT_EQ(obj->serializeAsString(), "");
|
||||
checkStructConversion(*obj);
|
||||
}
|
||||
|
||||
TEST(WorkloadMetadataObjectTest, ConvertFromEndpointMetadata) {
|
||||
|
@ -171,8 +173,8 @@ TEST(WorkloadMetadataObjectTest, ConvertFromEndpointMetadata) {
|
|||
EXPECT_EQ(absl::nullopt, convertEndpointMetadata("a;b;c;d"));
|
||||
auto obj = convertEndpointMetadata("foo-pod;default;foo-service;v1;my-cluster");
|
||||
ASSERT_TRUE(obj.has_value());
|
||||
EXPECT_EQ(obj->baggage(), "k8s.pod.name=foo-pod,k8s.cluster.name=my-cluster,k8s.namespace."
|
||||
"name=default,service.name=foo-service,service.version=v1");
|
||||
EXPECT_EQ(obj->serializeAsString(), "workload=foo-pod,cluster=my-cluster,"
|
||||
"namespace=default,service=foo-service,revision=v1");
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/* Copyright 2020 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Wasm.Common;
|
||||
|
||||
table KeyVal {
|
||||
key:string (key);
|
||||
value:string;
|
||||
}
|
||||
|
||||
// NodeInfo represents the information extracted from proxy node metadata.
|
||||
table FlatNode {
|
||||
// Name of the workload instance. e.g. in k8s, name is the pod name.
|
||||
name:string;
|
||||
|
||||
// Namespace that the workload instance runs in.
|
||||
namespace:string;
|
||||
|
||||
// K8s or vm workload attributes on the workload instance.
|
||||
labels:[KeyVal];
|
||||
owner:string;
|
||||
workload_name:string;
|
||||
|
||||
// DO NOT USE.
|
||||
// Platform metadata uses prefixed keys GCP uses gcp_* keys
|
||||
platform_metadata:[KeyVal];
|
||||
|
||||
// DO NOT USE.
|
||||
// Version identifier for the proxy.
|
||||
istio_version:string;
|
||||
|
||||
// DO NOT USE.
|
||||
// Unique identifier for the mesh. Taken from global mesh id parameter (or
|
||||
// the configured trust domain when not specified).
|
||||
mesh_id:string;
|
||||
|
||||
// DO NOT USE.
|
||||
// List of short names for application containers that are using this proxy.
|
||||
// This is only used for kubernetes, and is populated by the sidecar injector.
|
||||
app_containers:[string];
|
||||
|
||||
// Identifier for the cluster to which this workload belongs (for k8s workloads).
|
||||
cluster_id:string;
|
||||
|
||||
// DO NOT USE.
|
||||
// instance ip addresses.
|
||||
instance_ips:[string];
|
||||
|
||||
// NOT IMPLEMENTED.
|
||||
// Identity of the proxy.
|
||||
identity:string;
|
||||
}
|
||||
|
||||
root_type FlatNode;
|
|
@ -1,141 +0,0 @@
|
|||
/* Copyright 2020 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "extensions/common/proto_util.h"
|
||||
|
||||
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
|
||||
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "extensions/common/util.h"
|
||||
#include "extensions/common/metadata_object.h"
|
||||
|
||||
// WASM_PROLOG
|
||||
#ifndef NULL_PLUGIN
|
||||
#include "proxy_wasm_intrinsics.h"
|
||||
|
||||
#else // NULL_PLUGIN
|
||||
|
||||
#include "include/proxy-wasm/null_plugin.h"
|
||||
|
||||
#endif // NULL_PLUGIN
|
||||
|
||||
// END WASM_PROLOG
|
||||
|
||||
namespace Wasm {
|
||||
namespace Common {
|
||||
|
||||
flatbuffers::DetachedBuffer
|
||||
extractNodeFlatBufferFromStruct(const google::protobuf::Struct& metadata) {
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
flatbuffers::Offset<flatbuffers::String> name, namespace_, owner, workload_name, cluster_id;
|
||||
std::vector<flatbuffers::Offset<KeyVal>> labels, platform_metadata;
|
||||
for (const auto& it : metadata.fields()) {
|
||||
if (it.first == "NAME") {
|
||||
name = fbb.CreateString(it.second.string_value());
|
||||
} else if (it.first == "NAMESPACE") {
|
||||
namespace_ = fbb.CreateString(it.second.string_value());
|
||||
} else if (it.first == "OWNER") {
|
||||
owner = fbb.CreateString(it.second.string_value());
|
||||
} else if (it.first == "WORKLOAD_NAME") {
|
||||
workload_name = fbb.CreateString(it.second.string_value());
|
||||
} else if (it.first == "CLUSTER_ID") {
|
||||
cluster_id = fbb.CreateString(it.second.string_value());
|
||||
} else if (it.first == "LABELS") {
|
||||
for (const auto& labels_it : it.second.struct_value().fields()) {
|
||||
if (labels_it.first == Istio::Common::CanonicalNameLabel ||
|
||||
labels_it.first == Istio::Common::CanonicalRevisionLabel ||
|
||||
labels_it.first == Istio::Common::AppLabel ||
|
||||
labels_it.first == Istio::Common::VersionLabel) {
|
||||
labels.push_back(CreateKeyVal(fbb, fbb.CreateString(labels_it.first),
|
||||
fbb.CreateString(labels_it.second.string_value())));
|
||||
}
|
||||
}
|
||||
} else if (it.first == "PLATFORM_METADATA") {
|
||||
for (const auto& platform_it : it.second.struct_value().fields()) {
|
||||
platform_metadata.push_back(
|
||||
CreateKeyVal(fbb, fbb.CreateString(platform_it.first),
|
||||
fbb.CreateString(platform_it.second.string_value())));
|
||||
}
|
||||
}
|
||||
}
|
||||
// finish pre-order construction
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyVal>>> labels_offset,
|
||||
platform_metadata_offset;
|
||||
if (labels.size() > 0) {
|
||||
labels_offset = fbb.CreateVectorOfSortedTables(&labels);
|
||||
}
|
||||
if (platform_metadata.size() > 0) {
|
||||
platform_metadata_offset = fbb.CreateVectorOfSortedTables(&platform_metadata);
|
||||
}
|
||||
FlatNodeBuilder node(fbb);
|
||||
node.add_name(name);
|
||||
node.add_namespace_(namespace_);
|
||||
node.add_owner(owner);
|
||||
node.add_workload_name(workload_name);
|
||||
node.add_cluster_id(cluster_id);
|
||||
node.add_labels(labels_offset);
|
||||
node.add_platform_metadata(platform_metadata_offset);
|
||||
auto data = node.Finish();
|
||||
fbb.Finish(data);
|
||||
return fbb.Release();
|
||||
}
|
||||
|
||||
void extractStructFromNodeFlatBuffer(const FlatNode& node, google::protobuf::Struct* metadata) {
|
||||
if (node.name()) {
|
||||
(*metadata->mutable_fields())["NAME"].set_string_value(node.name()->str());
|
||||
}
|
||||
if (node.namespace_()) {
|
||||
(*metadata->mutable_fields())["NAMESPACE"].set_string_value(node.namespace_()->str());
|
||||
}
|
||||
if (node.owner()) {
|
||||
(*metadata->mutable_fields())["OWNER"].set_string_value(node.owner()->str());
|
||||
}
|
||||
if (node.workload_name()) {
|
||||
(*metadata->mutable_fields())["WORKLOAD_NAME"].set_string_value(node.workload_name()->str());
|
||||
}
|
||||
if (node.cluster_id()) {
|
||||
(*metadata->mutable_fields())["CLUSTER_ID"].set_string_value(node.cluster_id()->str());
|
||||
}
|
||||
if (node.labels()) {
|
||||
auto* map = (*metadata->mutable_fields())["LABELS"].mutable_struct_value();
|
||||
for (const auto keyval : *node.labels()) {
|
||||
(*map->mutable_fields())[flatbuffers::GetString(keyval->key())].set_string_value(
|
||||
flatbuffers::GetString(keyval->value()));
|
||||
}
|
||||
}
|
||||
if (node.platform_metadata()) {
|
||||
auto* map = (*metadata->mutable_fields())["PLATFORM_METADATA"].mutable_struct_value();
|
||||
for (const auto keyval : *node.platform_metadata()) {
|
||||
(*map->mutable_fields())[flatbuffers::GetString(keyval->key())].set_string_value(
|
||||
flatbuffers::GetString(keyval->value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool serializeToStringDeterministic(const google::protobuf::Message& metadata,
|
||||
std::string* metadata_bytes) {
|
||||
google::protobuf::io::StringOutputStream md(metadata_bytes);
|
||||
google::protobuf::io::CodedOutputStream mcs(&md);
|
||||
|
||||
mcs.SetSerializationDeterministic(true);
|
||||
if (!metadata.SerializeToCodedStream(&mcs)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Wasm
|
|
@ -1,40 +0,0 @@
|
|||
/* Copyright 2020 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "extensions/common/node_info_generated.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "google/protobuf/struct.pb.h"
|
||||
|
||||
/**
|
||||
* Utilities that require protobuf import.
|
||||
*/
|
||||
namespace Wasm {
|
||||
namespace Common {
|
||||
|
||||
// Extract node info into a flatbuffer from a struct.
|
||||
flatbuffers::DetachedBuffer
|
||||
extractNodeFlatBufferFromStruct(const google::protobuf::Struct& metadata);
|
||||
|
||||
// Extract struct from a flatbuffer. This is an inverse of the above function.
|
||||
void extractStructFromNodeFlatBuffer(const FlatNode& node, google::protobuf::Struct* metadata);
|
||||
|
||||
// Serialize deterministically a protobuf to a string.
|
||||
bool serializeToStringDeterministic(const google::protobuf::Message& metadata,
|
||||
std::string* metadata_bytes);
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Wasm
|
|
@ -1,220 +0,0 @@
|
|||
/* Copyright 2019 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "extensions/common/metadata_object.h"
|
||||
#include "extensions/common/node_info_generated.h"
|
||||
#include "extensions/common/proto_util.h"
|
||||
#include "extensions/common/util.h"
|
||||
#include "google/protobuf/util/json_util.h"
|
||||
#include "source/common/common/base64.h"
|
||||
#include "source/common/stream_info/filter_state_impl.h"
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "test/test_common/status_utility.h"
|
||||
|
||||
// WASM_PROLOG
|
||||
#ifdef NULL_PLUGIN
|
||||
namespace Wasm {
|
||||
#endif // NULL_PLUGIN
|
||||
|
||||
// END WASM_PROLOG
|
||||
|
||||
namespace Common {
|
||||
|
||||
using namespace google::protobuf::util;
|
||||
|
||||
constexpr std::string_view node_metadata_json = R"###(
|
||||
{
|
||||
"NAME":"test_pod",
|
||||
"NAMESPACE":"test_namespace",
|
||||
"LABELS": {
|
||||
"app": "productpage",
|
||||
"version": "v1",
|
||||
"pod-template-hash": "84975bc778"
|
||||
},
|
||||
"OWNER":"test_owner",
|
||||
"WORKLOAD_NAME":"test_workload",
|
||||
"PLATFORM_METADATA":{
|
||||
"gcp_project":"test_project",
|
||||
"gcp_cluster_location":"test_location",
|
||||
"gcp_cluster_name":"test_cluster"
|
||||
},
|
||||
"ISTIO_VERSION":"istio-1.4",
|
||||
"MESH_ID":"test-mesh"
|
||||
}
|
||||
)###";
|
||||
|
||||
constexpr std::string_view metadata_id_key = "envoy.wasm.metadata_exchange.downstream_id";
|
||||
constexpr std::string_view metadata_key = "envoy.wasm.metadata_exchange.downstream";
|
||||
constexpr std::string_view node_id = "test_pod.test_namespace";
|
||||
|
||||
static void setData(Envoy::StreamInfo::FilterStateImpl& filter_state, std::string_view key,
|
||||
std::string_view value) {
|
||||
Envoy::Extensions::Filters::Common::Expr::CelStatePrototype prototype;
|
||||
auto state_ptr = std::make_unique<Envoy::Extensions::Filters::Common::Expr::CelState>(prototype);
|
||||
state_ptr->setValue(toAbslStringView(value));
|
||||
filter_state.setData(toAbslStringView(key), std::move(state_ptr),
|
||||
Envoy::StreamInfo::FilterState::StateType::Mutable);
|
||||
}
|
||||
|
||||
static const std::string& getData(Envoy::StreamInfo::FilterStateImpl& filter_state,
|
||||
std::string_view key) {
|
||||
return filter_state
|
||||
.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(toAbslStringView(key))
|
||||
->value();
|
||||
}
|
||||
|
||||
static void BM_ReadFlatBuffer(benchmark::State& state) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
ASSERT_OK(
|
||||
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
|
||||
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
|
||||
|
||||
Envoy::StreamInfo::FilterStateImpl filter_state{
|
||||
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
|
||||
setData(filter_state, metadata_key,
|
||||
std::string_view(reinterpret_cast<const char*>(out.data()), out.size()));
|
||||
|
||||
size_t size = 0;
|
||||
for (auto _ : state) {
|
||||
auto buf = getData(filter_state, metadata_key);
|
||||
auto peer = flatbuffers::GetRoot<FlatNode>(buf.data());
|
||||
size += peer->workload_name()->size() + peer->namespace_()->size() +
|
||||
peer->labels()->LookupByKey("app")->value()->size() +
|
||||
peer->labels()->LookupByKey("version")->value()->size();
|
||||
benchmark::DoNotOptimize(size);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_ReadFlatBuffer);
|
||||
|
||||
static void BM_WriteRawBytes(benchmark::State& state) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
ASSERT_OK(
|
||||
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
|
||||
auto bytes = metadata_struct.SerializeAsString();
|
||||
Envoy::StreamInfo::FilterStateImpl filter_state{
|
||||
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
|
||||
|
||||
for (auto _ : state) {
|
||||
setData(filter_state, metadata_id_key, node_id);
|
||||
setData(filter_state, metadata_key, bytes);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_WriteRawBytes);
|
||||
|
||||
static void BM_WriteFlatBufferWithCache(benchmark::State& state) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
ASSERT_OK(
|
||||
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options));
|
||||
auto bytes = metadata_struct.SerializeAsString();
|
||||
Envoy::StreamInfo::FilterStateImpl filter_state{
|
||||
Envoy::StreamInfo::FilterState::LifeSpan::TopSpan};
|
||||
|
||||
std::unordered_map<std::string, std::string> cache;
|
||||
|
||||
for (auto _ : state) {
|
||||
// lookup cache by key
|
||||
auto nodeinfo_it = cache.find(std::string(node_id));
|
||||
std::string node_info;
|
||||
if (nodeinfo_it == cache.end()) {
|
||||
google::protobuf::Struct test_struct;
|
||||
test_struct.ParseFromArray(bytes.data(), bytes.size());
|
||||
benchmark::DoNotOptimize(test_struct);
|
||||
|
||||
auto out = extractNodeFlatBufferFromStruct(test_struct);
|
||||
|
||||
node_info =
|
||||
cache.emplace(node_id, std::string(reinterpret_cast<const char*>(out.data()), out.size()))
|
||||
.first->second;
|
||||
} else {
|
||||
node_info = nodeinfo_it->second;
|
||||
}
|
||||
|
||||
setData(filter_state, metadata_id_key, node_id);
|
||||
setData(filter_state, metadata_key, node_info);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_WriteFlatBufferWithCache);
|
||||
|
||||
constexpr std::string_view node_flatbuffer_json = R"###(
|
||||
{
|
||||
"NAME":"test_pod",
|
||||
"NAMESPACE":"default",
|
||||
"CLUSTER_ID": "client-cluster",
|
||||
"LABELS": {
|
||||
"app": "productpage",
|
||||
"version": "v1",
|
||||
"service.istio.io/canonical-name": "productpage-v1",
|
||||
"service.istio.io/canonical-revision": "version-1"
|
||||
},
|
||||
"OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/productpage-v1",
|
||||
"WORKLOAD_NAME":"productpage-v1"
|
||||
}
|
||||
)###";
|
||||
|
||||
// Measure decoding performance of x-envoy-peer-metadata.
|
||||
static void BM_DecodeFlatBuffer(benchmark::State& state) {
|
||||
// Construct a header from sample value.
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
ASSERT_OK(
|
||||
JsonStringToMessage(std::string(node_flatbuffer_json), &metadata_struct, json_parse_options));
|
||||
std::string metadata_bytes;
|
||||
::Wasm::Common::serializeToStringDeterministic(metadata_struct, &metadata_bytes);
|
||||
const std::string header_value =
|
||||
Envoy::Base64::encode(metadata_bytes.data(), metadata_bytes.size());
|
||||
|
||||
size_t size = 0;
|
||||
for (auto _ : state) {
|
||||
auto bytes = Envoy::Base64::decodeWithoutPadding(header_value);
|
||||
google::protobuf::Struct metadata;
|
||||
metadata.ParseFromString(bytes);
|
||||
auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata);
|
||||
size += fb.size();
|
||||
benchmark::DoNotOptimize(size);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DecodeFlatBuffer);
|
||||
|
||||
// Measure decoding performance of baggage.
|
||||
static void BM_DecodeBaggage(benchmark::State& state) {
|
||||
// Construct a header from sample value.
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
ASSERT_OK(
|
||||
JsonStringToMessage(std::string(node_flatbuffer_json), &metadata_struct, json_parse_options));
|
||||
auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata_struct);
|
||||
const auto& node = *flatbuffers::GetRoot<Wasm::Common::FlatNode>(fb.data());
|
||||
const std::string baggage = Istio::Common::convertFlatNodeToWorkloadMetadata(node).baggage();
|
||||
|
||||
size_t size = 0;
|
||||
for (auto _ : state) {
|
||||
auto obj = Istio::Common::WorkloadMetadataObject::fromBaggage(baggage);
|
||||
size += obj.namespace_name_.size();
|
||||
benchmark::DoNotOptimize(size);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_DecodeBaggage);
|
||||
|
||||
} // namespace Common
|
||||
|
||||
// WASM_EPILOG
|
||||
#ifdef NULL_PLUGIN
|
||||
} // namespace Wasm
|
||||
#endif
|
|
@ -1,110 +0,0 @@
|
|||
/* Copyright 2019 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "extensions/common/proto_util.h"
|
||||
|
||||
#include "extensions/common/node_info_generated.h"
|
||||
#include "google/protobuf/struct.pb.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "google/protobuf/util/json_util.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// WASM_PROLOG
|
||||
#ifdef NULL_PLUGIN
|
||||
namespace Wasm {
|
||||
#endif // NULL_PLUGIN
|
||||
|
||||
// END WASM_PROLOG
|
||||
|
||||
namespace Common {
|
||||
|
||||
using namespace google::protobuf;
|
||||
using namespace google::protobuf::util;
|
||||
|
||||
constexpr std::string_view node_metadata_json = R"###(
|
||||
{
|
||||
"NAME":"test_pod",
|
||||
"NAMESPACE":"test_namespace",
|
||||
"OWNER":"test_owner",
|
||||
"WORKLOAD_NAME":"test_workload",
|
||||
"CLUSTER_ID":"test-cluster",
|
||||
"LABELS":{
|
||||
"app":"test",
|
||||
"version":"v1"
|
||||
},
|
||||
"PLATFORM_METADATA":{
|
||||
"gcp_cluster_location":"test_location",
|
||||
"gcp_cluster_name":"test_cluster",
|
||||
"gcp_project":"test_project"
|
||||
},
|
||||
}
|
||||
)###";
|
||||
|
||||
// Test all possible metadata field.
|
||||
TEST(ProtoUtilTest, extractNodeMetadata) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
EXPECT_TRUE(
|
||||
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options)
|
||||
.ok());
|
||||
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
|
||||
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
|
||||
EXPECT_EQ(peer->name()->string_view(), "test_pod");
|
||||
EXPECT_EQ(peer->namespace_()->string_view(), "test_namespace");
|
||||
EXPECT_EQ(peer->owner()->string_view(), "test_owner");
|
||||
EXPECT_EQ(peer->workload_name()->string_view(), "test_workload");
|
||||
EXPECT_EQ(peer->cluster_id()->string_view(), "test-cluster");
|
||||
EXPECT_EQ(peer->platform_metadata()->Get(2)->key()->string_view(), "gcp_project");
|
||||
EXPECT_EQ(peer->platform_metadata()->Get(2)->value()->string_view(), "test_project");
|
||||
}
|
||||
|
||||
// Test roundtripping
|
||||
TEST(ProtoUtilTest, Rountrip) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
JsonParseOptions json_parse_options;
|
||||
EXPECT_TRUE(
|
||||
JsonStringToMessage(std::string(node_metadata_json), &metadata_struct, json_parse_options)
|
||||
.ok());
|
||||
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
|
||||
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
|
||||
|
||||
google::protobuf::Struct output_struct;
|
||||
extractStructFromNodeFlatBuffer(*peer, &output_struct);
|
||||
|
||||
// Validate serialized bytes
|
||||
std::string input_bytes;
|
||||
EXPECT_TRUE(serializeToStringDeterministic(metadata_struct, &input_bytes));
|
||||
std::string output_bytes;
|
||||
EXPECT_TRUE(serializeToStringDeterministic(output_struct, &output_bytes));
|
||||
EXPECT_EQ(input_bytes, output_bytes)
|
||||
<< metadata_struct.DebugString() << output_struct.DebugString();
|
||||
}
|
||||
|
||||
// Test roundtrip for an empty struct (for corner cases)
|
||||
TEST(ProtoUtilTest, RountripEmpty) {
|
||||
google::protobuf::Struct metadata_struct;
|
||||
auto out = extractNodeFlatBufferFromStruct(metadata_struct);
|
||||
auto peer = flatbuffers::GetRoot<FlatNode>(out.data());
|
||||
google::protobuf::Struct output_struct;
|
||||
extractStructFromNodeFlatBuffer(*peer, &output_struct);
|
||||
EXPECT_EQ(0, output_struct.fields().size());
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
||||
// WASM_EPILOG
|
||||
#ifdef NULL_PLUGIN
|
||||
} // namespace Wasm
|
||||
#endif
|
|
@ -1,231 +0,0 @@
|
|||
/* Copyright 2019 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "extensions/common/util.h"
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
namespace Wasm {
|
||||
namespace Common {
|
||||
|
||||
namespace {
|
||||
|
||||
// This replicates the flag lists in envoyproxy/envoy, because the property
|
||||
// access API does not support returning response flags as a short string since
|
||||
// it is not owned by any object and always generated on demand:
|
||||
// https://github.com/envoyproxy/envoy/blob/v1.18.3/source/common/stream_info/utility.h#L21
|
||||
constexpr static absl::string_view DOWNSTREAM_CONNECTION_TERMINATION = "DC";
|
||||
constexpr static absl::string_view FAILED_LOCAL_HEALTH_CHECK = "LH";
|
||||
constexpr static absl::string_view NO_HEALTHY_UPSTREAM = "UH";
|
||||
constexpr static absl::string_view UPSTREAM_REQUEST_TIMEOUT = "UT";
|
||||
constexpr static absl::string_view LOCAL_RESET = "LR";
|
||||
constexpr static absl::string_view UPSTREAM_REMOTE_RESET = "UR";
|
||||
constexpr static absl::string_view UPSTREAM_CONNECTION_FAILURE = "UF";
|
||||
constexpr static absl::string_view UPSTREAM_CONNECTION_TERMINATION = "UC";
|
||||
constexpr static absl::string_view UPSTREAM_OVERFLOW = "UO";
|
||||
constexpr static absl::string_view UPSTREAM_RETRY_LIMIT_EXCEEDED = "URX";
|
||||
constexpr static absl::string_view NO_ROUTE_FOUND = "NR";
|
||||
constexpr static absl::string_view DELAY_INJECTED = "DI";
|
||||
constexpr static absl::string_view FAULT_INJECTED = "FI";
|
||||
constexpr static absl::string_view RATE_LIMITED = "RL";
|
||||
constexpr static absl::string_view UNAUTHORIZED_EXTERNAL_SERVICE = "UAEX";
|
||||
constexpr static absl::string_view RATELIMIT_SERVICE_ERROR = "RLSE";
|
||||
constexpr static absl::string_view STREAM_IDLE_TIMEOUT = "SI";
|
||||
constexpr static absl::string_view INVALID_ENVOY_REQUEST_HEADERS = "IH";
|
||||
constexpr static absl::string_view DOWNSTREAM_PROTOCOL_ERROR = "DPE";
|
||||
constexpr static absl::string_view UPSTREAM_MAX_STREAM_DURATION_REACHED = "UMSDR";
|
||||
constexpr static absl::string_view RESPONSE_FROM_CACHE_FILTER = "RFCF";
|
||||
constexpr static absl::string_view NO_FILTER_CONFIG_FOUND = "NFCF";
|
||||
constexpr static absl::string_view DURATION_TIMEOUT = "DT";
|
||||
constexpr static absl::string_view UPSTREAM_PROTOCOL_ERROR = "UPE";
|
||||
constexpr static absl::string_view NO_CLUSTER_FOUND = "NC";
|
||||
constexpr static absl::string_view OVERLOAD_MANAGER = "OM";
|
||||
constexpr static absl::string_view DNS_RESOLUTION_FAILURE = "DF";
|
||||
constexpr static absl::string_view DROP_OVERLOAD = "DO";
|
||||
constexpr static absl::string_view DOWNSTREAM_REMOTE_RESET = "DR";
|
||||
|
||||
enum ResponseFlag {
|
||||
FailedLocalHealthCheck = 0x1,
|
||||
NoHealthyUpstream = 0x2,
|
||||
UpstreamRequestTimeout = 0x4,
|
||||
LocalReset = 0x8,
|
||||
UpstreamRemoteReset = 0x10,
|
||||
UpstreamConnectionFailure = 0x20,
|
||||
UpstreamConnectionTermination = 0x40,
|
||||
UpstreamOverflow = 0x80,
|
||||
NoRouteFound = 0x100,
|
||||
DelayInjected = 0x200,
|
||||
FaultInjected = 0x400,
|
||||
RateLimited = 0x800,
|
||||
UnauthorizedExternalService = 0x1000,
|
||||
RateLimitServiceError = 0x2000,
|
||||
DownstreamConnectionTermination = 0x4000,
|
||||
UpstreamRetryLimitExceeded = 0x8000,
|
||||
StreamIdleTimeout = 0x10000,
|
||||
InvalidEnvoyRequestHeaders = 0x20000,
|
||||
DownstreamProtocolError = 0x40000,
|
||||
UpstreamMaxStreamDurationReached = 0x80000,
|
||||
ResponseFromCacheFilter = 0x100000,
|
||||
NoFilterConfigFound = 0x200000,
|
||||
DurationTimeout = 0x400000,
|
||||
UpstreamProtocolError = 0x800000,
|
||||
NoClusterFound = 0x1000000,
|
||||
OverloadManager = 0x2000000,
|
||||
DnsResolutionFailed = 0x4000000,
|
||||
DropOverLoad = 0x8000000,
|
||||
DownstreamRemoteReset = 0x10000000,
|
||||
LastFlag = DownstreamRemoteReset,
|
||||
};
|
||||
|
||||
void appendString(std::string& result, const absl::string_view& append) {
|
||||
if (result.empty()) {
|
||||
result = std::string(append);
|
||||
} else {
|
||||
absl::StrAppend(&result, ",", append);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const std::string parseResponseFlag(uint64_t response_flag) {
|
||||
std::string result;
|
||||
|
||||
if (response_flag & FailedLocalHealthCheck) {
|
||||
appendString(result, FAILED_LOCAL_HEALTH_CHECK);
|
||||
}
|
||||
|
||||
if (response_flag & NoHealthyUpstream) {
|
||||
appendString(result, NO_HEALTHY_UPSTREAM);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamRequestTimeout) {
|
||||
appendString(result, UPSTREAM_REQUEST_TIMEOUT);
|
||||
}
|
||||
|
||||
if (response_flag & LocalReset) {
|
||||
appendString(result, LOCAL_RESET);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamRemoteReset) {
|
||||
appendString(result, UPSTREAM_REMOTE_RESET);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamConnectionFailure) {
|
||||
appendString(result, UPSTREAM_CONNECTION_FAILURE);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamConnectionTermination) {
|
||||
appendString(result, UPSTREAM_CONNECTION_TERMINATION);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamOverflow) {
|
||||
appendString(result, UPSTREAM_OVERFLOW);
|
||||
}
|
||||
|
||||
if (response_flag & NoRouteFound) {
|
||||
appendString(result, NO_ROUTE_FOUND);
|
||||
}
|
||||
|
||||
if (response_flag & DelayInjected) {
|
||||
appendString(result, DELAY_INJECTED);
|
||||
}
|
||||
|
||||
if (response_flag & FaultInjected) {
|
||||
appendString(result, FAULT_INJECTED);
|
||||
}
|
||||
|
||||
if (response_flag & RateLimited) {
|
||||
appendString(result, RATE_LIMITED);
|
||||
}
|
||||
|
||||
if (response_flag & UnauthorizedExternalService) {
|
||||
appendString(result, UNAUTHORIZED_EXTERNAL_SERVICE);
|
||||
}
|
||||
|
||||
if (response_flag & RateLimitServiceError) {
|
||||
appendString(result, RATELIMIT_SERVICE_ERROR);
|
||||
}
|
||||
|
||||
if (response_flag & DownstreamConnectionTermination) {
|
||||
appendString(result, DOWNSTREAM_CONNECTION_TERMINATION);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamRetryLimitExceeded) {
|
||||
appendString(result, UPSTREAM_RETRY_LIMIT_EXCEEDED);
|
||||
}
|
||||
|
||||
if (response_flag & StreamIdleTimeout) {
|
||||
appendString(result, STREAM_IDLE_TIMEOUT);
|
||||
}
|
||||
|
||||
if (response_flag & InvalidEnvoyRequestHeaders) {
|
||||
appendString(result, INVALID_ENVOY_REQUEST_HEADERS);
|
||||
}
|
||||
|
||||
if (response_flag & DownstreamProtocolError) {
|
||||
appendString(result, DOWNSTREAM_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamMaxStreamDurationReached) {
|
||||
appendString(result, UPSTREAM_MAX_STREAM_DURATION_REACHED);
|
||||
}
|
||||
|
||||
if (response_flag & ResponseFromCacheFilter) {
|
||||
appendString(result, RESPONSE_FROM_CACHE_FILTER);
|
||||
}
|
||||
|
||||
if (response_flag & NoFilterConfigFound) {
|
||||
appendString(result, NO_FILTER_CONFIG_FOUND);
|
||||
}
|
||||
|
||||
if (response_flag & DurationTimeout) {
|
||||
appendString(result, DURATION_TIMEOUT);
|
||||
}
|
||||
|
||||
if (response_flag & UpstreamProtocolError) {
|
||||
appendString(result, UPSTREAM_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
if (response_flag & NoClusterFound) {
|
||||
appendString(result, NO_CLUSTER_FOUND);
|
||||
}
|
||||
|
||||
if (response_flag & OverloadManager) {
|
||||
appendString(result, OVERLOAD_MANAGER);
|
||||
}
|
||||
|
||||
if (response_flag & DnsResolutionFailed) {
|
||||
appendString(result, DNS_RESOLUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (response_flag & DropOverLoad) {
|
||||
appendString(result, DROP_OVERLOAD);
|
||||
}
|
||||
|
||||
if (response_flag & DownstreamRemoteReset) {
|
||||
appendString(result, DOWNSTREAM_REMOTE_RESET);
|
||||
}
|
||||
|
||||
if (response_flag >= (LastFlag << 1)) {
|
||||
// Response flag integer overflows. Append the integer to avoid information
|
||||
// loss.
|
||||
appendString(result, std::to_string(response_flag));
|
||||
}
|
||||
|
||||
return result.empty() ? ::Wasm::Common::NONE : result;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Wasm
|
|
@ -1,44 +0,0 @@
|
|||
/* Copyright 2019 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace Wasm {
|
||||
namespace Common {
|
||||
|
||||
// None response flag.
|
||||
const char NONE[] = "-";
|
||||
|
||||
// Parses an integer response flag into a readable short string.
|
||||
const std::string parseResponseFlag(uint64_t response_flag);
|
||||
|
||||
// Used for converting sanctioned uses of std string_view (e.g. extensions) to
|
||||
// absl::string_view for internal use.
|
||||
inline absl::string_view toAbslStringView(std::string_view view) {
|
||||
return absl::string_view(view.data(), view.size());
|
||||
}
|
||||
|
||||
// Used for converting internal absl::string_view to sanctioned uses of std
|
||||
// string_view (e.g. extensions).
|
||||
inline std::string_view toStdStringView(absl::string_view view) {
|
||||
return std::string_view(view.data(), view.size());
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Wasm
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright 2019 Istio Authors. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "extensions/common/util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace Wasm {
|
||||
namespace Common {
|
||||
namespace {
|
||||
|
||||
TEST(WasmCommonUtilsTest, ParseResponseFlag) {
|
||||
std::vector<std::pair<uint64_t, std::string>> expected = {
|
||||
std::make_pair(0x1, "LH"), std::make_pair(0x2, "UH"), std::make_pair(0x4, "UT"),
|
||||
std::make_pair(0x8, "LR"), std::make_pair(0x10, "UR"), std::make_pair(0x20, "UF"),
|
||||
std::make_pair(0x40, "UC"), std::make_pair(0x80, "UO"), std::make_pair(0x100, "NR"),
|
||||
std::make_pair(0x200, "DI"), std::make_pair(0x400, "FI"), std::make_pair(0x800, "RL"),
|
||||
std::make_pair(0x1000, "UAEX"), std::make_pair(0x2000, "RLSE"), std::make_pair(0x4000, "DC"),
|
||||
std::make_pair(0x8000, "URX"), std::make_pair(0x10000, "SI"), std::make_pair(0x20000, "IH"),
|
||||
std::make_pair(0x40000, "DPE"),
|
||||
};
|
||||
|
||||
for (const auto& test_case : expected) {
|
||||
EXPECT_EQ(test_case.second, parseResponseFlag(test_case.first));
|
||||
}
|
||||
|
||||
// No flag is set.
|
||||
{ EXPECT_EQ("-", parseResponseFlag(0x0)); }
|
||||
|
||||
// Test combinations.
|
||||
// These are not real use cases, but are used to cover multiple response flags
|
||||
// case.
|
||||
{ EXPECT_EQ("UT,DI,FI", parseResponseFlag(0x604)); }
|
||||
{ EXPECT_EQ("DPE,DO", parseResponseFlag(0x8040000)); }
|
||||
{ EXPECT_EQ("DPE,DO,DR", parseResponseFlag(0x18040000)); }
|
||||
|
||||
// Test overflow.
|
||||
{ EXPECT_EQ("DPE,DO,DR,939786240", parseResponseFlag(0x38040000)); }
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Common
|
||||
} // namespace Wasm
|
32
go.mod
32
go.mod
|
@ -1,33 +1,33 @@
|
|||
module istio.io/proxy
|
||||
|
||||
go 1.22
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b
|
||||
github.com/envoyproxy/go-control-plane v0.12.1-0.20240712172404-1da4500d00e2
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f
|
||||
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/prometheus/client_model v0.6.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.46.0
|
||||
go.opentelemetry.io/proto/otlp v1.1.0
|
||||
go.starlark.net v0.0.0-20240123142251-f86470692795
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237
|
||||
google.golang.org/grpc v1.62.1
|
||||
google.golang.org/protobuf v1.33.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a
|
||||
google.golang.org/grpc v1.73.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.15.0 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
|
||||
cel.dev/expr v0.23.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
golang.org/x/net v0.23.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
|
||||
)
|
||||
|
|
86
go.sum
86
go.sum
|
@ -1,21 +1,29 @@
|
|||
cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
|
||||
cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss=
|
||||
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.12.1-0.20240712172404-1da4500d00e2 h1:srxDNbrp+NoyasdIUVEDwu/xkoajQwNyBr/NDKW/27o=
|
||||
github.com/envoyproxy/go-control-plane v0.12.1-0.20240712172404-1da4500d00e2/go.mod h1:GK6eJxJBjVz+a2poLMTx017aQ1mfAkZ5knBOlpWe+hc=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a h1:k0yPxzI8NWvWx9TKX3ysJabi1XEkrKmutgfIe27WX7M=
|
||||
github.com/envoyproxy/go-control-plane v0.13.5-0.20250705082150-f8f2cd45490a/go.mod h1:whHrEUXbTAzBJlzd3Gz4us5zEFP1gL6o3LbfA+a/xbg=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
|
@ -26,36 +34,46 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgm
|
|||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
|
||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y=
|
||||
github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
|
||||
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
|
||||
go.starlark.net v0.0.0-20240123142251-f86470692795 h1:LmbG8Pq7KDGkglKVn8VpZOZj6vb9b8nKEGcg9l03epM=
|
||||
go.starlark.net v0.0.0-20240123142251-f86470692795/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo=
|
||||
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
|
@ -31,7 +31,8 @@ GOPATH=/home/prow/go
|
|||
ROOT=/go/src
|
||||
|
||||
# Configure available resources and disable IPv6 tests.
|
||||
export BAZEL_BUILD_ARGS="--verbose_failures --test_env=ENVOY_IP_TEST_VERSIONS=v4only --test_output=errors"
|
||||
BAZEL_BUILD_ARGS="${BAZEL_BUILD_EXTRA_ARGS:-} --verbose_failures --test_env=ENVOY_IP_TEST_VERSIONS=v4only --test_output=errors"
|
||||
export BAZEL_BUILD_ARGS="${BAZEL_BUILD_ARGS# }"
|
||||
|
||||
# Override envoy.
|
||||
if [[ "${ENVOY_REPOSITORY:-}" && "${ENVOY_PREFIX:-}" ]]; then
|
||||
|
|
|
@ -134,7 +134,7 @@ do
|
|||
fi
|
||||
;;
|
||||
"debug")
|
||||
CONFIG_PARAMS="--config=debug"
|
||||
CONFIG_PARAMS="-c dbg"
|
||||
BINARY_BASE_NAME="${BASE_BINARY_NAME}-debug"
|
||||
# shellcheck disable=SC2086
|
||||
BAZEL_OUT="$(bazel info ${BAZEL_BUILD_ARGS} output_path)/${ARCH_NAME}-dbg/bin"
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2021 Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# This script verifies the LastFlag response flag in istio/proxy matches the one in envoyproxy/envoy
|
||||
# and fails with a non-zero exit code if they differ.
|
||||
|
||||
set -x
|
||||
|
||||
if [[ -n "${ENVOY_REPOSITORY}" ]]; then
|
||||
echo "Skipping LastFlag verification, custom envoy used"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
WORKSPACE=${ROOT}/WORKSPACE
|
||||
PATH_LASTFLAG_SPEC_DOWNSTREAM="${ROOT}/extensions/common/util.cc"
|
||||
PATH_LASTFLAG_SPEC_UPSTREAM="stream_info.h"
|
||||
ENVOY_PATH_LASTFLAG_SPEC="envoy/stream_info/stream_info.h"
|
||||
|
||||
ENVOY_ORG="$(grep -Pom1 "^ENVOY_ORG = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
|
||||
ENVOY_REPO="$(grep -Pom1 "^ENVOY_REPO = \"\K[a-zA-Z-]+" "${WORKSPACE}")"
|
||||
ENVOY_SHA="$(grep -Pom1 "^ENVOY_SHA = \"\K[a-zA-Z0-9]{40}" "${WORKSPACE}")"
|
||||
|
||||
trap 'rm -rf ${PATH_LASTFLAG_SPEC_UPSTREAM}' EXIT
|
||||
curl -sSL "https://raw.githubusercontent.com/${ENVOY_ORG}/${ENVOY_REPO}/${ENVOY_SHA}/${ENVOY_PATH_LASTFLAG_SPEC}" > "${PATH_LASTFLAG_SPEC_UPSTREAM}"
|
||||
|
||||
# Extract the LastFlag specification from both sources and trim all white spaces.
|
||||
|
||||
if grep -q "^\s*LastFlag\s*=.*$" "${PATH_LASTFLAG_SPEC_DOWNSTREAM}"
|
||||
then
|
||||
DOWNSTREAM_LASTFLAG=$(grep -m1 "^\s*LastFlag\s*=.*$" "${PATH_LASTFLAG_SPEC_DOWNSTREAM}"|tr -d '[:space:]')
|
||||
else
|
||||
echo "istio/proxy: LastFlag not specified in ${PATH_LASTFLAG_SPEC_DOWNSTREAM}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -q "^\s*LastFlag\s*=.*$" ${PATH_LASTFLAG_SPEC_UPSTREAM}
|
||||
then
|
||||
UPSTREAM_LASTFLAG=$(grep -m1 "^\s*LastFlag\s*=.*$" ${PATH_LASTFLAG_SPEC_UPSTREAM}|tr -d '[:space:]')
|
||||
else
|
||||
echo "envoyproxy/envoy: LastFlag not specified in https://raw.githubusercontent.com/${ENVOY_ORG}/${ENVOY_REPO}/${ENVOY_SHA}/${ENVOY_PATH_LASTFLAG_SPEC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The trailing comma is optional and will be removed from the extracted values before comparison.
|
||||
|
||||
if [[ "${DOWNSTREAM_LASTFLAG:${#DOWNSTREAM_LASTFLAG}-1}" == "," ]]
|
||||
then
|
||||
DOWNSTREAM_LASTFLAG="${DOWNSTREAM_LASTFLAG:0:${#DOWNSTREAM_LASTFLAG}-1}"
|
||||
fi
|
||||
|
||||
if [[ "${UPSTREAM_LASTFLAG:${#UPSTREAM_LASTFLAG}-1}" == "," ]]
|
||||
then
|
||||
UPSTREAM_LASTFLAG="${UPSTREAM_LASTFLAG:0:${#UPSTREAM_LASTFLAG}-1}"
|
||||
fi
|
||||
|
||||
if [[ "$DOWNSTREAM_LASTFLAG" != "$UPSTREAM_LASTFLAG" ]]
|
||||
then
|
||||
echo "The LastFlag specification for downstream and upstream differs. Downstream is ${DOWNSTREAM_LASTFLAG}. Upstream is ${UPSTREAM_LASTFLAG}."
|
||||
exit 1
|
||||
fi
|
|
@ -31,6 +31,7 @@
|
|||
namespace Envoy::Extensions::Common::WorkloadDiscovery {
|
||||
namespace {
|
||||
constexpr absl::string_view DefaultNamespace = "default";
|
||||
constexpr absl::string_view DefaultServiceAccount = "default";
|
||||
constexpr absl::string_view DefaultTrustDomain = "cluster.local";
|
||||
Istio::Common::WorkloadMetadataObject convert(const istio::workload::Workload& workload) {
|
||||
auto workload_type = Istio::Common::WorkloadType::Deployment;
|
||||
|
@ -50,6 +51,7 @@ Istio::Common::WorkloadMetadataObject convert(const istio::workload::Workload& w
|
|||
|
||||
absl::string_view ns = workload.namespace_();
|
||||
absl::string_view trust_domain = workload.trust_domain();
|
||||
absl::string_view service_account = workload.service_account();
|
||||
// Trust domain may be elided if it's equal to "cluster.local"
|
||||
if (trust_domain.empty()) {
|
||||
trust_domain = DefaultTrustDomain;
|
||||
|
@ -58,10 +60,14 @@ Istio::Common::WorkloadMetadataObject convert(const istio::workload::Workload& w
|
|||
if (ns.empty()) {
|
||||
ns = DefaultNamespace;
|
||||
}
|
||||
const auto identity = absl::StrCat("spiffe://", trust_domain, "/ns/", workload.namespace_(),
|
||||
"/sa/", workload.service_account());
|
||||
// The service account may be elided if it's equal to "default"
|
||||
if (service_account.empty()) {
|
||||
service_account = DefaultServiceAccount;
|
||||
}
|
||||
const auto identity =
|
||||
absl::StrCat("spiffe://", trust_domain, "/ns/", ns, "/sa/", service_account);
|
||||
return Istio::Common::WorkloadMetadataObject(
|
||||
workload.name(), workload.cluster_id(), workload.namespace_(), workload.workload_name(),
|
||||
workload.name(), workload.cluster_id(), ns, workload.workload_name(),
|
||||
workload.canonical_name(), workload.canonical_revision(), workload.canonical_name(),
|
||||
workload.canonical_revision(), workload_type, identity);
|
||||
}
|
||||
|
@ -243,6 +249,8 @@ public:
|
|||
});
|
||||
}
|
||||
|
||||
void onWorkerThreadInitialized() override{};
|
||||
|
||||
private:
|
||||
Server::Configuration::ServerFactoryContext& factory_context_;
|
||||
const istio::workload::BootstrapExtension config_;
|
||||
|
|
|
@ -26,6 +26,18 @@ option go_package = "test/envoye2e/workloadapi";
|
|||
* 2) append bootstrap extension stub;
|
||||
*/
|
||||
|
||||
// NetworkMode indicates how the addresses of the workload should be treated.
|
||||
enum NetworkMode {
|
||||
// STANDARD means that the workload is uniquely identified by its address (within its network).
|
||||
STANDARD = 0;
|
||||
// HOST_NETWORK means the workload has an IP address that is shared by many workloads. The data plane should avoid
|
||||
// attempting to lookup these workloads by IP address (which could return the wrong result).
|
||||
HOST_NETWORK = 1;
|
||||
}
|
||||
|
||||
// Workload represents a workload - an endpoint (or collection behind a hostname).
|
||||
// The xds primary key is "uid" as defined on the workload below.
|
||||
// Secondary (alias) keys are the unique `network/IP` pairs that the workload can be reached at.
|
||||
message Workload {
|
||||
// UID represents a globally unique opaque identifier for this workload.
|
||||
// For k8s resources, it is recommended to use the more readable format:
|
||||
|
@ -63,7 +75,6 @@ message Workload {
|
|||
// a workload that backs a Kubernetes service will typically have only endpoints. A
|
||||
// workload that backs a headless Kubernetes service, however, will have both
|
||||
// addresses as well as a hostname used for direct access to the headless endpoint.
|
||||
// TODO: support this field
|
||||
string hostname = 21;
|
||||
|
||||
// Network represents the network this workload is on. This may be elided for the default network.
|
||||
|
@ -124,10 +135,21 @@ message Workload {
|
|||
// The cluster ID that the workload instance belongs to
|
||||
string cluster_id = 18;
|
||||
|
||||
// The Locality defines information about where a workload is geographically deployed
|
||||
Locality locality = 24;
|
||||
|
||||
NetworkMode network_mode = 25;
|
||||
|
||||
// Reservations for deleted fields.
|
||||
reserved 15;
|
||||
}
|
||||
|
||||
message Locality {
|
||||
string region = 1;
|
||||
string zone = 2;
|
||||
string subzone = 3;
|
||||
}
|
||||
|
||||
enum WorkloadStatus {
|
||||
// Workload is healthy and ready to serve traffic.
|
||||
HEALTHY = 0;
|
||||
|
@ -196,10 +218,8 @@ message GatewayAddress {
|
|||
}
|
||||
// port to reach the gateway at for mTLS HBONE connections
|
||||
uint32 hbone_mtls_port = 3;
|
||||
// port to reach the gateway at for single tls HBONE connections
|
||||
// used for sending unauthenticated traffic originating outside the mesh to a waypoint-enabled destination
|
||||
// A value of 0 = unset
|
||||
uint32 hbone_single_tls_port = 4;
|
||||
reserved "hbone_single_tls_port";
|
||||
reserved 4;
|
||||
}
|
||||
|
||||
// NetworkAddress represents an address bound to a specific network.
|
||||
|
|
|
@ -46,7 +46,6 @@ envoy_cc_library(
|
|||
deps = [
|
||||
":alpn_filter",
|
||||
"@envoy//envoy/registry",
|
||||
"@envoy//source/exe:all_extensions_lib",
|
||||
"@envoy//source/extensions/filters/http/common:factory_base_lib",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
---
|
||||
title: ALPN filter for overriding ALPN for upstream TLS connections.
|
||||
layout: protoc-gen-docs
|
||||
generator: protoc-gen-docs
|
||||
number_of_entries: 3
|
||||
---
|
||||
<h2 id="FilterConfig">FilterConfig</h2>
|
||||
<section>
|
||||
<p>FilterConfig is the config for Istio-specific filter.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="FilterConfig-alpn_override">
|
||||
<td><code>alpn_override</code></td>
|
||||
<td><code><a href="#FilterConfig-AlpnOverride">AlpnOverride[]</a></code></td>
|
||||
<td>
|
||||
<p>Map from upstream protocol to list of ALPN</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="FilterConfig-AlpnOverride">FilterConfig.AlpnOverride</h2>
|
||||
<section>
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="FilterConfig-AlpnOverride-upstream_protocol">
|
||||
<td><code>upstream_protocol</code></td>
|
||||
<td><code><a href="#FilterConfig-Protocol">Protocol</a></code></td>
|
||||
<td>
|
||||
<p>Upstream protocol</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FilterConfig-AlpnOverride-alpn_override">
|
||||
<td><code>alpn_override</code></td>
|
||||
<td><code>string[]</code></td>
|
||||
<td>
|
||||
<p>A list of ALPN that will override the ALPN for upstream TLS connections.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="FilterConfig-Protocol">FilterConfig.Protocol</h2>
|
||||
<section>
|
||||
<p>Upstream protocols</p>
|
||||
|
||||
<table class="enum-values">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="FilterConfig-Protocol-HTTP10">
|
||||
<td><code>HTTP10</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FilterConfig-Protocol-HTTP11">
|
||||
<td><code>HTTP11</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FilterConfig-Protocol-HTTP2">
|
||||
<td><code>HTTP2</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
|
@ -46,7 +46,6 @@ envoy_cc_library(
|
|||
"@envoy//source/common/http:header_utility_lib",
|
||||
"@envoy//source/common/network:utility_lib",
|
||||
"@envoy//source/common/stream_info:utility_lib",
|
||||
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
|
||||
"@envoy//source/extensions/filters/common/expr:context_lib",
|
||||
"@envoy//source/extensions/filters/common/expr:evaluator_lib",
|
||||
"@envoy//source/extensions/filters/http/common:pass_through_filter_lib",
|
||||
|
|
|
@ -1,293 +0,0 @@
|
|||
---
|
||||
title: Stats Config
|
||||
description: Configuration for Stats Filter.
|
||||
location: https://istio.io/docs/reference/config/proxy_extensions/stats.html
|
||||
layout: protoc-gen-docs
|
||||
generator: protoc-gen-docs
|
||||
weight: 20
|
||||
number_of_entries: 5
|
||||
---
|
||||
<h2 id="MetricConfig">MetricConfig</h2>
|
||||
<section>
|
||||
<p>Metric instance configuration overrides.
|
||||
The metric value and the metric type are optional and permit changing the
|
||||
reported value for an existing metric.
|
||||
The standard metrics are optimized and reported through a “fast-path”.
|
||||
The customizations allow full configurability, at the cost of a “slower”
|
||||
path.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="MetricConfig-dimensions">
|
||||
<td><code>dimensions</code></td>
|
||||
<td><code>map<string, string></code></td>
|
||||
<td>
|
||||
<p>(Optional) Collection of tag names and tag expressions to include in the
|
||||
metric. Conflicts are resolved by the tag name by overriding previously
|
||||
supplied values.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricConfig-name">
|
||||
<td><code>name</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td>
|
||||
<p>(Optional) Metric name to restrict the override to a metric. If not
|
||||
specified, applies to all.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricConfig-tags_to_remove">
|
||||
<td><code>tags_to_remove</code></td>
|
||||
<td><code>string[]</code></td>
|
||||
<td>
|
||||
<p>(Optional) A list of tags to remove.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricConfig-match">
|
||||
<td><code>match</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td>
|
||||
<p>NOT IMPLEMENTED. (Optional) Conditional enabling the override.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricConfig-drop">
|
||||
<td><code>drop</code></td>
|
||||
<td><code>bool</code></td>
|
||||
<td>
|
||||
<p>(Optional) If this is set to true, the metric(s) selected by this
|
||||
configuration will not be generated or reported.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="MetricDefinition">MetricDefinition</h2>
|
||||
<section>
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="MetricDefinition-name">
|
||||
<td><code>name</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td>
|
||||
<p>Metric name.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricDefinition-value">
|
||||
<td><code>value</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td>
|
||||
<p>Metric value expression.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricDefinition-type">
|
||||
<td><code>type</code></td>
|
||||
<td><code><a href="#MetricType">MetricType</a></code></td>
|
||||
<td>
|
||||
<p>Metric type.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="PluginConfig">PluginConfig</h2>
|
||||
<section>
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="PluginConfig-disable_host_header_fallback">
|
||||
<td><code>disable_host_header_fallback</code></td>
|
||||
<td><code>bool</code></td>
|
||||
<td>
|
||||
<p>Optional: Disable using host header as a fallback if destination service is
|
||||
not available from the controlplane. Disable the fallback if the host
|
||||
header originates outsides the mesh, like at ingress.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-tcp_reporting_duration">
|
||||
<td><code>tcp_reporting_duration</code></td>
|
||||
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
|
||||
<td>
|
||||
<p>Optional. Allows configuration of the time between calls out to for TCP
|
||||
metrics reporting. The default duration is <code>5s</code>.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-metrics">
|
||||
<td><code>metrics</code></td>
|
||||
<td><code><a href="#MetricConfig">MetricConfig[]</a></code></td>
|
||||
<td>
|
||||
<p>Metric overrides.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-definitions">
|
||||
<td><code>definitions</code></td>
|
||||
<td><code><a href="#MetricDefinition">MetricDefinition[]</a></code></td>
|
||||
<td>
|
||||
<p>Metric definitions.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-reporter">
|
||||
<td><code>reporter</code></td>
|
||||
<td><code><a href="#Reporter">Reporter</a></code></td>
|
||||
<td>
|
||||
<p>Proxy deployment type.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-rotation_interval">
|
||||
<td><code>rotation_interval</code></td>
|
||||
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
|
||||
<td>
|
||||
<p>Metric scope rotation interval. Set to 0 to disable the metric scope rotation.
|
||||
Defaults to 0.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="PluginConfig-graceful_deletion_interval">
|
||||
<td><code>graceful_deletion_interval</code></td>
|
||||
<td><code><a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#duration">Duration</a></code></td>
|
||||
<td>
|
||||
<p>Metric expiry graceful deletion interval. No-op if the metric rotation is disabled.
|
||||
Defaults to 5m. Must be >=1s.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="MetricType">MetricType</h2>
|
||||
<section>
|
||||
<table class="enum-values">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="MetricType-COUNTER">
|
||||
<td><code>COUNTER</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricType-GAUGE">
|
||||
<td><code>GAUGE</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetricType-HISTOGRAM">
|
||||
<td><code>HISTOGRAM</code></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="Reporter">Reporter</h2>
|
||||
<section>
|
||||
<p>Specifies the proxy deployment type.</p>
|
||||
|
||||
<table class="enum-values">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="Reporter-UNSPECIFIED">
|
||||
<td><code>UNSPECIFIED</code></td>
|
||||
<td>
|
||||
<p>Default value is inferred from the listener direction, as either client or
|
||||
server sidecar.</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Reporter-SERVER_GATEWAY">
|
||||
<td><code>SERVER_GATEWAY</code></td>
|
||||
<td>
|
||||
<p>Shared server gateway, e.g. “waypoint”.</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
|
@ -27,8 +27,8 @@
|
|||
#include "source/common/http/header_utility.h"
|
||||
#include "source/common/network/utility.h"
|
||||
#include "source/common/stream_info/utility.h"
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "source/extensions/filters/common/expr/context.h"
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "source/extensions/filters/common/expr/evaluator.h"
|
||||
#include "source/extensions/filters/http/common/pass_through_filter.h"
|
||||
#include "source/extensions/filters/http/grpc_stats/grpc_stats_filter.h"
|
||||
|
@ -117,29 +117,53 @@ enum class Reporter {
|
|||
bool peerInfoRead(Reporter reporter, const StreamInfo::FilterState& filter_state) {
|
||||
const auto& filter_state_key =
|
||||
reporter == Reporter::ServerSidecar || reporter == Reporter::ServerGateway
|
||||
? "wasm.downstream_peer_id"
|
||||
: "wasm.upstream_peer_id";
|
||||
? Istio::Common::DownstreamPeer
|
||||
: Istio::Common::UpstreamPeer;
|
||||
return filter_state.hasDataWithName(filter_state_key) ||
|
||||
filter_state.hasDataWithName(
|
||||
"wasm.envoy.wasm.metadata_exchange.peer_unknown"); // kMetadataPrefix+kMetadataNotFoundValue
|
||||
filter_state.hasDataWithName(Istio::Common::NoPeer);
|
||||
}
|
||||
|
||||
const Wasm::Common::FlatNode* peerInfo(Reporter reporter,
|
||||
const StreamInfo::FilterState& filter_state) {
|
||||
std::optional<Istio::Common::WorkloadMetadataObject>
|
||||
peerInfo(Reporter reporter, const StreamInfo::FilterState& filter_state) {
|
||||
const auto& filter_state_key =
|
||||
reporter == Reporter::ServerSidecar || reporter == Reporter::ServerGateway
|
||||
? "wasm.downstream_peer"
|
||||
: "wasm.upstream_peer";
|
||||
const auto* object =
|
||||
? Istio::Common::DownstreamPeer
|
||||
: Istio::Common::UpstreamPeer;
|
||||
// This's a workaround before FilterStateObject support operation like `.labels['role']`.
|
||||
// The workaround is to use CelState to store the peer metadata.
|
||||
// Rebuild the WorkloadMetadataObject from the CelState.
|
||||
const auto* cel_state =
|
||||
filter_state.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
|
||||
filter_state_key);
|
||||
return object ? flatbuffers::GetRoot<Wasm::Common::FlatNode>(object->value().data()) : nullptr;
|
||||
if (!cel_state) {
|
||||
return {};
|
||||
}
|
||||
|
||||
ProtobufWkt::Struct obj;
|
||||
if (!obj.ParseFromString(absl::string_view(cel_state->value()))) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Istio::Common::WorkloadMetadataObject peer_info(
|
||||
extractString(obj, Istio::Common::InstanceNameToken),
|
||||
extractString(obj, Istio::Common::ClusterNameToken),
|
||||
extractString(obj, Istio::Common::NamespaceNameToken),
|
||||
extractString(obj, Istio::Common::WorkloadNameToken),
|
||||
extractString(obj, Istio::Common::ServiceNameToken),
|
||||
extractString(obj, Istio::Common::ServiceVersionToken),
|
||||
extractString(obj, Istio::Common::AppNameToken),
|
||||
extractString(obj, Istio::Common::AppVersionToken),
|
||||
Istio::Common::fromSuffix(extractString(obj, Istio::Common::WorkloadTypeToken)),
|
||||
extractString(obj, Istio::Common::IdentityToken));
|
||||
|
||||
return peer_info;
|
||||
}
|
||||
|
||||
// Process-wide context shared with all filter instances.
|
||||
struct Context : public Singleton::Instance {
|
||||
explicit Context(Stats::SymbolTable& symbol_table, const envoy::config::core::v3::Node& node)
|
||||
: pool_(symbol_table), node_(node), stat_namespace_(pool_.add(CustomStatNamespace)),
|
||||
explicit Context(Stats::SymbolTable& symbol_table, const LocalInfo::LocalInfo& local_info)
|
||||
: pool_(symbol_table), local_info_(local_info),
|
||||
stat_namespace_(pool_.add(CustomStatNamespace)),
|
||||
requests_total_(pool_.add("istio_requests_total")),
|
||||
request_duration_milliseconds_(pool_.add("istio_request_duration_milliseconds")),
|
||||
request_bytes_(pool_.add("istio_request_bytes")),
|
||||
|
@ -177,19 +201,20 @@ struct Context : public Singleton::Instance {
|
|||
connection_security_policy_(pool_.add("connection_security_policy")),
|
||||
response_code_(pool_.add("response_code")),
|
||||
grpc_response_status_(pool_.add("grpc_response_status")),
|
||||
workload_name_(pool_.add(extractString(node.metadata(), "WORKLOAD_NAME"))),
|
||||
namespace_(pool_.add(extractString(node.metadata(), "NAMESPACE"))),
|
||||
canonical_name_(pool_.add(
|
||||
extractMapString(node.metadata(), "LABELS", Istio::Common::CanonicalNameLabel))),
|
||||
canonical_revision_(pool_.add(
|
||||
extractMapString(node.metadata(), "LABELS", Istio::Common::CanonicalRevisionLabel))),
|
||||
cluster_name_(pool_.add(extractString(node.metadata(), "CLUSTER_ID"))),
|
||||
app_name_(pool_.add(extractMapString(node.metadata(), "LABELS", Istio::Common::AppLabel))),
|
||||
app_version_(
|
||||
pool_.add(extractMapString(node.metadata(), "LABELS", Istio::Common::VersionLabel))),
|
||||
workload_name_(pool_.add(extractString(local_info.node().metadata(), "WORKLOAD_NAME"))),
|
||||
namespace_(pool_.add(extractString(local_info.node().metadata(), "NAMESPACE"))),
|
||||
canonical_name_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
|
||||
Istio::Common::CanonicalNameLabel))),
|
||||
canonical_revision_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
|
||||
Istio::Common::CanonicalRevisionLabel))),
|
||||
app_name_(pool_.add(
|
||||
extractMapString(local_info.node().metadata(), "LABELS", Istio::Common::AppNameLabel))),
|
||||
app_version_(pool_.add(extractMapString(local_info.node().metadata(), "LABELS",
|
||||
Istio::Common::AppVersionLabel))),
|
||||
cluster_name_(pool_.add(extractString(local_info.node().metadata(), "CLUSTER_ID"))),
|
||||
waypoint_(pool_.add("waypoint")), istio_build_(pool_.add("istio_build")),
|
||||
component_(pool_.add("component")), proxy_(pool_.add("proxy")), tag_(pool_.add("tag")),
|
||||
istio_version_(pool_.add(extractString(node.metadata(), "ISTIO_VERSION"))) {
|
||||
istio_version_(pool_.add(extractString(local_info.node().metadata(), "ISTIO_VERSION"))) {
|
||||
all_metrics_ = {
|
||||
{"requests_total", requests_total_},
|
||||
{"request_duration_milliseconds", request_duration_milliseconds_},
|
||||
|
@ -232,7 +257,7 @@ struct Context : public Singleton::Instance {
|
|||
}
|
||||
|
||||
Stats::StatNamePool pool_;
|
||||
const envoy::config::core::v3::Node& node_;
|
||||
const LocalInfo::LocalInfo& local_info_;
|
||||
absl::flat_hash_map<std::string, Stats::StatName> all_metrics_;
|
||||
absl::flat_hash_map<std::string, Stats::StatName> all_tags_;
|
||||
|
||||
|
@ -296,9 +321,9 @@ struct Context : public Singleton::Instance {
|
|||
const Stats::StatName namespace_;
|
||||
const Stats::StatName canonical_name_;
|
||||
const Stats::StatName canonical_revision_;
|
||||
const Stats::StatName cluster_name_;
|
||||
const Stats::StatName app_name_;
|
||||
const Stats::StatName app_version_;
|
||||
const Stats::StatName cluster_name_;
|
||||
const Stats::StatName waypoint_;
|
||||
|
||||
// istio_build metric:
|
||||
|
@ -316,8 +341,6 @@ using ContextSharedPtr = std::shared_ptr<Context>;
|
|||
|
||||
SINGLETON_MANAGER_REGISTRATION(Context)
|
||||
|
||||
using google::api::expr::runtime::CelValue;
|
||||
|
||||
// Instructions on dropping, creating, and overriding labels.
|
||||
// This is not the "hot path" of the metrics system and thus, fairly
|
||||
// unoptimized.
|
||||
|
@ -486,7 +509,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
[&factory_context] {
|
||||
return std::make_shared<Context>(
|
||||
factory_context.serverFactoryContext().scope().symbolTable(),
|
||||
factory_context.serverFactoryContext().localInfo().node());
|
||||
factory_context.serverFactoryContext().localInfo());
|
||||
})),
|
||||
scope_(factory_context, PROTOBUF_GET_MS_OR_DEFAULT(proto_config, rotation_interval, 0),
|
||||
PROTOBUF_GET_MS_OR_DEFAULT(proto_config, graceful_deletion_interval,
|
||||
|
@ -494,6 +517,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
disable_host_header_fallback_(proto_config.disable_host_header_fallback()),
|
||||
report_duration_(
|
||||
PROTOBUF_GET_MS_OR_DEFAULT(proto_config, tcp_reporting_duration, /* 5s */ 5000)) {
|
||||
recordVersion(factory_context);
|
||||
reporter_ = Reporter::ClientSidecar;
|
||||
switch (proto_config.reporter()) {
|
||||
case stats::Reporter::UNSPECIFIED:
|
||||
|
@ -641,6 +665,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
const Http::ResponseTrailerMap* response_trailers = nullptr) {
|
||||
evaluated_ = true;
|
||||
if (parent_.metric_overrides_) {
|
||||
local_info_ = &parent_.context_->local_info_;
|
||||
activation_info_ = &info;
|
||||
activation_request_headers_ = request_headers;
|
||||
activation_response_headers_ = response_headers;
|
||||
|
@ -652,6 +677,13 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
Protobuf::Arena arena;
|
||||
auto eval_status = compiled_exprs[id].first->Evaluate(*this, &arena);
|
||||
if (!eval_status.ok() || eval_status.value().IsError()) {
|
||||
if (!eval_status.ok()) {
|
||||
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}", eval_status.status());
|
||||
}
|
||||
if (eval_status.value().IsError()) {
|
||||
ENVOY_LOG(debug, "Failed to evaluate metric expression: {}",
|
||||
eval_status.value().ErrorOrDie()->message());
|
||||
}
|
||||
expr_values_.push_back(std::make_pair(parent_.context_->unknown_, 0));
|
||||
} else {
|
||||
const auto string_value = Filters::Common::Expr::print(eval_status.value());
|
||||
|
@ -670,27 +702,6 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
}
|
||||
}
|
||||
|
||||
absl::optional<CelValue> FindValue(absl::string_view name,
|
||||
Protobuf::Arena* arena) const override {
|
||||
auto obj = StreamActivation::FindValue(name, arena);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
if (name == "node") {
|
||||
return Filters::Common::Expr::CelProtoWrapper::CreateMessage(&parent_.context_->node_,
|
||||
arena);
|
||||
}
|
||||
if (activation_info_) {
|
||||
const auto* obj = activation_info_->filterState()
|
||||
.getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
|
||||
absl::StrCat("wasm.", name));
|
||||
if (obj) {
|
||||
return obj->exprValue(arena, false);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void addCounter(Stats::StatName metric, const Stats::StatNameTagVector& tags,
|
||||
uint64_t amount = 1) {
|
||||
ASSERT(evaluated_);
|
||||
|
@ -764,13 +775,13 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
bool evaluated_{false};
|
||||
};
|
||||
|
||||
void recordVersion() {
|
||||
void recordVersion(Server::Configuration::FactoryContext& factory_context) {
|
||||
Stats::StatNameTagVector tags;
|
||||
tags.push_back({context_->component_, context_->proxy_});
|
||||
tags.push_back({context_->tag_, context_->istio_version_.empty() ? context_->unknown_
|
||||
: context_->istio_version_});
|
||||
|
||||
Stats::Utility::gaugeFromStatNames(*scope(),
|
||||
Stats::Utility::gaugeFromStatNames(factory_context.scope(),
|
||||
{context_->stat_namespace_, context_->istio_build_},
|
||||
Stats::Gauge::ImportMode::Accumulate, tags)
|
||||
.set(1);
|
||||
|
@ -791,6 +802,7 @@ struct Config : public Logger::Loggable<Logger::Id::filter> {
|
|||
using ConfigSharedPtr = std::shared_ptr<Config>;
|
||||
|
||||
class IstioStatsFilter : public Http::PassThroughFilter,
|
||||
public Logger::Loggable<Logger::Id::filter>,
|
||||
public AccessLog::Instance,
|
||||
public Network::ReadFilter,
|
||||
public Network::ConnectionCallbacks {
|
||||
|
@ -917,6 +929,7 @@ private:
|
|||
const auto& info = decoder_callbacks_->streamInfo();
|
||||
peer_read_ = peerInfoRead(config_->reporter(), info.filterState());
|
||||
if (peer_read_ || end_stream) {
|
||||
ENVOY_LOG(trace, "Populating peer metadata from HTTP MX.");
|
||||
populatePeerInfo(info, info.filterState());
|
||||
}
|
||||
if (is_grpc_ && (peer_read_ || end_stream)) {
|
||||
|
@ -955,6 +968,7 @@ private:
|
|||
peer_read_ = peerInfoRead(config_->reporter(), filter_state);
|
||||
// Report connection open once peer info is read or connection is closed.
|
||||
if (peer_read_ || end_stream) {
|
||||
ENVOY_LOG(trace, "Populating peer metadata from TCP MX.");
|
||||
populatePeerInfo(info, filter_state);
|
||||
tags_.push_back({context_.request_protocol_, context_.tcp_});
|
||||
populateFlagsAndConnectionSecurity(info);
|
||||
|
@ -999,9 +1013,9 @@ private:
|
|||
const StreamInfo::FilterState& filter_state) {
|
||||
// Compute peer info with client-side fallbacks.
|
||||
absl::optional<Istio::Common::WorkloadMetadataObject> peer;
|
||||
const auto* object = peerInfo(config_->reporter(), filter_state);
|
||||
auto object = peerInfo(config_->reporter(), filter_state);
|
||||
if (object) {
|
||||
peer.emplace(Istio::Common::convertFlatNodeToWorkloadMetadata(*object));
|
||||
peer.emplace(object.value());
|
||||
} else if (config_->reporter() == Reporter::ClientSidecar) {
|
||||
if (auto label_obj = extractEndpointMetadata(info); label_obj) {
|
||||
peer.emplace(label_obj.value());
|
||||
|
@ -1062,7 +1076,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
absl::string_view peer_san;
|
||||
std::string peer_san;
|
||||
absl::string_view local_san;
|
||||
switch (config_->reporter()) {
|
||||
case Reporter::ServerSidecar:
|
||||
|
@ -1093,9 +1107,19 @@ private:
|
|||
case Reporter::ClientSidecar: {
|
||||
const Ssl::ConnectionInfoConstSharedPtr ssl_info =
|
||||
info.upstreamInfo() ? info.upstreamInfo()->upstreamSslConnection() : nullptr;
|
||||
std::optional<Istio::Common::WorkloadMetadataObject> endpoint_peer;
|
||||
if (ssl_info && !ssl_info->uriSanPeerCertificate().empty()) {
|
||||
peer_san = ssl_info->uriSanPeerCertificate()[0];
|
||||
}
|
||||
if (peer_san.empty()) {
|
||||
auto endpoint_object = peerInfo(config_->reporter(), filter_state);
|
||||
if (endpoint_object) {
|
||||
endpoint_peer.emplace(endpoint_object.value());
|
||||
peer_san = endpoint_peer->identity_;
|
||||
}
|
||||
}
|
||||
// This won't work for sidecar/ingress -> ambient becuase of the CONNECT
|
||||
// tunnel.
|
||||
if (ssl_info && !ssl_info->uriSanLocalCertificate().empty()) {
|
||||
local_san = ssl_info->uriSanLocalCertificate()[0];
|
||||
}
|
||||
|
@ -1143,38 +1167,51 @@ private:
|
|||
switch (config_->reporter()) {
|
||||
case Reporter::ServerGateway: {
|
||||
std::optional<Istio::Common::WorkloadMetadataObject> endpoint_peer;
|
||||
const auto* endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state);
|
||||
auto endpoint_object = peerInfo(Reporter::ClientSidecar, filter_state);
|
||||
if (endpoint_object) {
|
||||
endpoint_peer.emplace(Istio::Common::convertFlatNodeToWorkloadMetadata(*endpoint_object));
|
||||
endpoint_peer.emplace(endpoint_object.value());
|
||||
}
|
||||
tags_.push_back(
|
||||
{context_.destination_workload_,
|
||||
endpoint_peer ? pool_.add(endpoint_peer->workload_name_) : context_.unknown_});
|
||||
{context_.destination_workload_, endpoint_peer && !endpoint_peer->workload_name_.empty()
|
||||
? pool_.add(endpoint_peer->workload_name_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_workload_namespace_,
|
||||
endpoint_peer && !endpoint_peer->namespace_name_.empty()
|
||||
? pool_.add(endpoint_peer->namespace_name_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_principal_,
|
||||
endpoint_peer ? pool_.add(endpoint_peer->identity_) : context_.unknown_});
|
||||
tags_.push_back(
|
||||
{context_.destination_principal_, endpoint_peer && !endpoint_peer->identity_.empty()
|
||||
? pool_.add(endpoint_peer->identity_)
|
||||
: context_.unknown_});
|
||||
// Endpoint encoding does not have app and version.
|
||||
tags_.push_back(
|
||||
{context_.destination_app_, endpoint_peer && !endpoint_peer->app_name_.empty()
|
||||
? pool_.add(endpoint_peer->app_name_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_version_, endpoint_peer
|
||||
? pool_.add(endpoint_peer->app_version_)
|
||||
: context_.unknown_});
|
||||
auto canonical_name =
|
||||
endpoint_peer ? pool_.add(endpoint_peer->canonical_name_) : context_.unknown_;
|
||||
tags_.push_back({context_.destination_service_,
|
||||
service_host.empty() ? canonical_name : pool_.add(service_host)});
|
||||
tags_.push_back({context_.destination_canonical_service_, canonical_name});
|
||||
tags_.push_back(
|
||||
{context_.destination_canonical_revision_,
|
||||
endpoint_peer ? pool_.add(endpoint_peer->canonical_revision_) : context_.unknown_});
|
||||
{context_.destination_version_, endpoint_peer && !endpoint_peer->app_version_.empty()
|
||||
? pool_.add(endpoint_peer->app_version_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_service_,
|
||||
service_host.empty() ? context_.unknown_ : pool_.add(service_host)});
|
||||
tags_.push_back({context_.destination_canonical_service_,
|
||||
endpoint_peer && !endpoint_peer->canonical_name_.empty()
|
||||
? pool_.add(endpoint_peer->canonical_name_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_canonical_revision_,
|
||||
endpoint_peer && !endpoint_peer->canonical_revision_.empty()
|
||||
? pool_.add(endpoint_peer->canonical_revision_)
|
||||
: context_.unknown_});
|
||||
tags_.push_back({context_.destination_service_name_, service_host_name.empty()
|
||||
? canonical_name
|
||||
? context_.unknown_
|
||||
: pool_.add(service_host_name)});
|
||||
tags_.push_back({context_.destination_service_namespace_, !service_namespace.empty()
|
||||
? pool_.add(service_namespace)
|
||||
: context_.unknown_});
|
||||
tags_.push_back(
|
||||
{context_.destination_cluster_, endpoint_peer && !endpoint_peer->cluster_name_.empty()
|
||||
? pool_.add(endpoint_peer->cluster_name_)
|
||||
: context_.unknown_});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1192,10 +1229,10 @@ private:
|
|||
tags_.push_back({context_.destination_service_name_, service_host_name.empty()
|
||||
? context_.canonical_name_
|
||||
: pool_.add(service_host_name)});
|
||||
tags_.push_back({context_.destination_service_namespace_, context_.namespace_});
|
||||
tags_.push_back({context_.destination_cluster_, context_.cluster_name_});
|
||||
break;
|
||||
}
|
||||
tags_.push_back({context_.destination_service_namespace_, context_.namespace_});
|
||||
tags_.push_back({context_.destination_cluster_, context_.cluster_name_});
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1275,7 +1312,6 @@ absl::StatusOr<Http::FilterFactoryCb> IstioStatsFilterConfigFactory::createFilte
|
|||
CustomStatNamespace);
|
||||
ConfigSharedPtr config = std::make_shared<Config>(
|
||||
dynamic_cast<const stats::PluginConfig&>(proto_config), factory_context);
|
||||
config->recordVersion();
|
||||
return [config](Http::FilterChainFactoryCallbacks& callbacks) {
|
||||
auto filter = std::make_shared<IstioStatsFilter>(config);
|
||||
callbacks.addStreamFilter(filter);
|
||||
|
@ -1295,7 +1331,6 @@ IstioStatsNetworkFilterConfigFactory::createFilterFactoryFromProto(
|
|||
CustomStatNamespace);
|
||||
ConfigSharedPtr config = std::make_shared<Config>(
|
||||
dynamic_cast<const stats::PluginConfig&>(proto_config), factory_context);
|
||||
config->recordVersion();
|
||||
return [config](Network::FilterManager& filter_manager) {
|
||||
filter_manager.addReadFilter(std::make_shared<IstioStatsFilter>(config));
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ load(
|
|||
"@envoy//bazel:envoy_build_system.bzl",
|
||||
"envoy_cc_library",
|
||||
"envoy_cc_test",
|
||||
"envoy_proto_library",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
@ -33,7 +34,6 @@ envoy_cc_library(
|
|||
deps = [
|
||||
":config_cc_proto",
|
||||
"//extensions/common:metadata_object_lib",
|
||||
"//extensions/common:proto_util",
|
||||
"//source/extensions/common/workload_discovery:api_lib",
|
||||
"@envoy//envoy/registry",
|
||||
"@envoy//source/common/common:base64_lib",
|
||||
|
@ -47,12 +47,7 @@ envoy_cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "config_cc_proto",
|
||||
deps = ["config"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
envoy_proto_library(
|
||||
name = "config",
|
||||
srcs = ["config.proto"],
|
||||
)
|
||||
|
@ -68,6 +63,5 @@ envoy_cc_test(
|
|||
"@envoy//test/mocks/server:factory_context_mocks",
|
||||
"@envoy//test/mocks/stream_info:stream_info_mocks",
|
||||
"@envoy//test/test_common:logging_lib",
|
||||
"@envoy//test/test_common:wasm_lib",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
---
|
||||
title: io.istio.http.peer_metadata
|
||||
layout: protoc-gen-docs
|
||||
generator: protoc-gen-docs
|
||||
number_of_entries: 6
|
||||
---
|
||||
<h2 id="Config">Config</h2>
|
||||
<section>
|
||||
<p>Peer metadata provider filter. This filter encapsulates the discovery of the
|
||||
peer telemetry attributes for consumption by the telemetry filters.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="Config-downstream_discovery">
|
||||
<td><code>downstream_discovery</code></td>
|
||||
<td><code><a href="#Config-DiscoveryMethod">DiscoveryMethod[]</a></code></td>
|
||||
<td>
|
||||
<p>The order of the derivation of the downstream peer metadata, in the precedence order.
|
||||
First successful lookup wins.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-upstream_discovery">
|
||||
<td><code>upstream_discovery</code></td>
|
||||
<td><code><a href="#Config-DiscoveryMethod">DiscoveryMethod[]</a></code></td>
|
||||
<td>
|
||||
<p>The order of the derivation of the upstream peer metadata, in the precedence order.
|
||||
First successful lookup wins.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-downstream_propagation">
|
||||
<td><code>downstream_propagation</code></td>
|
||||
<td><code><a href="#Config-PropagationMethod">PropagationMethod[]</a></code></td>
|
||||
<td>
|
||||
<p>Downstream injection of the metadata via a response header.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-upstream_propagation">
|
||||
<td><code>upstream_propagation</code></td>
|
||||
<td><code><a href="#Config-PropagationMethod">PropagationMethod[]</a></code></td>
|
||||
<td>
|
||||
<p>Upstream injection of the metadata via a request header.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-shared_with_upstream">
|
||||
<td><code>shared_with_upstream</code></td>
|
||||
<td><code>bool</code></td>
|
||||
<td>
|
||||
<p>True to enable sharing with the upstream.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="Config-Baggage">Config.Baggage</h2>
|
||||
<section>
|
||||
<p>DEPRECATED.
|
||||
This method uses <code>baggage</code> header encoding.</p>
|
||||
|
||||
</section>
|
||||
<h2 id="Config-WorkloadDiscovery">Config.WorkloadDiscovery</h2>
|
||||
<section>
|
||||
<p>This method uses the workload metadata xDS. Requires that the bootstrap extension is enabled.
|
||||
For downstream discovery, the remote address is the lookup key in xDS.
|
||||
For upstream discovery:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>If the upstream host address is an IP, this IP is used as the lookup key;</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>If the upstream host address is internal, uses the
|
||||
“filter_metadata.tunnel.destination” dynamic metadata value as the lookup key.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
<h2 id="Config-IstioHeaders">Config.IstioHeaders</h2>
|
||||
<section>
|
||||
<p>This method uses Istio HTTP metadata exchange headers, e.g. <code>x-envoy-peer-metadata</code>. Removes these headers if found.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="Config-IstioHeaders-skip_external_clusters">
|
||||
<td><code>skip_external_clusters</code></td>
|
||||
<td><code>bool</code></td>
|
||||
<td>
|
||||
<p>Strip x-envoy-peer-metadata and x-envoy-peer-metadata-id headers on HTTP requests to services outside the mesh.
|
||||
Detects upstream clusters with <code>istio</code> and <code>external</code> filter metadata fields</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="Config-DiscoveryMethod">Config.DiscoveryMethod</h2>
|
||||
<section>
|
||||
<p>An exhaustive list of the derivation methods.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="Config-DiscoveryMethod-baggage" class="oneof oneof-start">
|
||||
<td><code>baggage</code></td>
|
||||
<td><code><a href="#Config-Baggage">Baggage (oneof)</a></code></td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-DiscoveryMethod-workload_discovery" class="oneof">
|
||||
<td><code>workload_discovery</code></td>
|
||||
<td><code><a href="#Config-WorkloadDiscovery">WorkloadDiscovery (oneof)</a></code></td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="Config-DiscoveryMethod-istio_headers" class="oneof">
|
||||
<td><code>istio_headers</code></td>
|
||||
<td><code><a href="#Config-IstioHeaders">IstioHeaders (oneof)</a></code></td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<h2 id="Config-PropagationMethod">Config.PropagationMethod</h2>
|
||||
<section>
|
||||
<p>An exhaustive list of the metadata propagation methods.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="Config-PropagationMethod-istio_headers" class="oneof oneof-start">
|
||||
<td><code>istio_headers</code></td>
|
||||
<td><code><a href="#Config-IstioHeaders">IstioHeaders (oneof)</a></code></td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
|
@ -75,4 +75,8 @@ message Config {
|
|||
|
||||
// True to enable sharing with the upstream.
|
||||
bool shared_with_upstream = 5;
|
||||
|
||||
// Additional labels to be added to the peer metadata to help your understand the traffic.
|
||||
// e.g. `role`, `location` etc.
|
||||
repeated string additional_labels = 6;
|
||||
}
|
||||
|
|
|
@ -16,42 +16,20 @@
|
|||
|
||||
#include "envoy/registry/registry.h"
|
||||
#include "envoy/server/factory_context.h"
|
||||
#include "extensions/common/metadata_object.h"
|
||||
#include "extensions/common/proto_util.h"
|
||||
#include "source/common/common/hash.h"
|
||||
#include "source/common/common/base64.h"
|
||||
#include "source/common/http/header_utility.h"
|
||||
#include "source/common/http/utility.h"
|
||||
#include "source/common/network/utility.h"
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
|
||||
#include "extensions/common/metadata_object.h"
|
||||
|
||||
namespace Envoy {
|
||||
namespace Extensions {
|
||||
namespace HttpFilters {
|
||||
namespace PeerMetadata {
|
||||
|
||||
// Extended peer info that supports "hashing" to enable sharing with the
|
||||
// upstream connection via an internal listener.
|
||||
class CelStateHashable : public Filters::Common::Expr::CelState, public Hashable {
|
||||
public:
|
||||
explicit CelStateHashable(const Filters::Common::Expr::CelStatePrototype& proto)
|
||||
: CelState(proto) {}
|
||||
absl::optional<uint64_t> hash() const override { return HashUtil::xxHash64(value()); }
|
||||
};
|
||||
|
||||
struct CelPrototypeValues {
|
||||
const Filters::Common::Expr::CelStatePrototype NodeInfo{
|
||||
true, Filters::Common::Expr::CelStateType::FlatBuffers,
|
||||
toAbslStringView(Istio::Common::nodeInfoSchema()),
|
||||
// Life span is only needed for Wasm set_property, not in the native filters.
|
||||
StreamInfo::FilterState::LifeSpan::FilterChain};
|
||||
const Filters::Common::Expr::CelStatePrototype NodeId{
|
||||
true, Filters::Common::Expr::CelStateType::String, absl::string_view(),
|
||||
// Life span is only needed for Wasm set_property, not in the native filters.
|
||||
StreamInfo::FilterState::LifeSpan::FilterChain};
|
||||
};
|
||||
|
||||
using CelPrototypes = ConstSingleton<CelPrototypeValues>;
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelState;
|
||||
|
||||
class XDSMethod : public DiscoveryMethod {
|
||||
public:
|
||||
|
@ -102,15 +80,17 @@ absl::optional<PeerInfo> XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo&
|
|||
}
|
||||
}
|
||||
}
|
||||
const auto metadata_object = metadata_provider_->GetMetadata(peer_address);
|
||||
if (metadata_object) {
|
||||
return Istio::Common::convertWorkloadMetadataToFlatNode(metadata_object.value());
|
||||
if (!peer_address) {
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
ENVOY_LOG_MISC(debug, "Peer address: {}", peer_address->asString());
|
||||
return metadata_provider_->GetMetadata(peer_address);
|
||||
}
|
||||
|
||||
MXMethod::MXMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context)
|
||||
: downstream_(downstream), tls_(factory_context.threadLocal()) {
|
||||
MXMethod::MXMethod(bool downstream, const absl::flat_hash_set<std::string> additional_labels,
|
||||
Server::Configuration::ServerFactoryContext& factory_context)
|
||||
: downstream_(downstream), tls_(factory_context.threadLocal()),
|
||||
additional_labels_(additional_labels) {
|
||||
tls_.set([](Event::Dispatcher&) { return std::make_shared<MXCache>(); });
|
||||
}
|
||||
|
||||
|
@ -154,43 +134,39 @@ absl::optional<PeerInfo> MXMethod::lookup(absl::string_view id, absl::string_vie
|
|||
if (!metadata.ParseFromString(bytes)) {
|
||||
return {};
|
||||
}
|
||||
const auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(metadata);
|
||||
std::string out(reinterpret_cast<const char*>(fb.data()), fb.size());
|
||||
auto out = Istio::Common::convertStructToWorkloadMetadata(metadata, additional_labels_);
|
||||
if (max_peer_cache_size_ > 0 && !id.empty()) {
|
||||
// do not let the cache grow beyond max cache size.
|
||||
if (static_cast<uint32_t>(cache.size()) > max_peer_cache_size_) {
|
||||
cache.erase(cache.begin(), std::next(cache.begin(), max_peer_cache_size_ / 4));
|
||||
}
|
||||
cache.emplace(id, out);
|
||||
cache.emplace(id, *out);
|
||||
}
|
||||
return out;
|
||||
return *out;
|
||||
}
|
||||
|
||||
MXPropagationMethod::MXPropagationMethod(
|
||||
bool downstream, Server::Configuration::ServerFactoryContext& factory_context,
|
||||
const absl::flat_hash_set<std::string>& additional_labels,
|
||||
const io::istio::http::peer_metadata::Config_IstioHeaders& istio_headers)
|
||||
: downstream_(downstream), id_(factory_context.localInfo().node().id()),
|
||||
value_(computeValue(factory_context)),
|
||||
value_(computeValue(additional_labels, factory_context)),
|
||||
skip_external_clusters_(istio_headers.skip_external_clusters()) {}
|
||||
|
||||
std::string MXPropagationMethod::computeValue(
|
||||
const absl::flat_hash_set<std::string>& additional_labels,
|
||||
Server::Configuration::ServerFactoryContext& factory_context) const {
|
||||
const auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(
|
||||
factory_context.localInfo().node().metadata());
|
||||
google::protobuf::Struct metadata;
|
||||
::Wasm::Common::extractStructFromNodeFlatBuffer(
|
||||
*flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fb.data()), &metadata);
|
||||
std::string metadata_bytes;
|
||||
::Wasm::Common::serializeToStringDeterministic(metadata, &metadata_bytes);
|
||||
const auto obj = Istio::Common::convertStructToWorkloadMetadata(
|
||||
factory_context.localInfo().node().metadata(), additional_labels);
|
||||
const google::protobuf::Struct metadata = Istio::Common::convertWorkloadMetadataToStruct(*obj);
|
||||
const std::string metadata_bytes = Istio::Common::serializeToStringDeterministic(metadata);
|
||||
return Base64::encode(metadata_bytes.data(), metadata_bytes.size());
|
||||
}
|
||||
|
||||
void MXPropagationMethod::inject(const StreamInfo::StreamInfo& info, Http::HeaderMap& headers,
|
||||
Context& ctx) const {
|
||||
if (skip_external_clusters_) {
|
||||
if (skipMXHeaders(info)) {
|
||||
return;
|
||||
}
|
||||
if (skipMXHeaders(skip_external_clusters_, info)) {
|
||||
return;
|
||||
}
|
||||
if (!downstream_ || ctx.request_peer_id_received_) {
|
||||
headers.setReference(Headers::get().ExchangeMetadataHeaderId, id_);
|
||||
|
@ -203,19 +179,24 @@ void MXPropagationMethod::inject(const StreamInfo::StreamInfo& info, Http::Heade
|
|||
FilterConfig::FilterConfig(const io::istio::http::peer_metadata::Config& config,
|
||||
Server::Configuration::FactoryContext& factory_context)
|
||||
: shared_with_upstream_(config.shared_with_upstream()),
|
||||
downstream_discovery_(
|
||||
buildDiscoveryMethods(config.downstream_discovery(), true, factory_context)),
|
||||
upstream_discovery_(
|
||||
buildDiscoveryMethods(config.upstream_discovery(), false, factory_context)),
|
||||
downstream_propagation_(
|
||||
buildPropagationMethods(config.downstream_propagation(), true, factory_context)),
|
||||
upstream_propagation_(
|
||||
buildPropagationMethods(config.upstream_propagation(), false, factory_context)) {}
|
||||
downstream_discovery_(buildDiscoveryMethods(config.downstream_discovery(),
|
||||
buildAdditionalLabels(config.additional_labels()),
|
||||
true, factory_context)),
|
||||
upstream_discovery_(buildDiscoveryMethods(config.upstream_discovery(),
|
||||
buildAdditionalLabels(config.additional_labels()),
|
||||
false, factory_context)),
|
||||
downstream_propagation_(buildPropagationMethods(
|
||||
config.downstream_propagation(), buildAdditionalLabels(config.additional_labels()), true,
|
||||
factory_context)),
|
||||
upstream_propagation_(buildPropagationMethods(
|
||||
config.upstream_propagation(), buildAdditionalLabels(config.additional_labels()), false,
|
||||
factory_context)) {}
|
||||
|
||||
std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
|
||||
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::DiscoveryMethod>&
|
||||
config,
|
||||
bool downstream, Server::Configuration::FactoryContext& factory_context) const {
|
||||
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
|
||||
Server::Configuration::FactoryContext& factory_context) const {
|
||||
std::vector<DiscoveryMethodPtr> methods;
|
||||
methods.reserve(config.size());
|
||||
for (const auto& method : config) {
|
||||
|
@ -227,8 +208,8 @@ std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
|
|||
break;
|
||||
case io::istio::http::peer_metadata::Config::DiscoveryMethod::MethodSpecifierCase::
|
||||
kIstioHeaders:
|
||||
methods.push_back(
|
||||
std::make_unique<MXMethod>(downstream, factory_context.serverFactoryContext()));
|
||||
methods.push_back(std::make_unique<MXMethod>(downstream, additional_labels,
|
||||
factory_context.serverFactoryContext()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -240,15 +221,17 @@ std::vector<DiscoveryMethodPtr> FilterConfig::buildDiscoveryMethods(
|
|||
std::vector<PropagationMethodPtr> FilterConfig::buildPropagationMethods(
|
||||
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::PropagationMethod>&
|
||||
config,
|
||||
bool downstream, Server::Configuration::FactoryContext& factory_context) const {
|
||||
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
|
||||
Server::Configuration::FactoryContext& factory_context) const {
|
||||
std::vector<PropagationMethodPtr> methods;
|
||||
methods.reserve(config.size());
|
||||
for (const auto& method : config) {
|
||||
switch (method.method_specifier_case()) {
|
||||
case io::istio::http::peer_metadata::Config::PropagationMethod::MethodSpecifierCase::
|
||||
kIstioHeaders:
|
||||
methods.push_back(std::make_unique<MXPropagationMethod>(
|
||||
downstream, factory_context.serverFactoryContext(), method.istio_headers()));
|
||||
methods.push_back(
|
||||
std::make_unique<MXPropagationMethod>(downstream, factory_context.serverFactoryContext(),
|
||||
additional_labels, method.istio_headers()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -257,6 +240,15 @@ std::vector<PropagationMethodPtr> FilterConfig::buildPropagationMethods(
|
|||
return methods;
|
||||
}
|
||||
|
||||
absl::flat_hash_set<std::string>
|
||||
FilterConfig::buildAdditionalLabels(const Protobuf::RepeatedPtrField<std::string>& labels) const {
|
||||
absl::flat_hash_set<std::string> result;
|
||||
for (const auto& label : labels) {
|
||||
result.emplace(label);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void FilterConfig::discoverDownstream(StreamInfo::StreamInfo& info, Http::RequestHeaderMap& headers,
|
||||
Context& ctx) const {
|
||||
discover(info, true, headers, ctx);
|
||||
|
@ -296,31 +288,20 @@ void FilterConfig::injectUpstream(const StreamInfo::StreamInfo& info,
|
|||
}
|
||||
|
||||
void FilterConfig::setFilterState(StreamInfo::StreamInfo& info, bool downstream,
|
||||
const std::string& value) const {
|
||||
const PeerInfo& value) const {
|
||||
const absl::string_view key =
|
||||
downstream ? Istio::Common::WasmDownstreamPeer : Istio::Common::WasmUpstreamPeer;
|
||||
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer;
|
||||
if (!info.filterState()->hasDataWithName(key)) {
|
||||
auto node_info = std::make_unique<CelStateHashable>(CelPrototypes::get().NodeInfo);
|
||||
node_info->setValue(value);
|
||||
// Use CelState to allow operation filter_state.upstream_peer.labels['role']
|
||||
auto pb = value.serializeAsProto();
|
||||
auto peer_info = std::make_unique<CelState>(FilterConfig::peerInfoPrototype());
|
||||
peer_info->setValue(absl::string_view(pb->SerializeAsString()));
|
||||
info.filterState()->setData(
|
||||
key, std::move(node_info), StreamInfo::FilterState::StateType::Mutable,
|
||||
key, std::move(peer_info), StreamInfo::FilterState::StateType::Mutable,
|
||||
StreamInfo::FilterState::LifeSpan::FilterChain, sharedWithUpstream());
|
||||
} else {
|
||||
ENVOY_LOG(debug, "Duplicate peer metadata, skipping");
|
||||
}
|
||||
// This is needed because stats filter awaits for the prefix on the wire and checks for the key
|
||||
// presence before emitting any telemetry.
|
||||
const absl::string_view id_key =
|
||||
downstream ? Istio::Common::WasmDownstreamPeerID : Istio::Common::WasmUpstreamPeerID;
|
||||
if (!info.filterState()->hasDataWithName(id_key)) {
|
||||
auto node_id = std::make_unique<Filters::Common::Expr::CelState>(CelPrototypes::get().NodeId);
|
||||
node_id->setValue("unknown");
|
||||
info.filterState()->setData(
|
||||
id_key, std::move(node_id), StreamInfo::FilterState::StateType::Mutable,
|
||||
StreamInfo::FilterState::LifeSpan::FilterChain, sharedWithUpstream());
|
||||
} else {
|
||||
ENVOY_LOG(debug, "Duplicate peer id, skipping");
|
||||
}
|
||||
}
|
||||
|
||||
Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool) {
|
||||
|
@ -329,19 +310,34 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers,
|
|||
return Http::FilterHeadersStatus::Continue;
|
||||
}
|
||||
|
||||
bool MXPropagationMethod::skipMXHeaders(const StreamInfo::StreamInfo& info) const {
|
||||
bool MXPropagationMethod::skipMXHeaders(const bool skip_external_clusters,
|
||||
const StreamInfo::StreamInfo& info) const {
|
||||
// We skip metadata in two cases.
|
||||
// 1. skip_external_clusters is enabled, and we detect the upstream as external.
|
||||
const auto& cluster_info = info.upstreamClusterInfo();
|
||||
if (cluster_info && cluster_info.value()) {
|
||||
const auto& cluster_name = cluster_info.value()->name();
|
||||
if (cluster_name == "PassthroughCluster") {
|
||||
// PassthroughCluster is always considered external
|
||||
if (skip_external_clusters && cluster_name == "PassthroughCluster") {
|
||||
return true;
|
||||
}
|
||||
const auto& filter_metadata = cluster_info.value()->metadata().filter_metadata();
|
||||
const auto& it = filter_metadata.find("istio");
|
||||
// Otherwise, cluster must be tagged as external
|
||||
if (it != filter_metadata.end()) {
|
||||
const auto& skip_mx = it->second.fields().find("external");
|
||||
if (skip_external_clusters) {
|
||||
const auto& skip_mx = it->second.fields().find("external");
|
||||
if (skip_mx != it->second.fields().end()) {
|
||||
if (skip_mx->second.bool_value()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto& skip_mx = it->second.fields().find("disable_mx");
|
||||
if (skip_mx != it->second.fields().end()) {
|
||||
return skip_mx->second.bool_value();
|
||||
if (skip_mx->second.bool_value()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "source/extensions/filters/http/common/factory_base.h"
|
||||
#include "source/extensions/filters/http/common/pass_through_filter.h"
|
||||
#include "source/extensions/filters/http/peer_metadata/config.pb.h"
|
||||
|
@ -25,6 +26,9 @@ namespace Extensions {
|
|||
namespace HttpFilters {
|
||||
namespace PeerMetadata {
|
||||
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelStatePrototype;
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelStateType;
|
||||
|
||||
struct HeaderValues {
|
||||
const Http::LowerCaseString ExchangeMetadataHeader{"x-envoy-peer-metadata"};
|
||||
const Http::LowerCaseString ExchangeMetadataHeaderId{"x-envoy-peer-metadata-id"};
|
||||
|
@ -32,8 +36,7 @@ struct HeaderValues {
|
|||
|
||||
using Headers = ConstSingleton<HeaderValues>;
|
||||
|
||||
// Peer info in the flatbuffers format.
|
||||
using PeerInfo = std::string;
|
||||
using PeerInfo = Istio::Common::WorkloadMetadataObject;
|
||||
|
||||
struct Context {
|
||||
bool request_peer_id_received_{false};
|
||||
|
@ -53,7 +56,8 @@ using DiscoveryMethodPtr = std::unique_ptr<DiscoveryMethod>;
|
|||
|
||||
class MXMethod : public DiscoveryMethod {
|
||||
public:
|
||||
MXMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context);
|
||||
MXMethod(bool downstream, const absl::flat_hash_set<std::string> additional_labels,
|
||||
Server::Configuration::ServerFactoryContext& factory_context);
|
||||
absl::optional<PeerInfo> derivePeerInfo(const StreamInfo::StreamInfo&, Http::HeaderMap&,
|
||||
Context&) const override;
|
||||
void remove(Http::HeaderMap&) const override;
|
||||
|
@ -62,9 +66,10 @@ private:
|
|||
absl::optional<PeerInfo> lookup(absl::string_view id, absl::string_view value) const;
|
||||
const bool downstream_;
|
||||
struct MXCache : public ThreadLocal::ThreadLocalObject {
|
||||
absl::flat_hash_map<std::string, std::string> cache_;
|
||||
absl::flat_hash_map<std::string, PeerInfo> cache_;
|
||||
};
|
||||
mutable ThreadLocal::TypedSlot<MXCache> tls_;
|
||||
const absl::flat_hash_set<std::string> additional_labels_;
|
||||
const int64_t max_peer_cache_size_{500};
|
||||
};
|
||||
|
||||
|
@ -80,16 +85,18 @@ using PropagationMethodPtr = std::unique_ptr<PropagationMethod>;
|
|||
class MXPropagationMethod : public PropagationMethod {
|
||||
public:
|
||||
MXPropagationMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context,
|
||||
const absl::flat_hash_set<std::string>& additional_labels,
|
||||
const io::istio::http::peer_metadata::Config_IstioHeaders&);
|
||||
void inject(const StreamInfo::StreamInfo&, Http::HeaderMap&, Context&) const override;
|
||||
|
||||
private:
|
||||
const bool downstream_;
|
||||
std::string computeValue(Server::Configuration::ServerFactoryContext&) const;
|
||||
std::string computeValue(const absl::flat_hash_set<std::string>&,
|
||||
Server::Configuration::ServerFactoryContext&) const;
|
||||
const std::string id_;
|
||||
const std::string value_;
|
||||
const bool skip_external_clusters_;
|
||||
bool skipMXHeaders(const StreamInfo::StreamInfo&) const;
|
||||
bool skipMXHeaders(const bool, const StreamInfo::StreamInfo&) const;
|
||||
};
|
||||
|
||||
class FilterConfig : public Logger::Loggable<Logger::Id::filter> {
|
||||
|
@ -101,20 +108,31 @@ public:
|
|||
void injectDownstream(const StreamInfo::StreamInfo&, Http::ResponseHeaderMap&, Context&) const;
|
||||
void injectUpstream(const StreamInfo::StreamInfo&, Http::RequestHeaderMap&, Context&) const;
|
||||
|
||||
static const CelStatePrototype& peerInfoPrototype() {
|
||||
static const CelStatePrototype* const prototype = new CelStatePrototype(
|
||||
true, CelStateType::Protobuf, "type.googleapis.com/google.protobuf.Struct",
|
||||
StreamInfo::FilterState::LifeSpan::FilterChain);
|
||||
return *prototype;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<DiscoveryMethodPtr> buildDiscoveryMethods(
|
||||
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::DiscoveryMethod>&,
|
||||
bool downstream, Server::Configuration::FactoryContext&) const;
|
||||
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
|
||||
Server::Configuration::FactoryContext&) const;
|
||||
std::vector<PropagationMethodPtr> buildPropagationMethods(
|
||||
const Protobuf::RepeatedPtrField<io::istio::http::peer_metadata::Config::PropagationMethod>&,
|
||||
bool downstream, Server::Configuration::FactoryContext&) const;
|
||||
const absl::flat_hash_set<std::string>& additional_labels, bool downstream,
|
||||
Server::Configuration::FactoryContext&) const;
|
||||
absl::flat_hash_set<std::string>
|
||||
buildAdditionalLabels(const Protobuf::RepeatedPtrField<std::string>&) const;
|
||||
StreamInfo::StreamSharingMayImpactPooling sharedWithUpstream() const {
|
||||
return shared_with_upstream_
|
||||
? StreamInfo::StreamSharingMayImpactPooling::SharedWithUpstreamConnectionOnce
|
||||
: StreamInfo::StreamSharingMayImpactPooling::None;
|
||||
}
|
||||
void discover(StreamInfo::StreamInfo&, bool downstream, Http::HeaderMap&, Context&) const;
|
||||
void setFilterState(StreamInfo::StreamInfo&, bool downstream, const std::string& value) const;
|
||||
void setFilterState(StreamInfo::StreamInfo&, bool downstream, const PeerInfo& value) const;
|
||||
const bool shared_with_upstream_;
|
||||
const std::vector<DiscoveryMethodPtr> downstream_discovery_;
|
||||
const std::vector<DiscoveryMethodPtr> upstream_discovery_;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "source/extensions/filters/http/peer_metadata/filter.h"
|
||||
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "source/common/network/address_impl.h"
|
||||
#include "test/common/stream_info/test_util.h"
|
||||
#include "test/mocks/stream_info/mocks.h"
|
||||
|
@ -77,24 +76,26 @@ protected:
|
|||
}
|
||||
void checkNoPeer(bool downstream) {
|
||||
EXPECT_FALSE(stream_info_.filterState()->hasDataWithName(
|
||||
downstream ? Istio::Common::WasmDownstreamPeerID : Istio::Common::WasmUpstreamPeerID));
|
||||
EXPECT_FALSE(stream_info_.filterState()->hasDataWithName(
|
||||
downstream ? Istio::Common::WasmDownstreamPeer : Istio::Common::WasmUpstreamPeer));
|
||||
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer));
|
||||
}
|
||||
void checkPeerNamespace(bool downstream, const std::string& expected) {
|
||||
EXPECT_TRUE(stream_info_.filterState()->hasDataWithName(
|
||||
downstream ? Istio::Common::WasmDownstreamPeerID : Istio::Common::WasmUpstreamPeerID));
|
||||
const auto* obj = stream_info_.filterState()->getDataReadOnly<Filters::Common::Expr::CelState>(
|
||||
downstream ? Istio::Common::WasmDownstreamPeer : Istio::Common::WasmUpstreamPeer);
|
||||
ASSERT_NE(nullptr, obj);
|
||||
Protobuf::Arena arena;
|
||||
auto map = obj->exprValue(&arena, false);
|
||||
ASSERT_TRUE(map.IsMap());
|
||||
auto value =
|
||||
(*map.MapOrDie())[google::api::expr::runtime::CelValue::CreateStringView("namespace")];
|
||||
ASSERT_TRUE(value.has_value());
|
||||
EXPECT_EQ(expected, value.value().StringOrDie().value());
|
||||
const auto* cel_state =
|
||||
stream_info_.filterState()
|
||||
->getDataReadOnly<Envoy::Extensions::Filters::Common::Expr::CelState>(
|
||||
downstream ? Istio::Common::DownstreamPeer : Istio::Common::UpstreamPeer);
|
||||
ProtobufWkt::Struct obj;
|
||||
ASSERT_TRUE(obj.ParseFromString(cel_state->value().data()));
|
||||
EXPECT_EQ(expected, extractString(obj, "namespace"));
|
||||
}
|
||||
|
||||
absl::string_view extractString(const ProtobufWkt::Struct& metadata, absl::string_view key) {
|
||||
const auto& it = metadata.fields().find(key);
|
||||
if (it == metadata.fields().end()) {
|
||||
return {};
|
||||
}
|
||||
return it->second.string_value();
|
||||
}
|
||||
|
||||
void checkShared(bool expected) {
|
||||
EXPECT_EQ(expected,
|
||||
stream_info_.filterState()->objectsSharedWithUpstreamConnection()->size() > 0);
|
||||
|
@ -132,8 +133,7 @@ TEST_F(PeerMetadataTest, DownstreamXDSNone) {
|
|||
|
||||
TEST_F(PeerMetadataTest, DownstreamXDS) {
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -155,8 +155,7 @@ TEST_F(PeerMetadataTest, DownstreamXDS) {
|
|||
|
||||
TEST_F(PeerMetadataTest, UpstreamXDS) {
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -192,8 +191,7 @@ TEST_F(PeerMetadataTest, UpstreamXDSInternal) {
|
|||
*host_metadata);
|
||||
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -262,8 +260,7 @@ TEST_F(PeerMetadataTest, DownstreamFallbackFirst) {
|
|||
|
||||
TEST_F(PeerMetadataTest, DownstreamFallbackSecond) {
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -285,7 +282,8 @@ TEST_F(PeerMetadataTest, DownstreamFallbackSecond) {
|
|||
|
||||
TEST(MXMethod, Cache) {
|
||||
NiceMock<Server::Configuration::MockServerFactoryContext> context;
|
||||
MXMethod method(true, context);
|
||||
absl::flat_hash_set<std::string> additional_labels;
|
||||
MXMethod method(true, additional_labels, context);
|
||||
NiceMock<StreamInfo::MockStreamInfo> stream_info;
|
||||
Http::TestRequestHeaderMapImpl request_headers;
|
||||
const int32_t max = 1000;
|
||||
|
@ -345,8 +343,7 @@ TEST_F(PeerMetadataTest, UpstreamFallbackFirst) {
|
|||
|
||||
TEST_F(PeerMetadataTest, UpstreamFallbackSecond) {
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -368,8 +365,7 @@ TEST_F(PeerMetadataTest, UpstreamFallbackSecond) {
|
|||
|
||||
TEST_F(PeerMetadataTest, UpstreamFallbackFirstXDS) {
|
||||
const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service",
|
||||
"v1alpha3", "foo-app", "v1", Istio::Common::WorkloadType::Pod,
|
||||
"");
|
||||
"v1alpha3", "", "", Istio::Common::WorkloadType::Pod, "");
|
||||
EXPECT_CALL(*metadata_provider_, GetMetadata(_))
|
||||
.WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address)
|
||||
-> std::optional<WorkloadMetadataObject> {
|
||||
|
@ -402,6 +398,20 @@ TEST_F(PeerMetadataTest, DownstreamMXPropagation) {
|
|||
checkNoPeer(false);
|
||||
}
|
||||
|
||||
TEST_F(PeerMetadataTest, DownstreamMXPropagationWithAdditionalLabels) {
|
||||
initialize(R"EOF(
|
||||
downstream_propagation:
|
||||
- istio_headers: {}
|
||||
additional_labels:
|
||||
- foo
|
||||
- bar
|
||||
)EOF");
|
||||
EXPECT_EQ(0, request_headers_.size());
|
||||
EXPECT_EQ(0, response_headers_.size());
|
||||
checkNoPeer(true);
|
||||
checkNoPeer(false);
|
||||
}
|
||||
|
||||
TEST_F(PeerMetadataTest, DownstreamMXDiscoveryPropagation) {
|
||||
request_headers_.setReference(Headers::get().ExchangeMetadataHeaderId, "test-pod");
|
||||
request_headers_.setReference(Headers::get().ExchangeMetadataHeader, SampleIstioHeader);
|
||||
|
|
|
@ -40,11 +40,9 @@ envoy_cc_library(
|
|||
repository = "@envoy",
|
||||
deps = [
|
||||
"//extensions/common:metadata_object_lib",
|
||||
"//extensions/common:proto_util",
|
||||
"//source/extensions/common/workload_discovery:api_lib",
|
||||
"//source/extensions/filters/network/metadata_exchange/config:metadata_exchange_cc_proto",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/base:endian",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@envoy//envoy/local_info:local_info_interface",
|
||||
"@envoy//envoy/network:connection_interface",
|
||||
|
@ -53,11 +51,12 @@ envoy_cc_library(
|
|||
"@envoy//envoy/stats:stats_macros",
|
||||
"@envoy//envoy/stream_info:filter_state_interface",
|
||||
"@envoy//source/common/http:utility_lib",
|
||||
"@envoy//source/common/network:filter_state_dst_address_lib",
|
||||
"@envoy//source/common/network:utility_lib",
|
||||
"@envoy//source/common/protobuf",
|
||||
"@envoy//source/common/protobuf:utility_lib",
|
||||
"@envoy//source/common/stream_info:bool_accessor_lib",
|
||||
"@envoy//source/extensions/filters/common/expr:cel_state_lib",
|
||||
"@envoy//source/extensions/filters/network:well_known_names",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -88,6 +87,5 @@ envoy_cc_test(
|
|||
"@envoy//test/mocks/network:network_mocks",
|
||||
"@envoy//test/mocks/protobuf:protobuf_mocks",
|
||||
"@envoy//test/mocks/server:server_factory_context_mocks",
|
||||
"@envoy//test/test_common:wasm_lib",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -31,9 +31,16 @@ Network::FilterFactoryCb createFilterFactoryHelper(
|
|||
Server::Configuration::ServerFactoryContext& context, FilterDirection filter_direction) {
|
||||
ASSERT(!proto_config.protocol().empty());
|
||||
|
||||
absl::flat_hash_set<std::string> additional_labels;
|
||||
if (!proto_config.additional_labels().empty()) {
|
||||
for (const auto& label : proto_config.additional_labels()) {
|
||||
additional_labels.emplace(label);
|
||||
}
|
||||
}
|
||||
|
||||
MetadataExchangeConfigSharedPtr filter_config(std::make_shared<MetadataExchangeConfig>(
|
||||
StatPrefix, proto_config.protocol(), filter_direction, proto_config.enable_discovery(),
|
||||
context, context.scope()));
|
||||
additional_labels, context, context.scope()));
|
||||
return [filter_config, &context](Network::FilterManager& filter_manager) -> void {
|
||||
filter_manager.addFilter(
|
||||
std::make_shared<MetadataExchangeFilter>(filter_config, context.localInfo()));
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
---
|
||||
title: envoy.tcp.metadataexchange.config
|
||||
layout: protoc-gen-docs
|
||||
generator: protoc-gen-docs
|
||||
number_of_entries: 1
|
||||
---
|
||||
<h2 id="MetadataExchange">MetadataExchange</h2>
|
||||
<section>
|
||||
<p>[#protodoc-title: MetadataExchange protocol match and data transfer]
|
||||
MetadataExchange protocol match and data transfer</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
<th>Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="MetadataExchange-protocol">
|
||||
<td><code>protocol</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td>
|
||||
<p>Protocol that Alpn should support on the server.
|
||||
[#comment:TODO(GargNupur): Make it a list.]</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="MetadataExchange-enable_discovery">
|
||||
<td><code>enable_discovery</code></td>
|
||||
<td><code>bool</code></td>
|
||||
<td>
|
||||
<p>If true, will attempt to use WDS in case the prefix peer metadata is not available.</p>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
No
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
|
@ -31,4 +31,8 @@ message MetadataExchange {
|
|||
|
||||
// If true, will attempt to use WDS in case the prefix peer metadata is not available.
|
||||
bool enable_discovery = 2;
|
||||
|
||||
// Additional labels to be added to the peer metadata to help your understand the traffic.
|
||||
// e.g. `role`, `location` etc.
|
||||
repeated string additional_labels = 3;
|
||||
}
|
||||
|
|
|
@ -25,26 +25,25 @@
|
|||
#include "envoy/stats/scope.h"
|
||||
#include "source/common/buffer/buffer_impl.h"
|
||||
#include "source/common/protobuf/utility.h"
|
||||
#include "source/common/network/utility.h"
|
||||
#include "source/common/network/filter_state_dst_address.h"
|
||||
#include "source/extensions/filters/network/metadata_exchange/metadata_exchange_initial_header.h"
|
||||
#include "source/common/stream_info/bool_accessor_impl.h"
|
||||
|
||||
namespace Envoy {
|
||||
namespace Tcp {
|
||||
namespace MetadataExchange {
|
||||
namespace {
|
||||
|
||||
constexpr std::string_view kMetadataPrefix = "wasm.";
|
||||
constexpr std::string_view kUpstreamMetadataIdKey = "upstream_peer_id";
|
||||
constexpr std::string_view kUpstreamMetadataKey = "upstream_peer";
|
||||
constexpr std::string_view kDownstreamMetadataIdKey = "downstream_peer_id";
|
||||
constexpr std::string_view kDownstreamMetadataKey = "downstream_peer";
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelState;
|
||||
|
||||
namespace {
|
||||
|
||||
// Sentinel key in the filter state, indicating that the peer metadata is
|
||||
// decidedly absent. This is different from a missing peer metadata ID key
|
||||
// which could indicate that the metadata is not received yet.
|
||||
const std::string kMetadataNotFoundValue = "envoy.wasm.metadata_exchange.peer_unknown";
|
||||
|
||||
std::unique_ptr<::Envoy::Buffer::OwnedImpl>
|
||||
constructProxyHeaderData(const Envoy::ProtobufWkt::Any& proxy_data) {
|
||||
std::unique_ptr<Buffer::OwnedImpl> constructProxyHeaderData(const ProtobufWkt::Any& proxy_data) {
|
||||
MetadataExchangeInitialHeader initial_header;
|
||||
std::string proxy_data_str = proxy_data.SerializeAsString();
|
||||
// Converting from host to network byte order so that most significant byte is
|
||||
|
@ -52,33 +51,23 @@ constructProxyHeaderData(const Envoy::ProtobufWkt::Any& proxy_data) {
|
|||
initial_header.magic = absl::ghtonl(MetadataExchangeInitialHeader::magic_number);
|
||||
initial_header.data_size = absl::ghtonl(proxy_data_str.length());
|
||||
|
||||
::Envoy::Buffer::OwnedImpl initial_header_buffer{absl::string_view(
|
||||
Buffer::OwnedImpl initial_header_buffer{absl::string_view(
|
||||
reinterpret_cast<const char*>(&initial_header), sizeof(MetadataExchangeInitialHeader))};
|
||||
auto proxy_data_buffer = std::make_unique<::Envoy::Buffer::OwnedImpl>(proxy_data_str);
|
||||
auto proxy_data_buffer = std::make_unique<Buffer::OwnedImpl>(proxy_data_str);
|
||||
proxy_data_buffer->prepend(initial_header_buffer);
|
||||
return proxy_data_buffer;
|
||||
}
|
||||
|
||||
bool serializeToStringDeterministic(const google::protobuf::Struct& metadata,
|
||||
std::string* metadata_bytes) {
|
||||
google::protobuf::io::StringOutputStream md(metadata_bytes);
|
||||
google::protobuf::io::CodedOutputStream mcs(&md);
|
||||
|
||||
mcs.SetSerializationDeterministic(true);
|
||||
if (!metadata.SerializeToCodedStream(&mcs)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MetadataExchangeConfig::MetadataExchangeConfig(
|
||||
const std::string& stat_prefix, const std::string& protocol,
|
||||
const FilterDirection filter_direction, bool enable_discovery,
|
||||
const absl::flat_hash_set<std::string> additional_labels,
|
||||
Server::Configuration::ServerFactoryContext& factory_context, Stats::Scope& scope)
|
||||
: scope_(scope), stat_prefix_(stat_prefix), protocol_(protocol),
|
||||
filter_direction_(filter_direction), stats_(generateStats(stat_prefix, scope)) {
|
||||
filter_direction_(filter_direction), stats_(generateStats(stat_prefix, scope)),
|
||||
additional_labels_(additional_labels) {
|
||||
if (enable_discovery) {
|
||||
metadata_provider_ = Extensions::Common::WorkloadDiscovery::GetProvider(factory_context);
|
||||
}
|
||||
|
@ -197,22 +186,22 @@ void MetadataExchangeFilter::writeNodeMetadata() {
|
|||
if (conn_state_ != WriteMetadata) {
|
||||
return;
|
||||
}
|
||||
|
||||
Envoy::ProtobufWkt::Struct data;
|
||||
Envoy::ProtobufWkt::Struct* metadata =
|
||||
(*data.mutable_fields())[ExchangeMetadataHeader].mutable_struct_value();
|
||||
getMetadata(metadata);
|
||||
ENVOY_LOG(trace, "Writing metadata to the connection.");
|
||||
ProtobufWkt::Struct data;
|
||||
const auto obj = Istio::Common::convertStructToWorkloadMetadata(local_info_.node().metadata(),
|
||||
config_->additional_labels_);
|
||||
*(*data.mutable_fields())[ExchangeMetadataHeader].mutable_struct_value() =
|
||||
Istio::Common::convertWorkloadMetadataToStruct(*obj);
|
||||
std::string metadata_id = getMetadataId();
|
||||
if (!metadata_id.empty()) {
|
||||
(*data.mutable_fields())[ExchangeMetadataHeaderId].set_string_value(metadata_id);
|
||||
}
|
||||
if (data.fields_size() > 0) {
|
||||
Envoy::ProtobufWkt::Any metadata_any_value;
|
||||
ProtobufWkt::Any metadata_any_value;
|
||||
metadata_any_value.set_type_url(StructTypeUrl);
|
||||
std::string serialized_data;
|
||||
serializeToStringDeterministic(data, &serialized_data);
|
||||
*metadata_any_value.mutable_value() = serialized_data;
|
||||
std::unique_ptr<::Envoy::Buffer::OwnedImpl> buf = constructProxyHeaderData(metadata_any_value);
|
||||
*metadata_any_value.mutable_value() = Istio::Common::serializeToStringDeterministic(data);
|
||||
;
|
||||
std::unique_ptr<Buffer::OwnedImpl> buf = constructProxyHeaderData(metadata_any_value);
|
||||
write_callbacks_->injectWriteDataToFilterChain(*buf, false);
|
||||
config_->stats().metadata_added_.inc();
|
||||
}
|
||||
|
@ -260,7 +249,7 @@ void MetadataExchangeFilter::tryReadProxyData(Buffer::Instance& data) {
|
|||
}
|
||||
std::string proxy_data_buf =
|
||||
std::string(static_cast<const char*>(data.linearize(proxy_data_length_)), proxy_data_length_);
|
||||
Envoy::ProtobufWkt::Any proxy_data;
|
||||
ProtobufWkt::Any proxy_data;
|
||||
if (!proxy_data.ParseFromString(proxy_data_buf)) {
|
||||
config_->stats().header_not_found_.inc();
|
||||
setMetadataNotFoundFilterState();
|
||||
|
@ -271,77 +260,106 @@ void MetadataExchangeFilter::tryReadProxyData(Buffer::Instance& data) {
|
|||
data.drain(proxy_data_length_);
|
||||
|
||||
// Set Metadata
|
||||
Envoy::ProtobufWkt::Struct value_struct =
|
||||
Envoy::MessageUtil::anyConvert<Envoy::ProtobufWkt::Struct>(proxy_data);
|
||||
ProtobufWkt::Struct value_struct = MessageUtil::anyConvert<ProtobufWkt::Struct>(proxy_data);
|
||||
auto key_metadata_it = value_struct.fields().find(ExchangeMetadataHeader);
|
||||
if (key_metadata_it != value_struct.fields().end()) {
|
||||
const auto fb =
|
||||
::Wasm::Common::extractNodeFlatBufferFromStruct(key_metadata_it->second.struct_value());
|
||||
std::string out(reinterpret_cast<const char*>(fb.data()), fb.size());
|
||||
updatePeer(out);
|
||||
}
|
||||
const auto key_metadata_id_it = value_struct.fields().find(ExchangeMetadataHeaderId);
|
||||
if (key_metadata_id_it != value_struct.fields().end()) {
|
||||
Envoy::ProtobufWkt::Value val = key_metadata_id_it->second;
|
||||
updatePeerId(config_->filter_direction_ == FilterDirection::Downstream
|
||||
? kDownstreamMetadataIdKey
|
||||
: kUpstreamMetadataIdKey,
|
||||
val.string_value());
|
||||
updatePeer(*Istio::Common::convertStructToWorkloadMetadata(
|
||||
key_metadata_it->second.struct_value(), config_->additional_labels_));
|
||||
}
|
||||
}
|
||||
|
||||
void MetadataExchangeFilter::updatePeer(const std::string& fb) {
|
||||
// Filter object captures schema by view, hence the global singleton for the
|
||||
// prototype.
|
||||
auto state = std::make_unique<::Envoy::Extensions::Filters::Common::Expr::CelState>(
|
||||
MetadataExchangeConfig::nodeInfoPrototype());
|
||||
state->setValue(fb);
|
||||
void MetadataExchangeFilter::updatePeer(const Istio::Common::WorkloadMetadataObject& value) {
|
||||
updatePeer(value, config_->filter_direction_);
|
||||
}
|
||||
|
||||
void MetadataExchangeFilter::updatePeer(const Istio::Common::WorkloadMetadataObject& value,
|
||||
FilterDirection direction) {
|
||||
auto filter_state_key = direction == FilterDirection::Downstream ? Istio::Common::DownstreamPeer
|
||||
: Istio::Common::UpstreamPeer;
|
||||
auto pb = value.serializeAsProto();
|
||||
auto peer_info = std::make_shared<CelState>(MetadataExchangeConfig::peerInfoPrototype());
|
||||
peer_info->setValue(absl::string_view(pb->SerializeAsString()));
|
||||
|
||||
auto key = config_->filter_direction_ == FilterDirection::Downstream ? kDownstreamMetadataKey
|
||||
: kUpstreamMetadataKey;
|
||||
read_callbacks_->connection().streamInfo().filterState()->setData(
|
||||
absl::StrCat(kMetadataPrefix, key), std::move(state),
|
||||
StreamInfo::FilterState::StateType::Mutable, StreamInfo::FilterState::LifeSpan::Connection);
|
||||
}
|
||||
|
||||
void MetadataExchangeFilter::updatePeerId(absl::string_view key, absl::string_view value) {
|
||||
CelStatePrototype prototype(
|
||||
/* read_only = */ false, ::Envoy::Extensions::Filters::Common::Expr::CelStateType::String,
|
||||
absl::string_view(), StreamInfo::FilterState::LifeSpan::Connection);
|
||||
auto state = std::make_unique<::Envoy::Extensions::Filters::Common::Expr::CelState>(prototype);
|
||||
state->setValue(value);
|
||||
read_callbacks_->connection().streamInfo().filterState()->setData(
|
||||
absl::StrCat(kMetadataPrefix, key), std::move(state),
|
||||
StreamInfo::FilterState::StateType::Mutable, prototype.life_span_);
|
||||
}
|
||||
|
||||
void MetadataExchangeFilter::getMetadata(google::protobuf::Struct* metadata) {
|
||||
if (local_info_.node().has_metadata()) {
|
||||
const auto fb = ::Wasm::Common::extractNodeFlatBufferFromStruct(local_info_.node().metadata());
|
||||
::Wasm::Common::extractStructFromNodeFlatBuffer(
|
||||
*flatbuffers::GetRoot<::Wasm::Common::FlatNode>(fb.data()), metadata);
|
||||
}
|
||||
filter_state_key, std::move(peer_info), StreamInfo::FilterState::StateType::Mutable,
|
||||
StreamInfo::FilterState::LifeSpan::Connection);
|
||||
}
|
||||
|
||||
std::string MetadataExchangeFilter::getMetadataId() { return local_info_.node().id(); }
|
||||
|
||||
void MetadataExchangeFilter::setMetadataNotFoundFilterState() {
|
||||
if (config_->metadata_provider_) {
|
||||
Network::Address::InstanceConstSharedPtr upstream_peer;
|
||||
const StreamInfo::StreamInfo& info = read_callbacks_->connection().streamInfo();
|
||||
if (info.upstreamInfo()) {
|
||||
auto upstream_host = info.upstreamInfo().value().get().upstreamHost();
|
||||
if (upstream_host) {
|
||||
const auto address = upstream_host->address();
|
||||
ENVOY_LOG(debug, "Trying to check upstream host info of host {}", address->asString());
|
||||
switch (address->type()) {
|
||||
case Network::Address::Type::Ip:
|
||||
upstream_peer = upstream_host->address();
|
||||
break;
|
||||
case Network::Address::Type::EnvoyInternal:
|
||||
if (upstream_host->metadata()) {
|
||||
ENVOY_LOG(debug, "Trying to check filter metadata of host {}",
|
||||
upstream_host->address()->asString());
|
||||
const auto& filter_metadata = upstream_host->metadata()->filter_metadata();
|
||||
const auto& it = filter_metadata.find("envoy.filters.listener.original_dst");
|
||||
if (it != filter_metadata.end()) {
|
||||
const auto& destination_it = it->second.fields().find("local");
|
||||
if (destination_it != it->second.fields().end()) {
|
||||
upstream_peer = Network::Utility::parseInternetAddressAndPortNoThrow(
|
||||
destination_it->second.string_value(), /*v6only=*/false);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get our metadata differently based on the direction of the filter
|
||||
auto downstream_peer_address = [&]() -> Network::Address::InstanceConstSharedPtr {
|
||||
if (upstream_peer) {
|
||||
// Query upstream peer data and save it in metadata for stats
|
||||
const auto metadata_object = config_->metadata_provider_->GetMetadata(upstream_peer);
|
||||
if (metadata_object) {
|
||||
ENVOY_LOG(debug, "Metadata found for upstream peer address {}",
|
||||
upstream_peer->asString());
|
||||
updatePeer(metadata_object.value(), FilterDirection::Upstream);
|
||||
}
|
||||
}
|
||||
|
||||
// Regardless, return the downstream address for downstream metadata
|
||||
return read_callbacks_->connection().connectionInfoProvider().remoteAddress();
|
||||
};
|
||||
|
||||
auto upstream_peer_address = [&]() -> Network::Address::InstanceConstSharedPtr {
|
||||
if (upstream_peer) {
|
||||
return upstream_peer;
|
||||
}
|
||||
ENVOY_LOG(debug, "Upstream peer address is null. Fall back to localAddress");
|
||||
return read_callbacks_->connection().connectionInfoProvider().localAddress();
|
||||
};
|
||||
const Network::Address::InstanceConstSharedPtr peer_address =
|
||||
read_callbacks_->connection().connectionInfoProvider().remoteAddress();
|
||||
config_->filter_direction_ == FilterDirection::Downstream ? downstream_peer_address()
|
||||
: upstream_peer_address();
|
||||
ENVOY_LOG(debug, "Look up metadata based on peer address {}", peer_address->asString());
|
||||
const auto metadata_object = config_->metadata_provider_->GetMetadata(peer_address);
|
||||
if (metadata_object) {
|
||||
updatePeer(Istio::Common::convertWorkloadMetadataToFlatNode(metadata_object.value()));
|
||||
updatePeerId(config_->filter_direction_ == FilterDirection::Downstream
|
||||
? kDownstreamMetadataIdKey
|
||||
: kUpstreamMetadataIdKey,
|
||||
"unknown");
|
||||
ENVOY_LOG(trace, "Metadata found for peer address {}", peer_address->asString());
|
||||
updatePeer(metadata_object.value());
|
||||
config_->stats().metadata_added_.inc();
|
||||
return;
|
||||
} else {
|
||||
ENVOY_LOG(debug, "Metadata not found for peer address {}", peer_address->asString());
|
||||
}
|
||||
}
|
||||
updatePeerId(kMetadataNotFoundValue, kMetadataNotFoundValue);
|
||||
read_callbacks_->connection().streamInfo().filterState()->setData(
|
||||
Istio::Common::NoPeer, std::make_shared<StreamInfo::BoolAccessorImpl>(true),
|
||||
StreamInfo::FilterState::StateType::Mutable, StreamInfo::FilterState::LifeSpan::Connection);
|
||||
}
|
||||
|
||||
} // namespace MetadataExchange
|
||||
|
|
|
@ -23,20 +23,20 @@
|
|||
#include "envoy/stats/scope.h"
|
||||
#include "envoy/stats/stats_macros.h"
|
||||
#include "envoy/stream_info/filter_state.h"
|
||||
#include "extensions/common/node_info_bfbs_generated.h"
|
||||
#include "extensions/common/proto_util.h"
|
||||
#include "extensions/common/metadata_object.h"
|
||||
#include "source/common/common/stl_helpers.h"
|
||||
#include "source/common/protobuf/protobuf.h"
|
||||
#include "source/extensions/filters/common/expr/cel_state.h"
|
||||
#include "source/extensions/filters/network/metadata_exchange/config/metadata_exchange.pb.h"
|
||||
#include "source/extensions/common/workload_discovery/api.h"
|
||||
|
||||
#include "extensions/common/metadata_object.h"
|
||||
|
||||
namespace Envoy {
|
||||
namespace Tcp {
|
||||
namespace MetadataExchange {
|
||||
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelStatePrototype;
|
||||
using ::Envoy::Extensions::Filters::Common::Expr::CelStateType;
|
||||
|
||||
/**
|
||||
* All MetadataExchange filter stats. @see stats_macros.h
|
||||
|
@ -68,6 +68,7 @@ class MetadataExchangeConfig {
|
|||
public:
|
||||
MetadataExchangeConfig(const std::string& stat_prefix, const std::string& protocol,
|
||||
const FilterDirection filter_direction, bool enable_discovery,
|
||||
const absl::flat_hash_set<std::string> additional_labels,
|
||||
Server::Configuration::ServerFactoryContext& factory_context,
|
||||
Stats::Scope& scope);
|
||||
|
||||
|
@ -85,11 +86,12 @@ public:
|
|||
Extensions::Common::WorkloadDiscovery::WorkloadMetadataProviderSharedPtr metadata_provider_;
|
||||
// Stats for MetadataExchange Filter.
|
||||
MetadataExchangeStats stats_;
|
||||
const absl::flat_hash_set<std::string> additional_labels_;
|
||||
|
||||
static const CelStatePrototype& nodeInfoPrototype() {
|
||||
static const CelStatePrototype& peerInfoPrototype() {
|
||||
static const CelStatePrototype* const prototype = new CelStatePrototype(
|
||||
true, ::Envoy::Extensions::Filters::Common::Expr::CelStateType::FlatBuffers,
|
||||
::Istio::Common::nodeInfoSchema(), StreamInfo::FilterState::LifeSpan::Connection);
|
||||
true, CelStateType::Protobuf, "type.googleapis.com/google.protobuf.Struct",
|
||||
StreamInfo::FilterState::LifeSpan::Connection);
|
||||
return *prototype;
|
||||
}
|
||||
|
||||
|
@ -117,7 +119,6 @@ public:
|
|||
Network::FilterStatus onWrite(Buffer::Instance& data, bool end_stream) override;
|
||||
void initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) override {
|
||||
read_callbacks_ = &callbacks;
|
||||
// read_callbacks_->connection().addConnectionCallbacks(*this);
|
||||
}
|
||||
void initializeWriteFilterCallbacks(Network::WriteFilterCallbacks& callbacks) override {
|
||||
write_callbacks_ = &callbacks;
|
||||
|
@ -137,11 +138,8 @@ private:
|
|||
void tryReadProxyData(Buffer::Instance& data);
|
||||
|
||||
// Helper function to share the metadata with other filters.
|
||||
void updatePeer(const std::string& fb);
|
||||
void updatePeerId(absl::string_view key, absl::string_view value);
|
||||
|
||||
// Helper function to get Dynamic metadata.
|
||||
void getMetadata(google::protobuf::Struct* metadata);
|
||||
void updatePeer(const Istio::Common::WorkloadMetadataObject& obj, FilterDirection direction);
|
||||
void updatePeer(const Istio::Common::WorkloadMetadataObject& obj);
|
||||
|
||||
// Helper function to get metadata id.
|
||||
std::string getMetadataId();
|
||||
|
@ -163,7 +161,7 @@ private:
|
|||
const std::string ExchangeMetadataHeader = "x-envoy-peer-metadata";
|
||||
const std::string ExchangeMetadataHeaderId = "x-envoy-peer-metadata-id";
|
||||
|
||||
// Type url of google::protobug::struct.
|
||||
// Type url of google::protobuf::struct.
|
||||
const std::string StructTypeUrl = "type.googleapis.com/google.protobuf.Struct";
|
||||
|
||||
// Captures the state machine of what is going on in the filter.
|
||||
|
|
|
@ -56,9 +56,12 @@ class MetadataExchangeFilterTest : public testing::Test {
|
|||
public:
|
||||
MetadataExchangeFilterTest() { ENVOY_LOG_MISC(info, "test"); }
|
||||
|
||||
void initialize() {
|
||||
void initialize() { initialize(absl::flat_hash_set<std::string>()); }
|
||||
|
||||
void initialize(absl::flat_hash_set<std::string> additional_labels) {
|
||||
config_ = std::make_shared<MetadataExchangeConfig>(
|
||||
stat_prefix_, "istio2", FilterDirection::Downstream, false, context_, *scope_.rootScope());
|
||||
stat_prefix_, "istio2", FilterDirection::Downstream, false, additional_labels, context_,
|
||||
*scope_.rootScope());
|
||||
filter_ = std::make_unique<MetadataExchangeFilter>(config_, local_info_);
|
||||
filter_->initializeReadFilterCallbacks(read_filter_callbacks_);
|
||||
filter_->initializeWriteFilterCallbacks(write_filter_callbacks_);
|
||||
|
@ -117,6 +120,29 @@ TEST_F(MetadataExchangeFilterTest, MetadataExchangeFound) {
|
|||
EXPECT_EQ(1UL, config_->stats().alpn_protocol_found_.value());
|
||||
}
|
||||
|
||||
TEST_F(MetadataExchangeFilterTest, MetadataExchangeAdditionalLabels) {
|
||||
initialize({"role"});
|
||||
initializeStructValues();
|
||||
|
||||
EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol()).WillRepeatedly(Return("istio2"));
|
||||
|
||||
::Envoy::Buffer::OwnedImpl data;
|
||||
MetadataExchangeInitialHeader initial_header;
|
||||
Envoy::ProtobufWkt::Any productpage_any_value;
|
||||
productpage_any_value.set_type_url("type.googleapis.com/google.protobuf.Struct");
|
||||
*productpage_any_value.mutable_value() = productpage_value_.SerializeAsString();
|
||||
ConstructProxyHeaderData(data, productpage_any_value, &initial_header);
|
||||
::Envoy::Buffer::OwnedImpl world{"world"};
|
||||
data.add(world);
|
||||
|
||||
EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onData(data, false));
|
||||
EXPECT_EQ(data.toString(), "world");
|
||||
|
||||
EXPECT_EQ(0UL, config_->stats().initial_header_not_found_.value());
|
||||
EXPECT_EQ(0UL, config_->stats().header_not_found_.value());
|
||||
EXPECT_EQ(1UL, config_->stats().alpn_protocol_found_.value());
|
||||
}
|
||||
|
||||
TEST_F(MetadataExchangeFilterTest, MetadataExchangeNotFound) {
|
||||
initialize();
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ func (v *verify) Run(p *Params) error {
|
|||
return fmt.Errorf("timed out waiting for all metrics to match")
|
||||
}
|
||||
}
|
||||
|
||||
func (v *verify) Cleanup() {
|
||||
}
|
||||
|
||||
|
|
|
@ -128,3 +128,42 @@ func TestNativeHTTPExchange(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPExchangeAdditionalLabels(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests)
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_native_inbound_labels.yaml.tmpl")
|
||||
// TCP MX should not break HTTP MX when there is no TCP prefix or TCP MX ALPN.
|
||||
params.Vars["ServerNetworkFilters"] = params.LoadTestData("testdata/filters/server_mx_network_filter.yaml.tmpl")
|
||||
metadata := EncodeMetadata(t, params)
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{Node: "server", Version: "0", Listeners: []string{driver.LoadTestData("testdata/listener/server.yaml.tmpl")}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl"), Concurrency: 2},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.Repeat{
|
||||
// Must be high enough to exercise cache eviction.
|
||||
N: 1000,
|
||||
Step: &driver.HTTPCall{
|
||||
IP: "127.0.0.2",
|
||||
Port: params.Ports.ServerPort,
|
||||
Body: "hello, world!",
|
||||
RequestHeaders: map[string]string{
|
||||
"x-envoy-peer-metadata-id": "client{{ .N }}",
|
||||
"x-envoy-peer-metadata": metadata,
|
||||
},
|
||||
ResponseHeaders: map[string]string{
|
||||
"x-envoy-peer-metadata-id": "server",
|
||||
"x-envoy-peer-metadata": driver.Any,
|
||||
},
|
||||
},
|
||||
},
|
||||
&driver.Stats{AdminPort: params.Ports.ServerAdmin, Matchers: map[string]driver.StatMatcher{
|
||||
"envoy_server_envoy_bug_failures": &driver.ExactStat{Metric: "testdata/metric/envoy_bug_failures.yaml"},
|
||||
}},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,12 +34,14 @@ func init() {
|
|||
"TestPassthroughCONNECT/h2",
|
||||
"TestHTTPExchange",
|
||||
"TestNativeHTTPExchange",
|
||||
"TestHTTPLocalRatelimit",
|
||||
"TestHTTPExchangeAdditionalLabels",
|
||||
"TestStats403Failure/#00",
|
||||
"TestStatsECDS/#00",
|
||||
"TestStatsEndpointLabels/#00",
|
||||
"TestStatsServerWaypointProxy",
|
||||
"TestStatsServerWaypointProxyCONNECT",
|
||||
"TestStatsServerWaypointProxyCONNECT/full_metadata",
|
||||
"TestStatsServerWaypointProxyCONNECT/empty_metadata",
|
||||
"TestTCPStatsServerWaypointProxyCONNECT",
|
||||
"TestStatsGrpc/#00",
|
||||
"TestStatsGrpcStream/#00",
|
||||
"TestStatsParallel/Default",
|
||||
|
@ -54,8 +56,10 @@ func init() {
|
|||
"TestTCPMetadataExchange/true",
|
||||
"TestTCPMetadataExchangeNoAlpn",
|
||||
"TestTCPMetadataExchangeWithConnectionTermination",
|
||||
"TestOtelPayload",
|
||||
"TestTCPMetadataNotFoundReporting",
|
||||
"TestStatsDestinationServiceNamespacePrecedence",
|
||||
"TestAdditionalLabels",
|
||||
"TestTCPMXAdditionalLabels",
|
||||
"TestStatsClientSidecarCONNECT",
|
||||
}...)
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright Istio Authors
|
||||
//
|
||||
// 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 otel
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"istio.io/proxy/test/envoye2e"
|
||||
"istio.io/proxy/test/envoye2e/driver"
|
||||
)
|
||||
|
||||
func enableMetadataExchange(t *testing.T, params *driver.Params) {
|
||||
t.Helper()
|
||||
params.Vars["ClientMetadata"] = driver.LoadTestData("testdata/client_node_metadata.json.tmpl")
|
||||
params.Vars["ServerMetadata"] = driver.LoadTestData("testdata/server_node_metadata.json.tmpl")
|
||||
params.Vars["ClientHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_native_outbound.yaml.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_native_inbound.yaml.tmpl")
|
||||
}
|
||||
|
||||
func enableOtelMetrics(t *testing.T, params *driver.Params, port uint16) {
|
||||
t.Helper()
|
||||
params.Vars["StatsConfig"] = driver.LoadTestData("testdata/bootstrap/otel_stats.yaml.tmpl")
|
||||
params.Vars["ClientHTTPFilters"] += "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] += "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl")
|
||||
params.Vars["OtelPort"] = strconv.Itoa(int(port))
|
||||
params.Vars["ClientStaticCluster"] = params.LoadTestData("testdata/cluster/otel.yaml.tmpl")
|
||||
params.Vars["ServerStaticCluster"] = params.LoadTestData("testdata/cluster/otel.yaml.tmpl")
|
||||
}
|
||||
|
||||
func TestOtelPayload(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests)
|
||||
port := params.Ports.Max
|
||||
enableMetadataExchange(t, params)
|
||||
enableOtelMetrics(t, params, port)
|
||||
otel := &driver.Otel{
|
||||
Port: port,
|
||||
Metrics: []string{
|
||||
"testdata/otel/client_request_count.yaml.tmpl",
|
||||
"testdata/otel/server_request_count.yaml.tmpl",
|
||||
},
|
||||
}
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
otel,
|
||||
&driver.Update{Node: "client", Version: "0", Listeners: []string{driver.LoadTestData("testdata/listener/client.yaml.tmpl")}},
|
||||
&driver.Update{Node: "server", Version: "0", Listeners: []string{driver.LoadTestData("testdata/listener/server.yaml.tmpl")}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.Repeat{N: 10, Step: driver.Get(params.Ports.ClientPort, "hello, world!")},
|
||||
otel.Wait(),
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright 2021 Istio Authors
|
||||
//
|
||||
// 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 ratelimit_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"istio.io/proxy/test/envoye2e"
|
||||
"istio.io/proxy/test/envoye2e/driver"
|
||||
)
|
||||
|
||||
// TestHTTPLocalRatelimit validates that envoy can rate limit based on:
|
||||
// - source attribute, produced by MX extension
|
||||
// - request header
|
||||
func TestHTTPLocalRatelimit(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests)
|
||||
params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl")
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl")
|
||||
params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_native_outbound.yaml.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_native_inbound.yaml.tmpl") + "\n" +
|
||||
params.LoadTestData("testdata/filters/local_ratelimit_inbound.yaml.tmpl")
|
||||
params.Vars["ServerRouteRateLimits"] = `
|
||||
rate_limits:
|
||||
- actions:
|
||||
- request_headers:
|
||||
header_name: user-id
|
||||
descriptor_key: id
|
||||
- extension:
|
||||
name: custom
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: type.googleapis.com/envoy.extensions.rate_limit_descriptors.expr.v3.Descriptor
|
||||
value:
|
||||
descriptor_key: app
|
||||
text: filter_state['wasm.downstream_peer'].labels['app'].value`
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{Node: "client", Version: "0", Listeners: []string{driver.LoadTestData("testdata/listener/client.yaml.tmpl")}},
|
||||
&driver.Update{Node: "server", Version: "0", Listeners: []string{driver.LoadTestData("testdata/listener/server.yaml.tmpl")}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.HTTPCall{
|
||||
Port: params.Ports.ClientPort,
|
||||
Body: "hello, world!",
|
||||
},
|
||||
// Only first call should pass with 1req/minute
|
||||
&driver.HTTPCall{
|
||||
Port: params.Ports.ClientPort,
|
||||
RequestHeaders: map[string]string{"user-id": "foo"},
|
||||
ResponseCode: 200,
|
||||
},
|
||||
&driver.HTTPCall{
|
||||
Port: params.Ports.ClientPort,
|
||||
RequestHeaders: map[string]string{"user-id": "foo"},
|
||||
ResponseCode: 429,
|
||||
Body: "local_rate_limited",
|
||||
},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -602,6 +602,14 @@ canonical_revision: version-1
|
|||
uid: //v1/pod/default/ratings
|
||||
service_account: ratings
|
||||
trust_domain: cluster.global
|
||||
cluster_id: ratings-cluster
|
||||
`
|
||||
|
||||
// A mostly empty metadata.
|
||||
// All workloads are guaranteed to have a UID and ought to have a namespace as well.
|
||||
const EmptyMetadata = `
|
||||
uid: //v1/pod/default/ratings
|
||||
namespace: default
|
||||
`
|
||||
|
||||
const ProductPageMetadata = `
|
||||
|
@ -654,7 +662,94 @@ func TestStatsServerWaypointProxy(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStatsClientSidecarCONNECT(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"RequestCount": "10",
|
||||
"EnableDelta": "true",
|
||||
"EnableMetadataDiscovery": "true",
|
||||
"StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_config.yaml"),
|
||||
"StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_config.yaml"),
|
||||
}, envoye2e.ProxyE2ETests)
|
||||
params.Vars["ServerClusterName"] = "internal_outbound"
|
||||
params.Vars["ServerInternalAddress"] = "internal_inbound"
|
||||
params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl")
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_waypoint_proxy_node_metadata.json.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_waypoint.yaml.tmpl") + "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl")
|
||||
params.Vars["EnableTunnelEndpointMetadata"] = "true"
|
||||
params.Vars["EnableOriginalDstPortOverride"] = "true"
|
||||
params.Vars["ClientHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_native_outbound.yaml.tmpl") + "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl")
|
||||
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{
|
||||
Node: "client", Version: "0",
|
||||
Clusters: []string{
|
||||
driver.LoadTestData("testdata/cluster/internal_outbound.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/cluster/original_dst.yaml.tmpl"),
|
||||
},
|
||||
Listeners: []string{
|
||||
driver.LoadTestData("testdata/listener/client.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/listener/internal_outbound.yaml.tmpl"),
|
||||
},
|
||||
Secrets: []string{
|
||||
driver.LoadTestData("testdata/secret/client.yaml.tmpl"),
|
||||
},
|
||||
},
|
||||
&driver.Update{
|
||||
Node: "server", Version: "0",
|
||||
Clusters: []string{
|
||||
driver.LoadTestData("testdata/cluster/internal_inbound.yaml.tmpl"),
|
||||
},
|
||||
Listeners: []string{
|
||||
driver.LoadTestData("testdata/listener/terminate_connect.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/listener/server.yaml.tmpl"),
|
||||
},
|
||||
Secrets: []string{
|
||||
driver.LoadTestData("testdata/secret/server.yaml.tmpl"),
|
||||
},
|
||||
},
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: ProductPageMetadata,
|
||||
}, {
|
||||
Address: "127.0.0.2", // We're going to pretend our server is a mesh service
|
||||
Metadata: BackendMetadata,
|
||||
}}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.Repeat{
|
||||
N: 10,
|
||||
Step: &driver.HTTPCall{
|
||||
Port: params.Ports.ClientPort,
|
||||
ResponseCode: 200,
|
||||
},
|
||||
},
|
||||
&driver.Stats{
|
||||
AdminPort: params.Ports.ClientAdmin,
|
||||
Matchers: map[string]driver.StatMatcher{
|
||||
"istio_requests_total": &driver.ExactStat{Metric: "testdata/metric/client_sidecar_connect_request_total.yaml.tmpl"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatsServerWaypointProxyCONNECT(t *testing.T) {
|
||||
t.Run("full metadata", func(t *testing.T) {
|
||||
runStatsServerWaypointProxyCONNECT(t, BackendMetadata, "testdata/metric/server_waypoint_proxy_connect_request_total.yaml.tmpl")
|
||||
})
|
||||
t.Run("empty metadata", func(t *testing.T) {
|
||||
runStatsServerWaypointProxyCONNECT(t, EmptyMetadata, "testdata/metric/server_waypoint_proxy_connect_emptymeta_request_total.yaml.tmpl")
|
||||
})
|
||||
}
|
||||
|
||||
func runStatsServerWaypointProxyCONNECT(t *testing.T, backendMetadata string, metricResult string) {
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"RequestCount": "10",
|
||||
"EnableDelta": "true",
|
||||
|
@ -704,7 +799,7 @@ func TestStatsServerWaypointProxyCONNECT(t *testing.T) {
|
|||
Metadata: ProductPageMetadata,
|
||||
}, {
|
||||
Address: "127.0.0.3",
|
||||
Metadata: BackendMetadata,
|
||||
Metadata: backendMetadata,
|
||||
}}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
|
@ -719,7 +814,80 @@ func TestStatsServerWaypointProxyCONNECT(t *testing.T) {
|
|||
&driver.Stats{
|
||||
AdminPort: params.Ports.ServerAdmin,
|
||||
Matchers: map[string]driver.StatMatcher{
|
||||
"istio_requests_total": &driver.ExactStat{Metric: "testdata/metric/server_waypoint_proxy_connect_request_total.yaml.tmpl"},
|
||||
"istio_requests_total": &driver.ExactStat{Metric: metricResult},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPStatsServerWaypointProxyCONNECT(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"EnableDelta": "true",
|
||||
"EnableMetadataDiscovery": "true",
|
||||
"DisableDirectResponse": "true",
|
||||
"ConnectionCount": "10",
|
||||
"StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_waypoint_proxy_config.yaml"),
|
||||
}, envoye2e.ProxyE2ETests)
|
||||
params.Vars["ServerClusterName"] = "internal_outbound"
|
||||
params.Vars["ServerInternalAddress"] = "internal_inbound"
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_waypoint_proxy_node_metadata.json.tmpl")
|
||||
params.Vars["ServerNetworkFilters"] = driver.LoadTestData("testdata/filters/mx_waypoint_tcp.yaml.tmpl") + "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl")
|
||||
params.Vars["EnableTunnelEndpointMetadata"] = "true"
|
||||
params.Vars["EnableOriginalDstPortOverride"] = "true"
|
||||
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{
|
||||
Node: "client", Version: "0",
|
||||
Clusters: []string{
|
||||
driver.LoadTestData("testdata/cluster/internal_outbound.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/cluster/original_dst.yaml.tmpl"),
|
||||
},
|
||||
Listeners: []string{
|
||||
driver.LoadTestData("testdata/listener/tcp_client.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/listener/internal_outbound.yaml.tmpl"),
|
||||
},
|
||||
Secrets: []string{
|
||||
driver.LoadTestData("testdata/secret/client.yaml.tmpl"),
|
||||
},
|
||||
},
|
||||
&driver.Update{
|
||||
Node: "server", Version: "0",
|
||||
Clusters: []string{
|
||||
driver.LoadTestData("testdata/cluster/internal_inbound.yaml.tmpl"),
|
||||
},
|
||||
Listeners: []string{
|
||||
driver.LoadTestData("testdata/listener/terminate_connect.yaml.tmpl"),
|
||||
driver.LoadTestData("testdata/listener/tcp_waypoint_server.yaml.tmpl"),
|
||||
},
|
||||
Secrets: []string{
|
||||
driver.LoadTestData("testdata/secret/server.yaml.tmpl"),
|
||||
},
|
||||
},
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: ProductPageMetadata,
|
||||
}, {
|
||||
Address: "127.0.0.3",
|
||||
Metadata: BackendMetadata,
|
||||
}}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.TCPServer{Prefix: "hello"},
|
||||
&driver.Repeat{
|
||||
N: 10,
|
||||
Step: &driver.TCPConnection{},
|
||||
},
|
||||
&driver.Stats{
|
||||
AdminPort: params.Ports.ServerAdmin,
|
||||
Matchers: map[string]driver.StatMatcher{
|
||||
"istio_tcp_connections_opened_total": &driver.ExactStat{Metric: "testdata/metric/server_waypoint_proxy_connect_connections_opened_total.yaml.tmpl"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -761,6 +929,7 @@ func TestStatsExpiry(t *testing.T) {
|
|||
&driver.Sleep{Duration: 4 * time.Second},
|
||||
&driver.Stats{AdminPort: params.Ports.ClientAdmin, Matchers: map[string]driver.StatMatcher{
|
||||
"istio_requests_total": &driver.MissingStat{Metric: "istio_requests_total"},
|
||||
"istio_build": &driver.ExactStat{Metric: "testdata/metric/istio_build.yaml"},
|
||||
}},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
|
@ -807,3 +976,50 @@ func TestStatsDestinationServiceNamespacePrecedence(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdditionalLabels(t *testing.T) {
|
||||
env.SkipTSan(t)
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"RequestCount": "10",
|
||||
"StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_additional_labels.yaml"),
|
||||
"StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_additional_labels.yaml"),
|
||||
"ResponseCodeClass": "2xx",
|
||||
}, envoye2e.ProxyE2ETests)
|
||||
params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl")
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl")
|
||||
params.Vars["ServerHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_native_inbound_labels.yaml.tmpl") + "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl")
|
||||
params.Vars["ClientHTTPFilters"] = driver.LoadTestData("testdata/filters/mx_native_outbound_labels.yaml.tmpl") + "\n" +
|
||||
driver.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl")
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{Node: "client", Version: "0", Listeners: []string{params.LoadTestData("testdata/listener/client.yaml.tmpl")}},
|
||||
&driver.Update{Node: "server", Version: "0", Listeners: []string{params.LoadTestData("testdata/listener/server.yaml.tmpl")}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.Repeat{
|
||||
N: 10,
|
||||
Step: &driver.HTTPCall{
|
||||
Port: params.Ports.ClientPort,
|
||||
Body: "hello, world!",
|
||||
},
|
||||
},
|
||||
&driver.Stats{
|
||||
AdminPort: params.Ports.ServerAdmin,
|
||||
Matchers: map[string]driver.StatMatcher{
|
||||
"istio_requests_total": &driver.ExactStat{Metric: "testdata/metric/server_request_total_labels.yaml.tmpl"},
|
||||
},
|
||||
},
|
||||
&driver.Stats{
|
||||
AdminPort: params.Ports.ClientAdmin,
|
||||
Matchers: map[string]driver.StatMatcher{
|
||||
"istio_requests_total": &driver.ExactStat{Metric: "testdata/metric/client_request_total_labels.yaml.tmpl"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,9 +66,10 @@ func TestTCPMetadataExchange(t *testing.T) {
|
|||
Clusters: []string{params.LoadTestData("testdata/cluster/tcp_server.yaml.tmpl")},
|
||||
Listeners: []string{params.LoadTestData("testdata/listener/tcp_server.yaml.tmpl")},
|
||||
},
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: `
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{
|
||||
{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: `
|
||||
namespace: default
|
||||
workload_name: productpage-v1
|
||||
workload_type: DEPLOYMENT
|
||||
|
@ -76,9 +77,10 @@ canonical_name: productpage-v1
|
|||
canonical_revision: version-1
|
||||
cluster_id: client-cluster
|
||||
uid: //v1/pod/default/productpage
|
||||
`}, {
|
||||
Address: "127.0.0.2",
|
||||
Metadata: `
|
||||
`,
|
||||
}, {
|
||||
Address: "127.0.0.2",
|
||||
Metadata: `
|
||||
namespace: default
|
||||
workload_name: ratings-v1
|
||||
workload_type: DEPLOYMENT
|
||||
|
@ -86,7 +88,8 @@ canonical_name: ratings
|
|||
canonical_revision: version-1
|
||||
cluster_id: server-cluster
|
||||
uid: //v1/pod/default/ratings
|
||||
`},
|
||||
`,
|
||||
},
|
||||
}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
|
@ -117,6 +120,68 @@ uid: //v1/pod/default/ratings
|
|||
}
|
||||
}
|
||||
|
||||
func TestTCPMXAdditionalLabels(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"DisableDirectResponse": "true",
|
||||
"StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"),
|
||||
}, envoye2e.ProxyE2ETests)
|
||||
mxStats := map[string]driver.StatMatcher{
|
||||
"envoy_metadata_exchange_metadata_added": &driver.ExactStat{Metric: "testdata/metric/tcp_server_mx_stats_metadata_added.yaml.tmpl"},
|
||||
}
|
||||
params.Vars["AlpnProtocol"] = "mx-protocol"
|
||||
mxStats["envoy_metadata_exchange_alpn_protocol_found"] = &driver.ExactStat{Metric: "testdata/metric/tcp_server_mx_stats_alpn_found.yaml.tmpl"}
|
||||
params.Vars["EnableAdditionalLabels"] = "true"
|
||||
params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl")
|
||||
params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl")
|
||||
params.Vars["ServerNetworkFilters"] = params.LoadTestData("testdata/filters/server_mx_network_filter.yaml.tmpl") + "\n" +
|
||||
params.LoadTestData("testdata/filters/server_stats_network_filter.yaml.tmpl")
|
||||
params.Vars["ClientUpstreamFilters"] = params.LoadTestData("testdata/filters/client_mx_network_filter.yaml.tmpl")
|
||||
params.Vars["ClientNetworkFilters"] = params.LoadTestData("testdata/filters/client_stats_network_filter.yaml.tmpl")
|
||||
params.Vars["ClientClusterTLSContext"] = params.LoadTestData("testdata/transport_socket/client.yaml.tmpl")
|
||||
params.Vars["ServerListenerTLSContext"] = params.LoadTestData("testdata/transport_socket/server.yaml.tmpl")
|
||||
|
||||
if err := (&driver.Scenario{
|
||||
Steps: []driver.Step{
|
||||
&driver.XDS{},
|
||||
&driver.Update{
|
||||
Node: "client",
|
||||
Version: "0",
|
||||
Clusters: []string{params.LoadTestData("testdata/cluster/tcp_client.yaml.tmpl")},
|
||||
Listeners: []string{params.LoadTestData("testdata/listener/tcp_client.yaml.tmpl")},
|
||||
},
|
||||
&driver.Update{
|
||||
Node: "server",
|
||||
Version: "0",
|
||||
Clusters: []string{params.LoadTestData("testdata/cluster/tcp_server.yaml.tmpl")},
|
||||
Listeners: []string{params.LoadTestData("testdata/listener/tcp_server.yaml.tmpl")},
|
||||
},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
&driver.TCPServer{Prefix: "hello"},
|
||||
&driver.Repeat{
|
||||
N: 10,
|
||||
Step: &driver.TCPConnection{},
|
||||
},
|
||||
&driver.Stats{AdminPort: params.Ports.ClientAdmin, Matchers: map[string]driver.StatMatcher{
|
||||
"istio_tcp_connections_closed_total": &driver.ExactStat{Metric: "testdata/metric/tcp_client_connection_close.yaml.tmpl"},
|
||||
"istio_tcp_connections_opened_total": &driver.ExactStat{Metric: "testdata/metric/tcp_client_connection_open.yaml.tmpl"},
|
||||
"istio_tcp_received_bytes_total": &driver.ExactStat{Metric: "testdata/metric/tcp_client_received_bytes.yaml.tmpl"},
|
||||
"istio_tcp_sent_bytes_total": &driver.ExactStat{Metric: "testdata/metric/tcp_client_sent_bytes.yaml.tmpl"},
|
||||
}},
|
||||
&driver.Stats{AdminPort: params.Ports.ServerAdmin, Matchers: map[string]driver.StatMatcher{
|
||||
"istio_tcp_connections_closed_total": &driver.ExactStat{Metric: "testdata/metric/tcp_server_connection_close.yaml.tmpl"},
|
||||
"istio_tcp_connections_opened_total": &driver.ExactStat{Metric: "testdata/metric/tcp_server_connection_open.yaml.tmpl"},
|
||||
"istio_tcp_received_bytes_total": &driver.ExactStat{Metric: "testdata/metric/tcp_server_received_bytes.yaml.tmpl"},
|
||||
"istio_tcp_sent_bytes_total": &driver.ExactStat{Metric: "testdata/metric/tcp_server_sent_bytes.yaml.tmpl"},
|
||||
}},
|
||||
&driver.Stats{AdminPort: params.Ports.ServerAdmin, Matchers: mxStats},
|
||||
},
|
||||
}).Run(params); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPMetadataExchangeNoAlpn(t *testing.T) {
|
||||
params := driver.NewTestParams(t, map[string]string{
|
||||
"DisableDirectResponse": "true",
|
||||
|
@ -234,9 +299,10 @@ func TestTCPMetadataNotFoundReporting(t *testing.T) {
|
|||
Clusters: []string{params.LoadTestData("testdata/cluster/tcp_client_unknown.yaml.tmpl")},
|
||||
Listeners: []string{params.LoadTestData("testdata/listener/tcp_client.yaml.tmpl")},
|
||||
},
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: `
|
||||
&driver.UpdateWorkloadMetadata{Workloads: []driver.WorkloadMetadata{
|
||||
{
|
||||
Address: "127.0.0.1",
|
||||
Metadata: `
|
||||
namespace: default
|
||||
workload_name: productpage-v1
|
||||
workload_type: DEPLOYMENT
|
||||
|
@ -244,7 +310,8 @@ canonical_name: productpage-v1
|
|||
canonical_revision: version-1
|
||||
cluster_id: client-cluster
|
||||
uid: //v1/pod/default/productpage
|
||||
`},
|
||||
`,
|
||||
},
|
||||
}},
|
||||
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
|
||||
&driver.Sleep{Duration: 1 * time.Second},
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAte/T9swhDpn0WlUtkdcE6giqD5/ixS5PbkaNvz9a4rw1CnJ/
|
||||
MxXlNJLURPhEzlVqyWfFqAui6ibHr/fKYKqvZKhMJo7FwAXw0FXYkYm4pG6RuV1f
|
||||
RpPaMQTLfox4ojQ5hbEM65+yNiGRxTq6opbuH6oYoHGNyaOsl28GfUSwF37PbhGt
|
||||
9IaVp1tPHg+SMTJ8eFT46+NjoxizMZxPW8l1xphqhrWPv0qUbVtWRV5emTpu6iks
|
||||
yFxNu6yivNJsKqeHrZZDb0LnCFkNA4jKhM+kw6Bq0Tej4zb8AFVIgAp8RUNgvPGt
|
||||
pyUWa7dL6UNd0P+6QXy52Y5vrVZRIc5pNxjlswIDAQABAoIBAAgF3WkCs2p7a4UY
|
||||
QHwv6S2Q2D78I/niAuqv/cwzNQTOm+AsEGPmUUcyOl4YPKCEr8LV6qdwa+y7bQ7b
|
||||
dHcyz602prUEkr/XAzmMr5IrapMFtTNhZLQuDO8gcQDRnPg6KVc16YXyct9kN5Nk
|
||||
9Zn54eJPk+pvV3tO1muPH9AiWUmP4PFxnjYQTQwA9jj7s1diYqK+9cr+BpkiI5IA
|
||||
WVVAOwse6KuStb0hQM3YyoUMQ7zxepCi4cgjFeXfPWblFsQrml46Xc3LsYKh19e6
|
||||
NxfFJ1833yYUzmy34hNPH0ZARtMcx/8FU4v2LvjR544cLioI8mtqfXd43UjlBS2r
|
||||
/iBewaECgYEA5EeXPPHvdM58Vg0XZCGCZME244jTl7KAnMP9ThM8+I0Ypn6M6Ids
|
||||
HX83682b2BZfW2MfhWs7HvO9/g4qgycLrL2EM2JICtzCcOKe3FExB/jwnrTO3D54
|
||||
DzIXxU9JL1/E09Bdkte5t4hEJ2RvswPMCUejOT6Hjnf9BvocxO8/SDsCgYEAzAea
|
||||
LyJB0JDD2NPa61oe0UgShS5IhmOvO8wOUnWWNP/s6pxSWO0yF1eWAfTEZ5PuyO6M
|
||||
t5KOT9NY0/kFTg/6PDcMNqhlZXFFQArDadzJvS32+/L1DD9hqsunZ25yi30uMpa2
|
||||
9JsuKra6JtIX2bsIbGHDdL0wn4CdqwBv7qgl+OkCgYAoATfK0WcyZCE7/01TGeA9
|
||||
AfM5irfyBLEvR9VzQkHUGP3x54mQEnNq8+l75GtkQf9yB3v1qKYStYpdJGRk2Ynd
|
||||
OtUZICcZ6DgXCk/msj/SctjQJ0V9KWFm4FN0G4Hq0HCw4foUCsQcGsA+2wYMLCUs
|
||||
lyZOmNuupu5rs5cpF/hSEwKBgQCXRGem3GIpTLs3LdMYPOeuSB4bCbaRlKSd0+sm
|
||||
bbGgt8IiKyXOcoV50uEPsDZRiNc3t80yaQED4/Dur6ikOKpRLIrslysd673o/lHl
|
||||
UeFsVgDQyU+u9ermYzlJMRTRoEy5Cw64CblPx8v57jfqoIVdPZpZGc9L4mKDHr7e
|
||||
FWKZyQKBgHZCTc6SHxbWYJX8fIEc4gpQiKs60MNj8Gt+dorn0mx5RvbRw8aNwenJ
|
||||
UUk0O8HBQtJ74giSAY/iLa8LCqTIPvwTYOjahZvdSqtQhmGawebye70jJ703JLmm
|
||||
uCkUhbGCgaCjciAIYMdHToZhWX2AHgou1aZcmnktJpxx6zEZ3RWb
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,21 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDgzCCAmugAwIBAgIUWuIdooRJ4EbBKVPXu4RxWMjdNb0wDQYJKoZIhvcNAQEL
|
||||
BQAwUTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMSEwHwYDVQQKDBhJbnRlcm5l
|
||||
dCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMDAyMjAw
|
||||
MDM1NTNaFw0zMDAyMTcwMDM1NTNaMFExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD
|
||||
QTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAls
|
||||
b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC179P2zCEO
|
||||
mfRaVS2R1wTqCKoPn+LFLk9uRo2/P1rivDUKcn8zFeU0ktRE+ETOVWrJZ8WoC6Lq
|
||||
Jsev98pgqq9kqEwmjsXABfDQVdiRibikbpG5XV9Gk9oxBMt+jHiiNDmFsQzrn7I2
|
||||
IZHFOrqilu4fqhigcY3Jo6yXbwZ9RLAXfs9uEa30hpWnW08eD5IxMnx4VPjr42Oj
|
||||
GLMxnE9byXXGmGqGtY+/SpRtW1ZFXl6ZOm7qKSzIXE27rKK80mwqp4etlkNvQucI
|
||||
WQ0DiMqEz6TDoGrRN6PjNvwAVUiACnxFQ2C88a2nJRZrt0vpQ13Q/7pBfLnZjm+t
|
||||
VlEhzmk3GOWzAgMBAAGjUzBRMB0GA1UdDgQWBBRHexBONqhsiM5OtjGMI0zNS2O9
|
||||
kDAfBgNVHSMEGDAWgBRHexBONqhsiM5OtjGMI0zNS2O9kDAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCPupx7dcgg0W92x40VsOxNs1mkVcM1pTeV
|
||||
OFykviaGwmSuNivIWilhV2Ap2DUlLa/FyR7ZIbJEKOdaREQD9p9dO03ZZTsSexKn
|
||||
9Cqkdv6J+a4AjNAyvqMKv8J6uGBiLLyDdwAInVUz5F4VcRf1BfzF8TW48wBHsZKr
|
||||
buG4AC68BJ5NdwaZ704kwq4ymNaQNMccna5tBDBumqy06uRdbw6lB9lCqDuc+DQV
|
||||
i8IdktB8ppiQmsXYNirnd5VhUykO/LknObcv3Y4rbqj+JLAWHrR4ibpdn1e+85by
|
||||
ZxVLTAnP6SvWwtvswDXLRXIAtAzK5m5Nl0MNg6KjG3U4I1yV/Ps3
|
||||
-----END CERTIFICATE-----
|
|
@ -10,7 +10,8 @@
|
|||
"pod-template-hash": "84975bc778",
|
||||
"version": "v1",
|
||||
"service.istio.io/canonical-name": "productpage-v1",
|
||||
"service.istio.io/canonical-revision": "version-1"
|
||||
"service.istio.io/canonical-revision": "version-1",
|
||||
"role": "client"
|
||||
},
|
||||
"MESH_ID": "mesh",
|
||||
"NAME": "productpage-v1-84975bc778-pxz2w",
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
name: internal_outbound
|
||||
metadata:
|
||||
filter_metadata:
|
||||
istio:
|
||||
services:
|
||||
- host: server.default.svc.cluster.local
|
||||
name: server
|
||||
namespace: default
|
||||
load_assignment:
|
||||
cluster_name: internal_outbound
|
||||
endpoints:
|
||||
|
@ -12,6 +19,8 @@ load_assignment:
|
|||
filter_metadata:
|
||||
envoy.filters.listener.original_dst:
|
||||
local: 127.0.0.2:{{ .Ports.ServerPort }}
|
||||
istio:
|
||||
workload: ratings-v1;default;ratings;version-1;server-cluster
|
||||
{{- end }}
|
||||
transport_socket:
|
||||
name: envoy.transport_sockets.internal_upstream
|
||||
|
|
|
@ -7,3 +7,7 @@
|
|||
{{- if eq .Vars.EnableMetadataDiscovery "true" }}
|
||||
enable_discovery: true
|
||||
{{- end }}
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
additional_labels:
|
||||
- role
|
||||
{{- end }}
|
||||
|
|
|
@ -18,4 +18,10 @@
|
|||
type_url: type.googleapis.com/stats.PluginConfig
|
||||
value:
|
||||
tcp_reporting_duration: 1s
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
metrics:
|
||||
- name: tcp_connections_opened_total
|
||||
dimensions:
|
||||
role: filter_state.upstream_peer.labels['role']
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
- name: ratelimit
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
|
||||
value:
|
||||
stat_prefix: rate_limit
|
||||
token_bucket:
|
||||
max_tokens: 1000
|
||||
tokens_per_fill: 1000
|
||||
fill_interval: 1s
|
||||
filter_enabled:
|
||||
runtime_key: local_rate_limit_enabled
|
||||
default_value: { numerator: 100, denominator: HUNDRED }
|
||||
filter_enforced:
|
||||
runtime_key: local_rate_limit_enforced
|
||||
default_value: { numerator: 100, denominator: HUNDRED }
|
||||
descriptors:
|
||||
- entries:
|
||||
- key: id
|
||||
value: foo
|
||||
- key: app
|
||||
value: productpage
|
||||
token_bucket:
|
||||
max_tokens: 1
|
||||
tokens_per_fill: 1
|
||||
fill_interval: 60s
|
|
@ -0,0 +1,11 @@
|
|||
- name: mx_inbound{{.N}}
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: type.googleapis.com/io.istio.http.peer_metadata.Config
|
||||
value:
|
||||
downstream_discovery:
|
||||
- istio_headers: {}
|
||||
downstream_propagation:
|
||||
- istio_headers: {}
|
||||
additional_labels:
|
||||
- role
|
|
@ -5,5 +5,6 @@
|
|||
value:
|
||||
upstream_discovery:
|
||||
- istio_headers: {}
|
||||
- workload_discovery: {}
|
||||
upstream_propagation:
|
||||
- istio_headers: {}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
- name: mx_outbound{{.N}}
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: type.googleapis.com/io.istio.http.peer_metadata.Config
|
||||
value:
|
||||
upstream_discovery:
|
||||
- istio_headers: {}
|
||||
upstream_propagation:
|
||||
- istio_headers: {}
|
||||
additional_labels:
|
||||
- role
|
|
@ -0,0 +1,7 @@
|
|||
- name: tc_mx_inbound{{.N}}
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange
|
||||
value:
|
||||
protocol: "istio-peer-exchange"
|
||||
enable_discovery: true
|
|
@ -7,3 +7,7 @@
|
|||
{{- if eq .Vars.EnableMetadataDiscovery "true" }}
|
||||
enable_discovery: true
|
||||
{{- end }}
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
additional_labels:
|
||||
- role
|
||||
{{- end }}
|
||||
|
|
|
@ -18,4 +18,10 @@
|
|||
type_url: type.googleapis.com/stats.PluginConfig
|
||||
value:
|
||||
tcp_reporting_duration: 1s
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
metrics:
|
||||
- name: tcp_connections_opened_total
|
||||
dimensions:
|
||||
role: filter_state.downstream_peer.labels['role']
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
- name: stackdriver_inbound
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.http.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_inbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_inbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_inbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{"enable_audit_log": true, "metric_expiry_duration": "10s", "metrics_overrides": {"server/request_count":{"tag_overrides":{"api_version":"'v12'"}}, "server/request_bytes":{"drop": true}, "server/connection_open_count":{"tag_overrides":{"mesh_uid":"'override'", "foo":"'ignored'"}}}}
|
|
@ -1,20 +0,0 @@
|
|||
- name: stackdriver_inbound
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.http.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_inbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_inbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_inbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{"access_logging_filter_expression": "request.headers['x-filter'] != 'filter'"}
|
|
@ -1,20 +0,0 @@
|
|||
- name: envoy.filters.network.wasm
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.network.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_inbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_inbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_inbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{"metrics_overrides": {"server/request_bytes":{"drop": true}, "server/connection_open_count":{"tag_overrides":{"mesh_uid":"'override'"}}}}
|
|
@ -1,20 +0,0 @@
|
|||
- name: envoy.filters.network.wasm
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.network.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_outbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_outbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_outbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{"access_logging": "FULL", "metrics_overrides": {"client/request_bytes":{"drop": true}, "client/request_count":{"tag_overrides":{"request_operation":"'override'"}}}}
|
|
@ -1,26 +0,0 @@
|
|||
- name: stackdriver_outbound
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.http.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_outbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_outbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_outbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{{- if .Vars.JustSendErrorClientLog }}
|
||||
{"access_logging": "ERRORS_ONLY", "enable_audit_log": true, "metrics_overrides": {"client/request_bytes":{"drop": true}, "client/request_count":{"tag_overrides":{"request_operation":"'override'"}}}}
|
||||
{{- else if .Vars.StackdriverFilterCustomClientConfig }}
|
||||
{{ .Vars.StackdriverFilterCustomClientConfig | fill }}
|
||||
{{- else }}
|
||||
{"access_logging": "FULL", "enable_audit_log": true, "metrics_overrides": {"client/request_bytes":{"drop": true}, "client/request_count":{"tag_overrides":{"request_operation":"'override'"}}}}
|
||||
{{- end }}
|
|
@ -1,20 +0,0 @@
|
|||
- name: stackdriver_outbound
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.http.wasm.v3.Wasm
|
||||
value:
|
||||
config:
|
||||
root_id: "stackdriver_outbound"
|
||||
vm_config:
|
||||
{{- if .Vars.ReloadVM }}
|
||||
vm_id: "stackdriver_outbound_{{ .Vars.Version }}"
|
||||
{{- else }}
|
||||
vm_id: "stackdriver_outbound"
|
||||
{{- end }}
|
||||
runtime: "envoy.wasm.runtime.null"
|
||||
code:
|
||||
local: { inline_string: "envoy.wasm.null.stackdriver" }
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{"access_logging": "FULL", "access_logging_filter_expression": "request.headers['x-filter'] != 'filter'"}
|
|
@ -20,4 +20,8 @@ filter_chains:
|
|||
type_url: envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
|
||||
value:
|
||||
stat_prefix: outbound_tcp
|
||||
{{- if .Vars.ServerClusterName }}
|
||||
cluster: {{ .Vars.ServerClusterName}}
|
||||
{{- else }}
|
||||
cluster: outbound|9080|tcp|server.default.svc.cluster.local
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
{{- if ne .Vars.ServerListeners "" }}
|
||||
{{ .Vars.ServerListeners }}
|
||||
{{- else }}
|
||||
{{- if ne .Vars.ServerInternalAddress "" }}
|
||||
name: {{ .Vars.ServerInternalAddress }}
|
||||
{{- else }}
|
||||
name: server
|
||||
{{- end }}
|
||||
traffic_direction: INBOUND
|
||||
{{- if ne .Vars.ServerInternalAddress "" }}
|
||||
internal_listener: {}
|
||||
{{- else }}
|
||||
address:
|
||||
socket_address:
|
||||
address: 127.0.0.2
|
||||
port_value: {{ .Ports.ServerPort }}
|
||||
{{- end }}
|
||||
filter_chains:
|
||||
- filters:
|
||||
{{ .Vars.ServerNetworkFilters | fill | indent 2 }}
|
||||
- name: tcp_proxy
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
|
||||
type_url: envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
|
||||
value:
|
||||
stat_prefix: server_inbound_tcp
|
||||
cluster: server-inbound-cluster
|
||||
{{ .Vars.ServerListenerTLSContext | indent 2 }}
|
||||
{{- end }}
|
|
@ -0,0 +1,62 @@
|
|||
name: istio_requests_total
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: {{ .Vars.RequestCount }}
|
||||
label:
|
||||
- name: reporter
|
||||
value: source
|
||||
- name: source_workload
|
||||
value: productpage-v1
|
||||
- name: source_canonical_service
|
||||
value: productpage-v1
|
||||
- name: source_canonical_revision
|
||||
value: version-1
|
||||
- name: source_workload_namespace
|
||||
value: default
|
||||
- name: source_principal
|
||||
value: unknown
|
||||
- name: source_app
|
||||
value: productpage
|
||||
- name: source_version
|
||||
value: v1
|
||||
- name: source_cluster
|
||||
value: client-cluster
|
||||
- name: destination_workload
|
||||
value: ratings-v1
|
||||
- name: destination_workload_namespace
|
||||
value: default
|
||||
- name: destination_principal
|
||||
value: unknown
|
||||
- name: destination_app
|
||||
value: ratings
|
||||
- name: destination_version
|
||||
value: v1
|
||||
- name: destination_service
|
||||
value: server.default.svc.cluster.local
|
||||
- name: destination_canonical_service
|
||||
value: ratings
|
||||
- name: destination_canonical_revision
|
||||
value: version-1
|
||||
- name: destination_service_name
|
||||
value: server
|
||||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: server-cluster
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
{{- else }}
|
||||
value: http
|
||||
{{- end }}
|
||||
- name: response_code
|
||||
value: "200"
|
||||
- name: grpc_response_status
|
||||
value: "{{ .Vars.GrpcResponseStatus }}"
|
||||
- name: response_flags
|
||||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: unknown
|
||||
- name: role
|
||||
value: server
|
|
@ -0,0 +1,60 @@
|
|||
name: istio_requests_total
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: {{ .Vars.RequestCount }}
|
||||
label:
|
||||
- name: reporter
|
||||
value: source
|
||||
- name: source_workload
|
||||
value: productpage-v1
|
||||
- name: source_canonical_service
|
||||
value: productpage-v1
|
||||
- name: source_canonical_revision
|
||||
value: version-1
|
||||
- name: source_workload_namespace
|
||||
value: default
|
||||
- name: source_principal
|
||||
value: unknown
|
||||
- name: source_app
|
||||
value: productpage
|
||||
- name: source_version
|
||||
value: v1
|
||||
- name: source_cluster
|
||||
value: client-cluster
|
||||
- name: destination_workload
|
||||
value: ratings-v1
|
||||
- name: destination_workload_namespace
|
||||
value: default
|
||||
- name: destination_principal
|
||||
value: spiffe://cluster.global/ns/default/sa/ratings
|
||||
- name: destination_app
|
||||
value: ratings
|
||||
- name: destination_version
|
||||
value: version-1
|
||||
- name: destination_service
|
||||
value: server.default.svc.cluster.local
|
||||
- name: destination_canonical_service
|
||||
value: ratings
|
||||
- name: destination_canonical_revision
|
||||
value: version-1
|
||||
- name: destination_service_name
|
||||
value: server
|
||||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: ratings-cluster
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
{{- else }}
|
||||
value: http
|
||||
{{- end }}
|
||||
- name: response_code
|
||||
value: "200"
|
||||
- name: grpc_response_status
|
||||
value: "{{ .Vars.GrpcResponseStatus }}"
|
||||
- name: response_flags
|
||||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: unknown # Because we can't verify the source principal (dumb reason)
|
|
@ -0,0 +1,62 @@
|
|||
name: istio_requests_total
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: {{ .Vars.RequestCount }}
|
||||
label:
|
||||
- name: reporter
|
||||
value: destination
|
||||
- name: source_workload
|
||||
value: productpage-v1
|
||||
- name: source_canonical_service
|
||||
value: productpage-v1
|
||||
- name: source_canonical_revision
|
||||
value: version-1
|
||||
- name: source_workload_namespace
|
||||
value: default
|
||||
- name: source_principal
|
||||
value: unknown
|
||||
- name: source_app
|
||||
value: productpage
|
||||
- name: source_version
|
||||
value: v1
|
||||
- name: source_cluster
|
||||
value: client-cluster
|
||||
- name: destination_workload
|
||||
value: ratings-v1
|
||||
- name: destination_workload_namespace
|
||||
value: default
|
||||
- name: destination_principal
|
||||
value: unknown
|
||||
- name: destination_app
|
||||
value: ratings
|
||||
- name: destination_version
|
||||
value: v1
|
||||
- name: destination_service
|
||||
value: server.default.svc.cluster.local
|
||||
- name: destination_canonical_service
|
||||
value: ratings
|
||||
- name: destination_canonical_revision
|
||||
value: version-1
|
||||
- name: destination_service_name
|
||||
value: server
|
||||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: server-cluster
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
{{- else }}
|
||||
value: http
|
||||
{{- end }}
|
||||
- name: response_code
|
||||
value: "200"
|
||||
- name: grpc_response_status
|
||||
value: "{{ .Vars.GrpcResponseStatus }}"
|
||||
- name: response_flags
|
||||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: none
|
||||
- name: role
|
||||
value: client
|
52
testdata/metric/server_waypoint_proxy_connect_connections_opened_total.yaml.tmpl
vendored
Normal file
52
testdata/metric/server_waypoint_proxy_connect_connections_opened_total.yaml.tmpl
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
name: istio_tcp_connections_opened_total
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: 10
|
||||
label:
|
||||
- name: reporter
|
||||
value: waypoint
|
||||
- name: source_workload
|
||||
value: productpage-v1
|
||||
- name: source_canonical_service
|
||||
value: unknown
|
||||
- name: source_canonical_revision
|
||||
value: latest
|
||||
- name: source_workload_namespace
|
||||
value: default
|
||||
- name: source_principal
|
||||
value: spiffe://cluster.local/ns/default/sa/client
|
||||
- name: source_app
|
||||
value: unknown
|
||||
- name: source_version
|
||||
value: unknown
|
||||
- name: source_cluster
|
||||
value: unknown
|
||||
- name: destination_workload
|
||||
value: ratings-v1
|
||||
- name: destination_workload_namespace
|
||||
value: default
|
||||
- name: destination_principal
|
||||
value: spiffe://cluster.global/ns/default/sa/ratings
|
||||
- name: destination_app
|
||||
value: ratings
|
||||
- name: destination_version
|
||||
value: version-1
|
||||
- name: destination_service
|
||||
value: server.default.svc.cluster.local
|
||||
- name: destination_canonical_service
|
||||
value: ratings
|
||||
- name: destination_canonical_revision
|
||||
value: version-1
|
||||
- name: destination_service_name
|
||||
value: server
|
||||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: ratings-cluster
|
||||
- name: request_protocol
|
||||
value: tcp
|
||||
- name: response_flags
|
||||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: mutual_tls
|
60
testdata/metric/server_waypoint_proxy_connect_emptymeta_request_total.yaml.tmpl
vendored
Normal file
60
testdata/metric/server_waypoint_proxy_connect_emptymeta_request_total.yaml.tmpl
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
name: istio_requests_total
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: {{ .Vars.RequestCount }}
|
||||
label:
|
||||
- name: reporter
|
||||
value: waypoint
|
||||
- name: source_workload
|
||||
value: productpage-v1
|
||||
- name: source_canonical_service
|
||||
value: unknown
|
||||
- name: source_canonical_revision
|
||||
value: latest
|
||||
- name: source_workload_namespace
|
||||
value: default
|
||||
- name: source_principal
|
||||
value: spiffe://cluster.local/ns/default/sa/client
|
||||
- name: source_app
|
||||
value: unknown
|
||||
- name: source_version
|
||||
value: unknown
|
||||
- name: source_cluster
|
||||
value: unknown
|
||||
- name: destination_workload
|
||||
value: unknown
|
||||
- name: destination_workload_namespace
|
||||
value: default
|
||||
- name: destination_principal
|
||||
value: spiffe://cluster.local/ns/default/sa/default
|
||||
- name: destination_app
|
||||
value: unknown
|
||||
- name: destination_version
|
||||
value: unknown
|
||||
- name: destination_service
|
||||
value: server.default.svc.cluster.local
|
||||
- name: destination_canonical_service
|
||||
value: unknown
|
||||
- name: destination_canonical_revision
|
||||
value: unknown
|
||||
- name: destination_service_name
|
||||
value: server
|
||||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: unknown
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
{{- else }}
|
||||
value: http
|
||||
{{- end }}
|
||||
- name: response_code
|
||||
value: "200"
|
||||
- name: grpc_response_status
|
||||
value: "{{ .Vars.GrpcResponseStatus }}"
|
||||
- name: response_flags
|
||||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: mutual_tls
|
|
@ -43,7 +43,7 @@ metric:
|
|||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: server-cluster
|
||||
value: ratings-cluster
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
|
|
|
@ -43,7 +43,7 @@ metric:
|
|||
- name: destination_service_namespace
|
||||
value: default
|
||||
- name: destination_cluster
|
||||
value: server-cluster
|
||||
value: ratings-cluster
|
||||
- name: request_protocol
|
||||
{{- if .Vars.GrpcResponseStatus }}
|
||||
value: grpc
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
name: type_logging_success_true_envoy_export_call
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: 1
|
||||
label:
|
||||
- name: wasm_filter
|
||||
value: stackdriver_filter
|
|
@ -1,8 +0,0 @@
|
|||
name: type_logging_success_true_envoy_export_call
|
||||
type: COUNTER
|
||||
metric:
|
||||
- counter:
|
||||
value: 2
|
||||
label:
|
||||
- name: wasm_filter
|
||||
value: stackdriver_filter
|
|
@ -55,3 +55,7 @@ metric:
|
|||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: unknown
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
- name: role
|
||||
value: unknown
|
||||
{{- end }}
|
||||
|
|
|
@ -57,3 +57,7 @@ metric:
|
|||
value: "-"
|
||||
- name: connection_security_policy
|
||||
value: mutual_tls
|
||||
{{- if eq .Vars.EnableAdditionalLabels "true" }}
|
||||
- name: role
|
||||
value: client
|
||||
{{- end }}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
name: "istiocustom.istio_requests_total"
|
||||
sum:
|
||||
data_points:
|
||||
- attributes:
|
||||
- key: "reporter"
|
||||
value:
|
||||
string_value: "source"
|
||||
- key: "source_workload"
|
||||
value:
|
||||
string_value: "productpage-v1"
|
||||
- key: "source_canonical_service"
|
||||
value:
|
||||
string_value: "productpage-v1"
|
||||
- key: "source_canonical_revision"
|
||||
value:
|
||||
string_value: "version-1"
|
||||
- key: "source_workload_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "source_principal"
|
||||
value:
|
||||
string_value: "unknown"
|
||||
- key: "source_app"
|
||||
value:
|
||||
string_value: "productpage"
|
||||
- key: "source_version"
|
||||
value:
|
||||
string_value: "v1"
|
||||
- key: "source_cluster"
|
||||
value:
|
||||
string_value: "client-cluster"
|
||||
- key: "destination_workload"
|
||||
value:
|
||||
string_value: "ratings-v1"
|
||||
- key: "destination_workload_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "destination_principal"
|
||||
value:
|
||||
string_value: "unknown"
|
||||
- key: "destination_app"
|
||||
value:
|
||||
string_value: "ratings"
|
||||
- key: "destination_version"
|
||||
value:
|
||||
string_value: "v1"
|
||||
- key: "destination_service"
|
||||
value:
|
||||
string_value: "server.default.svc.cluster.local"
|
||||
- key: "destination_canonical_service"
|
||||
value:
|
||||
string_value: "ratings"
|
||||
- key: "destination_canonical_revision"
|
||||
value:
|
||||
string_value: "version-1"
|
||||
- key: "destination_service_name"
|
||||
value:
|
||||
string_value: "server"
|
||||
- key: "destination_service_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "destination_cluster"
|
||||
value:
|
||||
string_value: "server-cluster"
|
||||
- key: "request_protocol"
|
||||
value:
|
||||
string_value: "http"
|
||||
- key: "response_code"
|
||||
value:
|
||||
string_value: "200"
|
||||
- key: "grpc_response_status"
|
||||
value:
|
||||
string_value: ""
|
||||
- key: "response_flags"
|
||||
value:
|
||||
string_value: "-"
|
||||
- key: "connection_security_policy"
|
||||
value:
|
||||
string_value: "unknown"
|
||||
as_int: 10
|
||||
aggregation_temporality: AGGREGATION_TEMPORALITY_CUMULATIVE
|
||||
is_monotonic: true
|
|
@ -1,82 +0,0 @@
|
|||
name: "istiocustom.istio_requests_total"
|
||||
sum:
|
||||
data_points:
|
||||
- attributes:
|
||||
- key: "reporter"
|
||||
value:
|
||||
string_value: "destination"
|
||||
- key: "source_workload"
|
||||
value:
|
||||
string_value: "productpage-v1"
|
||||
- key: "source_canonical_service"
|
||||
value:
|
||||
string_value: "productpage-v1"
|
||||
- key: "source_canonical_revision"
|
||||
value:
|
||||
string_value: "version-1"
|
||||
- key: "source_workload_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "source_principal"
|
||||
value:
|
||||
string_value: "unknown"
|
||||
- key: "source_app"
|
||||
value:
|
||||
string_value: "productpage"
|
||||
- key: "source_version"
|
||||
value:
|
||||
string_value: "v1"
|
||||
- key: "source_cluster"
|
||||
value:
|
||||
string_value: "client-cluster"
|
||||
- key: "destination_workload"
|
||||
value:
|
||||
string_value: "ratings-v1"
|
||||
- key: "destination_workload_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "destination_principal"
|
||||
value:
|
||||
string_value: "unknown"
|
||||
- key: "destination_app"
|
||||
value:
|
||||
string_value: "ratings"
|
||||
- key: "destination_version"
|
||||
value:
|
||||
string_value: "v1"
|
||||
- key: "destination_service"
|
||||
value:
|
||||
string_value: "server.default.svc.cluster.local"
|
||||
- key: "destination_canonical_service"
|
||||
value:
|
||||
string_value: "ratings"
|
||||
- key: "destination_canonical_revision"
|
||||
value:
|
||||
string_value: "version-1"
|
||||
- key: "destination_service_name"
|
||||
value:
|
||||
string_value: "server"
|
||||
- key: "destination_service_namespace"
|
||||
value:
|
||||
string_value: "default"
|
||||
- key: "destination_cluster"
|
||||
value:
|
||||
string_value: "server-cluster"
|
||||
- key: "request_protocol"
|
||||
value:
|
||||
string_value: "http"
|
||||
- key: "response_code"
|
||||
value:
|
||||
string_value: "200"
|
||||
- key: "grpc_response_status"
|
||||
value:
|
||||
string_value: ""
|
||||
- key: "response_flags"
|
||||
value:
|
||||
string_value: "-"
|
||||
- key: "connection_security_policy"
|
||||
value:
|
||||
string_value: "none"
|
||||
as_int: 10
|
||||
aggregation_temporality: AGGREGATION_TEMPORALITY_CUMULATIVE
|
||||
is_monotonic: true
|
|
@ -10,7 +10,8 @@
|
|||
"pod-template-hash": "84975bc778",
|
||||
"version": "v1",
|
||||
"service.istio.io/canonical-name": "ratings",
|
||||
"service.istio.io/canonical-revision": "version-1"
|
||||
"service.istio.io/canonical-revision": "version-1",
|
||||
"role": "server"
|
||||
},
|
||||
"MESH_ID": "proj-123",
|
||||
"NAME": "ratings-v1-84975bc778-pxz2w",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
metrics:
|
||||
- name: requests_total
|
||||
dimensions:
|
||||
role: filter_state.upstream_peer.labels['role']
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue