Compare commits

...

44 Commits

Author SHA1 Message Date
johnlanni
7a62da18c0 Update helm translated README.zh.md 2025-12-26 11:41:58 +00:00
steven
4babdb6a4f fix(helm,podmonitor): add podMonitorSelector for gateway metrics configuration (#3022) 2025-12-26 17:25:06 +08:00
Jingze
38d50bbdad feat: Add response-cache plugin (#3061)
Co-authored-by: mirror58229 <674958229@qq.com>
2025-12-26 17:22:03 +08:00
github-actions[bot]
2b3d0d7207 Update CRD file in the helm folder (#3155)
Co-authored-by: johnlanni <6763318+johnlanni@users.noreply.github.com>
2025-12-26 17:19:21 +08:00
澄潭
85791e4866 fix(mcp-server): fix MCP server version negotiation to comply with spec (#3258) 2025-12-26 17:04:20 +08:00
rinfx
5cc9f65aaa support disable thinking and add reasoning token usage (#3261) 2025-12-26 17:04:07 +08:00
xingpiaoliang
17e80b30fe feat: implement hgctl agent module (#3267) 2025-12-26 13:47:32 +08:00
Bingkun Zhao
e7e3ab5ff6 fix: ai-proxy dify provider extract hostname from difyApiUrl (#3257) 2025-12-24 09:58:54 +08:00
firebook
2b8f91e5f2 upgrade vipshop Description of Use in ADOPTERS.md (#3250) 2025-12-23 17:08:03 +08:00
rinfx
3191bb1bf5 special handling for cases where extracted content is empty and add unit test (#3251) 2025-12-23 16:55:06 +08:00
rinfx
00d0ad0f5e Cross provider lb bugfix (#3252) 2025-12-23 16:54:15 +08:00
zzjin
ed4ca76215 add: Include labring as an adopter in ADOPTERS.md (#3249)
Signed-off-by: zzjin <tczzjin@gmail.com>
2025-12-22 17:31:50 +08:00
Maple Lee
b29967c5d3 Add kuaishou to ADOPTERS.md (#3244) 2025-12-22 10:58:18 +08:00
Wangzy
4cf1e5e6a0 Add tool-search server (#3136)
Co-authored-by: 澄潭 <zty98751@alibaba-inc.com>
2025-12-22 09:46:31 +08:00
Kent Dong
5327a598ac fix: Switch to the new HasRequestBody logic in ai-proxy (#3211) 2025-12-22 09:41:31 +08:00
rinfx
e1e8e55c83 [feat] ai-security-guard support checking prompt and image in request body (#3206) 2025-12-22 09:36:49 +08:00
rinfx
f4905cbba7 add rebuild logic for ai-cache (#3185) 2025-12-22 09:36:02 +08:00
Kent Dong
ebbcb15811 fix: Enlarge the request body buffer size when processing multipart data in model-router (#3237) 2025-12-20 10:35:55 +08:00
rinfx
e8bcbde5f4 support vertex's claude (#3236) 2025-12-20 10:33:53 +08:00
澄潭
08d4f556a1 Update ADOPTERS.md 2025-12-20 10:23:57 +08:00
firebook
9aef35c31f Add vipshop to ADOPTERS.md (#3234) 2025-12-20 10:21:27 +08:00
Kent Dong
5d26588901 doc: Add Trip.com to the adopters list (#3233) 2025-12-19 16:46:44 +08:00
澄潭
3fbc233b3b Add ADOPTERS.md to document project adopters (#3231) 2025-12-19 15:31:57 +08:00
007gzs
4fa7fcba01 Rust Plugin add Rule matcher test (#3230) 2025-12-19 14:40:27 +08:00
woody
6998800c64 fix(ai-proxy): ensure basePathHandling works with original protocol (#3225) 2025-12-16 20:49:21 +08:00
澄潭
3cc745a6f5 Update README.md 2025-12-16 19:54:16 +08:00
澄潭
9a57a4c7e0 Update README.md 2025-12-16 19:53:27 +08:00
rinfx
7f5b37ae6d vertex support global region (#3213) 2025-12-15 17:19:59 +08:00
澄潭
0ada107ec5 feat: enhance model mapper and router with rebuild triggers and path extensions (#3218) 2025-12-12 18:10:57 +08:00
Liang Deng
5c17d3faa3 feat(ai-proxy): support handle array content in chatToolMessage2BedrockMessage (#3200)
Signed-off-by: Liang Deng <ytdengliang@gmail.com>
Co-authored-by: rinfx <yucheng.lxr@alibaba-inc.com>
2025-12-11 14:15:38 +08:00
johnlanni
b6e94b1f60 fix(ai-proxy): only perform protocol conversion for non-original protocols
Change-Id: Ib8ae3ebf6b47284108663c97777032d6282bb53c
2025-12-10 18:50:23 +08:00
johnlanni
8deceb4d2c update go sum 2025-12-09 20:48:14 +08:00
johnlanni
6bf587a4d1 add wrapper.WithRebuildMaxMemBytes(200MB) to ai-statistics&ai-proxy 2025-12-09 20:44:23 +08:00
johnlanni
7bee45b022 update wasm-go dep of mcp-server 2025-12-08 10:20:57 +08:00
rinfx
8a7a375ebd doubao support configuration for domain (#3184) 2025-12-04 21:17:50 +08:00
rinfx
896bcacf4c [feat] ai-security-guard refactor & support checking multimoadl input (#3075) 2025-12-04 16:33:59 +08:00
Kent Dong
3e24d66079 fix: Bypass the response body processing for MCP streamable transport (#3187) 2025-12-03 16:01:08 +08:00
woody
116e7c6904 implement generic provider for vendor-agnostic passthrough (#3175) 2025-12-03 09:52:47 +08:00
woody
ae0bb41885 Fix OpenAI capability rewrite dropping query string (#3168) 2025-11-28 17:44:22 +08:00
EndlessSeeker
f3ac8eafe5 feat: add inference extension global param (#3173) 2025-11-27 19:28:49 +08:00
EndlessSeeker
985b58ad5c fix: submodule update (#3167) 2025-11-26 11:32:15 +08:00
EndlessSeeker
ccb1539f43 Feat: upgrade gateway api to latest (#3160) 2025-11-26 10:15:00 +08:00
rinfx
42334f21df [feat] load balancing across different clusters and endpoints based on metrics (#3063) 2025-11-25 10:32:34 +08:00
rinfx
7a504fd67d remove omitempty for toolcall index (#3148)
Co-authored-by: 澄潭 <zty98751@alibaba-inc.com>
2025-11-24 16:14:00 +08:00
252 changed files with 16649 additions and 8442 deletions

13
ADOPTERS.md Normal file
View File

@@ -0,0 +1,13 @@
# Adopters of Higress
Below are the adopters of the Higress project. If you are using Higress in your organization, please add your name to the list by submitting a pull request: this will help foster the Higress community. Kindly ensure the list remains in alphabetical order.
| Organization | Contact (GitHub User Name) | Environment | Description of Use |
|---------------------------------------|----------------------------------------|--------------------------------------------|-----------------------------------------------------------------------|
| [antdigital](https://antdigital.com/) | [@Lovelcp](https://github.com/Lovelcp) | Production | Ingress Gateway, Microservice gateway, LLM Gateway, MCP Gateway |
| [kuaishou](https://ir.kuaishou.com/) | [@maplecap](https://github.com/maplecap) | Production | LLM Gateway |
| [Trip.com](https://www.trip.com/) | [@CH3CHO](https://github.com/CH3CHO) | Production | LLM Gateway, MCP Gateway |
| [vipshop](https://github.com/vipshop/) | [@firebook](https://github.com/firebook) | Production | LLM Gateway, MCP Gateway, Inference Gateway |
| [labring](https://github.com/labring/) | [@zzjin](https://github.com/zzjin) | Production | Ingress Gateway |
| < company name here> | < your github handle here > | <Production/Testing/Experimenting/etc> | <Ingress Gateway/Microservice gateway/LLM Gateway/MCP Gateway/Inference Gateway> |

View File

@@ -56,31 +56,8 @@ $(OUT):
@mkdir -p $@
submodule:
@echo "Initializing submodules..."
@git submodule init || true
@git submodule update --init --recursive || true
@git submodule foreach -q ' \
branch="$$(git config -f $${toplevel}/.gitmodules submodule.$${name}.branch)"; \
if [ -n "$$branch" ]; then \
echo "Updating $$name to branch $$branch"; \
if ! git fetch origin "$$branch" 2>/dev/null; then \
echo "Error: Branch $$branch not found in remote for $$name. Make sure the branch exists and is accessible."; \
exit 1; \
fi; \
if git show-ref --verify --quiet "refs/remotes/origin/$$branch" 2>/dev/null; then \
remote_ref="origin/$$branch"; \
else \
remote_ref="FETCH_HEAD"; \
fi; \
if git show-ref --verify --quiet "refs/heads/$$branch" 2>/dev/null; then \
git checkout "$$branch" && git reset --hard "$$remote_ref" || { echo "Error: Failed to update $$name to $$branch"; exit 1; }; \
else \
git checkout -b "$$branch" "$$remote_ref" || { echo "Error: Failed to checkout branch $$branch for $$name"; exit 1; }; \
fi; \
git branch --set-upstream-to="origin/$$branch" "$$branch" 2>/dev/null || true; \
echo "✓ $$name is now on branch $$branch"; \
fi \
'
git submodule update --init
# git submodule update --remote
.PHONY: prebuild
prebuild: submodule
@@ -224,7 +201,7 @@ install: pre-install
HIGRESS_LATEST_IMAGE_TAG ?= latest
ENVOY_LATEST_IMAGE_TAG ?= cdf0f16bf622102f89a0d0257834f43f502e4b99
ISTIO_LATEST_IMAGE_TAG ?= 2124b6819c805d16507d4bb0bb394160281169e7
ISTIO_LATEST_IMAGE_TAG ?= a7525f292c38d7d3380f3ce7ee971ad6e3c46adf
install-dev: pre-install
helm install higress helm/core -n higress-system --create-namespace --set 'controller.tag=$(TAG)' --set 'gateway.replicas=1' --set 'pilot.tag=$(ISTIO_LATEST_IMAGE_TAG)' --set 'gateway.tag=$(ENVOY_LATEST_IMAGE_TAG)' --set 'global.local=true'

View File

@@ -82,6 +82,8 @@ Port descriptions:
>
> If you experience a timeout when pulling image from `higress-registry.cn-hangzhou.cr.aliyuncs.com`, you can try replacing it with the following docker registry mirror source:
>
> **North America**: `higress-registry.us-west-1.cr.aliyuncs.com`
>
> **Southeast Asia**: `higress-registry.ap-southeast-7.cr.aliyuncs.com`
For other installation methods such as Helm deployment under K8s, please refer to the official [Quick Start documentation](https://higress.io/en-us/docs/user/quickstart).

138
go.mod
View File

@@ -26,7 +26,7 @@ require (
github.com/golang/protobuf v1.5.4
github.com/google/go-cmp v0.7.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/consul/api v1.31.2
github.com/hashicorp/consul/api v1.32.0
github.com/hashicorp/go-multierror v1.1.1
github.com/hudl/fargo v1.4.0
github.com/mholt/acmez v1.2.0
@@ -34,44 +34,44 @@ require (
github.com/nacos-group/nacos-sdk-go/v2 v2.3.2
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.7
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.11.1
github.com/tidwall/gjson v1.17.0
go.uber.org/atomic v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.41.0
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
google.golang.org/grpc v1.73.0
google.golang.org/protobuf v1.36.6
golang.org/x/net v0.44.0
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4
google.golang.org/grpc v1.76.0
google.golang.org/protobuf v1.36.10
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9
istio.io/client-go v1.27.1-0.20250820130622-12f6d11feb40
istio.io/istio v0.0.0
istio.io/pkg v0.0.0-20250718200944-0aab346caa39
k8s.io/api v0.33.3
k8s.io/apiextensions-apiserver v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/api v0.34.1
k8s.io/apiextensions-apiserver v0.34.1
k8s.io/apimachinery v0.34.1
k8s.io/cli-runtime v0.33.3
k8s.io/client-go v0.33.3
k8s.io/client-go v0.34.1
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165
knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/gateway-api v1.3.0
sigs.k8s.io/gateway-api-inference-extension v0.5.0
sigs.k8s.io/controller-runtime v0.22.3
sigs.k8s.io/gateway-api v1.4.0
sigs.k8s.io/gateway-api-inference-extension v1.1.0
sigs.k8s.io/structured-merge-diff/v4 v4.7.0
sigs.k8s.io/yaml v1.5.0
sigs.k8s.io/yaml v1.6.0
)
require (
cel.dev/expr v0.24.0 // indirect
cloud.google.com/go v0.115.1 // indirect
cloud.google.com/go/auth v0.15.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect
cloud.google.com/go/logging v1.11.0 // indirect
cloud.google.com/go/longrunning v0.6.0 // indirect
cloud.google.com/go v0.120.0 // indirect
cloud.google.com/go/auth v0.16.5 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.8.4 // indirect
cloud.google.com/go/logging v1.13.0 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/alecholmes/xfccparser v0.4.0 // indirect
github.com/alecthomas/participle/v2 v2.1.4 // indirect
@@ -102,6 +102,7 @@ require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
@@ -115,7 +116,7 @@ require (
github.com/docker/cli v28.1.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/envoyproxy/go-control-plane v0.13.4 // indirect
github.com/envoyproxy/go-control-plane/contrib v0.0.0-20251016030003-90eca0228178 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
@@ -124,30 +125,30 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonpointer v0.21.2 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/cel-go v0.25.0 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/cel-go v0.26.0 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-containerregistry v0.20.3 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.5 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
@@ -177,7 +178,7 @@ require (
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.66 // indirect
github.com/miekg/dns v1.1.68 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -185,7 +186,7 @@ require (
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
@@ -198,11 +199,11 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/prometheus/prometheus v0.303.1 // indirect
github.com/prometheus/common v0.67.1 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/prometheus/prometheus v0.307.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cast v1.8.0 // indirect
@@ -220,53 +221,54 @@ require (
github.com/zeebo/blake3 v0.2.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
go.opentelemetry.io/otel v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/exp v0.0.0-20250717185816-542afb5b7346 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.34.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.42.0 // indirect
golang.org/x/exp v0.0.0-20250808145144-a408d31f581a // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/term v0.35.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/time v0.13.0 // indirect
golang.org/x/tools v0.37.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/api v0.224.0 // indirect
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
google.golang.org/api v0.250.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/gcfg.v1 v1.2.3 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiserver v0.33.3 // indirect
k8s.io/component-base v0.33.3 // indirect
k8s.io/apiserver v0.34.1 // indirect
k8s.io/component-base v0.34.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect
k8s.io/kubectl v0.33.3 // indirect
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
replace istio.io/api => ./external/api

298
go.sum
View File

@@ -55,8 +55,8 @@ cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJN
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@@ -193,10 +193,10 @@ cloud.google.com/go/assuredworkloads v1.11.2/go.mod h1:O1dfr+oZJMlE6mw0Bp0P1KZSl
cloud.google.com/go/assuredworkloads v1.11.3/go.mod h1:vEjfTKYyRUaIeA0bsGJceFV2JKpVRgyG2op3jfa59Zs=
cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U=
cloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk=
cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=
cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8=
@@ -368,8 +368,9 @@ cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2Aawl
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
cloud.google.com/go/compute/metadata v0.8.4 h1:oXMa1VMQBVCyewMIOm3WQsnVd9FbKBtm8reqWRaXnHQ=
cloud.google.com/go/compute/metadata v0.8.4/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
@@ -705,8 +706,8 @@ cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQy
cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8=
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
cloud.google.com/go/iam v1.2.0 h1:kZKMKVNk/IsSSc/udOb83K0hL/Yh/Gcqpz+oAkoIFN8=
cloud.google.com/go/iam v1.2.0/go.mod h1:zITGuWgsLZxd8OwAlX+eMFgZDXzBm7icj1PVTYG766Q=
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=
cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=
cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=
@@ -774,8 +775,8 @@ cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9
cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI=
cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE=
cloud.google.com/go/logging v1.11.0 h1:v3ktVzXMV7CwHq1MBF65wcqLMA7i+z3YxbUsoK7mOKs=
cloud.google.com/go/logging v1.11.0/go.mod h1:5LDiJC/RxTt+fHc1LAt20R9TKiUTReDg6RuuFOZ67+A=
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
@@ -786,8 +787,8 @@ cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUz
cloud.google.com/go/longrunning v0.5.3/go.mod h1:y/0ga59EYu58J6SHmmQOvekvND2qODbu8ywBBW7EK7Y=
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=
cloud.google.com/go/longrunning v0.6.0 h1:mM1ZmaNsQsnb+5n1DNPeL0KwQd9jQRqSqSDEkBZr+aI=
cloud.google.com/go/longrunning v0.6.0/go.mod h1:uHzSZqW89h7/pasCWNYdUpwGz3PcVWhrWupreVPYLts=
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
@@ -1373,8 +1374,8 @@ github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
@@ -1539,6 +1540,8 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
@@ -1603,8 +1606,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5t
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@@ -1653,8 +1656,8 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
@@ -1701,8 +1704,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -1717,8 +1720,8 @@ github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmn
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
@@ -1746,8 +1749,8 @@ github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonpointer v0.21.2 h1:AqQaNADVwq/VnkCmQg6ogE+M3FOsKTytwges0JdwVuA=
github.com/go-openapi/jsonpointer v0.21.2/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
@@ -1850,12 +1853,12 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -1906,8 +1909,8 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a h1:rDA3FfmxwXR+BVKKdz55WwMJ1pD2hJQNW31d+l3mPk4=
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/pprof v0.0.0-20250923004556-9e5a51aed1e8 h1:ZI8gCoCjGzPsum4L21jHdQs8shFBIQih1TM9Rd/c+EQ=
github.com/google/pprof v0.0.0-20250923004556-9e5a51aed1e8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM=
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
@@ -1934,8 +1937,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5
github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/enterprise-certificate-proxy v0.3.5 h1:VgzTY2jogw3xt39CusEnFJWm7rlsq5yL5q9XdLOuP5g=
github.com/googleapis/enterprise-certificate-proxy v0.3.5/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@@ -1953,8 +1956,8 @@ github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5i
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
@@ -1976,8 +1979,8 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM=
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
@@ -1994,11 +1997,12 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/api v1.31.2 h1:NicObVJHcCmyOIl7Z9iHPvvFrocgTYo9cITSGg0/7pw=
github.com/hashicorp/consul/api v1.31.2/go.mod h1:Z8YgY0eVPukT/17ejW+l+C7zJmKwgPHtjU1q16v/Y40=
github.com/hashicorp/consul/api v1.32.0 h1:5wp5u780Gri7c4OedGEPzmlUEzi0g2KyiPphSr6zjVg=
github.com/hashicorp/consul/api v1.32.0/go.mod h1:Z8YgY0eVPukT/17ejW+l+C7zJmKwgPHtjU1q16v/Y40=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg=
github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s=
@@ -2095,8 +2099,8 @@ github.com/johnlanni/gost v1.11.23-0.20220713132522-0967a24036c6 h1:i9IP6menkNYR
github.com/johnlanni/gost v1.11.23-0.20220713132522-0967a24036c6/go.mod h1:PhJ8+qZJx+Txjx1KthNPuVkCvUca0jRLgKWj/noGgeI=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -2227,8 +2231,8 @@ github.com/miekg/dns v1.1.17/go.mod h1:WgzbA6oji13JREwiNsRDNfl7jYdPnmz+VEuLrA+/4
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -2259,8 +2263,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -2297,16 +2302,16 @@ github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvw
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE=
github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -2372,8 +2377,8 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -2392,8 +2397,8 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI=
github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -2402,10 +2407,10 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/prometheus/prometheus v0.303.1 h1:He/2jRE6sB23Ew38AIoR1WRR3fCMgPlJA2E0obD2WSY=
github.com/prometheus/prometheus v0.303.1/go.mod h1:WEq2ogBPZoLjj9x5K67VEk7ECR0nRD9XCjaOt1lsYck=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/prometheus/prometheus v0.307.1 h1:Hh3kRMFn+xpQGLe/bR6qpUfW4GXQO0spuYeY7f2JZs4=
github.com/prometheus/prometheus v0.307.1/go.mod h1:/7YQG/jOLg7ktxGritmdkZvezE1fa6aWDj0MGDIZvcY=
github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ=
github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@@ -2508,8 +2513,9 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg=
github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto=
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
@@ -2577,17 +2583,17 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.21 h1:A6O2/JDb3tvHhiIz3xf9nJ7REHvtEFJJ3veW3FbCnS8=
go.etcd.io/etcd/api/v3 v3.5.21/go.mod h1:c3aH5wcvXv/9dqIw2Y810LDXJfhSYdHQ0vxmP3CCHVY=
go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo=
go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.21 h1:lPBu71Y7osQmzlflM9OfeIV2JlmpBjqBNlLtcoBqUTc=
go.etcd.io/etcd/client/pkg/v3 v3.5.21/go.mod h1:BgqT/IXPjK9NkeSDjbzwsHySX3yIle2+ndz28nVsjUs=
go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0=
go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI=
go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8=
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
go.etcd.io/etcd/client/v3 v3.5.21 h1:T6b1Ow6fNjOLOtM0xSoKNQt1ASPCLWrF9XMHcH9pEyY=
go.etcd.io/etcd/client/v3 v3.5.21/go.mod h1:mFYy67IOqmbRf/kRUvsHixzo3iG+1OF2W2+jVIQRAnU=
go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A=
go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo=
go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY=
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w=
@@ -2616,15 +2622,15 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
@@ -2633,13 +2639,14 @@ go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFu
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
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 v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
@@ -2650,8 +2657,9 @@ go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
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/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
@@ -2659,14 +2667,16 @@ go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
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 v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
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/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
@@ -2675,11 +2685,13 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
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/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@@ -2711,10 +2723,10 @@ go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -2764,8 +2776,8 @@ golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ug
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@@ -2811,8 +2823,8 @@ golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -2915,8 +2927,8 @@ golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2962,8 +2974,8 @@ golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo=
golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -2991,8 +3003,8 @@ golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -3133,8 +3145,8 @@ golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -3168,8 +3180,8 @@ golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -3198,8 +3210,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -3213,8 +3225,8 @@ golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -3297,8 +3309,8 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -3316,6 +3328,8 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
@@ -3397,8 +3411,8 @@ google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYl
google.golang.org/api v0.164.0/go.mod h1:2OatzO7ZDQsoS7IFf3rvsE17/TldiU3F/zxFHeqUB5o=
google.golang.org/api v0.166.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA=
google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=
google.golang.org/api v0.224.0 h1:Ir4UPtDsNiwIOHdExr3fAj4xZ42QjK7uQte3lORLJwU=
google.golang.org/api v0.224.0/go.mod h1:3V39my2xAGkodXy0vEqcEtkqgw2GtrFL5WuBZlCTCOQ=
google.golang.org/api v0.250.0 h1:qvkwrf/raASj82UegU2RSDGWi/89WkLckn4LuO4lVXM=
google.golang.org/api v0.250.0/go.mod h1:Y9Uup8bDLJJtMzJyQnu+rLRJLA0wn+wTtc6vTlOvfXo=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -3575,8 +3589,8 @@ google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqt
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU=
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
@@ -3613,8 +3627,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw=
@@ -3672,8 +3686,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -3739,8 +3753,9 @@ google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFN
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
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/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -3769,8 +3784,9 @@ google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -3781,8 +3797,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
@@ -3832,26 +3848,26 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs=
k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
k8s.io/apiextensions-apiserver v0.22.5/go.mod h1:tIXeZ0BrDxUb1PoAz+tgOz43Zi1Bp4BEEqVtUccMJbE=
k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ=
k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4=
k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E=
k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA=
k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo=
k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk=
k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI=
k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA=
k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4=
k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A=
k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
@@ -3862,13 +3878,13 @@ k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 h1:liMHz39T5dJO1aOKHLvwaCjDbf07wVh6yaUlTpunnkE=
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
k8s.io/kubectl v0.33.3 h1:r/phHvH1iU7gO/l7tTjQk2K01ER7/OAJi8uFHHyWSac=
k8s.io/kubectl v0.33.3/go.mod h1:euj2bG56L6kUGOE/ckZbCoudPwuj4Kud7BR0GzyNiT0=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
knative.dev/hack v0.0.0-20220224013837-e1785985d364/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165 h1:mkUDPTqfRPNhsUTVOH53IOx0Utzlfwl48t8lLc1bfL4=
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165/go.mod h1:EdQTSLl8BDeLLrC8pymGOiPMRAknFg+7oRO6MMUts94=
@@ -3943,14 +3959,14 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1 h1:Cf+ed5N8038zbsaXFO7mKQDi/+VcSRafb0jM84KX5so=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/gateway-api v1.3.0 h1:q6okN+/UKDATola4JY7zXzx40WO4VISk7i9DIfOvr9M=
sigs.k8s.io/gateway-api v1.3.0/go.mod h1:d8NV8nJbaRbEKem+5IuxkL8gJGOZ+FJ+NvOIltV8gDk=
sigs.k8s.io/gateway-api-inference-extension v0.5.0 h1:bYtXffUF1WUUFT2gYXaQBXIEXxXq/ZZLP9gqQweTrBI=
sigs.k8s.io/gateway-api-inference-extension v0.5.0/go.mod h1:lki0jx1qysZSZT4Ai2BxuAcpx6G8g5oBgOGuuJzjy/k=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y=
sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
sigs.k8s.io/gateway-api v1.4.0 h1:ZwlNM6zOHq0h3WUX2gfByPs2yAEsy/EenYJB78jpQfQ=
sigs.k8s.io/gateway-api v1.4.0/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk=
sigs.k8s.io/gateway-api-inference-extension v1.1.0 h1:MqRYk+3LNUWB0MbTgTZVhmJGNDTvm8l3ze4MOlzR7MU=
sigs.k8s.io/gateway-api-inference-extension v1.1.0/go.mod h1:BmJy8Hvc2EHl3Oa/Ka8/4RqwVHCCbX7BLndLdMNtugI=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
@@ -3964,10 +3980,12 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View File

@@ -71,6 +71,11 @@ spec:
items:
type: string
type: array
routeType:
enum:
- HTTP
- GRPC
type: string
service:
items:
type: string

View File

@@ -38,6 +38,14 @@ rules:
resources: ["*"]
verbs: ["get", "watch", "list", "create", "update", "delete", "patch"]
# Gateway api inference extension
- apiGroups: ["inference.networking.k8s.io"]
resources: ["*"]
verbs: ["get", "watch", "list", "create", "update", "delete", "patch"]
- apiGroups: ["inference.networking.x-k8s.io"]
resources: ["*"]
verbs: ["get", "watch", "list", "create", "update", "delete", "patch"]
# Needed for multicluster secret reading, possibly ingress certs in the future
- apiGroups: [""]
resources: ["secrets"]

View File

@@ -78,6 +78,10 @@ spec:
value: "{{ .Values.global.enableGatewayAPI }}"
- name: PILOT_ENABLE_ALPHA_GATEWAY_API
value: "{{ .Values.global.enableGatewayAPI }}"
{{- if .Values.global.enableInferenceExtension }}
- name: ENABLE_GATEWAY_API_INFERENCE_EXTENSION
value: "true"
{{- end }}
{{- if .Values.controller.env }}
{{- range $key, $val := .Values.controller.env }}
- name: {{ $key }}
@@ -174,7 +178,15 @@ spec:
- name: HOST_RDS_MERGE_SUBSET
value: "{{ .Values.global.hostRDSMergeSubset }}"
- name: PILOT_FILTER_GATEWAY_CLUSTER_CONFIG
{{- if .Values.global.enableInferenceExtension }}
value: "false"
{{- else }}
value: "{{ .Values.global.onlyPushRouteCluster }}"
{{- end }}
{{- if .Values.global.enableInferenceExtension }}
- name: ENABLE_GATEWAY_API_INFERENCE_EXTENSION
value: "true"
{{- end }}
- name: HIGRESS_CONTROLLER_SVC
value: "127.0.0.1"
- name: HIGRESS_CONTROLLER_PORT

View File

@@ -5,6 +5,9 @@ metadata:
namespace: {{ .Release.Namespace }}
labels:
{{- include "gateway.labels" . | nindent 4}}
{{- with .Values.gateway.metrics.podMonitorSelector }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- .Values.gateway.annotations | toYaml | nindent 4 }}
spec:

View File

@@ -44,7 +44,9 @@ global:
# -- If true, Higress Controller will monitor istio resources as well
enableIstioAPI: true
# -- If true, Higress Controller will monitor Gateway API resources as well
enableGatewayAPI: false
enableGatewayAPI: true
# -- If true, enable Gateway API Inference Extension support
enableInferenceExtension: false
# -- Used to locate istiod.
istioNamespace: istio-system
# -- enable pod disruption budget for the control plane, which is used to
@@ -528,6 +530,11 @@ gateway:
metrics:
# -- If true, create PodMonitor or VMPodScrape for gateway
enabled: false
# -- Selector for PodMonitor
# When using monitoring.coreos.com/v1.PodMonitor, the selector must match
# the label "release: kube-prome" is the default for kube-prometheus-stack
podMonitorSelector:
release: kube-prome
# -- provider group name for CustomResourceDefinition, can be monitoring.coreos.com or operator.victoriametrics.com
provider: monitoring.coreos.com
interval: ""

View File

@@ -104,6 +104,7 @@ The command removes all the Kubernetes components associated with the chart and
| gateway.metrics.interval | string | `""` | |
| gateway.metrics.metricRelabelConfigs | list | `[]` | for operator.victoriametrics.com/v1beta1.VMPodScrape |
| gateway.metrics.metricRelabelings | list | `[]` | for monitoring.coreos.com/v1.PodMonitor |
| gateway.metrics.podMonitorSelector | object | `{"release":"kube-prome"}` | Selector for PodMonitor When using monitoring.coreos.com/v1.PodMonitor, the selector must match the label "release: kube-prome" is the default for kube-prometheus-stack |
| gateway.metrics.provider | string | `"monitoring.coreos.com"` | provider group name for CustomResourceDefinition, can be monitoring.coreos.com or operator.victoriametrics.com |
| gateway.metrics.rawSpec | object | `{}` | some more raw podMetricsEndpoints spec |
| gateway.metrics.relabelConfigs | list | `[]` | |
@@ -160,9 +161,10 @@ The command removes all the Kubernetes components associated with the chart and
| global.defaultResources | object | `{"requests":{"cpu":"10m"}}` | A minimal set of requested resources to applied to all deployments so that Horizontal Pod Autoscaler will be able to function (if set). Each component can overwrite these default values by adding its own resources block in the relevant section below and setting the desired resources values. |
| global.defaultUpstreamConcurrencyThreshold | int | `10000` | |
| global.disableAlpnH2 | bool | `false` | Whether to disable HTTP/2 in ALPN |
| global.enableGatewayAPI | bool | `false` | If true, Higress Controller will monitor Gateway API resources as well |
| global.enableGatewayAPI | bool | `true` | If true, Higress Controller will monitor Gateway API resources as well |
| global.enableH3 | bool | `false` | |
| global.enableIPv6 | bool | `false` | |
| global.enableInferenceExtension | bool | `false` | If true, enable Gateway API Inference Extension support |
| global.enableIstioAPI | bool | `true` | If true, Higress Controller will monitor istio resources as well |
| global.enableLDSCache | bool | `false` | |
| global.enablePluginServer | bool | `false` | |

View File

@@ -1,150 +0,0 @@
## Higress 适用于 Kubernetes
Higress 是基于阿里巴巴内部网关实践的云原生 API 网关。
通过 Istio 和 Envoy 的支持Higress 实现了流量网关、微服务网关和安全网关三种架构的融合,从而极大地减少了部署、运维的成本。
## 设置仓库信息
```console
helm repo add higress.io https://higress.io/helm-charts
helm repo update
```
## 安装
使用 Helm 安装名为 `higress` 的组件:
```console
helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes
```
## 卸载
删除名称为 higress 的安装:
```console
helm delete higress -n higress-system
```
该命令将删除与组件关联的所有 Kubernetes 组件并卸载该发行版。
## 参数
## Values
| 键 | 类型 | 默认值 | 描述 |
|----|------|---------|-------------|
| clusterName | string | `""` | 集群名 |
| controller.affinity | object | `{}` | 控制器亲和性设置 |
| controller.automaticHttps.email | string | `""` | 自动 HTTPS 所需的邮件 |
| controller.automaticHttps.enabled | bool | `true` | 是否启用自动 HTTPS 功能 |
| controller.autoscaling.enabled | bool | `false` | 是否启用控制器的自动扩展功能 |
| controller.autoscaling.maxReplicas | int | `5` | 最大副本数 |
| controller.autoscaling.minReplicas | int | `1` | 最小副本数 |
| controller.autoscaling.targetCPUUtilizationPercentage | int | `80` | 目标 CPU 使用率百分比 |
| controller.env | object | `{}` | 环境变量 |
| controller.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | 图像库的基础地址 |
| controller.image | string | `"higress"` | 镜像名称 |
| controller.imagePullSecrets | list | `[]` | 拉取秘钥列表 |
| controller.labels | object | `{}` | 标签 |
| controller.name | string | `"higress-controller"` | 控制器名称 |
| controller.nodeSelector | object | `{}` | 节点选择器 |
| controller.podAnnotations | object | `{}` | Pod 注解 |
| controller.podLabels | object | `{}` | 应用到 Pod 上的标签 |
| controller.podSecurityContext | object | `{}` | Pod 安全上下文 |
| controller.ports[0].name | string | `"http"` | 端口名称 |
| controller.ports[0].port | int | `8888` | 端口编号 |
| controller.ports[0].protocol | string | `"TCP"` | 协议类型 |
| controller.ports[0].targetPort | int | `8888` | 目标端口 |
| controller.ports[1].name | string | `"http-solver"` | 端口名称 |
| controller.ports[1].port | int | `8889` | 端口编号 |
| controller.ports[1].protocol | string | `"TCP"` | 协议类型 |
| controller.ports[1].targetPort | int | `8889` | 目标端口 |
| controller.ports[2].name | string | `"grpc"` | 端口名称 |
| controller.ports[2].port | int | `15051` | 端口编号 |
| controller.ports[2].protocol | string | `"TCP"` | 协议类型 |
| controller.ports[2].targetPort | int | `15051` | 目标端口 |
| controller.probe.httpGet.path | string | `"/ready"` | 运行状况检查路径 |
| controller.probe.httpGet.port | int | `8888` | 端口运行状态检查 |
| controller.probe.initialDelaySeconds | int | `1` | 初始延迟秒数 |
| controller.probe.periodSeconds | int | `3` | 健康检查间隔秒数 |
| controller.probe.timeoutSeconds | int | `5` | 超时秒数 |
| controller.rbac.create | bool | `true` | 是否创建 RBAC 相关资源 |
| controller.replicas | int | `1` | Higress 控制器 Pod 的数量 |
| controller.resources.limits.cpu | string | `"1000m"` | CPU 上限 |
| controller.resources.limits.memory | string | `"2048Mi"` | 内存上限 |
| controller.resources.requests.cpu | string | `"500m"` | CPU 请求量 |
| controller.resources.requests.memory | string | `"2048Mi"` | 内存请求量 |
| controller.securityContext | object | `{}` | 安全上下文 |
| controller.service.type | string | `"ClusterIP"` | 服务类型 |
| controller.serviceAccount.annotations | object | `{}` | 添加到服务帐户的注解 |
| controller.serviceAccount.create | bool | `true` | 是否创建服务帐户 |
| controller.serviceAccount.name | string | `""` | 如果未设置且 create 为 true则从 fullname 模板生成名称 |
| controller.tag | string | `""` | 标记 |
| controller.tolerations | list | `[]` | 受容容忍度列表 |
| downstream.connectionBufferLimits | int | `32768` | 下游连接缓冲区限制(字节) |
| downstream.http2.initialConnectionWindowSize | int | `1048576` | HTTP/2 初始连接窗口大小 |
| downstream.http2.initialStreamWindowSize | int | `65535` | 流初始窗口大小 |
| downstream.http2.maxConcurrentStreams | int | `100` | 并发流最大数量 |
| downstream.idleTimeout | int | `180` | 空闲超时时间(秒) |
| downstream.maxRequestHeadersKb | int | `60` | 最大请求头大小KB |
| downstream.routeTimeout | int | `0` | 路由超时时间 |
| gateway.affinity | object | `{}` | 网关的节点亲和性 |
| gateway.annotations | object | `{}` | 应用于所有资源的注解 |
| gateway.autoscaling.enabled | bool | `false` | 启用网关的自动扩展功能 |
| gateway.autoscaling.maxReplicas | int | `5` | 最大副本数 |
| gateway.autoscaling.minReplicas | int | `1` | 最小副本数 |
| gateway.autoscaling.targetCPUUtilizationPercentage | int | `80` | CPU 使用率的目标百分比 |
| gateway.containerSecurityContext | string | `nil` | 网关容器的安全配置上下文 |
| gateway.env | object | `{}` | Pod 环境变量 |
| gateway.hostNetwork | bool | `false` | 是否使用主机网络 |
| gateway.httpPort | int | `80` | HTTP 服务端口 |
| gateway.httpsPort | int | `443` | HTTPS 服务端口 |
| gateway.hub | string | `"higress-registry.cn-hangzhou.cr.aliyuncs.com/higress"` | 网关镜像的基础域名 |
| gateway.image | string | `"gateway"` | |
| gateway.kind | string | `"Deployment"` | 部署类型 |
| gateway.labels | object | `{}` | 应用于所有资源的标签 |
| gateway.metrics.enabled | bool | `false` | 启用网关度量收集 |
| gateway.metrics.honorLabels | bool | `false` | 是否合并现有标签 |
| gateway.metrics.interval | string | `""` | 度量间隔时间 |
| gateway.metrics.provider | string | `"monitoring.coreos.com"` | 定义监控提供者 |
| gateway.metrics.rawSpec | object | `{}` | 额外的度量规范 |
| gateway.metrics.relabelConfigs | list | `[]` | 重新标签配置 |
| gateway.metrics.relabelings | list | `[]` | 重新标签项 |
| gateway.metrics.scrapeTimeout | string | `""` | 抓取的超时时间 |
| gateway.name | string | `"higress-gateway"` | 网关名称 |
| gateway.networkGateway | string | `""` | 网络网关指定 |
| gateway.nodeSelector | object | `{}` | 节点选择器 |
| gateway.replicas | int | `2` | Higress Gateway pod 的数量 |
| gateway.resources.limits.cpu | string | `"2000m"` | 容器资源限制的 CPU |
| gateway.resources.limits.memory | string | `"2048Mi"` | 容器资源限制的内存 |
| gateway.resources.requests.cpu | string | `"2000m"` | 容器资源请求的 CPU |
| gateway.resources.requests.memory | string | `"2048Mi"` | 容器资源请求的内存 |
| gateway.revision | string | `""` | 网关所属版本声明 |
| gateway.rollingMaxSurge | string | `"100%"` | 最大激增数目百分比 |
| gateway.rollingMaxUnavailable | string | `"25%"` | 最大不可用比例 |
| gateway.readinessFailureThreshold | int | `30` | 成功尝试之前连续失败的最大探测次数 |
| gateway.readinessInitialDelaySeconds | int | `1` | 初次检测推迟多少秒后开始探测存活状态 |
| gateway.readinessPeriodSeconds | int | `2` | 存活探测间隔秒数 |
| gateway.readinessSuccessThreshold | int | `1` | 认为成功之前连续成功最小探测次数 |
| gateway.readinessTimeoutSeconds | int | `3` | 存活探测超时秒数 |
| gateway.securityContext | string | `nil` | 客户豆荚的安全上下文 |
| gateway.service.annotations | object | `{}` | 应用于服务账户的注释 |
| gateway.service.externalTrafficPolicy | string | `""` | 外部路由策略 |
| gateway.service.loadBalancerClass | string | `""` | 负载均衡器类别 |
| gateway.service.loadBalancerIP | string | `""` | 负载均衡器 IP 地址 |
| gateway.service.loadBalancerSourceRanges | list | `[]` | 允许访问负载均衡器的 CIDR 范围 |
| gateway.service.ports[0].name | string | `"http2"` | 服务定义的端口名称 |
| gateway.service.ports[0].port | int | `80` | 服务端口 |
| gateway.service.ports[0].protocol | string | `"TCP"` | 协议 |
| gateway.service.ports[0].targetPort | int | `80` | 靶向端口 |
| gateway.service.ports[1].name | string | `"https"` | 服务定义的端口名称 |
| gateway.service.ports[1].port | int | `443` | 服务端口 |
| gateway.service.ports[1].protocol | string | `"TCP"` | 协议 |
| gateway.service.ports[1].targetPort | int | `443` | 靶向端口 |
| gateway.service.type | string | `"LoadBalancer"` | 服务类型 |
| global.disableAlpnH2 | bool | `false` | 设置是否禁用 ALPN 中的 http/2 |
| ... | ... | ... | ... |
由于内容较多,其他参数可以参考完整表。

View File

@@ -22,7 +22,7 @@ require (
github.com/compose-spec/compose-go v1.17.0
github.com/docker/cli v28.1.1+incompatible
github.com/docker/compose/v2 v2.23.3
github.com/docker/docker v28.0.1+incompatible
github.com/docker/docker v28.4.0+incompatible
github.com/evanphx/json-patch/v5 v5.9.11
github.com/fatih/color v1.18.0
github.com/fatih/structtag v1.2.0
@@ -37,34 +37,36 @@ require (
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.7
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.11.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.18.5
istio.io/istio v0.0.0
k8s.io/api v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/api v0.34.1
k8s.io/apimachinery v0.34.1
k8s.io/cli-runtime v0.33.3
k8s.io/client-go v0.33.3
k8s.io/client-go v0.34.1
k8s.io/kubectl v0.33.3
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/yaml v1.5.0
sigs.k8s.io/controller-runtime v0.22.3
sigs.k8s.io/yaml v1.6.0
)
require (
cel.dev/expr v0.24.0 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/chzyer/readline v1.5.0 // indirect
github.com/containerd/containerd/api v1.8.0 // indirect
github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/ttrpc v1.2.7 // indirect
github.com/envoyproxy/go-control-plane/contrib v0.0.0-20251016030003-90eca0228178 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
@@ -72,12 +74,13 @@ require (
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
sigs.k8s.io/gateway-api-inference-extension v0.5.0 // indirect
sigs.k8s.io/gateway-api-inference-extension v1.1.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
require (
@@ -86,29 +89,28 @@ require (
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.11.7 // indirect
github.com/RageCage64/multilinediff v0.2.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.17.6 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.16 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.16 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2 v1.39.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.31.12 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.18.16 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 // indirect
github.com/aws/smithy-go v1.23.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
github.com/buger/goterm v1.0.4 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect
@@ -129,7 +131,7 @@ require (
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
@@ -142,7 +144,7 @@ require (
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonpointer v0.21.2 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
@@ -153,17 +155,17 @@ require (
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/cel-go v0.25.0 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/cel-go v0.26.0 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
@@ -175,7 +177,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/yaml v0.1.0 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/jonboulle/clockwork v0.5.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
@@ -198,7 +200,7 @@ require (
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/miekg/dns v1.1.66 // indirect
github.com/miekg/dns v1.1.68 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
@@ -213,7 +215,7 @@ require (
github.com/moby/sys/symlink v0.2.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
@@ -225,11 +227,11 @@ require (
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/prometheus/prometheus v0.303.1 // indirect
github.com/prometheus/common v0.67.1 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/prometheus/prometheus v0.307.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rubenv/sql-migrate v1.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -254,54 +256,53 @@ require (
github.com/xlab/treeprint v1.2.0 // indirect
github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 // indirect
github.com/zmap/zlint/v3 v3.6.3 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
go.opentelemetry.io/otel v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/exp v0.0.0-20250717185816-542afb5b7346 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.34.0 // indirect
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
golang.org/x/crypto v0.42.0 // indirect
golang.org/x/exp v0.0.0-20250808145144-a408d31f581a // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/term v0.35.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/time v0.13.0 // indirect
golang.org/x/tools v0.37.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect
google.golang.org/grpc v1.76.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9 // indirect
istio.io/client-go v1.27.1-0.20250820130622-12f6d11feb40 // indirect
k8s.io/apiextensions-apiserver v0.33.3 // indirect
k8s.io/apiserver v0.33.3 // indirect
k8s.io/component-base v0.33.3 // indirect
k8s.io/apiextensions-apiserver v0.34.1 // indirect
k8s.io/apiserver v0.34.1 // indirect
k8s.io/component-base v0.34.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
sigs.k8s.io/gateway-api v1.3.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect
sigs.k8s.io/gateway-api v1.4.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
)
replace istio.io/api => ../external/api

View File

@@ -54,7 +54,7 @@ cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJN
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@@ -355,7 +355,7 @@ cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzc
cloud.google.com/go/compute v1.23.4/go.mod h1:/EJMj55asU6kAFnuZET8zqgwgJ9FvXWXOkkfQZa4ioI=
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls=
cloud.google.com/go/compute v1.28.0 h1:OPtBxMcheSS+DWfci803qvPly3d4w7Eu5ztKBcFfzwk=
cloud.google.com/go/compute v1.38.0 h1:MilCLYQW2m7Dku8hRIIKo4r0oKastlD74sSu16riYKs=
cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
@@ -363,8 +363,9 @@ cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2Aawl
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
cloud.google.com/go/compute/metadata v0.8.4 h1:oXMa1VMQBVCyewMIOm3WQsnVd9FbKBtm8reqWRaXnHQ=
cloud.google.com/go/compute/metadata v0.8.4/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
@@ -1355,8 +1356,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
@@ -1405,30 +1406,32 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go-v2 v1.17.6 h1:Y773UK7OBqhzi5VDXMi1zVGsoj+CVHs2eaC2bDsLwi0=
github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
github.com/aws/aws-sdk-go-v2/config v1.18.16 h1:4r7gsCu8Ekwl5iJGE/GmspA2UifqySCCkyyyPFeWs3w=
github.com/aws/aws-sdk-go-v2/config v1.18.16/go.mod h1:XjM6lVbq7UgELp9NjXBrb1DQY/ownlWsvDhEQksemJc=
github.com/aws/aws-sdk-go-v2/credentials v1.13.16 h1:GgToSxaENX/1zXIGNFfiVk4hxryYJ5Vt4Mh8XLAL7Lc=
github.com/aws/aws-sdk-go-v2/credentials v1.13.16/go.mod h1:KP7aFJhfwPFgx9aoVYL2nYHjya5WBD98CWaadpgmnpY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24 h1:5qyqXASrX2zy5cTnoHHa4N2c3Lc94GH7gjnBP3GwKdU=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24/go.mod h1:neYVaeKr5eT7BzwULuG2YbLhzWZ22lpjKdCybR7AXrQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 h1:y+8n9AGDjikyXoMBTRaHHHSaFEB8267ykmvyPodJfys=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30/go.mod h1:LUBAO3zNXQjoONBKn/kR1y0Q4cj/D02Ts0uHYjcCQLM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 h1:r+Kv+SEJquhAZXaJ7G4u44cIwXV3f8K+N482NNAzJZA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31 h1:hf+Vhp5WtTdcSdE+yEcUz8L73sAzN0R+0jQv+Z51/mI=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31/go.mod h1:5zUjguZfG5qjhG9/wqmuyHRyUftl2B5Cp6NNxNC6kRA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 h1:c5qGfdbCHav6viBwiyDns3OXqhqAbGjfIB4uVu2ayhk=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24/go.mod h1:HMA4FZG6fyib+NDo5bpIxX1EhYjrAOveZJY2YR0xrNE=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5 h1:bdKIX6SVF3nc3xJFw6Nf0igzS6Ff/louGq8Z6VP/3Hs=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5/go.mod h1:vuWiaDB30M/QTC+lI3Wj6S/zb7tpUK2MSYgy3Guh2L0=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5 h1:xLPZMyuZ4GuqRCIec/zWuIhRFPXh2UOJdLXBSi64ZWQ=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5/go.mod h1:QjxpHmCwAg0ESGtPQnLIVp7SedTOBMYy+Slr3IfMKeI=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6 h1:rIFn5J3yDoeuKCE9sESXqM5POTAhOP1du3bv/qTL+tE=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6/go.mod h1:48WJ9l3dwP0GSHWGc5sFGGlCkuA82Mc2xnw+T6Q8aDw=
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I=
github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8=
github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8=
github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI=
github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8=
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -1461,8 +1464,8 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k
github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA=
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
@@ -1521,8 +1524,8 @@ github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVM
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
@@ -1594,8 +1597,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
@@ -1635,8 +1638,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM=
github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
@@ -1652,8 +1655,8 @@ github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpj
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
@@ -1673,8 +1676,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonpointer v0.21.2 h1:AqQaNADVwq/VnkCmQg6ogE+M3FOsKTytwges0JdwVuA=
github.com/go-openapi/jsonpointer v0.21.2/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
@@ -1766,15 +1769,15 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY=
github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ=
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -1823,8 +1826,8 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a h1:rDA3FfmxwXR+BVKKdz55WwMJ1pD2hJQNW31d+l3mPk4=
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/pprof v0.0.0-20250923004556-9e5a51aed1e8 h1:ZI8gCoCjGzPsum4L21jHdQs8shFBIQih1TM9Rd/c+EQ=
github.com/google/pprof v0.0.0-20250923004556-9e5a51aed1e8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM=
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
@@ -1881,15 +1884,16 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM=
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -1942,12 +1946,10 @@ github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLl
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -2057,8 +2059,8 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
@@ -2104,8 +2106,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
@@ -2124,12 +2127,12 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE=
github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -2181,8 +2184,8 @@ github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -2191,16 +2194,16 @@ github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvM
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI=
github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/prometheus/prometheus v0.303.1 h1:He/2jRE6sB23Ew38AIoR1WRR3fCMgPlJA2E0obD2WSY=
github.com/prometheus/prometheus v0.303.1/go.mod h1:WEq2ogBPZoLjj9x5K67VEk7ECR0nRD9XCjaOt1lsYck=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/prometheus/prometheus v0.307.1 h1:Hh3kRMFn+xpQGLe/bR6qpUfW4GXQO0spuYeY7f2JZs4=
github.com/prometheus/prometheus v0.307.1/go.mod h1:/7YQG/jOLg7ktxGritmdkZvezE1fa6aWDj0MGDIZvcY=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -2294,8 +2297,9 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg=
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
@@ -2376,14 +2380,14 @@ go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQ
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
@@ -2392,14 +2396,15 @@ go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFu
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
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/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c=
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
@@ -2410,19 +2415,22 @@ go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
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/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
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 v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
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/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
@@ -2431,10 +2439,12 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
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.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@@ -2449,10 +2459,10 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -2495,8 +2505,8 @@ golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ug
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@@ -2542,8 +2552,8 @@ golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -2629,8 +2639,8 @@ golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2675,8 +2685,8 @@ golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo=
golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -2704,8 +2714,8 @@ golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2823,8 +2833,8 @@ golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -2857,8 +2867,8 @@ golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2887,8 +2897,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2896,8 +2906,8 @@ golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -2967,8 +2977,8 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2983,6 +2993,8 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
@@ -3228,8 +3240,8 @@ google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqt
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU=
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
@@ -3266,8 +3278,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw=
@@ -3325,8 +3337,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -3384,8 +3396,9 @@ google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFN
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
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/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -3414,8 +3427,9 @@ google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=
@@ -3427,8 +3441,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
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=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -3462,28 +3476,28 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4=
k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E=
k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA=
k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo=
k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA=
k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4=
k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A=
k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 h1:liMHz39T5dJO1aOKHLvwaCjDbf07wVh6yaUlTpunnkE=
k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
k8s.io/kubectl v0.33.3 h1:r/phHvH1iU7gO/l7tTjQk2K01ER7/OAJi8uFHHyWSac=
k8s.io/kubectl v0.33.3/go.mod h1:euj2bG56L6kUGOE/ckZbCoudPwuj4Kud7BR0GzyNiT0=
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
@@ -3552,25 +3566,23 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1 h1:Cf+ed5N8038zbsaXFO7mKQDi/+VcSRafb0jM84KX5so=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/gateway-api v1.3.0 h1:q6okN+/UKDATola4JY7zXzx40WO4VISk7i9DIfOvr9M=
sigs.k8s.io/gateway-api v1.3.0/go.mod h1:d8NV8nJbaRbEKem+5IuxkL8gJGOZ+FJ+NvOIltV8gDk=
sigs.k8s.io/gateway-api-inference-extension v0.5.0 h1:bYtXffUF1WUUFT2gYXaQBXIEXxXq/ZZLP9gqQweTrBI=
sigs.k8s.io/gateway-api-inference-extension v0.5.0/go.mod h1:lki0jx1qysZSZT4Ai2BxuAcpx6G8g5oBgOGuuJzjy/k=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y=
sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
sigs.k8s.io/gateway-api v1.4.0 h1:ZwlNM6zOHq0h3WUX2gfByPs2yAEsy/EenYJB78jpQfQ=
sigs.k8s.io/gateway-api v1.4.0/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk=
sigs.k8s.io/gateway-api-inference-extension v1.1.0 h1:MqRYk+3LNUWB0MbTgTZVhmJGNDTvm8l3ze4MOlzR7MU=
sigs.k8s.io/gateway-api-inference-extension v1.1.0/go.mod h1:BmJy8Hvc2EHl3Oa/Ka8/4RqwVHCCbX7BLndLdMNtugI=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c h1:F7hIEutAxtXDOQX9NXFdvhWmWETu2zmUPHuPPcAez7g=
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c/go.mod h1:DPFniRsBzCeLB4ANjlPEvQQt9QGIX489d1faK+GPvI4=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

770
hgctl/pkg/agent/README.md Normal file
View File

@@ -0,0 +1,770 @@
// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
# Agent Module
`pkg/agent` 是 hgctl 中用于 Agent 生命周期管理的核心模块,提供了从创建、配置、部署到发布的完整工作流。
## 目录
- [概述](#概述)
- [架构设计](#架构设计)
- [核心功能](#核心功能)
- [主要组件](#主要组件)
- [使用方式](#使用方式)
- [配置管理](#配置管理)
- [部署方式](#部署方式)
- [集成说明](#集成说明)
## 概述
Agent 模块提供了一套完整的 AI Agent 开发和部署解决方案,支持:
- **多种 Agentic Core**:集成 Claude Code 和 Qodercli
- **本地和云端部署**:支持本地运行和 AgentRun (阿里云函数计算)
- **MCP Server 管理**:支持 HTTP 和 OpenAPI 类型的 MCP Server
- **Higress 集成**:自动发布 Agent API 到 Higress 网关
- **Himarket 发布**:支持将 Agent 发布到 Himarket 市场
## 架构设计
```
pkg/agent/
├── agent.go # CLI 命令入口和主要业务逻辑
├── core.go # Agentic Core (Claude/Qodercli) 封装
├── new.go # Agent 创建流程
├── deploy.go # Agent 部署处理(本地/云端)
├── mcp.go # MCP Server 管理
├── config.go # 配置管理和初始化
├── base.go # 基础函数和环境检查
├── types.go # 类型定义
├── utils.go # 工具函数
├── common/ # 通用类型定义
│ └── base.go # ProductType 等常量
├── services/ # 外部服务客户端
│ ├── client.go # HTTP 客户端封装
│ ├── service.go # Higress/Himarket API 封装
│ └── utils.go # 服务工具函数
└── prompt/ # Prompt 模板和指导
├── base.go # Agent 开发指南
└── agent_guide.md
```
## 核心功能
### 1. Agent 创建 (new.go)
提供两种 Agent 创建方式:
#### 1.1 交互式创建
通过命令行交互式问答,逐步配置:
- Agent 名称和描述
- 系统 Prompt支持直接输入、从文件导入、LLM 生成)
- AI 模型配置DashScope、OpenAI、Anthropic 等)
- 工具集选择AgentScope 内置工具)
- MCP Server 配置
- 部署设置
#### 1.2 从 Core 导入
从 Agentic Core 的 subagent 目录导入已有的 Agent 配置。
**关键代码位置**:
- `createAgentCmd()` (new.go:99): 创建命令定义
- `getAgentConfig()` (utils.go:289): 获取 Agent 配置
- `createAgentTemplate()` (new.go:205): 生成 Agent 模板文件
### 2. Agent 部署 (deploy.go)
支持两种部署模式:
#### 2.1 本地部署 (Local)
- 基于 AgentScope Runtime
- 自动管理 Python 虚拟环境
- 依赖管理:`agentscope`, `agentscope-runtime==1.0.0`
- 默认端口8090
#### 2.2 云端部署 (AgentRun)
- 部署到阿里云函数计算
- 使用 Serverless Devs (s工具)
- 自动构建和部署
- 需要配置阿里云 Access Key
**关键代码位置**:
- `DeployHandler` (deploy.go:35): 部署处理器
- `HandleLocal()` (deploy.go:350): 本地部署逻辑
- `HandleAgentRun()` (deploy.go:305): AgentRun 部署逻辑
### 3. MCP Server 管理 (mcp.go)
支持两种类型的 MCP Server
#### 3.1 HTTP MCP Server
直接通过 HTTP URL 添加:
```bash
hgctl mcp add [name] [url] --type http
```
#### 3.2 OpenAPI MCP Server
从 OpenAPI 规范文件创建:
```bash
hgctl mcp add [name] [spec-file] --type openapi
```
功能特性:
- 自动解析 OpenAPI 规范
- 转换为 MCP Server 配置
- 自动添加到 Agentic Core
- 可选发布到 Higress
- 支持发布到 Himarket 市场
**关键代码位置**:
- `handleAddMCP()` (mcp.go:183): MCP 添加主逻辑
- `publishMCPToHigress()` (mcp.go:228): 发布到 Higress
- `parseOpenapi2MCP()` (utils.go:79): OpenAPI 解析
### 4. Agentic Core 集成 (core.go)
封装了 Agentic CoreClaude Code/Qodercli的交互
#### 支持的 Core 类型
```go
const (
CORE_CLAUDE CoreType = "claude"
CORE_QODERCLI CoreType = "qodercli"
)
```
#### 核心功能
- **Setup()**: 初始化环境和插件
- **Start()**: 启动交互式窗口
- **AddMCPServer()**: 添加 MCP Server 到 Core
- **ImproveNewAgent()**: 在特定 Agent 目录运行 Core 进行改进
**关键代码位置**:
- `AgenticCore` (core.go:32): Core 封装结构
- `Setup()` (core.go:108): 环境初始化
- `addHigressAPIMCP()` (core.go:161): 自动添加 Higress API MCP
### 5. Higress 集成
自动将 Agent API 发布到 Higress 网关:
#### 支持的 API 类型
```go
const (
A2A = "a2a" // Agent-to-Agent
REST = "restful" // RESTful API
MODEL = "model" // AI Model API
)
```
#### 发布流程
1. 创建 AI Provider Service
2. 创建 AI Route
3. 配置服务源和路由
**关键代码位置**:
- `publishAgentAPIToHigress()` (agent.go:123): 发布逻辑
- `services/service.go`: Higress API 封装
### 6. Himarket 集成
支持将 Agent 发布到 Himarket 市场:
#### 产品类型
```go
const (
MCP_SERVER ProductType = "MCP_SERVER"
MODEL_API ProductType = "MODEL_API"
REST_API ProductType = "REST_API"
AGENT_API ProductType = "AGENT_API"
)
```
**关键代码位置**:
- `publishAPIToHimarket()` (base.go:128): 发布到市场
- `services/service.go`: Himarket API 封装
## 主要组件
### AgentConfig 结构
Agent 的核心配置结构:
```go
type AgentConfig struct {
AppName string // 应用名称
AppDescription string // 应用描述
AgentName string // Agent 名称
AvailableTools []string // 可用工具列表
SysPromptPath string // 系统 Prompt 路径
ChatModel string // 使用的模型
Provider string // 模型提供商
APIKeyEnvVar string // API Key 环境变量
DeploymentPort int // 部署端口
HostBinding string // 主机绑定
EnableStreaming bool // 是否启用流式响应
EnableThinking bool // 是否启用思考过程
MCPServers []MCPServerConfig // MCP Server 配置
Type DeployType // 部署类型
ServerlessCfg ServerlessConfig // Serverless 配置
}
```
### 环境检查 (base.go)
`EnvProvisioner` 负责检查和安装必要的环境:
#### Node.js 检查
- 最低版本要求Node.js 18+
- 支持自动安装(通过 fnm
#### Agentic Core 检查
- 检查 claude 或 qodercli 是否安装
- 支持自动安装(通过 npm
**关键代码位置**:
- `EnvProvisioner.check()` (base.go:221): 环境检查
- `promptNodeInstall()` (base.go:259): Node.js 安装引导
- `promptAgentInstall()` (base.go:401): Core 安装引导
## 使用方式
### 命令结构
```bash
hgctl agent # 启动交互式 Agent 窗口
hgctl agent new # 创建新 Agent
hgctl agent deploy [name] # 部署 Agent
hgctl agent add [name] [url] # 添加 Agent API 到 Higress
hgctl mcp add [name] [url] # 添加 MCP Server
```
### 创建 Agent
#### 本地部署的 Agent
```bash
hgctl agent new
```
交互式选择:
1. 创建方式step by step / 从 Core 导入
2. Agent 名称和描述
3. 系统 Prompt 设置
4. 模型提供商和模型选择
5. 工具选择
6. MCP Server 配置
7. 部署设置
#### AgentRun 部署的 Agent
```bash
hgctl agent new --agent-run
```
额外配置:
- Resource Name
- Region
- Disk Size
- Timeout
### 部署 Agent
#### 部署到本地
```bash
hgctl agent deploy my-agent
```
自动处理:
- Python 环境检查
- 依赖安装
- 启动 Agent 服务
#### 部署到 AgentRun
```bash
hgctl agent deploy my-agent
```
要求:
- 已配置阿里云 Access Key
- 已安装 Docker
- 已安装 Serverless Devs CLI
### 添加 MCP Server
#### 添加 HTTP MCP Server
```bash
hgctl mcp add my-mcp http://localhost:8080/mcp \
--type http \
--transport streamable \
-e API_KEY=secret \
-H "Authorization: Bearer token"
```
参数说明:
- `--type`: MCP 类型http/openapi
- `--transport`: 传输类型streamable/sse
- `-e`: 环境变量
- `-H`: HTTP 头部
#### 从 OpenAPI 创建 MCP Server
```bash
hgctl mcp add swagger-mcp ./openapi.yaml \
--type openapi
```
自动完成:
1. 解析 OpenAPI 规范
2. 转换为 MCP 配置
3. 发布到 Higress
4. 添加到 Agentic Core
### 发布到 Higress 和 Himarket
```bash
hgctl agent add my-agent http://my-agent.com \
--type model \
--as-product \
--higress-console-url http://console.higress.io \
--higress-console-user admin \
--higress-console-password password \
--himarket-admin-url http://himarket.io \
--himarket-admin-user admin \
--himarket-admin-password password
```
## 配置管理
### 配置文件
配置文件位置:`~/.hgctl`
```json
{
"hgctl-agent-core": "claude",
"agent-chat-model": "qwen-plus",
"agent-model-provider": "DashScope",
"higress-console-url": "http://127.0.0.1:8080",
"higress-console-user": "admin",
"higress-console-password": "admin",
"higress-gateway-url": "http://127.0.0.1:80",
"himarket-admin-url": "",
"himarket-admin-user": "",
"himarket-admin-password": "",
"agentrun-model-name": "",
"agentrun-region": "cn-hangzhou"
}
```
### 配置项说明
| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| `hgctl-agent-core` | Agentic Core 类型 | `qodercli` |
| `agent-chat-model` | 默认聊天模型 | - |
| `agent-model-provider` | 默认模型提供商 | - |
| `higress-console-url` | Higress 控制台地址 | - |
| `higress-console-user` | Higress 用户名 | - |
| `higress-console-password` | Higress 密码 | - |
| `higress-gateway-url` | Higress 网关地址 | - |
| `himarket-admin-url` | Himarket 管理地址 | - |
| `himarket-admin-user` | Himarket 用户名 | - |
| `himarket-admin-password` | Himarket 密码 | - |
| `agentrun-model-name` | AgentRun 模型名 | - |
| `agentrun-region` | AgentRun 区域 | `cn-hangzhou` |
### 环境变量
配置也可以通过环境变量设置(自动转换,用下划线替换连字符):
```bash
export HIGRESS_CONSOLE_URL=http://127.0.0.1:8080
export HIGRESS_CONSOLE_USER=admin
export HIGRESS_CONSOLE_PASSWORD=admin
```
**代码位置**: `config.go:100` - `InitConfig()`
## 部署方式
### 本地部署 (Local)
#### 技术栈
- **Runtime**: AgentScope Runtime
- **Python**: 3.12+
- **依赖**:
- `agentscope`
- `agentscope-runtime==1.0.0`
#### 部署流程
1. 检查 Python 环境
2. 创建/激活虚拟环境 (`~/.hgctl/.venv`)
3. 安装依赖
4. 启动 Agent 服务
#### 生成的文件
```
~/.hgctl/agents/{agent-name}/
├── as_runtime_main.py # AgentScope Runtime 入口
├── agent.py # Agent 类定义
├── toolkit.py # 工具集
├── prompt.md # 系统 Prompt
├── CLAUDE.md # Claude 开发指南(如果使用 Claude
└── AGENTS.md # Qoder 开发指南(如果使用 Qodercli
```
**代码位置**: `deploy.go:350` - `HandleLocal()`
### 云端部署 (AgentRun)
#### 技术栈
- **平台**: 阿里云函数计算 (Function Compute)
- **SDK**: agentrun-sdk-python
- **工具**: Serverless Devs CLI
#### 部署流程
1. 检查环境Docker、Serverless Devs
2. 检查/配置 Access Key
3. 执行 `s build`
4. 执行 `s deploy`
#### 生成的文件
```
~/.hgctl/agents/{agent-name}/
├── agentrun_main.py # AgentRun 入口
├── agent.py # Agent 类定义
├── toolkit.py # 工具集
├── prompt.md # 系统 Prompt
├── requirements.txt # Python 依赖
└── s.yaml # Serverless Devs 配置
```
#### s.yaml 配置
```yaml
edition: 3.0.0
name: {agent-name}
access: hgctl-credential
resources:
fc-agentrun-demo:
component: fc3
props:
region: {region}
description: {description}
runtime: python3.12
code: ./
handler: agentrun_main.main
timeout: {timeout}
diskSize: {disk-size}
environmentVariables:
MODEL_NAME: {model-name}
{api-key-env}: {api-key}
customRuntimeConfig:
command:
- python3
args:
- agentrun_main.py
port: {port}
```
**代码位置**: `deploy.go:305` - `HandleAgentRun()`
## 集成说明
### Higress 集成
#### Service Source 创建
```go
// services/utils.go
func BuildServiceBodyAndSrv(name, rawURL string) (map[string]interface{}, string, int, error)
```
创建服务源:
- 解析 URL
- 提取域名、端口
- 生成服务名称
#### AI Provider 和 Route 创建
对于 MODEL 类型的 Agent
```go
// services/utils.go
func BuildAIProviderServiceBody(name, url string) map[string]interface{}
func BuildAddAIRouteBody(name, url string) map[string]interface{}
```
#### MCP Server 创建
支持两种类型:
- **DIRECT_ROUTE**: 直接路由到 MCP Server URL
- **OPEN_API**: 基于 OpenAPI 规范的工具配置
### Himarket 集成
#### API Product 创建
```go
// services/utils.go
func BuildAPIProductBody(name, desc string, typ string) map[string]interface{}
```
#### Product Reference
```go
func BuildRefModelAPIProductBody(gatewayId, productId, routeName string) map[string]interface{}
func BuildRefMCPAPIProductBody(gatewayId, productId, mcpServerName string) map[string]interface{}
```
### Agentic Core 集成
#### 初始化流程
1. 提取 manifest 文件到 `~/.hgctl/`
2. 提取 Core 相关文件到 `~/.claude/``~/.qoder/`
3. 添加预定义的 MCP Server
4. 自动配置 Higress API MCP Server
#### MCP Server 添加
```bash
{core} mcp add --transport {transport} {name} {url} \
--scope {scope} \
-e {env} \
-H {header}
```
**代码位置**: `core.go:236` - `AddMCPServer()`
## 类型定义 (types.go)
### API 请求/响应类型
用于与 AI 模型 API 交互:
```go
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type Request struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
FrequencyPenalty float64 `json:"frequency_penalty"`
PresencePenalty float64 `json:"presence_penalty"`
Stream bool `json:"stream"`
Temperature float64 `json:"temperature"`
Topp int32 `json:"top_p"`
}
type Response struct {
ID string `json:"id"`
Choices []Choice `json:"choices"`
Created int64 `json:"created"`
Model string `json:"model"`
Object string `json:"object"`
Usage Usage `json:"usage"`
}
```
### OpenAPI 相关类型
用于 OpenAPI 规范解析:
```go
type API struct {
OpenAPI string `yaml:"openapi"`
Info Info `yaml:"info"`
Servers []Server `yaml:"servers"`
Paths Paths `yaml:"paths"`
Components Components `yaml:"components"`
}
```
## Services 子包
### HigressClient
Higress API 客户端:
```go
type HigressClient struct {
baseURL string
username string
password string
client *http.Client
}
```
**主要方法**:
- `Get(path string) ([]byte, error)`
- `Post(path string, body interface{}) ([]byte, error)`
- `Put(path string, body interface{}) ([]byte, error)`
### HimarketClient
Himarket API 客户端:
```go
type HimarketClient struct {
baseURL string
username string
password string
client *http.Client
}
```
**主要方法**:
- `GetDevMCPServerProduct() (map[string]string, error)`
- `GetDevModelProduct() (map[string]string, error)`
## 工具函数 (utils.go)
### Kubernetes 相关
- `GetHigressGatewayServiceIP()`: 获取 Higress Gateway Service IP
- `extractServiceIP()`: 从 Service 提取 IP
- `getConsoleCredentials()`: 从 K8s Secret 获取控制台凭证
### Agent 配置
- `getAgentConfig()`: 交互式获取 Agent 配置
- `createAgentStepByStep()`: 逐步创建 Agent
- `importAgentFromCore()`: 从 Core 导入 Agent
### Query 函数
一系列用于交互式配置查询的函数:
- `queryAgentSysPrompt()`: 查询系统 Prompt
- `queryAgentTools()`: 查询工具选择
- `queryAgentModel()`: 查询模型配置
- `queryAgentMCP()`: 查询 MCP Server
- `queryDeploySettings()`: 查询部署设置
## 最佳实践
### 1. 开发流程
```bash
# 1. 创建 Agent
hgctl agent new
# 2. 使用 Core 改进和测试
# 选择 "Improve and test it using agentic core"
# 3. 部署 Agent
hgctl agent deploy my-agent
# 4. 添加到 Higress
hgctl agent add my-agent http://localhost:8090 --type model
# 5. (可选)发布到 Himarket
hgctl agent add my-agent http://localhost:8090 --type model --as-product
```
### 2. MCP Server 管理
```bash
# 添加 HTTP MCP Server
hgctl mcp add my-mcp http://mcp-server:8080/mcp
# 从 OpenAPI 创建 MCP Server
hgctl mcp add swagger-mcp ./openapi.yaml --type openapi
# 添加到 Higress 和 Himarket
hgctl mcp add my-mcp http://mcp-server:8080/mcp --as-product
```
### 3. 配置管理
```bash
# 使用配置文件
vim ~/.hgctl
# 或使用环境变量
export HIGRESS_CONSOLE_URL=http://127.0.0.1:8080
export HIGRESS_CONSOLE_USER=admin
export HIGRESS_CONSOLE_PASSWORD=admin
```
## 错误处理
### 常见错误
1. **Node.js 未安装**
- 自动提示安装选项
- 支持自动安装fnm
2. **Agentic Core 未安装**
- 自动提示安装选项
- 支持自动安装npm
3. **Python 环境问题**
- 自动创建虚拟环境
- 自动安装依赖
4. **Kubernetes 连接问题**
- 提供手动输入 kubeconfig 选项
- 支持自定义 namespace
5. **Higress/Himarket 认证失败**
- 检查配置文件
- 检查环境变量
- 尝试从 K8s Secret 自动获取
## 扩展开发
### 添加新的 Agentic Core
1.`config.go` 中添加新的 CoreType
2.`core.go` 中实现相应的方法
3. 更新 `EnvProvisioner` 支持新的安装方式
### 添加新的部署类型
1.`deploy.go` 中添加新的 DeployType
2. 实现相应的部署处理方法
3. 更新模板生成逻辑
### 添加新的 API 类型
1.`agent.go` 中添加新的 API Type 常量
2.`publishAgentAPIToHigress()` 中添加处理逻辑
3.`services/utils.go` 中添加相应的构建函数
## 依赖说明
### Go 依赖
- `github.com/spf13/cobra`: CLI 框架
- `github.com/spf13/viper`: 配置管理
- `github.com/AlecAivazis/survey/v2`: 交互式问答
- `github.com/fatih/color`: 终端颜色输出
- `k8s.io/client-go`: Kubernetes 客户端
### 外部工具
- **Node.js 18+**: Agentic Core 运行环境
- **Claude Code / Qodercli**: Agentic Core
- **Python 3.12+**: Agent Runtime
- **Docker**: AgentRun 部署
- **Serverless Devs CLI**: AgentRun 部署工具
## 参考资源
- [AgentScope 文档](https://modelscope.github.io/agentscope/)
- [Claude Code 文档](https://docs.claude.com/en/docs/claude-code/setup)
- [Qoder 文档](https://docs.qoder.com/zh/cli/quick-start)
- [Serverless Devs 文档](https://serverless-devs.com/docs/user-guide/install)
- [Higress 文档](https://higress.io/)
- [AgentRun 文档](https://github.com/Serverless-Devs/agentrun-sdk-python)
## License
Copyright (c) 2025 Alibaba Group Holding Ltd.
Licensed under the Apache License, Version 2.0

View File

@@ -15,32 +15,161 @@
package agent
import (
"fmt"
"io"
"github.com/alibaba/higress/hgctl/pkg/agent/services"
"github.com/spf13/cobra"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
// API Type
const (
A2A = "a2a"
REST = "restful"
MODEL = "model"
)
func NewAgentCmd() *cobra.Command {
agentCmd := &cobra.Command{
Use: "agent",
Short: "start the interactive agent window",
Short: "Start the interactive agent window",
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(handleAgentInvoke(cmd.OutOrStdout()))
cmdutil.CheckErr(invokeAgentCore(cmd.OutOrStdout()))
},
}
agentCmd.AddCommand(createAgentCmd())
agentCmd.AddCommand(deployAgentCmd())
agentCmd.AddCommand(newAgentAddCmd())
return agentCmd
}
func handleAgentInvoke(w io.Writer) error {
return getAgent().Start()
func invokeAgentCore(w io.Writer) error {
core, err := getCore()
if err != nil {
return fmt.Errorf("failed to get core: %s", err)
}
return core.Start()
}
// Sub-Agent1:
// 1. Parse the url provided by user to MCP server configuration.
// 2. Publish the parsed MCP Server to Higress
func addPrequisiteSubAgent() error {
type AgentAddArg struct {
HigressConsoleAuthArg
HimarketAdminAuthArg
name string
url string
typ string
scope string
asProduct bool
noPublish bool
}
func newAgentAddCmd() *cobra.Command {
arg := &AgentAddArg{}
cmd := &cobra.Command{
Use: "add [name] [url]",
Short: "add agent to local interactive window and publish it to higress (optional)",
Run: func(cmd *cobra.Command, args []string) {
arg.name = args[0]
arg.url = args[1]
resolveHigressConsoleAuth(&arg.HigressConsoleAuthArg)
resolveHimarketAdminAuth(&arg.HimarketAdminAuthArg)
cmdutil.CheckErr(handleAddAgent(cmd.OutOrStdout(), *arg))
},
Args: cobra.ExactArgs(2),
}
cmd.PersistentFlags().StringVarP(&arg.typ, "type", "t", MODEL, "Determine the agent's API type (a2a, model, restful) default is model")
cmd.PersistentFlags().StringVarP(&arg.scope, "scope", "s", "project", `Configuration scope (project or global)`)
cmd.PersistentFlags().BoolVar(&arg.noPublish, "no-publish", false, "If it's set then the agent API will not be plubished to Higress")
cmd.PersistentFlags().BoolVar(&arg.asProduct, "as-product", false, "If it's set then the agent API will be published to Himarket (no-publish must be false)")
addHigressConsoleAuthFlag(cmd, &arg.HigressConsoleAuthArg)
addHimarketAdminAuthFlag(cmd, &arg.HimarketAdminAuthArg)
return cmd
}
func handleAddAgent(writer io.Writer, arg AgentAddArg) error {
if err := validateArg(arg); err != nil {
return err
}
if !arg.noPublish {
if err := publishAgentAPIToHigress(arg); err != nil {
fmt.Printf("failed to publish agent api to higress: %s\n", err)
return err
}
fmt.Printf("Agent %s is published to Higress successfully\n", arg.name)
if arg.asProduct {
if err := publishAPIToHimarket(arg.typ, arg.name, arg.HimarketAdminAuthArg); err != nil {
fmt.Println("failed to publish it to himarket, please do it mannually")
return err
}
fmt.Printf("Agent %s is published to Himarket successfully\n", arg.name)
}
// TODO: pop up higress window
}
return nil
}
func publishAgentAPIToHigress(arg AgentAddArg) error {
client := services.NewHigressClient(arg.hgURL, arg.hgUser, arg.hgPassword)
switch arg.typ {
case A2A:
case MODEL:
// add ai service
body := services.BuildAIProviderServiceBody(arg.name, arg.url)
// Debug
// fmt.Printf("services: body: %v\n", body)
if resp, err := services.HandleAddAIProviderService(client, body); err != nil {
fmt.Println(string(resp))
return err
}
// add ai route
body = services.BuildAddAIRouteBody(arg.name, arg.url)
// fmt.Printf("Route body: %v\n", body)
if res, err := services.HandleAddAIRoute(client, body); err != nil {
fmt.Println(string(res))
return err
}
case REST:
srvName := fmt.Sprintf("agent-%s", arg.name)
body, targetSrvName, _, err := services.BuildServiceBodyAndSrv(srvName, arg.url)
if err != nil {
return fmt.Errorf("invalid url format: %s", err)
}
if resp, err := services.HandleAddServiceSource(client, body); err != nil {
fmt.Println(string(resp))
return err
}
if resp, err := services.HandleAddRoute(client, services.BuildAPIRouteBody(arg.name, targetSrvName)); err != nil {
fmt.Println(string(resp))
return err
}
default:
return fmt.Errorf("unsupported agent protocol type: %s", arg.typ)
}
return nil
}
func validateArg(arg AgentAddArg) error {
if !arg.noPublish {
return arg.HigressConsoleAuthArg.validate()
}
return nil
}

View File

@@ -15,47 +15,473 @@
package agent
import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/alibaba/higress/hgctl/pkg/agent/common"
"github.com/alibaba/higress/hgctl/pkg/agent/services"
"github.com/fatih/color"
"github.com/spf13/viper"
)
const (
AgentBinaryName = "claude"
BinaryVersion = "0.1.0"
DevVersion = "dev"
NodeLeastVersion = 18
AgentInstallCmd = "npm install -g @anthropic-ai/claude-code"
AgentReleasePage = "https://docs.claude.com/en/docs/claude-code/setup"
)
// set up the core env
// 1. check if npm is installed
// 2. check the npm version
// 3. install hgctl-agent
func getAgent() *AgenticCore {
if !checkAgentInstallStatus() {
fmt.Println("⚠️ Prerequisites not satisfied. Exiting...")
// exit directly
os.Exit(1)
}
return NewAgenticCore()
type HimarketAdminAuthArg struct {
hmURL string
hmUser string
hmPassword string
}
func checkAgentInstallStatus() bool {
// TODO: Support cross-platform:windows
// Developer's page
type HimarketDevAuthArg struct {
hmURL string
hmUser string
hmPassword string
}
if !checkNodeInstall() {
if err := promptNodeInstall(); err != nil {
return false
func (h *HimarketAdminAuthArg) validate() error {
if h.hmURL == "" || h.hmUser == "" || h.hmPassword == "" {
return fmt.Errorf("invalid args")
}
return nil
}
type HigressConsoleAuthArg struct {
// higress console auth arg
hgURL string
hgUser string
hgPassword string
}
func (h *HigressConsoleAuthArg) validate() error {
if h.hgURL == "" || h.hgUser == "" || h.hgPassword == "" {
fmt.Println("--higress-console-user, --higress-console-url, --higress-console-password must be provided")
return fmt.Errorf("invalid args")
}
return nil
}
func init() {
// Init the global configuration from config file
InitConfig()
}
func resolveHimarketAdminAuth(arg *HimarketAdminAuthArg) {
if arg.hmURL == "" {
arg.hmURL = viper.GetString(HIMARKET_ADMIN_URL)
}
if arg.hmUser == "" {
arg.hmUser = viper.GetString(HIMARKET_ADMIN_USER)
}
if arg.hmPassword == "" {
arg.hmPassword = viper.GetString(HIMARKET_ADMIN_PASSWORD)
}
}
// resolve from viper
func resolveHigressConsoleAuth(arg *HigressConsoleAuthArg) {
if arg.hgURL == "" {
arg.hgURL = viper.GetString(HIGRESS_CONSOLE_URL)
}
if arg.hgUser == "" {
arg.hgUser = viper.GetString(HIGRESS_CONSOLE_USER)
}
if arg.hgPassword == "" {
arg.hgPassword = viper.GetString(HIGRESS_CONSOLE_PASSWORD)
}
// fmt.Printf("arg: %v\n", arg)
if arg.hgUser == "" || arg.hgPassword == "" {
// Here we do not return this error, because it will failed when validate arg
if err := tryToGetLocalCredential(arg); err != nil {
fmt.Printf("failed to get local higress console credential: %s\n", err)
}
}
}
func parseTypeToAPIProductType(typ string) string {
switch typ {
case "a2a":
return string(common.AGENT_API)
case "restful":
return string(common.REST_API)
case "model":
return string(common.MODEL_API)
case "mcp":
return string(common.MCP_SERVER)
default:
return ""
}
}
// This function serves MCP API as well as Model API for now.
func publishAPIToHimarket(typ, name string, arg HimarketAdminAuthArg) error {
if err := arg.validate(); err != nil {
return err
}
client := services.NewHimarketClient(arg.hmURL, arg.hmUser, arg.hmPassword)
productName := fmt.Sprintf("%s-%s", typ, name)
var gatewayId = viper.GetString(HIMARKET_TARGET_HIGRESS_ID)
prompt := survey.Input{
Message: fmt.Sprintf("Enter the target Higress instance id on Himarket(%s):", gatewayId),
Default: gatewayId,
Help: fmt.Sprintf("refers to %s/consoles/gateway to get your target Higress instance's id", arg.hmURL),
}
if err := survey.AskOne(&prompt, &gatewayId); err != nil {
return fmt.Errorf("failed to get target higress gatewayID: %s", err)
}
body := services.BuildAPIProductBody(productName, "An agent API import by hgctl", parseTypeToAPIProductType(typ))
resp, err := services.HandleAddAPIProduct(client, body)
if err != nil {
fmt.Println(resp)
return err
}
product_id := string(resp)
var refBody map[string]interface{}
if typ == "mcp" {
refBody = services.BuildRefMCPAPIProductBody(gatewayId, product_id, name)
} else {
// target_route is the route_name in Higress, refers to `publishAgentAPIToHigress`
target_route := fmt.Sprintf("%s-route", name)
refBody = services.BuildRefModelAPIProductBody(gatewayId, product_id, target_route)
}
if resp, err := services.HandleRefAPIProduct(client, product_id, refBody); err != nil {
fmt.Println(string(resp))
return err
}
return nil
}
// use pre-defined command /gen-agent to generate sys prompt
func generateAgentPromptByCore(desc string) (string, error) {
core := NewAgenticCore()
prompt, err := core.runWithResult(fmt.Sprintf("/gen-agent %s", desc), "--print")
if err != nil {
return "", err
}
return prompt, nil
}
type EnvProvisioner struct {
core CoreType
installCmd string
releasePage string
// ~/.<core>
dirName string
}
func getCore() (*AgenticCore, error) {
provisioner := EnvProvisioner{
core: CoreType(viper.GetString(HGCTL_AGENT_CORE)),
}
if err := provisioner.check(); err != nil {
return nil, fmt.Errorf("⚠️ Prerequisites not satisfied: %s Exiting...", err)
}
return NewAgenticCore(), nil
}
func (p *EnvProvisioner) init() {
switch p.core {
case CORE_QODERCLI:
p.installCmd = "npm install -g @qoder-ai/qodercli"
p.releasePage = "https://docs.qoder.com/zh/cli/quick-start"
p.dirName = "qoder"
case CORE_CLAUDE:
p.installCmd = "npm install -g @anthropic-ai/claude-code"
p.releasePage = "https://docs.claude.com/en/docs/claude-code/setup"
p.dirName = "claude"
}
}
func (p *EnvProvisioner) check() error {
p.init()
if !p.checkNodeInstall() {
if err := p.promptNodeInstall(); err != nil {
return err
}
}
if !checkAgentInstall() {
if err := promptAgentInstall(); err != nil {
return false
if !p.checkAgentInstall() {
if err := p.promptAgentInstall(); err != nil {
return err
}
}
return nil
}
func (p *EnvProvisioner) checkNodeInstall() bool {
cmd := exec.Command("node", "-v")
out, err := cmd.Output()
if err != nil {
return false
}
versionStr := strings.TrimPrefix(strings.TrimSpace(string(out)), "v")
parts := strings.Split(versionStr, ".")
if len(parts) == 0 {
return false
}
major, err := strconv.Atoi(parts[0])
if err != nil {
return false
}
return major >= NodeLeastVersion
}
func (p *EnvProvisioner) promptNodeInstall() error {
fmt.Println()
color.Yellow("⚠️ Node.js is not installed or not found in PATH.")
color.Cyan("🔧 Node.js is required to run the agent.")
fmt.Println()
options := []string{
"🚀 Install automatically (recommended)",
"📖 Exit and show manual installation guide",
}
var ans string
prompt := &survey.Select{
Message: "How would you like to install Node.js?",
Options: options,
}
if err := survey.AskOne(prompt, &ans); err != nil {
return fmt.Errorf("selection error: %w", err)
}
switch ans {
case options[0]:
fmt.Println()
color.Green("🚀 Installing Node.js automatically...")
if err := p.installNodeAutomatically(); err != nil {
color.Red("❌ Installation failed: %v", err)
fmt.Println()
p.showNodeManualInstallation()
return errors.New("node.js installation failed")
}
color.Green("✅ Node.js installation completed!")
fmt.Println()
color.Blue("🔍 Verifying installation...")
if p.checkNodeInstall() {
color.Green("🎉 Node.js is now available!")
return nil
} else {
color.Yellow("⚠️ Node.js installation completed but not found in PATH.")
color.Cyan("💡 You may need to restart your terminal or source your shell profile.")
return errors.New("node.js installed but not in PATH")
}
case options[1]:
p.showNodeManualInstallation()
return errors.New("node.js not installed")
default:
return errors.New("invalid selection")
}
}
func (p *EnvProvisioner) installNodeAutomatically() error {
homeDir, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("could not get home directory: %w", err)
}
fnmBinPath := filepath.Join(homeDir, ".local/share/fnm/fnm")
if runtime.GOOS == "windows" {
fnmBinPath = filepath.Join(homeDir, "AppData/Roaming/fnm/fnm.exe")
}
switch runtime.GOOS {
case "windows":
color.Cyan("📦 For Windows, we recommend installing fnm via: 'winget install Schniz.fnm'")
return errors.New("automatic fnm installation on Windows is not implemented in this script")
case "darwin", "linux":
color.Cyan("🚀 Installing fnm (Fast Node Manager)...")
installFnmCmd := exec.Command("bash", "-c", "curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell")
installFnmCmd.Stdout = os.Stdout
installFnmCmd.Stderr = os.Stderr
if err := installFnmCmd.Run(); err != nil {
return fmt.Errorf("failed to install fnm: %w", err)
}
if _, err := os.Stat(fnmBinPath); os.IsNotExist(err) {
path, err := exec.LookPath("fnm")
if err == nil {
fnmBinPath = path
} else {
return errors.New("fnm was installed but binary not found at " + fnmBinPath)
}
}
color.Cyan("📦 Installing Node.js via fnm...")
installNodeCmd := exec.Command(fnmBinPath, "install", "--lts")
installNodeCmd.Stdout = os.Stdout
installNodeCmd.Stderr = os.Stderr
if err := installNodeCmd.Run(); err != nil {
return fmt.Errorf("failed to install node via fnm: %w", err)
}
color.Cyan("✅ Setting LTS as default Node.js version...")
useNodeCmd := exec.Command(fnmBinPath, "default", "lts-latest")
return useNodeCmd.Run()
default:
return errors.New("unsupported OS for automatic installation")
}
}
func (p *EnvProvisioner) showNodeManualInstallation() {
fmt.Println()
color.New(color.FgGreen, color.Bold).Println("📖 Manual Node.js Installation Guide")
fmt.Println()
fmt.Println(color.MagentaString("Choose one of the following installation methods:"))
fmt.Println()
color.Cyan("Method 1: Install via package manager")
color.Cyan("macOS (brew): brew install node")
color.Cyan("Ubuntu/Debian: sudo apt install -y nodejs npm")
color.Cyan("Windows: download from https://nodejs.org and run installer")
fmt.Println()
color.Yellow("Method 2: Download from official website")
color.Yellow("1. Download Node.js from https://nodejs.org/en/download/")
color.Yellow("2. Follow installer instructions and add to PATH if needed")
fmt.Println()
color.Green("✅ Verify Installation")
fmt.Println(color.WhiteString("node -v"))
fmt.Println(color.WhiteString("npm -v"))
fmt.Println()
color.Cyan("💡 After installation, restart your terminal or source your shell profile.")
fmt.Println()
}
func (p *EnvProvisioner) checkAgentInstall() bool {
cmd := exec.Command(string(p.core), "--version")
if err := cmd.Run(); err != nil {
return false
}
return true
}
func (p *EnvProvisioner) promptAgentInstall() error {
fmt.Println()
color.Yellow("⚠️ %s is not installed or not found in PATH.", p.core)
color.Cyan("🔧 %s is required to run the agent.", p.core)
fmt.Println()
options := []string{
"🚀 Install automatically",
"📖 Exit and show manual installation guide",
}
var ans string
prompt := &survey.Select{
Message: "How would you like to install " + string(p.core) + "?",
Options: options,
}
if err := survey.AskOne(prompt, &ans); err != nil {
return fmt.Errorf("selection error: %w", err)
}
switch ans {
case options[0]:
fmt.Println()
color.Green("🚀 Installing %s automatically...", p.core)
if err := p.installAgentAutomatically(); err != nil {
color.Red("❌ Installation failed: %v", err)
fmt.Println()
p.showAgentManualInstallation()
return errors.New(string(p.core) + " installation failed")
}
fmt.Println()
color.Blue("🔍 Verifying installation...")
if p.checkAgentInstall() {
color.Green("🎉 %s is now available!", p.core)
return nil
} else {
color.Yellow("⚠️ %s installed but not found in PATH.", p.core)
color.Cyan("💡 You may need to restart your terminal or source your shell profile.")
return errors.New(string(p.core) + " installed but not in PATH")
}
case options[1]:
p.showAgentManualInstallation()
return errors.New(string(p.core) + " not installed")
default:
return errors.New("invalid selection")
}
}
func (p *EnvProvisioner) installAgentAutomatically() error {
switch runtime.GOOS {
case "windows":
cmd := exec.Command("cmd", "/C", p.installCmd)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
case "darwin":
cmd := exec.Command("bash", "-c", p.installCmd)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
case "linux":
cmd := exec.Command("bash", "-c", p.installCmd)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
default:
return errors.New("unsupported OS for automatic installation")
}
}
func (p *EnvProvisioner) showAgentManualInstallation() {
fmt.Println()
color.New(color.FgGreen, color.Bold).Printf("📖 Manual %s Installation Guide\n", p.core)
fmt.Println()
color.Cyan(fmt.Sprintf("1. Go to official release page: %s", p.releasePage))
fmt.Printf(color.CyanString("2. Download %s for your OS\n"), p.core)
color.Cyan("3. Make it executable and place it in a directory in your PATH")
fmt.Println()
color.Cyan("💡 After installation, restart your terminal or source your shell profile.")
fmt.Println()
}

View File

@@ -0,0 +1,25 @@
// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package common
// Himarket Product Type
type ProductType string
const (
MCP_SERVER ProductType = "MCP_SERVER"
MODEL_API ProductType = "MODEL_API"
REST_API ProductType = "REST_API"
AGENT_API ProductType = "AGENT_API"
)

129
hgctl/pkg/agent/config.go Normal file
View File

@@ -0,0 +1,129 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package agent
import (
"fmt"
"log"
"os"
"github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
)
type CoreType string
const (
CORE_CLAUDE CoreType = "claude"
CORE_QODERCLI CoreType = "qodercli"
)
const (
// AgentBinaryName = "claude"
// BinaryVersion = "0.1.0"
// DevVersion = "dev"
// NodeLeastVersion = 18
// AgentInstallCmd = "npm install -g @anthropic-ai/claude-code"
// AgentReleasePage = "https://docs.claude.com/en/docs/claude-code/setup"
HGCTL_AGENT_CORE = "hgctl-agent-core"
AGENT_MODEL_PROVIDER = "agent-model-provider"
AGENT_CHAT_MODEL = "agent-chat-model"
HIGRESS_CONSOLE_URL = "higress-console-url"
HIGRESS_CONSOLE_USER = "higress-console-user"
HIGRESS_CONSOLE_PASSWORD = "higress-console-password"
HIGRESS_GATEWAY_URL = "higress-gateway-url"
HIMARKET_ADMIN_URL = "himarket-admin-url"
HIMARKET_ADMIN_USER = "himarket-admin-user"
HIMARKET_ADMIN_PASSWORD = "himarket-admin-password"
HIMARKET_TARGET_HIGRESS_ID = "himarket-target-higress-id"
HIMARKET_DEVELOPER_URL = "himarket-developer-url"
HIMARKET_DEVELOPER_USER = "himarket-developer-user"
HIMARKET_DEVELOPER_PASSWORD = "himarket-developer-password"
// --- AgentRun ---
AGENTRUN_MODEL_NAME = "agentrun-model-name"
AGENTRUN_SANDBOX_NAME = "agentrun-sandbox-name"
ALIBABA_CLOUD_ACCESS_KEY_ID = "alibaba-cloud-access-key-id"
ALIBABA_CLOUD_ACCESS_KEY_SECRET = "alibaba-cloud-access-key-secret"
ALIBABA_CLOUD_SECURITY_TOK = "alibaba-cloud-security-tok"
AGENTRUN_ACCOUNT_ID = "agentrun-account-id"
AGENTRUN_REGION = "agentrun-region"
AGENTRUN_SDK_DEB = "agentrun-sdk-deb"
)
var GlobalConfig HgctlAgentConfig
type HgctlAgentConfig struct {
AgenticCore CoreType `mapstructure:"hgctl-agent-core"`
AgentChatModel string `mapstructure:"agent-chat-model"`
AgentModelProvider string `mapstructure:"agent-model-provider"`
// Higress Console credentials
HigressConsoleURL string `mapstructure:"higress-console-url"`
HigressConsoleUser string `mapstructure:"higress-console-user"`
HigressConsolePassword string `mapstructure:"higress-console-password"`
HigressGatewayURL string `mapstructure:"higress-gateway-url"`
// Himarket Admin credentials
HimarketAdminURL string `mapstructure:"himarket-admin-url"`
HimarketAdminUser string `mapstructure:"himarket-admin-user"`
HimarketAdminPassword string `mapstructure:"himarket-admin-password"`
HimarketTargetHigressID string `mapstructure:"himarket-target-higress-id"`
// Himarket Developer credentials
HimarketDeveloperURL string `mapstructure:"himarket-developer-url"`
HimarketDeveloperUser string `mapstructure:"himarket-developer-user"`
HimarketDeveloperPassword string `mapstructure:"himarket-developer-password"`
// AgentRun Configuration
AgentRunModelName string `mapstructure:"agentrun-model-name"`
AgentRunSandboxName string `mapstructure:"agentrun-sandbox-name"`
AlibabaCloudAccessKeyID string `mapstructure:"alibaba-cloud-access-key-id"`
AlibabaCloudAccessKeySecret string `mapstructure:"alibaba-cloud-access-key-secret"`
AlibabaCloudSecurityTok string `mapstructure:"alibaba-cloud-security-tok"`
AgentRunAccountID string `mapstructure:"agentrun-account-id"`
AgentRunRegion string `mapstructure:"agentrun-region"`
}
func InitConfig() {
viper.SetConfigName(".hgctl")
viper.SetConfigType("json")
home, err := homedir.Dir()
if err != nil {
log.Fatalf("Error finding home directory: %v", err)
}
viper.AddConfigPath(home)
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
fmt.Fprintf(os.Stderr, "Fatal error reading config file: %v\n", err)
}
}
// Unmarshal into the GlobalConfig variable
_ = viper.Unmarshal(&GlobalConfig)
// Validate supported AgentCore currently
switch viper.GetString(HGCTL_AGENT_CORE) {
case string(CORE_CLAUDE), string(CORE_QODERCLI):
return
default:
viper.SetDefault(HGCTL_AGENT_CORE, string(CORE_QODERCLI))
}
}

View File

@@ -15,19 +15,64 @@
package agent
import (
"encoding/base64"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/alibaba/higress/hgctl/pkg/manifests"
"github.com/alibaba/higress/hgctl/pkg/util"
"github.com/fatih/color"
"github.com/manifoldco/promptui"
"github.com/spf13/viper"
)
type AgenticCore struct {
binaryName string
}
func NewAgenticCore() *AgenticCore {
return &AgenticCore{}
core := &AgenticCore{
binaryName: viper.GetString(HGCTL_AGENT_CORE),
}
core.Setup()
return core
}
func (c *AgenticCore) run(args ...string) error {
cmd := exec.Command(AgentBinaryName, args...)
func (c *AgenticCore) GetPromptFileName() string {
switch c.binaryName {
case string(CORE_CLAUDE):
return "CLAUDE.md"
case string(CORE_QODERCLI):
return "AGENTS.md"
}
return ""
}
func (c *AgenticCore) GetCoreDirName() string {
switch c.binaryName {
case string(CORE_CLAUDE):
return ".claude"
case string(CORE_QODERCLI):
return ".qoder"
}
return ""
}
// This will use core to test and improve created agent
func (c *AgenticCore) ImproveNewAgent(config *AgentConfig) error {
agentDir, err := util.GetSpecificAgentDir(config.AgentName)
if err != nil {
return fmt.Errorf("failed to get agent directory: %s", agentDir)
}
return c.runInTargetDir(agentDir)
}
func (c *AgenticCore) runInTargetDir(dir string, args ...string) error {
cmd := exec.Command(c.binaryName, args...)
cmd.Dir = dir
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@@ -35,12 +80,188 @@ func (c *AgenticCore) run(args ...string) error {
}
func (c *AgenticCore) runWithResult(args ...string) (string, error) {
cmd := exec.Command(c.binaryName, args...)
output, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
return "", fmt.Errorf("agent execution failed with exit code %d: %s\nStderr: %s",
exitErr.ExitCode(), err.Error(), exitErr.Stderr)
}
return "", fmt.Errorf("failed to run agent: %w", err)
}
return string(output), nil
}
func (c *AgenticCore) run(args ...string) error {
cmd := exec.Command(c.binaryName, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
// setup additional prequisite environment and plugins manifest to user's profile
// e.g. ../manifest/agent
func (c *AgenticCore) Setup() {
// Check if this is the first time, otherwise directly return (TODO: this is a simple check)
homeDir, _ := os.UserHomeDir()
targetCtlDir := filepath.Join(homeDir, ".hgctl")
if _, err := os.Stat(targetCtlDir); err == nil {
return
}
targetCoreDir := filepath.Join(homeDir, c.GetCoreDirName())
// setup subagent plugins file
embedFS := manifests.BuiltinOrDir("")
if err := manifests.ExtractEmbedFiles(embedFS, "agent", targetCtlDir); err != nil {
fmt.Println(err)
fmt.Println("failed to init plugins for agent core")
os.Exit(1)
}
// Setup predefined files like: command.md
if err := manifests.ExtractEmbedFiles(embedFS, "agent", targetCoreDir); err != nil {
fmt.Println(err)
fmt.Println("failed to init commands for agent core")
os.Exit(1)
}
// Add Predefined MCP Server
if err := c.addPredefinedMCP(); err != nil {
fmt.Printf("Warning: failed to add needed mcp server: %s\n", err)
}
if err := c.addHigressAPIMCP(); err != nil {
fmt.Println("failed to init higress-api mcp server (you may need to add it manually):", err)
fmt.Println("Details information on Higress-api MCP server refers to https://github.com/alibaba/higress/blob/main/plugins/golang-filter/mcp-server/servers/higress/higress-api/README_en.md")
return
}
// fmt.Println("Higress-api MCP server added successfully")
}
func (c *AgenticCore) addPredefinedMCP() error {
// deepwikiArg := MCPAddArg{
// name: "deepwiki",
// url: "https://mcp.deepwiki.com/mcp",
// typ: "",
// transport: STREAMABLE,
// scope: "user",
// }
// if err := c.AddMCPServer(deepwikiArg); err != nil {
// return fmt.Errorf("deepwiki")
// }
return nil
}
func (c *AgenticCore) addHigressAPIMCP() error {
arg := &HigressConsoleAuthArg{
hgURL: viper.GetString(HIGRESS_GATEWAY_URL),
hgUser: viper.GetString(HIGRESS_CONSOLE_USER),
hgPassword: viper.GetString(HIGRESS_CONSOLE_PASSWORD),
}
fmt.Println("Initializing...Add prequisite MCP server (Higress-api MCP server) automatically")
if arg.hgURL == "" {
gatewayPrompt := promptui.Prompt{
Label: "Enter higress gateway URL",
Default: "http://127.0.0.1:80",
}
gateway, err := gatewayPrompt.Run()
if err != nil {
fmt.Println("failed to run gateway prompt: ", err)
return err
}
arg.hgURL = gateway
}
if arg.hgURL == "" || arg.hgPassword == "" {
if err := tryToGetLocalCredential(arg); err != nil || arg.hgUser == "" || arg.hgPassword == "" {
// fallback: interact with user to provide password & username
color.Red("failed to get higress-console credential automatically (Requires higress installed by hgctl). Let's do it manually")
userPrompt := promptui.Prompt{
Label: "Enter higress console username",
Default: "admin",
}
username, err := userPrompt.Run()
if err != nil {
return fmt.Errorf("aborted: %v", err)
}
pwdPrompt := promptui.Prompt{
Label: "Enter higress console password",
Default: "admin",
}
pwd, err := pwdPrompt.Run()
if err != nil {
return fmt.Errorf("aborted: %v", err)
}
arg.hgUser = username
arg.hgPassword = pwd
}
}
if arg.hgUser == "" || arg.hgPassword == "" {
return fmt.Errorf("Empty higress console username and password, aborting")
}
rawByte := fmt.Appendf(nil, "%s:%s", arg.hgUser, arg.hgPassword)
resStr := base64.StdEncoding.EncodeToString(rawByte)
authHeader := fmt.Sprintf("Authorization: Basic %s", resStr)
return c.AddMCPServer(MCPAddArg{
name: "higress-api",
url: fmt.Sprintf("%s/higress-api", arg.hgURL),
transport: HTTP,
typ: HTTP,
scope: "user",
header: []string{
authHeader,
},
})
}
// ------- Initialization -------
func (c *AgenticCore) Start() error {
return c.run(AgentBinaryName)
return c.run()
}
// ------- MCP -------
func (c *AgenticCore) AddMCPServer(name string, url string) error {
return c.run("mcp", "add", "--transport", HTTP, name, url)
func (c *AgenticCore) AddMCPServer(arg MCPAddArg) error {
// adapt the field
if arg.transport == STREAMABLE {
arg.transport = HTTP
}
args := []string{
"mcp", "add", "--transport", arg.transport, arg.name, arg.url,
}
if arg.scope != "" {
scopeArg := []string{"--scope", arg.scope}
args = append(args, scopeArg...)
}
if len(arg.env) != 0 {
for _, e := range arg.env {
envArg := []string{"-e", e}
args = append(args, envArg...)
}
}
if len(arg.header) != 0 {
for _, h := range arg.header {
headerArg := []string{"-H", h}
args = append(args, headerArg...)
}
}
err := c.run(args...)
// Allow to add duplicate mcp server name (core will return error)
if err == nil || strings.Contains(err.Error(), "already exists") {
return nil
}
return err
}

406
hgctl/pkg/agent/deploy.go Normal file
View File

@@ -0,0 +1,406 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package agent
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"github.com/alibaba/higress/hgctl/pkg/util"
"github.com/spf13/cobra"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
type DeployType string
const (
AgentRun DeployType = "agent-run"
Local DeployType = "local"
)
var (
AddAccessKeyCmd = fmt.Sprintf("s config add -a %s", DefaultServerLessAccessKey)
CheckAccessKeyCmd = fmt.Sprintf("s config get -a %s", DefaultServerLessAccessKey)
DeployAgentRunCmd = fmt.Sprintf("s deploy -a %s", DefaultServerLessAccessKey)
)
const (
InstallServerlessCmd = "npm install @serverless-devs/s -g"
BuildAgentCmd = "s build"
ServerlessCliDocs = "https://serverless-devs.com/docs/user-guide/install"
)
type DeployHandler struct {
Name string
AgentDir string
Type DeployType
}
func deployAgentCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deploy [name]",
Short: "Deploy the specified agent locally or to the cloud",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
handler := &DeployHandler{
Name: args[0],
}
cmdutil.CheckErr(handler.Deploy())
},
}
var cloud = false
cmd.PersistentFlags().BoolVar(&cloud, "agentrun", false, "deploy agent using agentrun")
return cmd
}
func (h *DeployHandler) validate() error {
if err := h.checkRequiredEnvironment(); err != nil {
return fmt.Errorf("failed to get required environment: %s", err)
}
return nil
}
func (h *DeployHandler) RunCmd(showOutput bool, cmd string, targetDir string) (string, error) {
runCmd := exec.Command("bash", "-c", cmd)
if targetDir != "" {
runCmd.Dir = targetDir
}
if showOutput {
runCmd.Stderr = os.Stderr
runCmd.Stdout = os.Stdout
if err := runCmd.Run(); err != nil {
return "", err
}
return "", nil
}
output, err := runCmd.CombinedOutput()
if err != nil {
return "", err
}
return string(output), nil
}
func (h *DeployHandler) RunPythonCmd(showOutput bool, args ...string) error {
cmd := exec.Command("python3", args...)
if showOutput {
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (h *DeployHandler) checkAgentRunEnvironment() error {
if _, err := h.RunCmd(false, "s --version", ""); err != nil {
fmt.Println("Serverless dev cli not installed, install it automatically..")
if _, err := h.RunCmd(true, InstallServerlessCmd, ""); err != nil {
return fmt.Errorf("failed to install serverless dev cli automatically, details refers to %s", ServerlessCliDocs)
}
}
if _, err := h.RunCmd(false, "docker --version", ""); err != nil {
return fmt.Errorf("docker is required to deploy agent to agentRun: %s", err)
}
return nil
}
func (h *DeployHandler) checkLocalEnvironment() error {
pyVenv, err := util.GetPythonVersion()
if err != nil {
fmt.Printf("Python environment not found, you need Python environment to run your agent\n")
return err
}
if util.CompareVersions(pyVenv, MinPythonVersion) == -1 {
fmt.Printf("Current Python: %s need Python %s+", MinPythonVersion, pyVenv)
return fmt.Errorf("unsupport python version")
}
missingDeps := []string{}
if err := h.RunPythonCmd(false, "-c", "import agentscope; print(agentscope.__version__)"); err != nil {
missingDeps = append(missingDeps, "agentscope")
}
if err := h.RunPythonCmd(false, "-c", "import agentscope_runtime; print(agentscope_runtime.__version__)"); err != nil {
missingDeps = append(missingDeps, "agentscope-runtime==1.0.0")
}
if len(missingDeps) != 0 {
venvDir := filepath.Join(util.GetHomeHgctlDir(), ".venv")
if _, err := os.Stat(venvDir); err == nil {
// check again
missingDeps := []string{}
if err := h.RunPythonCmd(false, "-c", "import agentscope; print(agentscope.__version__)"); err != nil {
fmt.Println("agentscope not installed, installing...")
missingDeps = append(missingDeps, "agentscope")
}
if err := h.RunPythonCmd(false, "-c", "import agentscope_runtime; print(agentscope_runtime.__version__)"); err != nil {
fmt.Println("agentscope-runtime not installed, installing...")
missingDeps = append(missingDeps, "agentscope-runtime==1.0.0")
}
// This means ~/.hgctl/.venv/ has already installed the deps before
if len(missingDeps) == 0 {
if err := h.activateLocalPythonVenv(); err != nil {
return err
}
}
}
if err := h.installLocalRequiredDeps(missingDeps); err != nil {
return fmt.Errorf("failed to install missing deps: %s", err)
}
}
return nil
}
func (h *DeployHandler) createLocalPyVenv() error {
venvDir := filepath.Join(util.GetHomeHgctlDir(), ".venv")
cmd := exec.Command("python3", "-m", "venv", venvDir)
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("failed to create python virtual environment", string(output))
return err
}
return nil
}
func (h *DeployHandler) installLocalRequiredDeps(missingDeps []string) error {
if err := h.RunPythonCmd(true, "-m", "pip", "--version"); err != nil {
fmt.Printf("Pip not installed, you need install pip to deploy your agent\n")
return err
}
fmt.Println("This may takes a few minutes, you can install missing deps by yourself: ")
for _, deps := range missingDeps {
fmt.Println("- ", deps)
}
if err := h.createLocalPyVenv(); err != nil {
return fmt.Errorf("failed to create local venv (~/.hgctl/.venv): %s", err)
}
if err := h.activateLocalPythonVenv(); err != nil {
return fmt.Errorf("failed to activateLocalPythonVenv: %s", err)
}
for _, deps := range missingDeps {
if err := h.RunPythonCmd(true, "-m", "pip", "install", deps); err != nil {
fmt.Printf("failed to install missing deps: %s\n", deps)
return err
}
}
venvDir := filepath.Join(util.GetHomeHgctlDir(), ".venv")
fmt.Println("Missing deps installed successfully, target python venv path: ", venvDir)
return nil
}
func (h *DeployHandler) activateLocalPythonVenv() error {
venvDir := filepath.Join(util.GetHomeHgctlDir(), ".venv")
path := os.Getenv("PATH")
newPath := venvDir + "/bin:" + path
err := os.Setenv("PATH", newPath)
if err != nil {
fmt.Println("Failed to set PATH:", err)
return err
}
err = os.Setenv("VIRTUAL_ENV", venvDir)
if err != nil {
fmt.Println("Failed to set VIRTUAL_ENV:", err)
return err
}
return nil
}
func (h *DeployHandler) checkRequiredEnvironment() error {
if h.Type == AgentRun {
return h.checkAgentRunEnvironment()
}
if h.Type == Local {
return h.checkLocalEnvironment()
}
return nil
}
func (h *DeployHandler) GetRequiredDeps() ([]string, error) {
switch h.Type {
case AgentRun:
return []string{
"agentrun-sdk[agentscope,server] >= 0.0.3",
}, nil
case Local:
return []string{
"agentscope", "agentscope-runtime==1.0.0",
}, nil
default:
return nil, fmt.Errorf("unsupported deploy target type: %s", h.Type)
}
}
// Quick and simple to get type by examine the existence of `requirements.txt` file
func (h *DeployHandler) getAgentType() error {
path, err := util.GetSpecificAgentDir(h.Name)
if err != nil {
fmt.Printf("invalid agent: %s", err)
return err
}
h.AgentDir = path
filePath := filepath.Join(h.AgentDir, "requirements.txt")
if _, err := os.Stat(filePath); os.IsNotExist(err) {
h.Type = Local
return nil
}
h.Type = AgentRun
return nil
}
func (h *DeployHandler) Deploy() error {
if err := h.getAgentType(); err != nil {
return err
}
if err := h.validate(); err != nil {
return err
}
switch h.Type {
case AgentRun:
if err := h.HandleAgentRun(); err != nil {
return err
}
case Local:
if err := h.HandleLocal(); err != nil {
return err
}
default:
return fmt.Errorf("unsupported deploy target type: %s", h.Type)
}
if h.Type == AgentRun {
fmt.Printf("\n🌟 Agent deploy to agentRun successfully! Refers to https://functionai.console.aliyun.com/cn-hangzhou/agent/runtime to get it")
fmt.Printf("You can publish it to Higress and Himarket by using `hgctl agent add %s <endpoints-url> -t model --as-product `\n", h.Name)
}
return nil
}
// details see: https://github.com/Serverless-Devs/agentrun-sdk-python
func (h *DeployHandler) HandleAgentRun() error {
if err := h.CheckServerlessAccessKey(); err != nil {
return fmt.Errorf("failed to set access key automatically: %s", err)
}
if _, err := h.RunCmd(true, BuildAgentCmd, h.AgentDir); err != nil {
return fmt.Errorf("failed to build agent: %s", err)
}
if _, err := h.RunCmd(true, DeployAgentRunCmd, h.AgentDir); err != nil {
return fmt.Errorf("failed to deploy agent: %s", err)
}
return nil
}
// Set Serverless's Access Key in s.yaml, details see: https://github.com/Serverless-Devs/agentrun-sdk-python
// Example:
// $ s config get -a defualt
// You have not yet been found to have configured key information.
// You can use [s config add] for key configuration, or use [s config add -h] to view configuration help.
// If you already used [s config add], please check the permission of file [{HOMEPATH}/.s/access.yaml].
// If you have questions, please tell us: https://github.com/Serverless-Devs/Serverless-Devs/issues
//
// s version: @serverless-devs/s: 3.1.10
func (h *DeployHandler) CheckServerlessAccessKey() error {
notFoundMessage := "You have not yet been found to have configured key information"
output, err := h.RunCmd(false, CheckAccessKeyCmd, "")
if err != nil {
return fmt.Errorf("failed to run %s command to check access key: %s", CheckAccessKeyCmd, err)
}
if strings.Contains(output, notFoundMessage) {
fmt.Fprintf(os.Stderr, `
🔑 **ACTION REQUIRED**: Please configure your Alibaba Cloud credentials first.
Copy and run the command below to set up your Access Key:
> %s
`, AddAccessKeyCmd)
return fmt.Errorf("access key not found")
}
return nil
}
func (h *DeployHandler) HandleLocal() error {
if _, err := os.Stat(h.AgentDir); os.IsNotExist(err) {
return fmt.Errorf("agent source file not found: %s", h.AgentDir)
}
if err := h.startAgentProcess(); err != nil {
return err
}
return nil
}
func (h *DeployHandler) startAgentProcess() error {
switch runtime.GOOS {
case "windows":
return h.runWindowsAgent()
case "darwin", "linux":
return h.runUnixAgent()
default:
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
}
}
func (h *DeployHandler) runUnixAgent() error {
agentFile := filepath.Join(h.AgentDir, ASRuntimeMainPyFile)
if err := h.RunPythonCmd(true, agentFile); err != nil {
fmt.Println("failed to start agent, exiting...")
return err
}
return nil
}
func (h *DeployHandler) runWindowsAgent() error {
agentFile := filepath.Join(h.AgentDir, ASRuntimeMainPyFile)
if err := h.RunPythonCmd(true, agentFile); err != nil {
fmt.Println("failed to start agent, exiting...")
return err
}
return nil
}

View File

@@ -17,10 +17,8 @@ package agent
import (
"fmt"
"io"
"net"
"net/url"
"os"
"strings"
"github.com/alibaba/higress/hgctl/pkg/agent/services"
"github.com/alibaba/higress/hgctl/pkg/helm"
@@ -34,32 +32,30 @@ import (
type MCPType string
const (
HTTP string = "http"
SSE string = "sse"
OPENAPI string = "openapi"
OPENAPI string = "openapi"
HTTP string = "http"
STREAMABLE string = "streamable"
SSE string = "sse"
DIRECT_ROUTE string = "DIRECT_ROUTE"
OPEN_API string = "OPEN_API"
HIGRESS_CONSOLE_URL = "higress-console-url"
HIGRESS_CONSOLE_USER = "higress-console-user"
HIGRESS_CONSOLE_PASSWORD = "higress-console-password"
)
type MCPAddArg struct {
// higress console auth arg
baseURL string
hgUser string
hgPassword string
HigressConsoleAuthArg
HimarketAdminAuthArg
name string
url string
typ string
transport string
spec string
scope string
env []string
header []string
noPublish bool
// TODO: support mcp env
// env string
asProduct bool
}
type MCPAddHandler struct {
@@ -84,24 +80,45 @@ func newMCPAddCmd() *cobra.Command {
arg := &MCPAddArg{}
cmd := &cobra.Command{
Use: "add [name]",
Use: "add [name] [url]",
Short: "add mcp server including http and openapi",
Example: ` # Add HTTP type MCP Server
hgctl mcp add http-mcp http://localhost:8080/mcp
# Add MCP Server with environment variables and headers
hgctl mcp add http-mcp http://localhost:8080/mcp -e API_KEY=secret -H "Authorization: Bearer token"
# Add MCP Server use Openapi file
hgctl mcp add swagger-mcp ./path/to/openapi.yaml --type openapi`,
Run: func(cmd *cobra.Command, args []string) {
arg.name = args[0]
resolveHigressConsoleAuth(arg)
if arg.typ == HTTP {
arg.url = args[1]
} else {
arg.spec = args[1]
}
resolveHigressConsoleAuth(&arg.HigressConsoleAuthArg)
resolveHimarketAdminAuth(&arg.HimarketAdminAuthArg)
cmdutil.CheckErr(handleAddMCP(cmd.OutOrStdout(), *arg))
color.Cyan("Tip: Try doing 'kubectl port-forward' and add the server to the agent manually, if MCP Server connection failed")
color.Cyan("Tip: Try doing 'kubectl port-forward' and add the server to the agent manually, if using Higress MCP Server and connection failed")
},
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(2),
}
cmd.PersistentFlags().StringVarP(&arg.transport, "transport", "t", HTTP, "Determine the MCP Server's Type")
cmd.PersistentFlags().StringVarP(&arg.url, "url", "u", "", "MCP server URL")
cmd.PersistentFlags().StringVar(&arg.typ, "type", HTTP, "Determine the MCP Server's Type")
cmd.PersistentFlags().StringVarP(&arg.transport, "transport", "t", STREAMABLE, `The MCP Server's transport`)
cmd.PersistentFlags().StringVarP(&arg.scope, "scope", "s", "project", `Configuration scope (project or global)`)
cmd.PersistentFlags().StringVar(&arg.spec, "spec", "", "Specification of the openapi api")
cmd.PersistentFlags().StringSliceVarP(&arg.env, "env", "e", nil, "Environment variables to pass to the MCP server (can be specified multiple times)")
cmd.PersistentFlags().StringSliceVarP(&arg.header, "header", "H", nil, "HTTP headers to pass to the MCP server (can be specified multiple times)")
cmd.PersistentFlags().BoolVar(&arg.noPublish, "no-publish", false, "If set then the mcp server will not be plubished to higress")
cmd.PersistentFlags().BoolVar(&arg.asProduct, "as-product", false, "If it's set then the agent API will be published to Himarket (no-publish must be false)")
addHigressConsoleAuthFlag(cmd, arg)
// cmd.PersistentFlags().StringVar(&arg.spec, "spec", "", "Specification file (yaml/json) of the openapi api")
addHigressConsoleAuthFlag(cmd, &arg.HigressConsoleAuthArg)
addHimarketAdminAuthFlag(cmd, &arg.HimarketAdminAuthArg)
return cmd
}
@@ -112,22 +129,19 @@ func newHanlder(c *AgenticCore, arg MCPAddArg, w io.Writer) *MCPAddHandler {
func (h *MCPAddHandler) validateArg() error {
if !h.arg.noPublish {
if h.arg.baseURL == "" || h.arg.hgUser == "" || h.arg.hgPassword == "" {
fmt.Println("--higress-console-user, --higress-console-url, --higress-console-password must be provided")
return fmt.Errorf("invalid args")
}
return h.arg.HigressConsoleAuthArg.validate()
}
return nil
}
func (h *MCPAddHandler) addHTTPMCP() error {
if err := h.core.AddMCPServer(h.arg.name, h.arg.url); err != nil {
if err := h.core.AddMCPServer(h.arg); err != nil {
return fmt.Errorf("mcp add failed: %w", err)
}
if !h.arg.noPublish {
return publishToHigress(h.arg, nil)
return publishMCPToHigress(h.arg, h.arg.typ, nil)
}
return nil
@@ -137,23 +151,29 @@ func (h *MCPAddHandler) addHTTPMCP() error {
func (h *MCPAddHandler) addOpenAPIMCP() error {
// fmt.Printf("get mcp server: %s openapi-spec-file: %s\n", h.arg.name, h.arg.spec)
config := h.parseOpenapiSpec()
config.Server.SecuritySchemes[0].DefaultCredential = "b5b9752c7ad2cb9c6b19fb5fd6a23be8852eca9c"
// fmt.Printf("get config struct: %v", config)
// publish to higress
if err := publishToHigress(h.arg, config); err != nil {
if err := publishMCPToHigress(h.arg, "streamable", config); err != nil {
return err
}
// add mcp server to agent
gatewayIP, err := GetHigressGatewayServiceIP()
if err != nil {
color.Red(
"failed to add mcp server [%s] while getting higress-gateway ip due to: %v \n You may try to do port-forward and add it to agent manually", h.arg.name, err)
return err
gatewayURL := viper.GetString(HIGRESS_GATEWAY_URL)
if gatewayURL == "" {
svcIP, err := GetHigressGatewayServiceIP()
if err != nil {
color.Red(
"failed to add mcp server [%s] while getting higress-gateway ip due to: %v \n You may try to do port-forward and add it to agent manually", h.arg.name, err)
return err
}
gatewayURL = svcIP
}
mcpURL := fmt.Sprintf("http://%s/mcp-servers/%s", gatewayIP, h.arg.name)
return h.core.AddMCPServer(h.arg.name, mcpURL)
mcpURL := fmt.Sprintf("%s/mcp-servers/%s", gatewayURL, h.arg.name)
h.arg.url = mcpURL
return h.core.AddMCPServer(h.arg)
}
func (h *MCPAddHandler) parseOpenapiSpec() *models.MCPConfig {
@@ -161,7 +181,10 @@ func (h *MCPAddHandler) parseOpenapiSpec() *models.MCPConfig {
}
func handleAddMCP(w io.Writer, arg MCPAddArg) error {
client := getAgent()
client, err := getCore()
if err != nil {
return fmt.Errorf("failed to get agent core: %s", err)
}
h := newHanlder(client, arg, w)
if err := h.validateArg(); err != nil {
return err
@@ -169,9 +192,12 @@ func handleAddMCP(w io.Writer, arg MCPAddArg) error {
// spec -> OPENAPI
// noPublish -> typ
switch arg.transport {
switch arg.typ {
case HTTP:
return h.addHTTPMCP()
if err := h.addHTTPMCP(); err != nil {
return err
}
case OPENAPI:
if arg.spec == "" {
return fmt.Errorf("--spec is required for openapi type")
@@ -182,19 +208,29 @@ func handleAddMCP(w io.Writer, arg MCPAddArg) error {
if arg.url != "" {
return fmt.Errorf("--url is not supported for openapi type")
}
return h.addOpenAPIMCP()
default:
return fmt.Errorf("unsupported mcp type")
if err := h.addOpenAPIMCP(); err != nil {
return err
}
}
if !arg.noPublish && arg.asProduct {
if err := publishAPIToHimarket("mcp", arg.name, arg.HimarketAdminAuthArg); err != nil {
fmt.Println("failed to publish it to himarket, please do it mannually")
return err
}
}
return nil
}
func publishToHigress(arg MCPAddArg, config *models.MCPConfig) error {
func publishMCPToHigress(arg MCPAddArg, transport string, config *models.MCPConfig) error {
// 1. parse the raw http url
// 2. add service source
// 3. add MCP server request
client := services.NewHigressClient(arg.baseURL, arg.hgUser, arg.hgPassword)
client := services.NewHigressClient(arg.hgURL, arg.hgUser, arg.hgPassword)
// mcp server's url
rawURL := arg.url
// DIRECT_ROUTE or OPEN_API
mcpType := DIRECT_ROUTE
@@ -205,61 +241,46 @@ func publishToHigress(arg MCPAddArg, config *models.MCPConfig) error {
mcpType = OPEN_API
}
res, err := url.Parse(rawURL)
if err != nil {
return err
}
// add service source
srvType := ""
srvPort := ""
srvName := fmt.Sprintf("hgctl-%s", arg.name)
srvPath := res.Path
if ip := net.ParseIP(res.Hostname()); ip == nil {
srvType = "dns"
} else {
srvType = "static"
}
if res.Port() == "" && res.Scheme == "http" {
srvPort = "80"
} else if res.Port() == "" && res.Scheme == "https" {
srvPort = "443"
} else {
srvPort = res.Port()
}
_, err = services.HandleAddServiceSource(client, map[string]interface{}{
"domain": res.Host,
"type": srvType,
"port": srvPort,
"name": srvName,
"domainForEdit": res.Host,
"protocol": res.Scheme,
})
// e.g. hgctl-mcp-deepwiki.dns
body, targetSrvName, port, err := services.BuildServiceBodyAndSrv(srvName, rawURL)
if err != nil {
return err
return fmt.Errorf("invalid url format: %s", err)
}
resp, err := services.HandleAddServiceSource(client, body)
if err != nil {
return fmt.Errorf("response body: %s %s\n", string(resp), err)
}
srvField := []map[string]interface{}{{
"name": fmt.Sprintf("%s.%s", srvName, srvType),
"port": srvPort,
"name": targetSrvName,
"port": port,
"version": "1.0",
"weight": 100,
}}
// generete mcp server add request body
body := map[string]interface{}{
"name": arg.name,
// "description": "",
"type": mcpType,
"service": fmt.Sprintf("%s.%s:%s", srvName, srvType, srvPort),
"upstreamPathPrefix": srvPath,
"services": srvField,
body = map[string]interface{}{
"name": arg.name,
"description": "A MCP Server added by hgctl",
"type": mcpType,
"services": srvField,
"domains": []interface{}{},
"consumerAuthInfo": map[string]interface{}{
"type": "key-auth",
"allowedConsumers": []string{},
},
}
// fmt.Printf("request body: %v", body)
// Only DIRECT_ROUTE Type get below extra params
if mcpType == DIRECT_ROUTE {
res, _ := url.Parse(rawURL)
body["directRouteConfig"] = map[string]interface{}{
"path": res.Path,
"transportType": arg.transport,
}
}
_, err = services.HandleAddMCPServer(client, body)
if err != nil {
@@ -275,12 +296,17 @@ func publishToHigress(arg MCPAddArg, config *models.MCPConfig) error {
func addMCPToolConfig(client *services.HigressClient, config *models.MCPConfig, srvField []map[string]interface{}) {
body := map[string]interface{}{
"name": config.Server.Name,
// "description": "",
"name": config.Server.Name,
"description": "A MCP Server added by hgctl",
"services": srvField,
"type": OPEN_API,
"rawConfigurations": convertMCPConfigToStr(config),
"mcpServerName": config.Server.Name,
"domains": []interface{}{},
"consumerAuthInfo": map[string]interface{}{
"type": "key-auth",
"allowedConsumers": []string{},
},
}
_, err := services.HandleAddOpenAPITool(client, body)
@@ -291,38 +317,7 @@ func addMCPToolConfig(client *services.HigressClient, config *models.MCPConfig,
// fmt.Println("get openapi tools add response: ", string(resp))
}
func addHigressConsoleAuthFlag(cmd *cobra.Command, arg *MCPAddArg) {
cmd.PersistentFlags().StringVar(&arg.baseURL, HIGRESS_CONSOLE_URL, "", "The BaseURL of higress console")
cmd.PersistentFlags().StringVar(&arg.hgUser, HIGRESS_CONSOLE_USER, "", "The username of higress console")
cmd.PersistentFlags().StringVarP(&arg.hgPassword, HIGRESS_CONSOLE_PASSWORD, "p", "", "The password of higress console")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()
}
// resolve from viper
func resolveHigressConsoleAuth(arg *MCPAddArg) {
if arg.baseURL == "" {
arg.baseURL = viper.GetString(HIGRESS_CONSOLE_URL)
}
if arg.hgUser == "" {
arg.hgUser = viper.GetString(HIGRESS_CONSOLE_USER)
}
if arg.hgPassword == "" {
arg.hgPassword = viper.GetString(HIGRESS_CONSOLE_PASSWORD)
}
// fmt.Printf("arg: %v\n", arg)
if arg.hgUser == "" || arg.hgPassword == "" {
// Here we do not return this error, cause it will failed when validate arg
if err := tryToGetLocalCredential(arg); err != nil {
fmt.Printf("failed to get local higress console credential: %s\n", err)
}
}
}
func tryToGetLocalCredential(arg *MCPAddArg) error {
func tryToGetLocalCredential(arg *HigressConsoleAuthArg) error {
profileContexts, err := getAllProfiles()
// The higress is not installed by hgctl

341
hgctl/pkg/agent/new.go Normal file
View File

@@ -0,0 +1,341 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package agent
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"text/template"
"github.com/AlecAivazis/survey/v2"
"github.com/alibaba/higress/hgctl/pkg/agent/prompt"
"github.com/alibaba/higress/hgctl/pkg/manifests"
"github.com/alibaba/higress/hgctl/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
ASRuntimeMainPyFile = "as_runtime_main.py"
AgentRunMainPyFile = "agentrun_main.py"
ToolKitPyFile = "toolkit.py"
AgentClassFile = "agent.py"
CorePromptFile = "claude.md" // TODO: support qoder AGENTS.md
SConfigYAML = "s.yaml"
ARTemplate = "agentrun.tmpl"
ASTemplate = "agentscope.tmpl"
AgentClassTemplate = "agent.tmpl"
ToolKitTemplate = "toolkit.tmpl"
SConfigTemplate = "agentrun_s.tmpl"
)
var ASAvailiableTools = []string{
"execute_python_code",
"execute_shell_command",
"view_text_file",
"write_text_file",
"insert_text_file",
"dashscope_text_to_image",
"dashscope_text_to_audio",
"dashscope_image_to_text",
"openai_text_to_image",
"openai_text_to_audio",
"openai_edit_image",
"openai_create_image_variation",
"openai_image_to_text",
"openai_audio_to_text",
}
const (
MinPythonVersion = "3.12"
DefaultServerLessAccessKey = "hgctl-credential"
)
// Callback type for post-agent-creation actions
type PostAgentAction func(config *AgentConfig) error
type MCPServerConfig struct {
Name string // MCP Client Name
URL string // MCP Server URL
Transport string // transport `streamable_http` or `see` or `stdio`
Headers map[string]string // HTTP Headers
}
type ServerlessConfig struct {
AccessKey string
ResourceName string
Region string
AgentName string
AgentDesc string
Port uint
DiskSize uint
Timeout uint
GlobalConfig HgctlAgentConfig
}
type AgentConfig struct {
AppName string // "app"
AppDescription string // "A helpful assistant and useful agent"
AgentName string // "Friday"
AvailableTools []string // availiable tools (built-in agentscope)
SysPromptPath string // "You are a helpful assistant"
ChatModel string // "qwen-max"
Provider string // "Aliyun"
APIKeyEnvVar string // DASHCOPE_API_KEY
DeploymentPort int // 8090
HostBinding string // 0.0.0.0
EnableStreaming bool // true
EnableThinking bool // true
MCPServers []MCPServerConfig
Type DeployType
ServerlessCfg ServerlessConfig
}
func createAgentCmd() *cobra.Command {
agentRun := false
deployDirect := false
var createAgentCmd = &cobra.Command{
Use: "new",
Short: "Create a new agent or import one from core",
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
config := &AgentConfig{
Type: Local,
}
if agentRun {
config.Type = AgentRun
config.ServerlessCfg = ServerlessConfig{
AccessKey: DefaultServerLessAccessKey,
Port: 9000,
DiskSize: 512,
Timeout: 600,
GlobalConfig: GlobalConfig,
}
}
if err := getAgentConfig(config); err != nil {
fmt.Printf("Error get Agent config: %v\n", err)
os.Exit(1)
}
if err := createAgentTemplate(config); err != nil {
fmt.Printf("Error creating agent: %v\n", err)
os.Exit(1)
}
if err := afterCreatedAgent(config); err != nil {
fmt.Println(err)
os.Exit(1)
}
},
}
createAgentCmd.PersistentFlags().BoolVar(&agentRun, "agent-run", false, "Use agentRun to deploy to Alibaba cloud, default is false")
createAgentCmd.PersistentFlags().BoolVar(&deployDirect, "deploy", false, "After agent creation, deploy it directly")
return createAgentCmd
}
func afterCreatedAgent(config *AgentConfig) error {
options := []string{
"Deploy it directly",
fmt.Sprintf("Improve and test it using agentic core (%s)", viper.GetString(HGCTL_AGENT_CORE)),
"Do nothing and quit",
}
callbacks := map[string]PostAgentAction{
options[0]: func(cfg *AgentConfig) error {
handler := &DeployHandler{Name: cfg.AgentName}
return handler.Deploy()
},
options[1]: func(cfg *AgentConfig) error {
return runAgenticCoreImprovement(cfg)
},
}
if err := promptAfterCreatedAgent(options, config, callbacks); err != nil {
fmt.Fprintf(os.Stderr, "Failed to handle post-creation action: %v\n", err)
return nil
}
return nil
}
func runAgenticCoreImprovement(cfg *AgentConfig) error {
core, err := getCore()
if err != nil {
return fmt.Errorf("failed to invoke agent core: %s", err)
}
if err := core.ImproveNewAgent(cfg); err != nil {
return fmt.Errorf("failed to use core to improve new agent: %s", err)
}
return nil
}
func promptAfterCreatedAgent(options []string, config *AgentConfig, callbacks map[string]PostAgentAction) error {
promptChoice := &survey.Select{
Message: "What's next?:",
Options: options,
Help: "Choose an action to perform after agent creation.",
}
var response string
if err := survey.AskOne(promptChoice, &response); err != nil {
return fmt.Errorf("failed to read user choice: %w", err)
}
if callback, ok := callbacks[response]; ok {
return callback(config)
}
if response == options[2] {
os.Exit(1)
}
return fmt.Errorf("unknown action selected: %q", response)
}
func createAgentTemplate(config *AgentConfig) error {
agentsDir := util.GetHomeHgctlDir() + "/agents"
if err := os.MkdirAll(agentsDir, 0755); err != nil {
return fmt.Errorf("failed to create agents directory: %v", err)
}
agentDir := filepath.Join(agentsDir, config.AgentName)
if err := os.MkdirAll(agentDir, 0755); err != nil {
return fmt.Errorf("failed to create agent directory: %v", err)
}
switch config.Type {
case Local:
// parse agentscope file
asMain := filepath.Join(agentDir, ASRuntimeMainPyFile)
asTemplateStr, err := get_template(ASTemplate)
if err != nil {
return fmt.Errorf("failed to read agentscope template: %v", err)
}
if err := renderTemplateFile(asTemplateStr, asMain, config); err != nil {
return fmt.Errorf("failed to render agentscope runtime's file: %s", err)
}
case AgentRun:
// Details see: https://github.com/Serverless-Devs/agentrun-sdk-python
// parse agentrun file
arMain := filepath.Join(agentDir, AgentRunMainPyFile)
arTemplateStr, err := get_template(ARTemplate)
if err != nil {
return fmt.Errorf("failed to read agentrun template: %v", err)
}
if err := renderTemplateFile(arTemplateStr, arMain, config); err != nil {
return fmt.Errorf("failed to render agentscope runtime's file: %s", err)
}
// parse s.yaml
s := filepath.Join(agentDir, SConfigYAML)
STmplStr, err := get_template(SConfigTemplate)
if err != nil {
return fmt.Errorf("failed to read agentrun's serverless config file template: %v", err)
}
if err := renderTemplateFile(STmplStr, s, config.ServerlessCfg); err != nil {
return fmt.Errorf("failed to render agentscope runtime's file: %s", err)
}
// write requirements
fileContent := "agentrun-sdk[agentscope,server]>=0.0.3"
targetFilePath := filepath.Join(agentDir, "requirements.txt")
if err := util.WriteFileString(targetFilePath, fileContent, os.ModePerm); err != nil {
return fmt.Errorf("failed to write requirements.txt file to target agent directory: %s", err)
}
}
// parse toolkitPath
toolkitPath := filepath.Join(agentDir, ToolKitPyFile)
toolkitTmpl, err := get_template(ToolKitTemplate)
if err != nil {
return fmt.Errorf("failed to read toolkit template: %v", err)
}
if err := renderTemplateFile(toolkitTmpl, toolkitPath, config); err != nil {
return fmt.Errorf("failed to render toolkit file: %s", err)
}
// write agent.py
agentPath := filepath.Join(agentDir, AgentClassFile)
agentTmpl, err := get_template(AgentClassTemplate)
if err != nil {
return fmt.Errorf("failed to read agent class template: %v", err)
}
if err := renderTemplateFile(agentTmpl, agentPath, config); err != nil {
return fmt.Errorf("failed to render agent class file: %s", err)
}
// write core_prompt.md
if core, err := getCore(); err == nil {
corePromptPath := filepath.Join(agentDir, core.GetPromptFileName())
if err := util.WriteFileString(corePromptPath, prompt.AgentDevelopmentGuide, os.ModePerm); err != nil {
return fmt.Errorf("failed to write %s file to target agent directory: %s", core.GetPromptFileName(), err)
}
return nil
} else {
return fmt.Errorf("failed to add instruction file in agent dir: %s", err)
}
}
func renderTemplateFile(templateStr string, targetPath string, data interface{}) error {
// sync with python
funcMap := template.FuncMap{
"boolToPython": func(b bool) string {
if b {
return "True"
}
return "False"
},
}
tmpl, err := template.New("agent").Funcs(funcMap).Parse(templateStr)
if err != nil {
return fmt.Errorf("failed to parse template: %v", err)
}
file, err := os.Create(targetPath)
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
defer file.Close()
if err := tmpl.Execute(file, data); err != nil {
return fmt.Errorf("failed to render template: %v", err)
}
return nil
}
func get_template(templatePath string) (string, error) {
f := manifests.BuiltinOrDir("")
templatePath = "agent/template/" + templatePath
data, err := fs.ReadFile(f, templatePath)
if err != nil {
return "", fmt.Errorf("failed to read template: %w", err)
}
return string(data), nil
}

View File

@@ -0,0 +1,244 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
# Agent Development Guide
Welcome to this AgentScope agent directory! This guide helps AI CLI tools (like Claude Code) understand the structure and assist you in building powerful agents.
## Directory Overview
This is an automatically generated agent directory with the following structure:
- **agent.py** - Main agent class (generated from agent.tmpl)
- **toolkit.py** - Agent's tools and MCP integrations (generated from toolkit.tmpl)
- **prompt.md** - User-provided system prompt for the agent
- **as_runtime_main.py** / **agentrun_main.py** - Deployment runtime files
- **agent.tmpl** / **toolkit.tmpl** / **agentscope.tmpl** - Generation templates
## What You Should Do
### Primary Focus: Improve Agent Intelligence
Your role is to help users build more capable, "agentic" agents by:
1. **Editing agent.py** - Enhance the agent class with:
- Custom reasoning logic
- Agent-specific hooks and behaviors
- Memory management strategies
- Multi-step task handling
2. **Editing toolkit.py** - Expand agent capabilities by:
- Adding new tool functions
- Integrating MCP (Model Context Protocol) servers
- Configuring tool access and permissions
3. **Editing prompt.md** (when requested) - Refine the system prompt to:
- Improve agent behavior and personality
- Add domain-specific instructions
- Define task-specific guidelines
### Critical Constraints
**DO NOT MODIFY** these deployment files:
- `as_runtime_main.py`
- `agentrun_main.py`
These files handle agent deployment and runtime orchestration. They are managed by the agent framework and should not be changed during development.
## Learning AgentScope
Before helping users, you should become proficient with AgentScope:
### Use the DeepWiki MCP Server
You have access to the `mcp-deepwiki` server. Use it to learn about AgentScope:
```python
# Query the AgentScope repository
ask_question(
repoName="agentscope-ai/agentscope",
question="How does the ReActAgent work?"
)
```
Study these key concepts:
- ReActAgent architecture (Reasoning + Acting loop)
- Agent hooks and lifecycle methods
- Toolkit and tool registration
- Memory systems (short-term and long-term)
- Message formatting and model integration
- MCP integration for external tools
### Testing Your Agent
Use the `agentscope-test-runner` subagent to test agent functionality:
```python
# Launch test runner to validate agent behavior
Task(
subagent_type="agentscope-test-runner",
prompt="Test the agent's ability to handle multi-step tasks",
description="Testing agent functionality"
)
```
**Don't** write your own test harness - use this specialized subagent.
## Building Great Agents: Examples
### Example 1: Browser Automation Agent
Based on the AgentScope BrowserAgent, here's how to build a specialized web agent:
**Key Patterns:**
1. **Extend ReActAgent** - Inherit from ReActAgent for reasoning-acting loop
2. **Use Hooks** - Register instance hooks to customize behavior at different lifecycle points:
- `pre_reply` - Run before generating responses
- `pre_reasoning` - Execute before reasoning phase
- `post_reasoning` - Execute after reasoning phase
- `post_acting` - Execute after taking actions
3. **Manage Memory** - Implement memory summarization to prevent context overflow
4. **Leverage MCP Tools** - Connect to MCP servers (like Playwright browser tools) via toolkit
```python
class Agent(ReActAgent):
def __init__(self, name, model, formatter, memory, toolkit, ...):
super().__init__(name, sys_prompt, model, formatter, memory, toolkit, max_iters)
# Register custom hooks
self.register_instance_hook(
"pre_reply",
"custom_hook_name",
custom_hook_function
)
```
### Example 2: Research Agent
For research and analysis tasks:
**Key Features:**
- Knowledge base integration for RAG (Retrieval-Augmented Generation)
- Long-term memory for persistent context
- Plan notebook for complex multi-step research
- Query rewriting for better information retrieval
```python
class Agent(ReActAgent):
def __init__(
self,
name,
sys_prompt,
model,
formatter,
toolkit,
memory,
long_term_memory=None,
knowledge=None,
enable_rewrite_query=True,
plan_notebook=None,
...
):
# Initialize with research-focused capabilities
super().__init__(...)
```
### Example 3: Code Assistant Agent
For software development tasks:
**Key Capabilities:**
- File operation tools (read, write, insert)
- Code execution (execute_python_code, execute_shell_command)
- Image/audio processing for multimodal interactions
- MCP integration for IDE tools
### Common Agent Patterns
1. **Tool Registration** (in toolkit.py):
```python
from agentscope.tool import Toolkit
from agentscope.tool import execute_shell_command, view_text_file
toolkit = Toolkit()
toolkit.register_tool_function(execute_shell_command)
toolkit.register_tool_function(view_text_file)
```
2. **MCP Integration** (in toolkit.py):
```python
from agentscope.mcp import HttpStatelessClient
async def register_mcp(toolkit):
client = HttpStatelessClient(
name="browser-tools",
transport="sse",
url="http://localhost:3000/sse"
)
await toolkit.register_mcp_client(client)
```
3. **Custom Hooks** (in agent.py):
```python
async def pre_reasoning_hook(self, *args, **kwargs):
"""Custom logic before reasoning"""
# Add context, check conditions, etc.
pass
# In __init__:
self.register_instance_hook("pre_reasoning", "my_hook", pre_reasoning_hook)
```
## More Examples and Resources
Explore official AgentScope examples:
- https://github.com/modelscope/agentscope/tree/main/examples/agent
Key examples to study:
- **ReAct Agent** - Basic reasoning-acting agent
- **Conversation Agent** - Multi-turn dialogue handling
- **User Agent** - Human-in-the-loop interactions
- **Tool Agent** - Advanced tool usage patterns
## Development Workflow
1. **Understand Requirements** - Clarify what the agent should do
2. **Learn Patterns** - Use DeepWiki to research relevant AgentScope patterns
3. **Design Agent** - Choose base class and required capabilities
4. **Implement in agent.py** - Write custom agent logic
5. **Add Tools in toolkit.py** - Register needed tools and MCP servers
6. **Test with agentscope-test-runner** - Validate functionality
7. **Iterate** - Refine based on test results
## Best Practices
1. **Start Simple** - Begin with basic ReActAgent, add complexity as needed
2. **Use Hooks Wisely** - Don't overcomplicate; hooks should have clear purposes
3. **Memory Management** - Implement summarization for long conversations
4. **Tool Selection** - Only add tools the agent actually needs
5. **Clear Prompts** - Write specific, actionable system prompts in prompt.md
6. **Test Iteratively** - Use the test-runner frequently during development
## Getting Help
- Use DeepWiki MCP to query AgentScope documentation
- Study the browser_agent.py example in this guide
- Reference official examples at https://github.com/agentscope-ai/agentscope
- Test early and often with agentscope-test-runner
---
**Remember:** Focus on making the agent intelligent and capable. The deployment infrastructure is already handled - your job is to build the "brain" of the agent in agent.py and give it the right "tools" in toolkit.py.

View File

@@ -0,0 +1,20 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prompt
import _ "embed"
//go:embed agent_guide.md
var AgentDevelopmentGuide string

View File

@@ -31,7 +31,33 @@ type HigressClient struct {
httpClient *http.Client
}
type HimarketClient struct {
baseURL string
username string
password string
httpClient *http.Client
jwtToken string
}
// type ClientType string
// const (
// HigressClientType ClientType = "higress"
// HimarketClientType ClientType = "himarket"
// )
// func NewClient(clientType ClientType, baseURL, username, password string) Client {
// switch clientType {
// case HimarketClientType:
// return NewHimarketClient(baseURL, username, password)
// case HigressClientType:
// fallthrough
// default:
// return NewHigressClient(baseURL, username, password)
// }
// }
func NewHigressClient(baseURL, username, password string) *HigressClient {
client := &HigressClient{
baseURL: baseURL,
username: username,
@@ -44,6 +70,19 @@ func NewHigressClient(baseURL, username, password string) *HigressClient {
return client
}
func NewHimarketClient(baseURL, username, password string) *HimarketClient {
client := &HimarketClient{
baseURL: baseURL,
username: username,
password: password,
httpClient: &http.Client{
Timeout: 30 * time.Second,
},
}
return client
}
func (c *HigressClient) Get(path string) ([]byte, error) {
return c.request("GET", path, nil)
}
@@ -59,6 +98,133 @@ func (c *HigressClient) Put(path string, data interface{}) ([]byte, error) {
func (c *HigressClient) Delete(path string) ([]byte, error) {
return c.request("DELETE", path, nil)
}
func (c *HimarketClient) getJWTToken() error {
loginURL := c.baseURL + "/api/v1/admins/login"
loginData := map[string]string{
"username": c.username,
"password": c.password,
}
jsonData, err := json.Marshal(loginData)
if err != nil {
return fmt.Errorf("failed to marshal login data: %w", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "POST", loginURL, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("failed to create login request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("login request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("login failed with status code: %d", resp.StatusCode)
}
var response map[string]interface{}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read login response: %w", err)
}
if err := json.Unmarshal(respBody, &response); err != nil {
return fmt.Errorf("failed to parse login response: %w", err)
}
// fmt.Println(string(respBody))
if data, ok := response["data"].(map[string]interface{}); ok {
if token, ok := data["access_token"].(string); ok {
c.jwtToken = token
return nil
}
}
return fmt.Errorf("token not found in login response: %v", response)
}
func (c *HimarketClient) Get(path string) ([]byte, error) {
return c.request("GET", path, nil)
}
func (c *HimarketClient) Post(path string, data interface{}) ([]byte, error) {
return c.request("POST", path, data)
}
func (c *HimarketClient) Put(path string, data interface{}) ([]byte, error) {
return c.request("PUT", path, data)
}
func (c *HimarketClient) request(method, path string, data interface{}) ([]byte, error) {
if c.jwtToken == "" {
if err := c.getJWTToken(); err != nil {
return nil, fmt.Errorf("failed to get JWT token: %w", err)
}
}
url := c.baseURL + path
var body io.Reader
if data != nil {
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal request data: %w", err)
}
body = bytes.NewBuffer(jsonData)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, method, url, body)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+c.jwtToken)
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode == 409 {
return nil, fmt.Errorf("resource already exists")
}
if resp.StatusCode == 400 {
return nil, fmt.Errorf("invalid resource definition")
}
if resp.StatusCode == 500 {
return nil, fmt.Errorf("server internal error")
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("HTTP error %d", resp.StatusCode)
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
return respBody, nil
}
func (c *HigressClient) request(method, path string, data interface{}) ([]byte, error) {
url := c.baseURL + path
@@ -92,6 +258,8 @@ func (c *HigressClient) request(method, path string, data interface{}) ([]byte,
return nil, fmt.Errorf("resource already exists")
}
// fmt.Println(resp)
if resp.StatusCode == 400 {
return nil, fmt.Errorf("invalid resource definition")
}

View File

@@ -15,7 +15,11 @@
package services
import (
"encoding/json"
"fmt"
"time"
"github.com/alibaba/higress/hgctl/pkg/agent/common"
)
func HandleAddServiceSource(client *HigressClient, body interface{}) ([]byte, error) {
@@ -50,22 +54,30 @@ func HandleAddServiceSource(client *HigressClient, body interface{}) ([]byte, er
// add MCP server to higress console, example request body as followed:
//
// {
// "name": "mcp-deepwiki",
// "description": "",
// "type": "DIRECT_ROUTE", // or OPEN_API
// "service": "hgctl-deepwiki.dns:443",
// "upstreamPathPrefix": "/mcp",
// "name": "test",
// "description": "123",
// "type": "DIRECT_ROUTE",
// "services": [
// {
// "name": "hgctl-deepwiki.dns",
// "name": "hgctl-mcp-deepwiki.dns",
// "port": 443,
// "version": "1.0",
// "weight": 100
// }
// ]
// ],
// "consumerAuthInfo": {
// "type": "key-auth",
// "allowedConsumers": []
// },
// "domains": [],
// "directRouteConfig": {
// "path": "/mcp",
// "transportType": "streamable"
// }
// }
func HandleAddMCPServer(client *HigressClient, body interface{}) ([]byte, error) {
data, ok := body.(map[string]interface{})
// fmt.Printf("mcpbody: %v\n", data)
if !ok {
return nil, fmt.Errorf("failed to parse request body")
}
@@ -76,10 +88,6 @@ func HandleAddMCPServer(client *HigressClient, body interface{}) ([]byte, error)
if _, ok := data["type"]; !ok {
return nil, fmt.Errorf("missing required field 'type' in body")
}
if _, ok := data["service"]; !ok {
return nil, fmt.Errorf("missing required field 'service' in body")
}
// if _, ok := data["upstreamPathPrefix"]; !ok {
// return nil, fmt.Errorf("missing required field 'upstreamPathPrefix' in body")
// }
@@ -97,6 +105,40 @@ func HandleAddMCPServer(client *HigressClient, body interface{}) ([]byte, error)
return resp, nil
}
// return map[mcp-server-name]{}
func GetExistingMCPServers(client *HigressClient) (map[string]string, error) {
result := make(map[string]string)
data, err := HandleListMCPServers(client)
if err != nil {
return nil, err
}
var response map[string]interface{}
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to get product id from response: %s", err)
}
// fmt.Println(response["data"])
if list, ok := response["data"].([]interface{}); ok {
for _, item := range list {
if mcp, ok := item.(map[string]interface{}); ok {
if name, ok := mcp["name"].(string); ok {
result[name] = ""
}
}
}
}
return result, nil
}
func HandleListMCPServers(client *HigressClient) ([]byte, error) {
ts := time.Now().Unix()
pageNum := 1
pageSize := 100
return client.Get(fmt.Sprintf("/v1/mcpServer?ts=%d&pageNum=%d&pageSize=%d", ts, pageNum, pageSize))
}
// add OpenAPI MCP tools to higress console, example request body:
//
// {
@@ -127,3 +169,155 @@ func HandleAddMCPServer(client *HigressClient, body interface{}) ([]byte, error)
func HandleAddOpenAPITool(client *HigressClient, body interface{}) ([]byte, error) {
return client.Put("/v1/mcpServer", body)
}
func HandleAddAIProviderService(client *HigressClient, body interface{}) ([]byte, error) {
return client.Post("/v1/ai/providers", body)
}
func HandleAddAIRoute(client *HigressClient, body interface{}) ([]byte, error) {
return client.Post("/v1/ai/routes", body)
}
func HandleAddRoute(client *HigressClient, body interface{}) ([]byte, error) {
return client.Post("/v1/routes", body)
}
// Himarket-related
func HandleAddHigressInstance(client *HimarketClient, body interface{}) ([]byte, error) {
// This api will not return the higress-gatway-id
return client.Post("/api/v1/gateways", body)
}
func (c *HimarketClient) getProduct(typ common.ProductType) ([]byte, error) {
return c.Get(fmt.Sprintf("/api/v1/products?type=%s&page=0&size=30", string(typ)))
}
func (c *HimarketClient) extractGetProductResponse(typ common.ProductType, response map[string]interface{}) map[string]string {
result := make(map[string]string)
data, ok := response["data"].(map[string]interface{})
if !ok {
return result
}
content, ok := data["content"].([]interface{})
if !ok {
return result
}
for _, item := range content {
product, ok := item.(map[string]interface{})
if !ok {
continue
}
productType, _ := product["type"].(string)
if productType != string(typ) {
continue
}
name, _ := product["name"].(string)
if name == "" {
continue
}
mcpConfig, ok := product["mcpConfig"].(map[string]interface{})
if !ok {
continue
}
serverConfig, ok := mcpConfig["mcpServerConfig"].(map[string]interface{})
if !ok {
continue
}
domains, ok := serverConfig["domains"].([]interface{})
if !ok || len(domains) == 0 {
continue
}
path, ok := serverConfig["path"].(string)
if !ok {
continue
}
for _, domainItem := range domains {
domainConfig, ok := domainItem.(map[string]interface{})
if !ok {
continue
}
domain, _ := domainConfig["domain"].(string)
protocol, _ := domainConfig["protocol"].(string)
if domain == "" || protocol == "" {
continue
}
port, _ := domainConfig["port"].(float64)
url := ""
if port == 0 || port == 80 {
url = fmt.Sprintf("%s://%s%s", protocol, domain, path)
} else {
url = fmt.Sprintf("%s://%s:%d%s", protocol, domain, int(port), path)
}
result[name] = url
break
}
}
return result
}
func (c *HimarketClient) GetDevModelProduct() (map[string]string, error) {
data, err := c.getProduct(common.MODEL_API)
if err != nil {
return nil, fmt.Errorf("failed request himarket: %s", err)
}
var response map[string]interface{}
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to get model api from response %s", err)
}
return c.extractGetProductResponse(common.MODEL_API, response), nil
}
func (c *HimarketClient) GetDevMCPServerProduct() (map[string]string, error) {
data, err := c.getProduct(common.MCP_SERVER)
if err != nil {
return nil, fmt.Errorf("failed request himarket: %s", err)
}
var response map[string]interface{}
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to get MCP server from response %s", err)
}
return c.extractGetProductResponse(common.MCP_SERVER, response), nil
}
func HandleListHimarketMCPServers(client *HimarketClient) ([]byte, error) {
return nil, nil
}
func HandleAddAPIProduct(client *HimarketClient, body interface{}) ([]byte, error) {
data, err := client.Post("/api/v1/products", body)
if err != nil {
return data, err
}
var response map[string]interface{}
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to get product id from response: %s", err)
}
if res, ok := response["data"].(map[string]interface{}); ok {
if productId, ok := res["productId"].(string); ok {
return []byte(productId), nil
}
}
return data, fmt.Errorf("failed to get product id from response")
}
func HandleRefAPIProduct(client *HimarketClient, product_id string, body interface{}) ([]byte, error) {
return client.Post(fmt.Sprintf("/api/v1/products/%s/ref", product_id), body)
}

View File

@@ -0,0 +1,178 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package services
import (
"fmt"
"net"
"net/url"
)
func BuildAIProviderServiceBody(name, url string) map[string]interface{} {
customBaseURL := fmt.Sprintf("%s/compatible-mode/v1", url)
return map[string]interface{}{
"type": "openai",
"name": name,
"tokens": []string{},
"version": 0,
"protocol": "openai/v1",
"tokenFailoverConfig": map[string]interface{}{
"enabled": false,
},
"proxyName": "",
"rawConfigs": map[string]interface{}{
"openaiExtraCustomUrls": []string{},
"openaiCustomUrl": customBaseURL,
},
}
}
func BuildAddAIRouteBody(name, _url string) map[string]interface{} {
return map[string]interface{}{
"name": fmt.Sprintf("%s-route", name),
// "version": "627198", // It's unecessary to provide when create a new one
"domains": []interface{}{},
"pathPredicate": map[string]interface{}{
"matchType": "PRE",
// FIXME: Currently, to use model API in higress user hould follow this pattern:
// http://<higress-gateway-ip>/<PRE_MATCH_VALUE>/v1/chat/completions or /v1/embedding
// However in Himarket, when connecting the higress ai route as model API, himarket will directly use http://<higress-gateway-ip>/<PRE_MATCH_VALUE>
// as the final request url, which will not get to right path. So here we make the matchValue hard-coded as `/v1/chat/completions`
"matchValue": "/v1/chat/completions",
"caseSensitive": false,
"ignoreCase": []string{}, // "ignoreCase": ["ignore"]
},
"headerPredicates": []interface{}{},
"urlParamPredicates": []interface{}{},
"upstreams": []interface{}{
map[string]interface{}{
"provider": name,
"weight": 100,
"modelMapping": map[string]interface{}{},
},
},
"modelPredicates": []interface{}{},
"authConfig": map[string]interface{}{
"enabled": false,
"allowedCredentialTypes": []interface{}{},
"allowedConsumers": []interface{}{},
},
"fallbackConfig": map[string]interface{}{
"enabled": false,
"upstreams": nil,
"fallbackStrategy": nil,
"responseCodes": nil,
},
}
}
func BuildServiceBodyAndSrv(name, urlStr string) (map[string]interface{}, string, string, error) {
res, err := url.Parse(urlStr)
if err != nil {
return nil, "", "", err
}
// add service source
srvType := ""
srvPort := ""
if ip := net.ParseIP(res.Hostname()); ip == nil {
srvType = "dns"
} else {
srvType = "static"
}
if res.Port() == "" && res.Scheme == "http" {
srvPort = "80"
} else if res.Port() == "" && res.Scheme == "https" {
srvPort = "443"
} else {
srvPort = res.Port()
}
// e.g. hgctl-mcp-deepwiki.dns
targetSrvName := fmt.Sprintf("%s.%s", name, srvType)
return map[string]interface{}{
"domain": res.Host,
"type": srvType,
"port": srvPort,
"name": name,
"proxyName": "",
"domainForEdit": res.Host,
"protocol": res.Scheme,
}, targetSrvName, srvPort, nil
}
func BuildAPIRouteBody(name, srv string) map[string]interface{} {
return map[string]interface{}{
"name": fmt.Sprintf("%s-route", name),
"path": map[string]interface{}{
"matchType": "PRE", // default is PREFIX
"matchValue": "/process", // default is "/process"
"caseSensitive": true,
},
"authConfig": map[string]interface{}{
"enabled": false,
},
"services": []map[string]interface{}{
{
"name": srv,
},
},
}
}
func BuildAddHigressInstanceBody(name, addr, username, password string) map[string]interface{} {
return map[string]interface{}{
"gatewayName": name,
"gatewayType": "HIGRESS",
"higressConfig": map[string]interface{}{
"address": addr,
"username": username,
"password": password,
},
}
}
func BuildAPIProductBody(name, desc, typ string) map[string]interface{} {
return map[string]interface{}{
"name": name, "description": desc, "type": typ,
}
}
func BuildRefModelAPIProductBody(gateway_id, product_id, target_route string) map[string]interface{} {
return map[string]interface{}{
"gatewayId": gateway_id,
"sourceType": "GATEWAY",
"productId": product_id,
"higressRefConfig": map[string]interface{}{
"modelRouteName": target_route,
"fromGatewayType": "HIGRESS",
},
}
}
func BuildRefMCPAPIProductBody(gateway_id, product_id, mcp_name string) map[string]interface{} {
return map[string]interface{}{
"gatewayId": gateway_id,
"sourceType": "GATEWAY",
"productId": product_id,
"higressRefConfig": map[string]interface{}{
"mcpServerName": mcp_name,
"fromGatewayType": "HIGRESS",
},
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ import (
"regexp"
"strings"
"istio.io/istio/operator/pkg/util"
"github.com/alibaba/higress/hgctl/pkg/util"
"sigs.k8s.io/yaml"
)

View File

@@ -0,0 +1,474 @@
---
name: agentscope-test-runner
description: >
Comprehensive Behavioral & Connectivity QA Specialist for AgentScope agents.
Executes end-to-end testing with proper setup, execution, and teardown phases.
Verifies agent behavior, validates responses semantically, and provides detailed reports.
Handles test isolation, resource cleanup, and error recovery automatically.
tools:
- Bash
- Read
- Grep
- Write
model: sonnet
permissionMode: default
---
# Identity & Purpose
You are the **AgentScope Test Runner** - a specialized QA agent responsible for comprehensive behavioral verification of AgentScope agents.
**Your Mission**: Validate that target agents correctly understand prompts, execute tasks, and return semantically appropriate responses through a complete test lifecycle.
**Core Principles**:
1. **Complete Test Lifecycle**: Setup → Execute → Verify → Teardown → Report
2. **Strict Isolation**: Each test runs in a clean environment
3. **Semantic Validation**: Judge response quality, not just API success
4. **Fail-Safe Cleanup**: Always cleanup resources, even on test failure
5. **Detailed Reporting**: Provide actionable insights via structured XML
# Test Lifecycle Overview
```
┌─────────────┐
│ SETUP │ → Prepare environment, validate dependencies
├─────────────┤
│ EXECUTE │ → Send test prompts, capture responses
├─────────────┤
│ VERIFY │ → Analyze semantic correctness
├─────────────┤
│ TEARDOWN │ → Cleanup temp files, restore state
├─────────────┤
│ REPORT │ → Return structured XML results
└─────────────┘
```
# Communication Contract
You communicate via **Structured XML Reports** with comprehensive diagnostics.
```xml
<test_report>
<status>PASS | FAIL | UNSTABLE | ERROR</status>
<test_id>Unique test identifier</test_id>
<target_endpoint>URL tested</target_endpoint>
<test_duration_ms>Execution time</test_duration_ms>
<setup_phase>
<status>SUCCESS | FAILED</status>
<details>Setup validation results</details>
</setup_phase>
<execution_phase>
<input_prompt>The prompt sent to agent</input_prompt>
<http_status>Response status code</http_status>
<response_snippet>First 500 chars of response</response_snippet>
<response_time_ms>API response time</response_time_ms>
</execution_phase>
<verification_phase>
<semantic_verdict>
Detailed analysis: Does the response correctly address the prompt?
Does it follow instructions? Is the output appropriate?
</semantic_verdict>
<verdict>PASS | FAIL | PARTIAL</verdict>
</verification_phase>
<teardown_phase>
<status>SUCCESS | FAILED</status>
<cleaned_resources>List of cleaned temp files</cleaned_resources>
</teardown_phase>
<diagnostics>
<root_cause>Error explanation if applicable</root_cause>
<recommendations>Suggestions for fixing issues</recommendations>
</diagnostics>
</test_report>
```
# Execution Protocol
## Phase 0: Test Planning & Preparation
**Extract Test Parameters** from Main Agent request:
- **TEST_PROMPT**: What to send to the agent
- **TARGET_URL**: Agent endpoint (default: `http://127.0.0.1:8090/process`)
- **EXPECTED_BEHAVIOR**: What constitutes a correct response
- **TEST_TYPE**: simple | multi-turn | performance | stress
**Generate Test ID**:
```bash
TEST_ID="test_$(date +%s)_$$"
TEST_DIR="/tmp/agentscope_test_${TEST_ID}"
```
## Phase 1: SETUP
**Critical**: Establish clean test environment and validate preconditions.
### 1.1 Create Test Environment
```bash
# Create isolated test directory
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
# Setup log files
SETUP_LOG="${TEST_DIR}/setup.log"
EXEC_LOG="${TEST_DIR}/execution.log"
CLEANUP_LOG="${TEST_DIR}/cleanup.log"
echo "[$(date -Iseconds)] Test setup initiated" > "$SETUP_LOG"
```
### 1.2 Validate Dependencies
```bash
# Check required tools
for tool in curl nc jq; do
if ! command -v "$tool" &> /dev/null; then
echo "ERROR: Required tool '$tool' not found" >> "$SETUP_LOG"
# Mark setup as failed and skip to reporting
fi
done
```
### 1.3 Connectivity Pre-flight Check
```bash
# Extract host and port from TARGET_URL
TARGET_HOST="127.0.0.1"
TARGET_PORT="8090"
# Verify port is open
nc -zv "$TARGET_HOST" "$TARGET_PORT" 2>&1 | tee -a "$SETUP_LOG"
if [ $? -ne 0 ]; then
echo "FAIL: Target endpoint unreachable" >> "$SETUP_LOG"
# Skip execution, proceed to teardown and reporting
fi
```
### 1.4 Validate Test Prompt
```bash
# Ensure TEST_PROMPT was extracted
if [ -z "$TEST_PROMPT" ]; then
# Use intelligent default based on context
TEST_PROMPT="Who are you and what can you do?"
echo "INFO: Using default test prompt" >> "$SETUP_LOG"
fi
echo "Test Prompt: $TEST_PROMPT" >> "$SETUP_LOG"
```
## Phase 2: EXECUTION
**Critical**: Send test prompts and capture complete responses.
### 2.1 Construct Payload Safely
Use heredoc for special character safety:
```bash
cat <<'EOF' > "${TEST_DIR}/payload.json"
{
"input": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "TEST_PROMPT_PLACEHOLDER"
}
]
}
]
}
EOF
# Safely inject TEST_PROMPT using jq
jq --arg prompt "$TEST_PROMPT" \
'.input[0].content[0].text = $prompt' \
"${TEST_DIR}/payload.json" > "${TEST_DIR}/payload_final.json"
```
### 2.2 Execute Test Request
Capture timing and full output:
```bash
# Record start time
START_TIME=$(date +%s%3N)
# Execute with comprehensive error capture
HTTP_CODE=$(curl -w "%{http_code}" -o "${TEST_DIR}/response.json" \
-sS -N -X POST "${TARGET_URL}" \
-H "Content-Type: application/json" \
-d @"${TEST_DIR}/payload_final.json" \
2> "${TEST_DIR}/curl_stderr.log")
# Record end time
END_TIME=$(date +%s%3N)
DURATION=$((END_TIME - START_TIME))
echo "HTTP Status: $HTTP_CODE" >> "$EXEC_LOG"
echo "Duration: ${DURATION}ms" >> "$EXEC_LOG"
```
### 2.3 Handle Execution Errors
```bash
if [ $HTTP_CODE -ne 200 ]; then
echo "ERROR: Non-200 response code: $HTTP_CODE" >> "$EXEC_LOG"
cat "${TEST_DIR}/curl_stderr.log" >> "$EXEC_LOG"
# Proceed to teardown
fi
```
## Phase 3: VERIFICATION
**Critical**: Perform semantic analysis of agent response.
### 3.1 Validate Response Format
```bash
# Check if response is valid JSON
if ! jq empty "${TEST_DIR}/response.json" 2>/dev/null; then
echo "FAIL: Invalid JSON response" >> "$EXEC_LOG"
VERDICT="FAIL"
fi
```
### 3.2 Extract Response Content
```bash
# Extract agent's text response
RESPONSE_TEXT=$(jq -r '.output[0].content[0].text // empty' \
"${TEST_DIR}/response.json" 2>/dev/null)
# Save snippet for reporting
echo "$RESPONSE_TEXT" | head -c 500 > "${TEST_DIR}/response_snippet.txt"
```
### 3.3 Semantic Analysis
Evaluate response against test prompt:
**Validation Criteria**:
1. **Non-Empty**: Response contains meaningful content
2. **Relevance**: Response addresses the prompt topic
3. **Correctness**: Response shows understanding of the task
4. **Completeness**: Response provides sufficient detail
**Common Failure Patterns**:
- Empty or null response
- Error messages instead of answers
- "I don't know" when knowledge is expected
- Off-topic responses
- Hallucinated or nonsensical content
- Refusal without valid reason
**Examples**:
- Prompt: "Write Python hello world" → Response should contain Python code
- Prompt: "Summarize AgentScope" → Response should be a summary
- Prompt: "Who are you?" → Response should identify as the agent
### 3.4 Assign Verdict
```bash
# Determine verdict based on analysis
if [ -z "$RESPONSE_TEXT" ]; then
VERDICT="FAIL"
REASON="Empty response received"
elif [[ "$RESPONSE_TEXT" == *"error"* ]] || [[ "$RESPONSE_TEXT" == *"Error"* ]]; then
VERDICT="FAIL"
REASON="Error message in response"
else
# Semantic check (implement based on TEST_PROMPT)
VERDICT="PASS" # or PARTIAL or FAIL
REASON="Response semantically appropriate"
fi
```
## Phase 4: TEARDOWN
**Critical**: Always execute cleanup, even if tests failed.
### 4.1 Cleanup Temporary Files
```bash
# Record cleanup actions
echo "[$(date -Iseconds)] Cleanup initiated" > "$CLEANUP_LOG"
# List files to be cleaned
ls -la "$TEST_DIR" >> "$CLEANUP_LOG"
CLEANED_FILES=(
"${TEST_DIR}/payload.json"
"${TEST_DIR}/payload_final.json"
"${TEST_DIR}/response.json"
"${TEST_DIR}/curl_stderr.log"
)
for file in "${CLEANED_FILES[@]}"; do
if [ -f "$file" ]; then
rm -f "$file"
echo "Removed: $file" >> "$CLEANUP_LOG"
fi
done
```
### 4.2 Archive Logs (Optional)
```bash
# If archiving is needed, compress logs before deletion
if [ "$ARCHIVE_LOGS" = "true" ]; then
tar -czf "/tmp/test_${TEST_ID}_logs.tar.gz" -C "$TEST_DIR" .
echo "Logs archived to /tmp/test_${TEST_ID}_logs.tar.gz" >> "$CLEANUP_LOG"
fi
```
### 4.3 Remove Test Directory
```bash
# Final cleanup
cd /tmp
rm -rf "$TEST_DIR"
if [ -d "$TEST_DIR" ]; then
echo "WARNING: Failed to remove test directory" >> "$CLEANUP_LOG"
CLEANUP_STATUS="FAILED"
else
echo "Test directory successfully removed" >> "$CLEANUP_LOG"
CLEANUP_STATUS="SUCCESS"
fi
```
### 4.4 Restore State
```bash
# If any environment variables were modified, restore them
# If any processes were started, stop them
# If any ports were occupied, release them
echo "[$(date -Iseconds)] Cleanup completed" >> "$CLEANUP_LOG"
```
## Phase 5: REPORTING
Generate comprehensive structured report with all phases.
**Report Assembly**:
1. Collect metrics from all phases
2. Include setup status and duration
3. Include execution results and timing
4. Include verification verdict
5. Include teardown status
6. Add diagnostic information
7. Provide actionable recommendations
**Status Determination**:
- **PASS**: All phases successful, semantic verdict positive
- **FAIL**: Execution succeeded but semantic verdict negative
- **UNSTABLE**: Intermittent issues detected
- **ERROR**: Setup or execution phase failed
# Advanced Testing Scenarios
## Multi-Turn Testing
For testing conversational agents:
```bash
# Send multiple prompts in sequence
for prompt in "${TEST_PROMPTS[@]}"; do
# Execute test with current prompt
# Maintain conversation context if needed
# Verify each response
done
```
## Performance Testing
Measure response time and throughput:
```bash
# Run test N times
for i in {1..10}; do
# Execute and record timing
# Calculate average, min, max response times
done
```
## Stress Testing
Test agent under load:
```bash
# Concurrent requests
for i in {1..5}; do
(execute_test "$TEST_PROMPT") &
done
wait
# Analyze results
```
# Error Recovery
**Fail-Safe Mechanism**: Use trap to ensure cleanup on error:
```bash
cleanup_on_exit() {
echo "Cleanup triggered by exit/error"
# Execute teardown logic
rm -rf "$TEST_DIR" 2>/dev/null
}
trap cleanup_on_exit EXIT ERR INT TERM
```
# Best Practices
1. **Always cleanup**: Use trap to ensure resources are freed
2. **Isolate tests**: Each test gets its own directory and ID
3. **Capture everything**: Log all phases for debugging
4. **Be specific**: Provide detailed semantic verdicts
5. **Handle errors**: Gracefully handle network, API, and format errors
6. **Time everything**: Track duration of each phase
7. **Validate inputs**: Check test prompts and endpoints before execution
# Quick Reference
## Default Test Flow
```bash
# 1. SETUP
mkdir -p /tmp/test_$$/
nc -zv 127.0.0.1 8090
# 2. EXECUTE
curl -X POST http://127.0.0.1:8090/process -d @payload.json
# 3. VERIFY
jq '.output[0].content[0].text' response.json
# 4. TEARDOWN
rm -rf /tmp/test_$$/
# 5. REPORT
echo "<test_report>...</test_report>"
```
## Common Test Prompts
- **Identity**: "Who are you and what can you do?"
- **Code generation**: "Write a Python hello world script"
- **Reasoning**: "Explain why the sky is blue"
- **Summarization**: "Summarize AgentScope in 2 sentences"
- **Tool use**: "List files in the current directory"
- **Multi-step**: "Research Python asyncio and write example code"
---
**Remember**: Your value lies not just in checking connectivity, but in validating that agents behave correctly, understand prompts, and produce semantically appropriate responses. Always complete the full test lifecycle: Setup → Execute → Verify → Teardown → Report.

View File

@@ -0,0 +1,51 @@
---
name: openapi-generator
description: Use this agent when you need to generate a standard OpenAPI 3.0.0 YAML specification from HTTP endpoints. This agent is particularly useful for API documentation, integration planning, and creating standardized API contracts. For example: 'I need to create OpenAPI docs for these REST endpoints', 'Generate OpenAPI spec for my new API', or 'I have these URLs that I want to document with OpenAPI format'.
---
You are an OpenAPI 3.0.0 specification generator agent with expertise in HTTP endpoint analysis and API documentation. Your primary function is to receive HTTP endpoints, curl them to analyze their responses, and generate comprehensive OpenAPI 3.0.0 YAML specifications.
You will follow these steps:
1. Parse any input containing HTTP endpoints - these could be URLs or REST API endpoints
2. For each endpoint, make HTTP requests using curl to analyze:
- HTTP methods (GET, POST, PUT, DELETE, etc.)
- Request parameters and body structures
- Response formats and status codes
- Authentication requirements
- Headers and content types
3. Analyze the responses to understand:
- Data models and structures
- Required and optional fields
- Data types and formats
- Error responses and their formats
4. Generate a comprehensive OpenAPI 3.0.0 YAML specification that includes:
- OpenAPI version (3.0.0)
- Info section with title, version, and description
- Server URLs
- Complete paths object with all endpoints
- Schemas for request/response models
- Proper parameter definitions
- Security schemes if authentication is detected
- Example values where appropriate
Best practices to follow:
- Use descriptive names for endpoints, parameters, and models
- Include appropriate descriptions for all major components
- Use proper data types and formats
- Handle both successful and error responses
- Include example responses where beneficial
- Follow OpenAPI 3.0.0 specification strictly
- Organize related endpoints under common paths
- Use reusable components to avoid duplication
When you encounter issues:
- If an endpoint is unreachable or returns errors, document this in the specification
- If authentication is required but not specified, mark as such in security schemes
- If responses are inconsistent, provide the most common structure and note variations
- For complex data structures, create clear schema definitions
Output format:
- Return only the complete OpenAPI 3.0.0 YAML specification
- Ensure proper YAML formatting and indentation
- Include all necessary components for a complete API specification
- Make the specification self-contained and ready for immediate use

View File

@@ -0,0 +1,35 @@
---
name: openapi-to-mcp-converter
description: Use this agent when you need to convert OpenAPI 3.0 YAML specifications into MCP Server Configurations for deployment on Higress. This should be used when you have an API specification in OpenAPI 3.0 format and want to automatically generate the corresponding MCP server configuration to expose that API through the Higress gateway. Examples include: when you receive an OpenAPI YAML file and want to convert it to MCP format, when you need to validate an OpenAPI spec before conversion, when you want to publish your API configuration to Higress, or when you need expert advice on optimizing your MCP configuration based on Higress best practices.
---
You are an OpenAPI to MCP Server Configuration specialist. Your primary role is to help users convert OpenAPI 3.0 YAML specifications into MCP Server Configurations using the higress-api MCP tool, with a focus on accuracy, completeness, and best practices.
Your core responsibilities include:
1. Receiving and thoroughly analyzing OpenAPI 3.0.0 YAML specifications provided by users
2. Validating specifications to ensure they meet OpenAPI standards
3. Using the 'higress-api' MCP server to perform the conversion from OpenAPI YAML to MCP Server Configuration
4. Presenting generated configurations clearly and comprehensively
5. Providing expert guidance on configuration improvements and optimizations
6. Assisting users with publishing their validated configurations to Higress
Your workflow follows these precise steps:
1. Receive and validate the OpenAPI 3.0 YAML specification from the user
2. Use the 'higress-api' MCP server to transform the specification into MCP Server Configuration
3. Return the complete, readable MCP Server Configuration with clear explanations
4. Provide specific, actionable recommendations for improvements based on Higress best practices
5. Assist with configuration modifications when requested by the user
6. Deploy the final configuration to Higress using the 'higress-api' MCP server's publishing functionality
Key operational requirements:
- Always verify input is a proper OpenAPI 3.0 YAML specification before proceeding
- Ensure all generated MCP Server Configurations are complete, properly formatted, and ready for deployment
- Provide clear explanations of configuration components and their functionality
- Offer optimization suggestions that align with Higress performance and security best practices
- Guide users through the entire conversion and publishing process step-by-step
- Handle all errors gracefully with specific troubleshooting guidance and actionable next steps
- Maintain clear communication about the conversion process, including any limitations or constraints
When presenting configurations, structure them logically with annotations for each major section, highlight important settings that users should review, and explain the purpose of generated components. Always connect your recommendations to specific benefits like improved performance, enhanced security, or better scalability.
If a conversion fails, provide a detailed error analysis with specific guidance on how to resolve issues in the original OpenAPI specification. When publishing, confirm successful deployment and provide next steps for verification and monitoring.

View File

@@ -0,0 +1,40 @@
You are a specialized prompt engineer tasked with generating high-quality, structured prompts for AI agents based on user descriptions. Your goal is to create agent prompts that follow a consistent format inspired by subagent creation workflows, similar to Claude's structured agent design.
When you receive an input in the format:
Get $ARGUMENT
ARGUMENT: [user's description of the desired agent]
You must analyze the description and generate a complete agent prompt in the exact format below. Do not add extra text, explanations, or deviations—output only the generated agent prompt.
The output format must be:
name: [a concise, hyphenated name for the agent based on its primary function, e.g., openapi-generator]
description: [A detailed paragraph describing the agent's purpose, use cases, and examples of when to invoke it. Make it informative and highlight key scenarios.]
You are [a descriptive title for the agent] with expertise in [key skills or domains]. Your primary function is to [core purpose based on the description].
You will follow these steps:
[Step 1: Break down the process logically]
[Step 2: Continue with sequential steps]
[Add more numbered steps as needed to cover the full workflow described by the user.]
Best practices to follow:
[Bullet point best practices relevant to the agent's task]
[More best practices]
When you encounter issues:
[Bullet point handling for common edge cases or errors]
[More issue handling]
Output format:
[Describe the exact output structure, e.g., Return only the complete result in a specific format]
[Additional output guidelines]
Adapt the content to fit the user's agent description precisely:
Infer and expand on steps, best practices, and error handling logically from the description.
Ensure the agent prompt is comprehensive, self-contained, and ready to use.
Keep the language professional, clear, and instructional.
If the description involves tools or external interactions (e.g., HTTP requests), incorporate them appropriately in steps.
Now, process the following input and generate the agent prompt accordingly.

View File

@@ -0,0 +1,51 @@
from typing import Literal
from agentscope.agent import ReActAgent
from agentscope.formatter import FormatterBase
from agentscope.memory import LongTermMemoryBase, MemoryBase
from agentscope.model import ChatModelBase
from agentscope.plan import PlanNotebook
from agentscope.rag import KnowledgeBase
from agentscope.tool import Toolkit
from agentscope.tts import TTSModelBase
class Agent(ReActAgent):
def __init__(
self,
name: str,
sys_prompt: str,
model: ChatModelBase,
formatter: FormatterBase,
toolkit: Toolkit | None = None,
memory: MemoryBase | None = None,
long_term_memory: LongTermMemoryBase | None = None,
long_term_memory_mode: (
Literal["agent_control"] | Literal["static_control"] | Literal["both"]
) = "both",
enable_meta_tool: bool = False,
parallel_tool_calls: bool = False,
knowledge: KnowledgeBase | list[KnowledgeBase] | None = None,
enable_rewrite_query: bool = True,
plan_notebook: PlanNotebook | None = None,
print_hint_msg: bool = False,
max_iters: int = 10,
tts_model: TTSModelBase | None = None,
) -> None:
super().__init__(
name,
sys_prompt,
model,
formatter,
toolkit,
memory,
long_term_memory,
long_term_memory_mode,
enable_meta_tool,
parallel_tool_calls,
knowledge,
enable_rewrite_query,
plan_notebook,
print_hint_msg,
max_iters,
tts_model,
)

View File

@@ -0,0 +1,95 @@
import asyncio
from typing import Any
import os
import sys
from agentscope.agent import ReActAgent
from agentscope.memory import InMemoryMemory
from agentscope.message import Msg
from agentscope.pipeline._functional import stream_printing_messages
from agentscope.agent import ReActAgent
from agentscope.model import DashScopeChatModel
from agentscope.formatter import DashScopeChatFormatter
from agentrun.integration.agentscope import model, sandbox_toolset, toolset
from agentrun.sandbox import TemplateType
from agentrun.server import AgentRequest, AgentRunServer
from agentrun.utils.log import logger
from agent import Agent
from toolkit import toolkit, init_toolkit_sync
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "python"))
MODEL_NAME = "{{ .ChatModel }}"
SANDBOX_NAME = os.getenv("AGENTRUN_SANDBOX_NAME")
if not MODEL_NAME:
raise ValueError("请将 MODEL_NAME 替换为您已经创建的模型名称")
code_interpreter_tools = []
if SANDBOX_NAME and not SANDBOX_NAME.startswith("<"):
code_interpreter_tools = sandbox_toolset(
template_name=SANDBOX_NAME,
template_type=TemplateType.CODE_INTERPRETER,
sandbox_idle_timeout_seconds=300,
)
else:
logger.warning("SANDBOX_NAME 未设置或未替换,跳过加载沙箱工具。")
def load_sys_prompt(prompt_file_name="prompt.md"):
script_dir = os.path.dirname(os.path.abspath(__file__))
prompt_path = os.path.join(script_dir, prompt_file_name)
with open(prompt_path, 'r', encoding='utf-8') as f:
return f.read()
agent = Agent(
name="{{ .AgentName }}",
model=model(MODEL_NAME), # type: ignore
sys_prompt=load_sys_prompt(),
toolkit=toolkit,
memory=InMemoryMemory(),
formatter=DashScopeChatFormatter(),
)
async def invoke_agent(request: AgentRequest):
try:
content = request.messages[0].content
input_msg = Msg(
name="user_message",
content=content, # type: ignore
role="user",
)
async for msg, _ in stream_printing_messages(
agents=[agent],
coroutine_task=agent(input_msg),
):
text = msg.get_text_content()
if text:
yield text
except Exception:
logger.exception("调用出错")
raise
def main():
init_toolkit_sync()
AgentRunServer(invoke_agent=invoke_agent).start()
if __name__ == "__main__":
main()
"""
curl 127.0.0.1:9000/openai/v1/chat/completions -XPOST \
-H "content-type: application/json" \
-d '{
"messages": [{"role": "user", "content": "写一段代码,查询现在是几点?"}],
"stream":true
}'
"""

View File

@@ -0,0 +1,81 @@
edition: 3.0.0
name: agentrun-app
access: "{{ .AccessKey }}"
resources:
hgctl-agent2:
component: agentrun
props:
region: "{{ .Region }}"
# ============= 新规范agent 配置 =============
agent:
# 基本信息
name: "{{ .AgentName }}"
description: "{{ .AgentDesc }}"
# 代码配置(直接指定路径,支持目录或 zip 文件,或使用 OSS 代码包)
code:
src: .
# ossBucketName: funagent-agent-quickstart-langchain-demo-code
# ossObjectName: agentrun-quickstart-code.zip
language: python3.12
command:
- python3
- agentrun_main.py
# 容器配置(使用容器模式时配置此项)
# customContainerConfig:
# image: registry.cn-hangzhou.aliyuncs.com/my-app:latest
# command:
# - python3
# - app.py
# port: 9000
# 资源配置
cpu: 2.0
memory: 4096
diskSize: {{ .DiskSize }} # 可选,默认 512 MB
timeout: {{ .Timeout }} # 可选,默认 600 秒
# 端口和并发
port: {{ .Port }}
instanceConcurrency: 100
# 网络配置 - 仅公网访问
internetAccess: true
# VPC 配置(需要 VPC 内网访问时配置)
# vpcConfig:
# vpcId: vpc-xxx
# vSwitchIds: [vsw-xxx] # 支持单个或多个
# securityGroupId: sg-xxx
# internetAccess: true # 同时配置 vpcConfig 和 internetAccess 表示内外网都可访问
# 环境变量需要填写以下环境变量使用推荐使用无明文AK方式在下方填写授信给FC包含AliyunAgentRunFullAccess的执行角色
environmentVariables:
AGENTRUN_ACCESS_KEY_ID: "{{ .GlobalConfig.AlibabaCloudAccessKeyID }}"
AGENTRUN_ACCESS_KEY_SECRET: "{{ .GlobalConfig.AlibabaCloudAccessKeySecret }}"
AGENTRUN_ACCOUNT_ID: "{{ .GlobalConfig.AgentRunAccountID }}"
AGENTRUN_REGION: "{{ .GlobalConfig.AgentRunRegion }}"
# 执行角色填写此角色无需填写上方AK、SK敏感凭据的环境变量角色需要授信给FC包含AliyunAgentRunFullAccess
# role: acs:ram::1160216277279558:role/AliyunFCDefaultRole
# 日志配置
# logConfig:
# project: ws-testhz
# logstore: acs-ecs-system
# 端点配置
endpoints:
- name: prod
version: LATEST
description: "生产环境端点"
# 灰度发布示例
# - name: gray
# version: 2
# description: "灰度环境端点"
# weight: 0.2 # 20% 流量到版本 2

View File

@@ -0,0 +1,122 @@
import os
import asyncio
from agentscope_runtime.engine import AgentApp
from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
from agentscope.model import {{ .Provider }}Model
from agentscope.formatter import {{ .Provider }}Formatter
from agentscope_runtime.adapters.agentscope.memory import AgentScopeSessionHistoryMemory
from agentscope_runtime.engine.services.agent_state import InMemoryStateService
from agentscope_runtime.engine.services.session_history import InMemorySessionHistoryService
from agentscope.pipeline import stream_printing_messages
from agentscope_runtime.engine.deployers.local_deployer import LocalDeployManager
from agentscope_runtime.engine.deployers.utils.deployment_modes import DeploymentMode
from agent import Agent
from toolkit import toolkit, init_toolkit_sync
app = AgentApp(
app_name="{{.AppName}}",
app_description="{{.AppDescription}}",
)
def load_sys_prompt(prompt_file_name="prompt.md"):
script_dir = os.path.dirname(os.path.abspath(__file__))
prompt_path = os.path.join(script_dir, prompt_file_name)
with open(prompt_path, 'r', encoding='utf-8') as f:
return f.read()
@app.init
async def init_func(self):
"""初始化状态和会话服务"""
self.state_service = InMemoryStateService()
self.session_service = InMemorySessionHistoryService()
await self.state_service.start()
await self.session_service.start()
@app.shutdown
async def shutdown_func(self):
"""清理服务"""
await self.state_service.stop()
await self.session_service.stop()
@app.query(framework="agentscope")
async def query_func(self, msgs, request: AgentRequest, **kwargs):
session_id = request.session_id
user_id = request.user_id
# 恢复 Agent 状态
state = await self.state_service.export_state(
session_id=session_id,
user_id=user_id,
)
# ---- 创建 Agent ----
agent = Agent(
name="{{.AgentName}}",
model={{ .Provider }}Model(
"{{.ChatModel}}",
api_key=os.getenv("{{.APIKeyEnvVar}}"),
stream={{.EnableStreaming | boolToPython}},
),
sys_prompt=load_sys_prompt(),
toolkit=toolkit,
memory=AgentScopeSessionHistoryMemory(
service=self.session_service,
session_id=session_id,
user_id=user_id,
),
formatter={{ .Provider }}Formatter(),
)
agent.set_console_output_enabled(enabled=False)
# 恢复状态
if state:
agent.load_state_dict(state)
# ---- 流式输出 ----
async for msg, last in stream_printing_messages(
agents=[agent],
coroutine_task=agent(msgs),
):
yield msg, last
# ---- 保存 Agent 状态 ----
state = agent.state_dict()
await self.state_service.save_state(
user_id=user_id,
session_id=session_id,
state=state,
)
async def main():
"""以独立进程模式部署应用"""
deployment_info = await app.deploy(
LocalDeployManager(host="{{.HostBinding}}", port={{.DeploymentPort}}),
mode=DeploymentMode.DETACHED_PROCESS,
)
url = deployment_info['url']
print(f"✅ 部署成功:{url}")
print(f"📍 部署 ID{deployment_info['deploy_id']}")
print(
f"""
Check health: curl {url}/health
Shutdown: curl -X POST {url}/admin/shutdown
"""
)
print(f"🌟 You can deploy it to Higress by using: hgctl agent add {url}")
return deployment_info
if __name__ == "__main__":
init_toolkit_sync()
asyncio.run(main())

View File

@@ -0,0 +1,69 @@
import os
import asyncio
from agentscope.tool import Toolkit
from agentscope.tool import execute_shell_command
from agentscope.tool import view_text_file
from agentscope.tool import write_text_file
from agentscope.tool import insert_text_file
from agentscope.tool import dashscope_text_to_image
from agentscope.tool import dashscope_text_to_audio
from agentscope.tool import dashscope_image_to_text
from agentscope.tool import openai_text_to_image
from agentscope.tool import openai_text_to_audio
from agentscope.tool import openai_edit_image
from agentscope.tool import openai_create_image_variation
from agentscope.tool import openai_image_to_text
from agentscope.tool import openai_audio_to_text
from agentscope.tool import execute_python_code
from agentscope.mcp import HttpStatelessClient
toolkit = Toolkit()
def _register_tools():
{{range .AvailableTools}}
toolkit.register_tool_function({{.}})
{{else}}
pass
{{end}}
def init_toolkit_sync():
_register_tools()
asyncio.run(register_all_MCP(toolkit))
async def init_toolkit_async():
_register_tools()
await register_all_MCP(toolkit)
async def register_single_MCP(toolkit: Toolkit, mcp_config):
"""注册单个MCP服务器"""
headers = mcp_config.get("Headers") or None
api_client = HttpStatelessClient(
name=mcp_config["Name"],
transport=mcp_config["Transport"],
url=mcp_config["URL"],
headers=headers,
)
await toolkit.register_mcp_client(api_client)
async def register_all_MCP(toolkit: Toolkit):
"""注册所有配置的MCP服务器"""
{{- range .MCPServers }}
await register_single_MCP(toolkit, {
"Name": "{{ .Name }}",
"URL": "{{ .URL }}",
"Transport": "{{ .Transport }}",
"Headers": {
{{- range $key, $value := .Headers }}
"{{ $key }}": "{{ $value }}",
{{- end }}
}
})
{{- end }}

View File

@@ -15,9 +15,11 @@
package manifests
import (
"bytes"
"embed"
"io/fs"
"os"
"path/filepath"
)
// FS embeds the manifests
@@ -25,6 +27,7 @@ import (
//go:embed profiles/*
//go:embed gatewayapi/*
//go:embed istiobase/*
//go:embed agent/*
var FS embed.FS
// BuiltinOrDir returns a FS for the provided directory. If no directory is passed, the compiled in
@@ -35,3 +38,39 @@ func BuiltinOrDir(dir string) fs.FS {
}
return os.DirFS(dir)
}
// This funciton will write the embed sourceDir's files to target dir
func ExtractEmbedFiles(fsys fs.FS, srcDir, targetDir string) error {
return fs.WalkDir(fsys, srcDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
relDir, err := filepath.Rel(srcDir, path)
if err != nil {
return err
}
targetPath := filepath.Join(targetDir, relDir)
if d.IsDir() {
return os.MkdirAll(targetPath, 0755)
}
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
// if this file already exists, then return
existing, err := os.ReadFile(targetPath)
if err == nil {
if bytes.Equal(existing, data) {
return nil
}
} else if !os.IsNotExist(err) {
return err
}
return os.WriteFile(targetPath, data, 0644)
})
}

79
hgctl/pkg/util/env.go Normal file
View File

@@ -0,0 +1,79 @@
// Copyright (c) 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package util
import (
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
)
func GetPythonVersion() (string, error) {
re := regexp.MustCompile(`\d+\.\d+(\.\d+)?`)
for _, cmd := range []string{"python3", "python"} {
out, err := exec.Command(cmd, "--version").CombinedOutput()
if err != nil {
continue
}
version := strings.TrimSpace(string(out))
match := re.FindString(version)
if match != "" {
return match, nil
}
}
return "", fmt.Errorf("python not found")
}
// compareVersions compares two version strings like "3.11.2" and "3.10".
// Returns:
//
// 1 if v1 > v2
// 0 if v1 == v2
// -1 if v1 < v2
func CompareVersions(v1, v2 string) int {
// Extract numeric parts only (e.g. "3.12.0b1" → "3.12.0")
re := regexp.MustCompile(`\d+`)
nums1 := re.FindAllString(v1, -1)
nums2 := re.FindAllString(v2, -1)
maxLen := len(nums1)
if len(nums2) > maxLen {
maxLen = len(nums2)
}
// Compare each part
for i := 0; i < maxLen; i++ {
var n1, n2 int
if i < len(nums1) {
n1, _ = strconv.Atoi(nums1[i])
}
if i < len(nums2) {
n2, _ = strconv.Atoi(nums2[i])
}
if n1 > n2 {
return 1
} else if n1 < n2 {
return -1
}
}
return 0
}

View File

@@ -16,9 +16,11 @@ package util
import (
"bufio"
"errors"
"fmt"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
)
@@ -93,3 +95,33 @@ func WriteFileString(fileName string, content string, perm os.FileMode) error {
writer.Flush()
return nil
}
// This function return ~/.hgctl file_path string (Currently Linux only)
func GetHomeHgctlDir() string {
homeDir, _ := os.UserHomeDir()
targetDir := filepath.Join(homeDir, ".hgctl")
return targetDir
}
func GetSpecificAgentDir(name string) (string, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed to get user home directory: %w", err)
}
targetDir := filepath.Join(homeDir, ".hgctl", "agents", name)
info, err := os.Stat(targetDir)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return "", fmt.Errorf("agent %q does not exist", name)
}
return "", fmt.Errorf("failed to stat agent directory %q: %w", targetDir, err)
}
if !info.IsDir() {
return "", fmt.Errorf("agent %q exists but is not a directory", name)
}
return targetDir, nil
}

View File

@@ -24,14 +24,13 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
gatewayalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayalpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
k8s "sigs.k8s.io/gateway-api/apis/v1beta1"
gw "sigs.k8s.io/gateway-api/apis/v1"
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
networking "istio.io/api/networking/v1alpha3"
networkingclient "istio.io/client-go/pkg/apis/networking/v1"
kubesecrets "istio.io/istio/pilot/pkg/credentials/kube"
"istio.io/istio/pilot/pkg/features"
"istio.io/istio/pilot/pkg/model/credentials"
"istio.io/istio/pilot/pkg/status"
"istio.io/istio/pilot/pkg/util/protoconv"
@@ -45,21 +44,33 @@ import (
"istio.io/istio/pkg/maps"
"istio.io/istio/pkg/ptr"
"istio.io/istio/pkg/slices"
"istio.io/istio/pkg/util/sets"
)
type TypedNamedspacedName struct {
type TypedNamespacedName struct {
types.NamespacedName
Kind kind.Kind
}
func (n TypedNamedspacedName) String() string {
func (n TypedNamespacedName) String() string {
return n.Kind.String() + "/" + n.NamespacedName.String()
}
type TypedNamespacedNamePerHost struct {
Target TypedNamespacedName
Host string
}
func (t TypedNamespacedNamePerHost) String() string {
return t.Target.String() + "/" + t.Host
}
type BackendPolicy struct {
Source TypedNamedspacedName
Source TypedNamespacedName
TargetIndex int
Target TypedNamedspacedName
Target TypedNamespacedName
Host string
SectionName *string
TLS *networking.ClientTLSSettings
LoadBalancer *networking.LoadBalancerSettings
RetryBudget *networking.TrafficPolicy_RetryBudget
@@ -67,11 +78,43 @@ type BackendPolicy struct {
}
func (b BackendPolicy) ResourceName() string {
return b.Source.String() + "/" + fmt.Sprint(b.TargetIndex)
return b.Source.String() + "/" + fmt.Sprint(b.TargetIndex) + "/" + b.Host
}
var TypedNamespacedNameIndexCollectionFunc = krt.WithIndexCollectionFromString(func(s string) TypedNamespacedName {
parts := strings.Split(s, "/")
if len(parts) != 3 {
panic("invalid TypedNamespacedName: " + s)
}
return TypedNamespacedName{
NamespacedName: types.NamespacedName{
Namespace: parts[1],
Name: parts[2],
},
Kind: kind.FromString(parts[0]),
}
})
var TypedNamespacedNamePerHostIndexCollectionFunc = krt.WithIndexCollectionFromString(func(s string) TypedNamespacedNamePerHost {
parts := strings.Split(s, "/")
if len(parts) != 4 {
panic("invalid TypedNamespacedNamePerHost: " + s)
}
return TypedNamespacedNamePerHost{
Target: TypedNamespacedName{
NamespacedName: types.NamespacedName{
Namespace: parts[1],
Name: parts[2],
},
Kind: kind.FromString(parts[0]),
},
Host: parts[3],
}
})
func (b BackendPolicy) Equals(other BackendPolicy) bool {
return b.Source == other.Source &&
ptr.Equal(b.SectionName, other.SectionName) &&
protoconv.Equals(b.TLS, other.TLS) &&
protoconv.Equals(b.LoadBalancer, other.LoadBalancer) &&
protoconv.Equals(b.RetryBudget, other.RetryBudget)
@@ -81,40 +124,33 @@ func (b BackendPolicy) Equals(other BackendPolicy) bool {
// policy types that are merged together.
func DestinationRuleCollection(
trafficPolicies krt.Collection[*gatewayx.XBackendTrafficPolicy],
tlsPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy],
tlsPolicies krt.Collection[*gw.BackendTLSPolicy],
ancestors krt.Index[TypedNamespacedName, AncestorBackend],
references *ReferenceSet,
domainSuffix string,
c *Controller,
services krt.Collection[*v1.Service],
opts krt.OptionsBuilder,
) krt.Collection[*config.Config] {
trafficPolicyStatus, backendTrafficPolicies := BackendTrafficPolicyCollection(trafficPolicies, references, opts)
trafficPolicyStatus, backendTrafficPolicies := BackendTrafficPolicyCollection(trafficPolicies, references, domainSuffix, opts)
status.RegisterStatus(c.status, trafficPolicyStatus, GetStatus)
tlsPolicyStatus, backendTLSPolicies := BackendTLSPolicyCollection(tlsPolicies, references, opts)
// TODO: BackendTrafficPolicy should also probably use ancestorCollection. However, its still up for debate in the
// Gateway API community if having the Gateway as an ancestor ref is required or not; we would prefer it to not be if possible.
// Until conformance requires it, for now we skip it.
ancestorCollection := ancestors.AsCollection(append(opts.WithName("AncestorBackend"), TypedNamespacedNameIndexCollectionFunc)...)
tlsPolicyStatus, backendTLSPolicies := BackendTLSPolicyCollection(tlsPolicies, ancestorCollection, references, domainSuffix, opts)
status.RegisterStatus(c.status, tlsPolicyStatus, GetStatus)
// We need to merge these by hostname into a single DR
allPolicies := krt.JoinCollection([]krt.Collection[BackendPolicy]{backendTrafficPolicies, backendTLSPolicies})
byTarget := krt.NewIndex(allPolicies, "target", func(o BackendPolicy) []TypedNamedspacedName {
return []TypedNamedspacedName{o.Target}
byTargetAndHost := krt.NewIndex(allPolicies, "targetAndHost", func(o BackendPolicy) []TypedNamespacedNamePerHost {
return []TypedNamespacedNamePerHost{{Target: o.Target, Host: o.Host}}
})
indexOpts := append(opts.WithName("BackendPolicyByTarget"), krt.WithIndexCollectionFromString(func(s string) TypedNamedspacedName {
parts := strings.Split(s, "/")
if len(parts) != 3 {
panic("invalid TypedNamedspacedName: " + s)
}
return TypedNamedspacedName{
NamespacedName: types.NamespacedName{
Namespace: parts[1],
Name: parts[2],
},
Kind: kind.FromString(parts[0]),
}
}))
indexOpts := append(opts.WithName("BackendPolicyByTarget"), TypedNamespacedNamePerHostIndexCollectionFunc)
merged := krt.NewCollection(
byTarget.AsCollection(indexOpts...),
func(ctx krt.HandlerContext, i krt.IndexObject[TypedNamedspacedName, BackendPolicy]) **config.Config {
svc := i.Key
byTargetAndHost.AsCollection(indexOpts...),
func(ctx krt.HandlerContext, i krt.IndexObject[TypedNamespacedNamePerHost, BackendPolicy]) **config.Config {
// Sort so we can pick the oldest, which will win.
// Not yet standardized but likely will be (https://github.com/kubernetes-sigs/gateway-api/issues/3516#issuecomment-2684039692)
pols := slices.SortFunc(i.Objects, func(a, b BackendPolicy) int {
@@ -129,19 +165,35 @@ func DestinationRuleCollection(
tlsSet := false
lbSet := false
rbSet := false
targetWithHost := i.Key
host := targetWithHost.Host
spec := &networking.DestinationRule{
Host: fmt.Sprintf("%s.%s.svc.%v", svc.Name, svc.Namespace, domainSuffix),
Host: host,
TrafficPolicy: &networking.TrafficPolicy{},
}
portLevelSettings := make(map[string]*networking.TrafficPolicy_PortTrafficPolicy)
parents := make([]string, 0, len(pols))
for _, pol := range pols {
if pol.TLS != nil {
if tlsSet {
// We only allow 1. TODO: report status if there are multiple
continue
if pol.SectionName != nil {
// Port-specific TLS setting
portName := *pol.SectionName
if _, exists := portLevelSettings[portName]; !exists {
portLevelSettings[portName] = &networking.TrafficPolicy_PortTrafficPolicy{
Port: &networking.PortSelector{Number: 0}, // Will be resolved later
Tls: pol.TLS,
}
}
} else {
// Service-wide TLS setting
if tlsSet {
// We only allow 1. TODO: report status if there are multiple
continue
}
tlsSet = true
spec.TrafficPolicy.Tls = pol.TLS
}
tlsSet = true
spec.TrafficPolicy.Tls = pol.TLS
}
if pol.LoadBalancer != nil {
if lbSet {
@@ -159,13 +211,64 @@ func DestinationRuleCollection(
rbSet = true
spec.TrafficPolicy.RetryBudget = pol.RetryBudget
}
parents = append(parents, fmt.Sprintf("%s/%s.%s", pol.Source.Kind, pol.Source.Namespace, pol.Source.Name))
parentName := pol.Source.Kind.String() + "/" + pol.Source.Namespace + "." + pol.Source.Name
if !slices.Contains(parents, parentName) {
parents = append(parents, parentName)
}
}
type servicePort struct {
Name string
Number uint32
}
var servicePorts []servicePort
target := targetWithHost.Target
switch target.Kind {
case kind.Service:
serviceKey := target.Namespace + "/" + target.Name
service := ptr.Flatten(krt.FetchOne(ctx, services, krt.FilterKey(serviceKey)))
if service != nil {
for _, port := range service.Spec.Ports {
servicePorts = append(servicePorts, servicePort{
Name: port.Name,
Number: uint32(port.Port),
})
}
}
case kind.ServiceEntry:
serviceEntryObj, err := references.LocalPolicyTargetRef(gw.LocalPolicyTargetReference{
Group: "networking.istio.io",
Kind: "ServiceEntry",
Name: gw.ObjectName(target.Name),
}, target.Namespace)
if err == nil {
if serviceEntryPtr, ok := serviceEntryObj.(*networkingclient.ServiceEntry); ok {
for _, port := range serviceEntryPtr.Spec.Ports {
servicePorts = append(servicePorts, servicePort{
Name: port.Name,
Number: port.Number,
})
}
}
}
}
for portName, portPolicy := range portLevelSettings {
for _, port := range servicePorts {
if port.Name == portName {
portPolicy.Port = &networking.PortSelector{Number: port.Number}
break
}
}
spec.TrafficPolicy.PortLevelSettings = append(spec.TrafficPolicy.PortLevelSettings, portPolicy)
}
cfg := &config.Config{
Meta: config.Meta{
GroupVersionKind: gvk.DestinationRule,
Name: fmt.Sprintf("%s-%s", svc.Name, constants.KubernetesGatewayName),
Namespace: svc.Namespace,
Name: generateDRName(target, host),
Namespace: target.Namespace,
Annotations: map[string]string{
constants.InternalParentNames: strings.Join(parents, ","),
},
@@ -178,93 +281,170 @@ func DestinationRuleCollection(
}
func BackendTLSPolicyCollection(
tlsPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy],
tlsPolicies krt.Collection[*gw.BackendTLSPolicy],
ancestors krt.IndexCollection[TypedNamespacedName, AncestorBackend],
references *ReferenceSet,
domainSuffix string,
opts krt.OptionsBuilder,
) (krt.StatusCollection[*gatewayalpha3.BackendTLSPolicy, gatewayalpha2.PolicyStatus], krt.Collection[BackendPolicy]) {
return krt.NewStatusManyCollection(tlsPolicies, func(ctx krt.HandlerContext, i *gatewayalpha3.BackendTLSPolicy) (
*gatewayalpha2.PolicyStatus,
) (krt.StatusCollection[*gw.BackendTLSPolicy, gw.PolicyStatus], krt.Collection[BackendPolicy]) {
return krt.NewStatusManyCollection(tlsPolicies, func(ctx krt.HandlerContext, i *gw.BackendTLSPolicy) (
*gw.PolicyStatus,
[]BackendPolicy,
) {
status := i.Status.DeepCopy()
res := make([]BackendPolicy, 0, len(i.Spec.TargetRefs))
ancestors := make([]gatewayalpha2.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
tls := &networking.ClientTLSSettings{Mode: networking.ClientTLSSettings_SIMPLE}
s := i.Spec
conds := map[string]*condition{
string(gatewayalpha2.PolicyConditionAccepted): {
reason: string(gatewayalpha2.PolicyReasonAccepted),
string(gw.PolicyConditionAccepted): {
reason: string(gw.PolicyReasonAccepted),
message: "Configuration is valid",
},
string(gw.BackendTLSPolicyConditionResolvedRefs): {
reason: string(gw.BackendTLSPolicyReasonResolvedRefs),
message: "Configuration is valid",
},
}
tls.Sni = string(s.Validation.Hostname)
tls.SubjectAltNames = slices.MapFilter(s.Validation.SubjectAltNames, func(e gatewayalpha3.SubjectAltName) *string {
tls.SubjectAltNames = slices.MapFilter(s.Validation.SubjectAltNames, func(e gw.SubjectAltName) *string {
switch e.Type {
case gatewayalpha3.HostnameSubjectAltNameType:
case gw.HostnameSubjectAltNameType:
return ptr.Of(string(e.Hostname))
case gatewayalpha3.URISubjectAltNameType:
case gw.URISubjectAltNameType:
return ptr.Of(string(e.URI))
}
return nil
})
tls.CredentialName = getBackendTLSCredentialName(s.Validation, i.Namespace, conds, references)
// In ancestor status, we need to report for Service (for mesh) and for each relevant Gateway.
// However, there is a max of 16 items we can report.
// Reporting per-Gateway has no value (perhaps for anyone, but certainly not for Istio), so we favor the Service attachments
// getting to take the 16 slots.
// The Gateway API spec says that if there are more than 16, the policy should not be applied. This is a terrible, anti-user, decision
// that Istio will not follow, even if it means failing conformance tests.
ancestorStatus := make([]gw.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
uniqueGateways := sets.New[types.NamespacedName]()
for idx, t := range i.Spec.TargetRefs {
conds = maps.Clone(conds)
refo, err := references.LocalPolicyTargetRef(t.LocalPolicyTargetReference, i.Namespace)
var sectionName *string
if err == nil {
switch refo.(type) {
switch refType := refo.(type) {
case *v1.Service:
if t.SectionName != nil && *t.SectionName != "" {
sectionName = ptr.Of(string(*t.SectionName))
portExists := false
for _, port := range refType.Spec.Ports {
if port.Name == *sectionName {
portExists = true
break
}
}
if !portExists {
err = fmt.Errorf("sectionName %q does not exist in Service %s/%s", *sectionName, refType.Namespace, refType.Name)
}
}
case *networkingclient.ServiceEntry:
if t.SectionName != nil && *t.SectionName != "" {
sectionName = ptr.Of(string(*t.SectionName))
portExists := false
for _, port := range refType.Spec.Ports {
if port.Name == *sectionName {
portExists = true
break
}
}
if !portExists {
err = fmt.Errorf("sectionName %q does not exist in ServiceEntry %s/%s", *sectionName, refType.Namespace, refType.Name)
}
}
default:
err = fmt.Errorf("unsupported reference kind: %v", t.Kind)
}
}
if err != nil {
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gatewayalpha2.PolicyReasonTargetNotFound),
Message: fmt.Sprintf("targetRefs invalid: %v", err),
conds[string(gw.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gw.PolicyReasonTargetNotFound),
Message: "targetRefs invalid: " + err.Error(),
}
} else {
// Only create an object if we can resolve the target
res = append(res, BackendPolicy{
Source: TypedNamedspacedName{
NamespacedName: config.NamespacedName(i),
Kind: kind.BackendTLSPolicy,
targetKind := gvk.MustToKind(schematypes.GvkFromObject(refo.(controllers.Object)))
target := TypedNamespacedName{
NamespacedName: types.NamespacedName{
Name: string(t.Name),
Namespace: i.Namespace,
},
TargetIndex: idx,
Target: TypedNamedspacedName{
NamespacedName: types.NamespacedName{
Name: string(t.Name),
Namespace: i.Namespace,
Kind: targetKind,
}
var hosts []string
if targetKind == kind.Service {
hosts = []string{string(t.Name) + "." + i.Namespace + ".svc." + domainSuffix}
} else if targetKind == kind.ServiceEntry {
if serviceEntryPtr, ok := refo.(*networkingclient.ServiceEntry); ok {
hosts = serviceEntryPtr.Spec.Hosts
}
}
for _, host := range hosts {
res = append(res, BackendPolicy{
Source: TypedNamespacedName{
NamespacedName: config.NamespacedName(i),
Kind: kind.BackendTLSPolicy,
},
Kind: gvk.MustToKind(schematypes.GvkFromObject(refo.(controllers.Object))),
},
TLS: tls,
CreationTime: i.CreationTimestamp.Time,
})
TargetIndex: idx,
Target: target,
Host: host,
SectionName: sectionName,
TLS: tls,
CreationTime: i.CreationTimestamp.Time,
})
ancestorBackends := krt.Fetch(ctx, ancestors, krt.FilterKey(target.String()))
for _, gwl := range ancestorBackends {
for _, i := range gwl.Objects {
uniqueGateways.Insert(i.Gateway)
}
}
}
}
// TODO: section name
ancestors = append(ancestors, setAncestorStatus(t.LocalPolicyTargetReference, status, i.Generation, conds))
// We add a status for Service (for mesh), and for each Gateway
meshPR := gw.ParentReference{
Group: &t.Group,
Kind: &t.Kind,
Name: t.Name,
SectionName: t.SectionName,
}
ancestorStatus = append(ancestorStatus, setAncestorStatus(meshPR, status, i.Generation, conds, constants.ManagedGatewayMeshController))
}
status.Ancestors = mergeAncestors(status.Ancestors, ancestors)
gwl := slices.SortBy(uniqueGateways.UnsortedList(), types.NamespacedName.String)
for _, g := range gwl {
pr := gw.ParentReference{
Group: ptr.Of(gw.Group(gvk.KubernetesGateway.Group)),
Kind: ptr.Of(gw.Kind(gvk.KubernetesGateway.Kind)),
Name: gw.ObjectName(g.Name),
}
ancestorStatus = append(ancestorStatus, setAncestorStatus(pr, status, i.Generation, conds, gw.GatewayController(higressconstants.ManagedGatewayController)))
}
status.Ancestors = mergeAncestors(status.Ancestors, ancestorStatus)
return status, res
}, opts.WithName("BackendTLSPolicy")...)
}
func getBackendTLSCredentialName(
validation gatewayalpha3.BackendTLSPolicyValidation,
validation gw.BackendTLSPolicyValidation,
policyNamespace string,
conds map[string]*condition,
references *ReferenceSet,
) string {
if wk := validation.WellKnownCACertificates; wk != nil {
switch *wk {
case gatewayalpha3.WellKnownCACertificatesSystem:
case gw.WellKnownCACertificatesSystem:
// Already our default, no action needed
default:
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gatewayalpha2.PolicyReasonInvalid),
conds[string(gw.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gw.PolicyReasonInvalid),
Message: fmt.Sprintf("Unknown wellKnownCACertificates: %v", *wk),
}
}
@@ -278,7 +458,7 @@ func getBackendTLSCredentialName(
// We only support 1
ref := validation.CACertificateRefs[0]
if len(validation.CACertificateRefs) > 1 {
conds[string(gatewayalpha2.PolicyConditionAccepted)].message += "; warning: only the first caCertificateRefs will be used"
conds[string(gw.PolicyConditionAccepted)].message += "; warning: only the first caCertificateRefs will be used"
}
refo, err := references.LocalPolicyRef(ref, policyNamespace)
if err == nil {
@@ -286,6 +466,10 @@ func getBackendTLSCredentialName(
case *v1.ConfigMap:
if _, rerr := kubesecrets.ExtractRootFromString(to.Data); rerr != nil {
err = rerr
conds[string(gw.BackendTLSPolicyReasonResolvedRefs)].error = &ConfigError{
Reason: string(gw.BackendTLSPolicyReasonInvalidCACertificateRef),
Message: "Certificate invalid: " + err.Error(),
}
} else {
return credentials.KubernetesConfigMapTypeURI + policyNamespace + "/" + string(ref.Name)
}
@@ -296,12 +480,28 @@ func getBackendTLSCredentialName(
// Additionally, we will need to ensure we don't accidentally authorize them to access the private key, just the ca.crt
default:
err = fmt.Errorf("unsupported reference kind: %v", ref.Kind)
conds[string(gw.BackendTLSPolicyReasonResolvedRefs)].error = &ConfigError{
Reason: string(gw.BackendTLSPolicyReasonInvalidKind),
Message: "Certificate reference invalid: " + err.Error(),
}
}
} else {
if strings.Contains(err.Error(), "unsupported kind") {
conds[string(gw.BackendTLSPolicyReasonResolvedRefs)].error = &ConfigError{
Reason: string(gw.BackendTLSPolicyReasonInvalidKind),
Message: "Certificate reference not supported: " + err.Error(),
}
} else {
conds[string(gw.BackendTLSPolicyReasonResolvedRefs)].error = &ConfigError{
Reason: string(gw.BackendTLSPolicyReasonInvalidCACertificateRef),
Message: "Certificate reference not found: " + err.Error(),
}
}
}
if err != nil {
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gatewayalpha2.PolicyReasonInvalid),
Message: fmt.Sprintf("Certificate reference invalid: %v", err),
conds[string(gw.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gw.BackendTLSPolicyReasonNoValidCACertificate),
Message: "Certificate reference invalid: " + err.Error(),
}
// Generate an invalid reference. This ensures traffic is blocked.
// See https://github.com/kubernetes-sigs/gateway-api/issues/3516 for upstream clarification on desired behavior here.
@@ -313,6 +513,7 @@ func getBackendTLSCredentialName(
func BackendTrafficPolicyCollection(
trafficPolicies krt.Collection[*gatewayx.XBackendTrafficPolicy],
references *ReferenceSet,
domainSuffix string,
opts krt.OptionsBuilder,
) (krt.StatusCollection[*gatewayx.XBackendTrafficPolicy, gatewayx.PolicyStatus], krt.Collection[BackendPolicy]) {
return krt.NewStatusManyCollection(trafficPolicies, func(ctx krt.HandlerContext, i *gatewayx.XBackendTrafficPolicy) (
@@ -321,14 +522,14 @@ func BackendTrafficPolicyCollection(
) {
status := i.Status.DeepCopy()
res := make([]BackendPolicy, 0, len(i.Spec.TargetRefs))
ancestors := make([]gatewayalpha2.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
ancestors := make([]gw.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
lb := &networking.LoadBalancerSettings{}
var retryBudget *networking.TrafficPolicy_RetryBudget
conds := map[string]*condition{
string(gatewayalpha2.PolicyConditionAccepted): {
reason: string(gatewayalpha2.PolicyReasonAccepted),
string(gw.PolicyConditionAccepted): {
reason: string(gw.PolicyReasonAccepted),
message: "Configuration is valid",
},
}
@@ -351,12 +552,12 @@ func BackendTrafficPolicyCollection(
}
if len(unsupported) > 0 {
msg := fmt.Sprintf("Configuration is valid, but Istio does not support the following fields: %v", humanReadableJoin(unsupported))
conds[string(gatewayalpha2.PolicyConditionAccepted)].message = msg
conds[string(gw.PolicyConditionAccepted)].message = msg
}
for idx, t := range i.Spec.TargetRefs {
conds = maps.Clone(conds)
refo, err := references.LocalPolicyTargetRef(t, i.Namespace)
refo, err := references.XLocalPolicyTargetRef(t, i.Namespace)
if err == nil {
switch refo.(type) {
case *v1.Service:
@@ -365,32 +566,39 @@ func BackendTrafficPolicyCollection(
}
}
if err != nil {
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gatewayalpha2.PolicyReasonTargetNotFound),
Message: fmt.Sprintf("targetRefs invalid: %v", err),
conds[string(gw.PolicyConditionAccepted)].error = &ConfigError{
Reason: string(gw.PolicyReasonTargetNotFound),
Message: "targetRefs invalid: " + err.Error(),
}
} else {
// Only create an object if we can resolve the target
res = append(res, BackendPolicy{
Source: TypedNamedspacedName{
Source: TypedNamespacedName{
NamespacedName: config.NamespacedName(i),
Kind: kind.XBackendTrafficPolicy,
},
TargetIndex: idx,
Target: TypedNamedspacedName{
Target: TypedNamespacedName{
NamespacedName: types.NamespacedName{
Name: string(t.Name),
Namespace: i.Namespace,
},
Kind: kind.Service,
},
Host: string(t.Name) + "." + i.Namespace + ".svc." + domainSuffix,
TLS: nil,
LoadBalancer: lb,
RetryBudget: retryBudget,
CreationTime: i.CreationTimestamp.Time,
})
}
ancestors = append(ancestors, setAncestorStatus(t, status, i.Generation, conds))
pr := gw.ParentReference{
Group: &t.Group,
Kind: &t.Kind,
Name: t.Name,
}
ancestors = append(ancestors, setAncestorStatus(pr, status, i.Generation, conds, constants.ManagedGatewayMeshController))
}
status.Ancestors = mergeAncestors(status.Ancestors, ancestors)
return status, res
@@ -398,31 +606,27 @@ func BackendTrafficPolicyCollection(
}
func setAncestorStatus(
t gatewayalpha2.LocalPolicyTargetReference,
status *gatewayalpha2.PolicyStatus,
pr gw.ParentReference,
status *gw.PolicyStatus,
generation int64,
conds map[string]*condition,
) gatewayalpha2.PolicyAncestorStatus {
pr := gatewayalpha2.ParentReference{
Group: &t.Group,
Kind: &t.Kind,
Name: t.Name,
}
currentAncestor := slices.FindFunc(status.Ancestors, func(ex gatewayalpha2.PolicyAncestorStatus) bool {
controller gw.GatewayController,
) gw.PolicyAncestorStatus {
currentAncestor := slices.FindFunc(status.Ancestors, func(ex gw.PolicyAncestorStatus) bool {
return parentRefEqual(ex.AncestorRef, pr)
})
var currentConds []metav1.Condition
if currentAncestor != nil {
currentConds = currentAncestor.Conditions
}
return gatewayalpha2.PolicyAncestorStatus{
return gw.PolicyAncestorStatus{
AncestorRef: pr,
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
ControllerName: controller,
Conditions: setConditions(generation, currentConds, conds),
}
}
func parentRefEqual(a, b gatewayalpha2.ParentReference) bool {
func parentRefEqual(a, b gw.ParentReference) bool {
return ptr.Equal(a.Group, b.Group) &&
ptr.Equal(a.Kind, b.Kind) &&
a.Name == b.Name &&
@@ -431,19 +635,20 @@ func parentRefEqual(a, b gatewayalpha2.ParentReference) bool {
ptr.Equal(a.Port, b.Port)
}
var outControllers = sets.New(gw.GatewayController(higressconstants.ManagedGatewayController), constants.ManagedGatewayMeshController)
// mergeAncestors merges an existing ancestor with in incoming one. We preserve order, prune stale references set by our controller,
// and add any new references from our controller.
func mergeAncestors(existing []gatewayalpha2.PolicyAncestorStatus, incoming []gatewayalpha2.PolicyAncestorStatus) []gatewayalpha2.PolicyAncestorStatus {
ourController := k8s.GatewayController(features.ManagedGatewayController)
func mergeAncestors(existing []gw.PolicyAncestorStatus, incoming []gw.PolicyAncestorStatus) []gw.PolicyAncestorStatus {
n := 0
for _, x := range existing {
if x.ControllerName != ourController {
if !outControllers.Contains(x.ControllerName) {
// Keep it as-is
existing[n] = x
n++
continue
}
replacement := slices.IndexFunc(incoming, func(status gatewayalpha2.PolicyAncestorStatus) bool {
replacement := slices.IndexFunc(incoming, func(status gw.PolicyAncestorStatus) bool {
return parentRefEqual(status.AncestorRef, x.AncestorRef)
})
if replacement != -1 {
@@ -457,5 +662,13 @@ func mergeAncestors(existing []gatewayalpha2.PolicyAncestorStatus, incoming []ga
existing = existing[:n]
// Add all remaining ones.
existing = append(existing, incoming...)
return existing
// There is a max of 16
return existing[:min(len(existing), 16)]
}
func generateDRName(target TypedNamespacedName, host string) string {
if target.Kind == kind.ServiceEntry {
return target.Name + "~" + strings.ReplaceAll(host, ".", "-") + "~" + constants.KubernetesGatewayName
}
return target.Name + "~" + constants.KubernetesGatewayName
}

View File

@@ -21,6 +21,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8s "sigs.k8s.io/gateway-api/apis/v1"
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
"istio.io/istio/pilot/pkg/features"
"istio.io/istio/pilot/pkg/model/kstatus"
"istio.io/istio/pkg/config/schema/gvk"
@@ -52,7 +53,7 @@ func createRouteStatus(
parentIndexes := map[string]int{}
for idx, p := range parents {
// Only consider our own
if p.ControllerName != k8s.GatewayController(features.ManagedGatewayController) {
if p.ControllerName != k8s.GatewayController(higressconstants.ManagedGatewayController) {
continue
}
rs := parentRefString(p.ParentRef, objectNamespace)
@@ -185,14 +186,14 @@ func createRouteStatus(
var currentConditions []metav1.Condition
currentStatus := slices.FindFunc(currentParents, func(s k8s.RouteParentStatus) bool {
return parentRefString(s.ParentRef, objectNamespace) == myRef &&
s.ControllerName == k8s.GatewayController(features.ManagedGatewayController)
s.ControllerName == k8s.GatewayController(higressconstants.ManagedGatewayController)
})
if currentStatus != nil {
currentConditions = currentStatus.Conditions
}
ns := k8s.RouteParentStatus{
ParentRef: gw.OriginalReference,
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
ControllerName: k8s.GatewayController(higressconstants.ManagedGatewayController),
Conditions: setConditions(generation, currentConditions, conds),
}
// Parent ref already exists, insert in the same place

View File

@@ -21,7 +21,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8s "sigs.k8s.io/gateway-api/apis/v1beta1"
"istio.io/istio/pilot/pkg/features"
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/config/schema/gvk"
)
@@ -39,7 +39,7 @@ func TestCreateRouteStatus(t *testing.T) {
},
{
ParentRef: parentRef,
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
ControllerName: k8s.GatewayController(higressconstants.ManagedGatewayController),
Conditions: []metav1.Condition{
{
Type: string(k8s.RouteReasonAccepted),

View File

@@ -16,15 +16,13 @@ package istio
import (
"fmt"
"go.uber.org/atomic"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayalpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
@@ -153,9 +151,9 @@ type Inputs struct {
ListenerSets krt.Collection[*gatewayx.XListenerSet]
ReferenceGrants krt.Collection[*gateway.ReferenceGrant]
BackendTrafficPolicy krt.Collection[*gatewayx.XBackendTrafficPolicy]
BackendTLSPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy]
BackendTLSPolicies krt.Collection[*gatewayv1.BackendTLSPolicy]
ServiceEntries krt.Collection[*networkingclient.ServiceEntry]
InferencePools krt.Collection[*inferencev1alpha2.InferencePool]
InferencePools krt.Collection[*inferencev1.InferencePool]
}
var _ model.GatewayController = &Controller{}
@@ -201,11 +199,12 @@ func NewController(
kclient.NewFiltered[*corev1.ConfigMap](kc, kubetypes.Filter{ObjectFilter: kc.ObjectFilter()}),
opts.WithName("informer/ConfigMaps")...,
),
Services: krt.WrapClient[*corev1.Service](svcClient, opts.WithName("informer/Services")...),
GatewayClasses: buildClient[*gateway.GatewayClass](c, kc, gvr.GatewayClass, opts, "informer/GatewayClasses"),
Gateways: buildClient[*gateway.Gateway](c, kc, gvr.KubernetesGateway, opts, "informer/Gateways"),
HTTPRoutes: buildClient[*gateway.HTTPRoute](c, kc, gvr.HTTPRoute, opts, "informer/HTTPRoutes"),
GRPCRoutes: buildClient[*gatewayv1.GRPCRoute](c, kc, gvr.GRPCRoute, opts, "informer/GRPCRoutes"),
Services: krt.WrapClient[*corev1.Service](svcClient, opts.WithName("informer/Services")...),
GatewayClasses: buildClient[*gateway.GatewayClass](c, kc, gvr.GatewayClass, opts, "informer/GatewayClasses"),
Gateways: buildClient[*gateway.Gateway](c, kc, gvr.KubernetesGateway, opts, "informer/Gateways"),
HTTPRoutes: buildClient[*gateway.HTTPRoute](c, kc, gvr.HTTPRoute, opts, "informer/HTTPRoutes"),
GRPCRoutes: buildClient[*gatewayv1.GRPCRoute](c, kc, gvr.GRPCRoute, opts, "informer/GRPCRoutes"),
BackendTLSPolicies: buildClient[*gatewayv1.BackendTLSPolicy](c, kc, gvr.BackendTLSPolicy, opts, "informer/BackendTLSPolicies"),
ReferenceGrants: buildClient[*gateway.ReferenceGrant](c, kc, gvr.ReferenceGrant, opts, "informer/ReferenceGrants"),
ServiceEntries: buildClient[*networkingclient.ServiceEntry](c, kc, gvr.ServiceEntry, opts, "informer/ServiceEntries"),
@@ -213,27 +212,26 @@ func NewController(
if features.EnableAlphaGatewayAPI {
inputs.TCPRoutes = buildClient[*gatewayalpha.TCPRoute](c, kc, gvr.TCPRoute, opts, "informer/TCPRoutes")
inputs.TLSRoutes = buildClient[*gatewayalpha.TLSRoute](c, kc, gvr.TLSRoute, opts, "informer/TLSRoutes")
inputs.BackendTLSPolicies = buildClient[*gatewayalpha3.BackendTLSPolicy](c, kc, gvr.BackendTLSPolicy, opts, "informer/BackendTLSPolicies")
inputs.BackendTrafficPolicy = buildClient[*gatewayx.XBackendTrafficPolicy](c, kc, gvr.XBackendTrafficPolicy, opts, "informer/XBackendTrafficPolicy")
inputs.ListenerSets = buildClient[*gatewayx.XListenerSet](c, kc, gvr.XListenerSet, opts, "informer/XListenerSet")
} else {
// If disabled, still build a collection but make it always empty
inputs.TCPRoutes = krt.NewStaticCollection[*gatewayalpha.TCPRoute](nil, nil, opts.WithName("disable/TCPRoutes")...)
inputs.TLSRoutes = krt.NewStaticCollection[*gatewayalpha.TLSRoute](nil, nil, opts.WithName("disable/TLSRoutes")...)
inputs.BackendTLSPolicies = krt.NewStaticCollection[*gatewayalpha3.BackendTLSPolicy](nil, nil, opts.WithName("disable/BackendTLSPolicies")...)
inputs.BackendTrafficPolicy = krt.NewStaticCollection[*gatewayx.XBackendTrafficPolicy](nil, nil, opts.WithName("disable/XBackendTrafficPolicy")...)
inputs.ListenerSets = krt.NewStaticCollection[*gatewayx.XListenerSet](nil, nil, opts.WithName("disable/XListenerSet")...)
}
if features.EnableGatewayAPIInferenceExtension {
inputs.InferencePools = buildClient[*inferencev1alpha2.InferencePool](c, kc, gvr.InferencePool, opts, "informer/InferencePools")
inputs.InferencePools = buildClient[*inferencev1.InferencePool](c, kc, gvr.InferencePool, opts, "informer/InferencePools")
} else {
// If disabled, still build a collection but make it always empty
inputs.InferencePools = krt.NewStaticCollection[*inferencev1alpha2.InferencePool](nil, nil, opts.WithName("disable/InferencePools")...)
inputs.InferencePools = krt.NewStaticCollection[*inferencev1.InferencePool](nil, nil, opts.WithName("disable/InferencePools")...)
}
references := NewReferenceSet(
AddReference(inputs.Services),
AddReference(inputs.ServiceEntries),
AddReference(inputs.ConfigMaps),
AddReference(inputs.Secrets),
)
@@ -252,6 +250,7 @@ func NewController(
GatewayClasses,
inputs.Namespaces,
ReferenceGrants,
inputs.ConfigMaps,
inputs.Secrets,
options.DomainSuffix,
c.gatewayContext,
@@ -261,15 +260,6 @@ func NewController(
)
status.RegisterStatus(c.status, ListenerSetStatus, GetStatus)
DestinationRules := DestinationRuleCollection(
inputs.BackendTrafficPolicy,
inputs.BackendTLSPolicies,
references,
c.domainSuffix,
c,
opts,
)
// GatewaysStatus is not fully complete until its join with route attachments to report attachedRoutes.
// Do not register yet.
GatewaysStatus, Gateways := GatewayCollection(
@@ -278,6 +268,7 @@ func NewController(
GatewayClasses,
inputs.Namespaces,
ReferenceGrants,
inputs.ConfigMaps,
inputs.Secrets,
c.domainSuffix,
c.gatewayContext,
@@ -352,6 +343,26 @@ func NewController(
RouteAttachmentsIndex := krt.NewIndex(RouteAttachments, "to", func(o RouteAttachment) []types.NamespacedName {
return []types.NamespacedName{o.To}
})
Ancestors := krt.JoinCollection([]krt.Collection[AncestorBackend]{
tcpRoutes.Ancestors,
tlsRoutes.Ancestors,
httpRoutes.Ancestors,
grpcRoutes.Ancestors,
}, opts.WithName("Ancestors")...)
AncestorsIndex := krt.NewIndex(Ancestors, "ancestors", func(o AncestorBackend) []TypedNamespacedName {
return []TypedNamespacedName{o.Backend}
})
DestinationRules := DestinationRuleCollection(
inputs.BackendTrafficPolicy,
inputs.BackendTLSPolicies,
AncestorsIndex,
references,
c.domainSuffix,
c,
inputs.Services,
opts,
)
GatewayFinalStatus := FinalGatewayStatusCollection(GatewaysStatus, RouteAttachments, RouteAttachmentsIndex, opts)
status.RegisterStatus(c.status, GatewayFinalStatus, GetStatus)

View File

@@ -17,11 +17,14 @@ package istio
import (
"cmp"
"crypto/tls"
"crypto/x509"
"fmt"
higressconfig "github.com/alibaba/higress/v2/pkg/config"
"github.com/alibaba/higress/v2/pkg/ingress/kube/util"
"istio.io/istio/pilot/pkg/credentials"
"net"
"path"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
"sort"
"strconv"
"strings"
@@ -32,10 +35,8 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
klabels "k8s.io/apimachinery/pkg/labels"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
k8s "sigs.k8s.io/gateway-api/apis/v1"
k8salpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayalpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1"
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
@@ -342,7 +343,7 @@ func parentTypes(rpi []routeParentReference) (mesh, gateway bool) {
gateway = true
}
}
return
return mesh, gateway
}
func augmentPortMatch(routes []*istio.HTTPRoute, port k8s.PortNumber) []*istio.HTTPRoute {
@@ -1269,7 +1270,7 @@ func createCorsFilter(filter *k8s.HTTPCORSFilter) *istio.CorsPolicy {
MatchType: &istio.StringMatch_Exact{Exact: string(r)},
})
}
if filter.AllowCredentials {
if ptr.OrEmpty(filter.AllowCredentials) {
res.AllowCredentials = wrappers.Bool(true)
}
for _, r := range filter.AllowMethods {
@@ -2013,11 +2014,13 @@ func extractGatewayServices(domainSuffix string, kgw *k8sbeta.Gateway, info clas
func buildListener(
ctx krt.HandlerContext,
configMaps krt.Collection[*corev1.ConfigMap],
secrets krt.Collection[*corev1.Secret],
grants ReferenceGrants,
namespaces krt.Collection[*corev1.Namespace],
obj controllers.Object,
status []k8s.ListenerStatus,
gw k8s.GatewaySpec,
l k8s.Listener,
listenerIndex int,
controllerName k8s.GatewayController,
@@ -2044,7 +2047,7 @@ func buildListener(
}
ok := true
tls, err := buildTLS(ctx, secrets, grants, l.TLS, obj, kube.IsAutoPassthrough(obj.GetLabels(), l))
tls, err := buildTLS(ctx, configMaps, secrets, grants, resolveGatewayTLS(l.Port, gw.TLS), l.TLS, obj, kube.IsAutoPassthrough(obj.GetLabels(), l))
if err != nil {
listenerConditions[string(k8s.ListenerConditionResolvedRefs)].error = err
listenerConditions[string(k8s.GatewayConditionProgrammed)].error = &ConfigError{
@@ -2135,11 +2138,27 @@ func listenerProtocolToIstio(name k8s.GatewayController, p k8s.ProtocolType) (st
return "", fmt.Errorf("protocol %q is unsupported", p)
}
func resolveGatewayTLS(port k8s.PortNumber, gw *k8s.GatewayTLSConfig) *k8s.TLSConfig {
if gw == nil || gw.Frontend == nil {
return nil
}
f := gw.Frontend
pp := slices.FindFunc(f.PerPort, func(portConfig k8s.TLSPortConfig) bool {
return portConfig.Port == port
})
if pp != nil {
return &pp.TLS
}
return &f.Default
}
func buildTLS(
ctx krt.HandlerContext,
configMaps krt.Collection[*corev1.ConfigMap],
secrets krt.Collection[*corev1.Secret],
grants ReferenceGrants,
tls *k8s.GatewayTLSConfig,
gatewayTLS *k8s.TLSConfig,
tls *k8s.ListenerTLSConfig,
gw controllers.Object,
isAutoPassthrough bool,
) (*istio.ServerTLSSettings, *ConfigError) {
@@ -2216,6 +2235,32 @@ func buildTLS(
} else {
out.CredentialNames = credNames
}
if gatewayTLS != nil && gatewayTLS.Validation != nil && len(gatewayTLS.Validation.CACertificateRefs) > 0 {
// TODO: add 'Mode'
if len(gatewayTLS.Validation.CACertificateRefs) > 1 {
return out, &ConfigError{
Reason: InvalidTLS,
Message: "only one caCertificateRef is supported",
}
}
caCertRef := gatewayTLS.Validation.CACertificateRefs[0]
cred, err := buildCaCertificateReference(ctx, caCertRef, gw, configMaps, secrets)
if err != nil {
return out, err
}
if cred.Namespace != namespace && !grants.SecretAllowed(ctx, schematypes.GvkFromObject(gw), cred.ResourceName, namespace) {
return out, &ConfigError{
Reason: InvalidListenerRefNotPermitted,
Message: fmt.Sprintf(
"caCertificateRef %v/%v not accessible to a Gateway in namespace %q (missing a ReferenceGrant?)",
cred.Namespace, caCertRef.Name, namespace,
),
}
}
out.Mode = istio.ServerTLSSettings_MUTUAL
//out.CaCertCredentialName = cred.ResourceName
}
case k8s.TLSModePassthrough:
out.Mode = istio.ServerTLSSettings_PASSTHROUGH
if isAutoPassthrough {
@@ -2232,7 +2277,7 @@ func buildSecretReference(
secrets krt.Collection[*corev1.Secret],
) (string, *ConfigError) {
if normalizeReference(ref.Group, ref.Kind, gvk.Secret) != gvk.Secret {
return "", &ConfigError{Reason: InvalidTLS, Message: fmt.Sprintf("invalid certificate reference %v, only secret is allowed", objectReferenceString(ref))}
return "", &ConfigError{Reason: InvalidTLS, Message: fmt.Sprintf("invalid certificate reference %v, only secret is allowed", secretObjectReferenceString(ref))}
}
secret := model.ConfigKey{
@@ -2246,26 +2291,101 @@ func buildSecretReference(
if scrt == nil {
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, secret %v not found", objectReferenceString(ref), key),
Message: fmt.Sprintf("invalid certificate reference %v, secret %v not found", secretObjectReferenceString(ref), key),
}
}
certInfo, err := kubecreds.ExtractCertInfo(scrt)
if err != nil {
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, %v", objectReferenceString(ref), err),
Message: fmt.Sprintf("invalid certificate reference %v, %v", secretObjectReferenceString(ref), err),
}
}
if _, err = tls.X509KeyPair(certInfo.Cert, certInfo.Key); err != nil {
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, the certificate is malformed: %v", objectReferenceString(ref), err),
Message: fmt.Sprintf("invalid certificate reference %v, the certificate is malformed: %v", secretObjectReferenceString(ref), err),
}
}
return creds.ToKubernetesGatewayResource(secret.Namespace, secret.Name), nil
}
func objectReferenceString(ref k8s.SecretObjectReference) string {
func buildCaCertificateReference(
ctx krt.HandlerContext,
ref k8s.ObjectReference,
gw controllers.Object,
configMaps krt.Collection[*corev1.ConfigMap],
secrets krt.Collection[*corev1.Secret],
) (*creds.SecretResource, *ConfigError) {
var resourceType string
var resourceKind kind.Kind
var certInfo *credentials.CertInfo
var certInfoErr error
namespace := ptr.OrDefault((*string)(ref.Namespace), gw.GetNamespace())
name := string(ref.Name)
switch normalizeReference(&ref.Group, &ref.Kind, config.GroupVersionKind{}) {
case gvk.ConfigMap:
resourceType = creds.KubernetesConfigMapType
resourceKind = kind.ConfigMap
key := namespace + "/" + name
cm := ptr.Flatten(krt.FetchOne(ctx, configMaps, krt.FilterKey(key)))
if cm == nil {
return nil, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid CA certificate reference %v, configmap %v not found", objectReferenceString(ref), key),
}
}
certInfo, certInfoErr = kubecreds.ExtractRootFromString(cm.Data)
case gvk.Secret:
resourceType = creds.KubernetesGatewaySecretType
resourceKind = kind.Secret
key := namespace + "/" + name
scrt := ptr.Flatten(krt.FetchOne(ctx, secrets, krt.FilterKey(key)))
if scrt == nil {
return nil, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid CA certificate reference %v, secret %v not found", objectReferenceString(ref), key),
}
}
certInfo, certInfoErr = kubecreds.ExtractRoot(scrt.Data)
default:
return nil, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid CA certificate reference %v, only secret and configmap are allowed", objectReferenceString(ref)),
}
}
if certInfoErr != nil {
return nil, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid CA certificate reference %v, %v", objectReferenceString(ref), certInfoErr),
}
}
if !x509.NewCertPool().AppendCertsFromPEM(certInfo.Cert) {
return nil, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid CA certificate reference %v, the bundle is malformed", objectReferenceString(ref)),
}
}
log.Warnf("buildCaCertificateReference %s://%s/%s%s", resourceType, namespace, ref.Name, creds.SdsCaSuffix)
return &creds.SecretResource{
ResourceType: resourceType,
ResourceKind: resourceKind,
Name: name + creds.SdsCaSuffix,
Namespace: namespace,
ResourceName: fmt.Sprintf("%s://%s/%s%s", resourceType, namespace, ref.Name, creds.SdsCaSuffix),
Cluster: "",
}, nil
}
func objectReferenceString(ref k8s.ObjectReference) string {
return fmt.Sprintf("%s/%s/%s.%s", ref.Group, ref.Kind, ref.Name, ptr.OrEmpty(ref.Namespace))
}
func secretObjectReferenceString(ref k8s.SecretObjectReference) string {
return fmt.Sprintf("%s/%s/%s.%s",
ptr.OrEmpty(ref.Group),
ptr.OrEmpty(ref.Kind),
@@ -2500,11 +2620,11 @@ func GetStatus[I, IS any](spec I) IS {
return any(t.Status).(IS)
case *gatewayx.XBackendTrafficPolicy:
return any(t.Status).(IS)
case *gatewayalpha3.BackendTLSPolicy:
case *k8s.BackendTLSPolicy:
return any(t.Status).(IS)
case *gatewayx.XListenerSet:
return any(t.Status).(IS)
case *inferencev1alpha2.InferencePool:
case *inferencev1.InferencePool:
return any(t.Status).(IS)
default:
log.Fatalf("unknown type %T", t)
@@ -2512,6 +2632,20 @@ func GetStatus[I, IS any](spec I) IS {
}
}
func GetBackendRef[I any](spec I) (config.GroupVersionKind, *k8s.Namespace, k8s.ObjectName) {
switch t := any(spec).(type) {
case k8s.HTTPBackendRef:
return normalizeReference(t.Group, t.Kind, gvk.Service), t.Namespace, t.Name
case k8s.GRPCBackendRef:
return normalizeReference(t.Group, t.Kind, gvk.Service), t.Namespace, t.Name
case k8s.BackendRef:
return normalizeReference(t.Group, t.Kind, gvk.Service), t.Namespace, t.Name
default:
log.Fatalf("unknown GetBackendRef type %T", t)
return config.GroupVersionKind{}, nil, ""
}
}
// Start - Added by Higress
// isCatchAll returns true if HTTPMatchRequest is a catchall match otherwise
// false. Note - this may not be exactly "catch all" as we don't know the full

View File

@@ -518,6 +518,33 @@ D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
"tls.key": []byte("SGVsbG8gd29ybGQK"),
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "malformed",
Namespace: "higress-system",
},
Data: map[string]string{
"not-ca.crt": "hello",
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "malformed-trustbundle",
Namespace: "higress-system",
},
Data: map[string]string{
"ca.crt": "hello",
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cert-http",
Namespace: "higress-system",
},
Data: map[string]string{
"ca.crt": rsaCertPEM,
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "malformed",
@@ -625,7 +652,7 @@ func TestConvertResources(t *testing.T) {
}{
{name: "http"},
{name: "tcp"},
//{name: "tls"}, // TODO: fix this case
{name: "tls"},
{name: "grpc"},
{name: "mismatch"},
{name: "weighted"},
@@ -672,7 +699,14 @@ func TestConvertResources(t *testing.T) {
//{name: "waypoint"},
//{name: "isolation"},
{name: "backend-lb-policy"},
{name: "backend-tls-policy"},
{
name: "backend-tls-policy",
validationIgnorer: crdvalidation.NewValidationIgnorer(
"default/echo-https",
"default/external-service",
"default/multi-host-service",
),
},
{name: "mix-backend-policy"},
//{name: "listenerset"},
//{name: "listenerset-cross-namespace"},
@@ -749,7 +783,7 @@ func TestConvertResources(t *testing.T) {
goldenFile := fmt.Sprintf("testdata/%s.yaml.golden", tt.name)
b := marshalYaml(t, res)
t.Logf("marshaled yaml result : %s", string(b))
//t.Logf("marshaled yaml result : %s", string(b))
util.CompareContent(t, b, goldenFile)

View File

@@ -16,6 +16,7 @@ package istio
import (
"fmt"
"istio.io/api/annotation"
"strings"
"go.uber.org/atomic"
@@ -77,6 +78,7 @@ func ListenerSetCollection(
gatewayClasses krt.Collection[GatewayClass],
namespaces krt.Collection[*corev1.Namespace],
grants ReferenceGrants,
configMaps krt.Collection[*corev1.ConfigMap],
secrets krt.Collection[*corev1.Secret],
domainSuffix string,
gatewayContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]],
@@ -151,7 +153,8 @@ func ListenerSetCollection(
l.Port = port
standardListener := convertListenerSetToListener(l)
originalStatus := slices.Map(status.Listeners, convertListenerSetStatusToStandardStatus)
server, updatedStatus, programmed := buildListener(ctx, secrets, grants, namespaces, obj, originalStatus, standardListener, i, controllerName, portErr)
server, updatedStatus, programmed := buildListener(ctx, configMaps, secrets, grants, namespaces,
obj, originalStatus, parentGwObj.Spec, standardListener, i, controllerName, portErr)
status.Listeners = slices.Map(updatedStatus, convertStandardStatusToListenerSetStatus(l))
servers = append(servers, server)
@@ -163,6 +166,11 @@ func ListenerSetCollection(
meta[constants.InternalGatewaySemantics] = constants.GatewaySemanticsGateway
//meta[model.InternalGatewayServiceAnnotation] = strings.Join(gatewayServices, ",")
meta[constants.InternalParentNamespace] = parentGwObj.Namespace
serviceAccountName := model.GetOrDefault(
parentGwObj.GetAnnotations()[annotation.GatewayServiceAccount.Name],
getDefaultName(parentGwObj.GetName(), &parentGwObj.Spec, classInfo.disableNameSuffix),
)
meta[constants.InternalServiceAccount] = serviceAccountName
// Start - Updated by Higress
var selector map[string]string
@@ -233,6 +241,7 @@ func GatewayCollection(
gatewayClasses krt.Collection[GatewayClass],
namespaces krt.Collection[*corev1.Namespace],
grants ReferenceGrants,
configMaps krt.Collection[*corev1.ConfigMap],
secrets krt.Collection[*corev1.Secret],
domainSuffix string,
gatewayContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]],
@@ -284,8 +293,19 @@ func GatewayCollection(
}
// End - Updated by Higress
// See: https://istio.io/latest/docs/tasks/traffic-management/ingress/gateway-api/#manual-deployment
// If we set and address of type hostname, then we have no idea what service accounts the gateway workloads will use.
// Thus, we don't enforce service account name restrictions (still look at namespaces though).
serviceAccountName := ""
if IsManaged(&obj.Spec) {
serviceAccountName = model.GetOrDefault(
obj.GetAnnotations()[annotation.GatewayServiceAccount.Name],
getDefaultName(obj.GetName(), &kgw, classInfo.disableNameSuffix),
)
}
for i, l := range kgw.Listeners {
server, updatedStatus, programmed := buildListener(ctx, secrets, grants, namespaces, obj, status.Listeners, l, i, controllerName, nil)
server, updatedStatus, programmed := buildListener(ctx, configMaps, secrets, grants, namespaces, obj, status.Listeners, kgw, l, i, controllerName, nil)
status.Listeners = updatedStatus
servers = append(servers, server)
@@ -296,6 +316,7 @@ func GatewayCollection(
}
meta := parentMeta(obj, &l.Name)
meta[constants.InternalGatewaySemantics] = constants.GatewaySemanticsGateway
meta[constants.InternalServiceAccount] = serviceAccountName
// Start - Updated by Higress
var selector map[string]string
if len(gatewayServices) != 0 {

View File

@@ -23,7 +23,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -63,11 +63,17 @@ func getSupportedControllers() sets.Set[gatewayv1.GatewayController] {
}
type shadowServiceInfo struct {
key types.NamespacedName
selector map[string]string
poolName string
poolUID types.UID
targetPort int32
key types.NamespacedName
selector map[string]string
poolName string
poolUID types.UID
// targetPorts is the port number on the pods selected by the selector.
// Currently, inference extension only supports a single target port.
targetPorts []targetPort
}
type targetPort struct {
port int32
}
type extRefInfo struct {
@@ -87,19 +93,19 @@ func (i InferencePool) ResourceName() string {
}
func InferencePoolCollection(
pools krt.Collection[*inferencev1alpha2.InferencePool],
pools krt.Collection[*inferencev1.InferencePool],
services krt.Collection[*corev1.Service],
httpRoutes krt.Collection[*gateway.HTTPRoute],
gateways krt.Collection[*gateway.Gateway],
routesByInferencePool krt.Index[string, *gateway.HTTPRoute],
c *Controller,
opts krt.OptionsBuilder,
) (krt.StatusCollection[*inferencev1alpha2.InferencePool, inferencev1alpha2.InferencePoolStatus], krt.Collection[InferencePool]) {
) (krt.StatusCollection[*inferencev1.InferencePool, inferencev1.InferencePoolStatus], krt.Collection[InferencePool]) {
return krt.NewStatusCollection(pools,
func(
ctx krt.HandlerContext,
pool *inferencev1alpha2.InferencePool,
) (*inferencev1alpha2.InferencePoolStatus, *InferencePool) {
pool *inferencev1.InferencePool,
) (*inferencev1.InferencePoolStatus, *InferencePool) {
// Fetch HTTPRoutes that reference this InferencePool once and reuse
routeList := krt.Fetch(ctx, httpRoutes, krt.FilterIndex(routesByInferencePool, pool.Namespace+"/"+pool.Name))
@@ -107,7 +113,7 @@ func InferencePoolCollection(
gatewayParents := findGatewayParents(pool, routeList)
// TODO: If no gateway parents, we should not do anything
// note: we stil need to filter out our Status to clean up previous reconciliations
// note: we still need to filter out our Status to clean up previous reconciliations
// Create the InferencePool only if there are Gateways connected
var inferencePool *InferencePool
@@ -124,20 +130,21 @@ func InferencePoolCollection(
}
// createInferencePoolObject creates the InferencePool object with shadow service and extension ref info
func createInferencePoolObject(pool *inferencev1alpha2.InferencePool, gatewayParents sets.Set[types.NamespacedName]) *InferencePool {
func createInferencePoolObject(pool *inferencev1.InferencePool, gatewayParents sets.Set[types.NamespacedName]) *InferencePool {
// Build extension reference info
extRef := extRefInfo{
name: string(pool.Spec.ExtensionRef.Name),
name: string(pool.Spec.EndpointPickerRef.Name),
}
if pool.Spec.ExtensionRef.PortNumber != nil {
extRef.port = int32(*pool.Spec.ExtensionRef.PortNumber)
} else {
extRef.port = 9002 // Default port for the inference extension
if pool.Spec.EndpointPickerRef.Port == nil {
log.Errorf("invalid InferencePool %s/%s; endpointPickerRef port is required", pool.Namespace, pool.Name)
return nil
}
if pool.Spec.ExtensionRef.FailureMode != nil {
extRef.failureMode = string(*pool.Spec.ExtensionRef.FailureMode)
} else {
extRef.failureMode = string(inferencev1alpha2.FailClose)
extRef.port = int32(pool.Spec.EndpointPickerRef.Port.Number)
extRef.failureMode = string(inferencev1.EndpointPickerFailClose) // Default failure mode
if pool.Spec.EndpointPickerRef.FailureMode != inferencev1.EndpointPickerFailClose {
extRef.failureMode = string(pool.Spec.EndpointPickerRef.FailureMode)
}
svcName, err := InferencePoolServiceName(pool.Name)
@@ -151,16 +158,20 @@ func createInferencePoolObject(pool *inferencev1alpha2.InferencePool, gatewayPar
Name: svcName,
Namespace: pool.GetNamespace(),
},
selector: make(map[string]string, len(pool.Spec.Selector)),
poolName: pool.GetName(),
targetPort: pool.Spec.TargetPortNumber,
poolUID: pool.GetUID(),
selector: make(map[string]string, len(pool.Spec.Selector.MatchLabels)),
poolName: pool.GetName(),
targetPorts: make([]targetPort, 0, len(pool.Spec.TargetPorts)),
poolUID: pool.GetUID(),
}
for k, v := range pool.Spec.Selector {
for k, v := range pool.Spec.Selector.MatchLabels {
shadowSvcInfo.selector[string(k)] = string(v)
}
for _, port := range pool.Spec.TargetPorts {
shadowSvcInfo.targetPorts = append(shadowSvcInfo.targetPorts, targetPort{port: int32(port.Number)})
}
return &InferencePool{
shadowService: shadowSvcInfo,
extRef: extRef,
@@ -170,22 +181,22 @@ func createInferencePoolObject(pool *inferencev1alpha2.InferencePool, gatewayPar
// calculateInferencePoolStatus calculates the complete status for an InferencePool
func calculateInferencePoolStatus(
pool *inferencev1alpha2.InferencePool,
pool *inferencev1.InferencePool,
gatewayParents sets.Set[types.NamespacedName],
services krt.Collection[*corev1.Service],
gateways krt.Collection[*gateway.Gateway],
routeList []*gateway.HTTPRoute,
) *inferencev1alpha2.InferencePoolStatus {
) *inferencev1.InferencePoolStatus {
// Calculate status for each gateway parent
existingParents := pool.Status.DeepCopy().Parents
finalParents := []inferencev1alpha2.PoolStatus{}
finalParents := []inferencev1.ParentStatus{}
// Add existing parents from other controllers (not managed by us)
for _, existingParent := range existingParents {
gtwName := string(existingParent.GatewayRef.Name)
gtwName := string(existingParent.ParentRef.Name)
gtwNamespace := pool.Namespace
if existingParent.GatewayRef.Namespace != nil {
gtwNamespace = string(*existingParent.GatewayRef.Namespace)
if existingParent.ParentRef.Namespace != "" {
gtwNamespace = string(existingParent.ParentRef.Namespace)
}
parentKey := types.NamespacedName{
Name: gtwName,
@@ -208,14 +219,14 @@ func calculateInferencePoolStatus(
finalParents = append(finalParents, parentStatus)
}
return &inferencev1alpha2.InferencePoolStatus{
return &inferencev1.InferencePoolStatus{
Parents: finalParents,
}
}
// findGatewayParents finds all Gateway parents that reference this InferencePool through HTTPRoutes
func findGatewayParents(
pool *inferencev1alpha2.InferencePool,
pool *inferencev1.InferencePool,
routeList []*gateway.HTTPRoute,
) sets.Set[types.NamespacedName] {
gatewayParents := sets.New[types.NamespacedName]()
@@ -251,7 +262,7 @@ func findGatewayParents(
}
// routeReferencesInferencePool checks if an HTTPRoute references the given InferencePool
func routeReferencesInferencePool(route *gateway.HTTPRoute, pool *inferencev1alpha2.InferencePool) bool {
func routeReferencesInferencePool(route *gateway.HTTPRoute, pool *inferencev1.InferencePool) bool {
for _, rule := range route.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
if !isInferencePoolBackendRef(backendRef.BackendRef) {
@@ -285,17 +296,17 @@ func isInferencePoolBackendRef(backendRef gatewayv1.BackendRef) bool {
// calculateSingleParentStatus calculates the status for a single gateway parent
func calculateSingleParentStatus(
pool *inferencev1alpha2.InferencePool,
pool *inferencev1.InferencePool,
gatewayParent types.NamespacedName,
services krt.Collection[*corev1.Service],
existingParents []inferencev1alpha2.PoolStatus,
existingParents []inferencev1.ParentStatus,
routeList []*gateway.HTTPRoute,
) inferencev1alpha2.PoolStatus {
) inferencev1.ParentStatus {
// Find existing status for this parent to preserve some conditions
var existingConditions []metav1.Condition
for _, existingParent := range existingParents {
if string(existingParent.GatewayRef.Name) == gatewayParent.Name &&
string(ptr.OrEmpty(existingParent.GatewayRef.Namespace)) == gatewayParent.Namespace {
if string(existingParent.ParentRef.Name) == gatewayParent.Name &&
string(existingParent.ParentRef.Namespace) == gatewayParent.Namespace {
existingConditions = existingParent.Conditions
break
}
@@ -303,8 +314,8 @@ func calculateSingleParentStatus(
// Filter to only keep conditions we manage
filteredConditions := filterUsedConditions(existingConditions,
inferencev1alpha2.InferencePoolConditionAccepted,
inferencev1alpha2.InferencePoolConditionResolvedRefs)
inferencev1.InferencePoolConditionAccepted,
inferencev1.InferencePoolConditionResolvedRefs)
// Calculate Accepted status by checking HTTPRoute parent status
acceptedStatus := calculateAcceptedStatus(pool, gatewayParent, routeList)
@@ -313,23 +324,23 @@ func calculateSingleParentStatus(
resolvedRefsStatus := calculateResolvedRefsStatus(pool, services)
// Build the final status
return inferencev1alpha2.PoolStatus{
GatewayRef: inferencev1alpha2.ParentGatewayReference{
Group: (*inferencev1alpha2.Group)(&gvk.Gateway.Group),
Kind: (*inferencev1alpha2.Kind)(&gvk.Gateway.Kind),
Namespace: (*inferencev1alpha2.Namespace)(&gatewayParent.Namespace),
Name: inferencev1alpha2.ObjectName(gatewayParent.Name),
return inferencev1.ParentStatus{
ParentRef: inferencev1.ParentReference{
Group: (*inferencev1.Group)(&gvk.Gateway.Group),
Kind: inferencev1.Kind(gvk.Gateway.Kind),
Namespace: inferencev1.Namespace(gatewayParent.Namespace),
Name: inferencev1.ObjectName(gatewayParent.Name),
},
Conditions: setConditions(pool.Generation, filteredConditions, map[string]*condition{
string(inferencev1alpha2.InferencePoolConditionAccepted): acceptedStatus,
string(inferencev1alpha2.InferencePoolConditionResolvedRefs): resolvedRefsStatus,
string(inferencev1.InferencePoolConditionAccepted): acceptedStatus,
string(inferencev1.InferencePoolConditionResolvedRefs): resolvedRefsStatus,
}),
}
}
// calculateAcceptedStatus determines if the InferencePool is accepted by checking HTTPRoute parent status
func calculateAcceptedStatus(
pool *inferencev1alpha2.InferencePool,
pool *inferencev1.InferencePool,
gatewayParent types.NamespacedName,
routeList []*gateway.HTTPRoute,
) *condition {
@@ -359,13 +370,13 @@ func calculateAcceptedStatus(
if parentCondition.Type == string(gatewayv1.RouteConditionAccepted) {
if parentCondition.Status == metav1.ConditionTrue {
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
reason: string(inferencev1.InferencePoolReasonAccepted),
status: metav1.ConditionTrue,
message: "Referenced by an HTTPRoute accepted by the parentRef Gateway",
}
}
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
reason: string(inferencev1.InferencePoolReasonHTTPRouteNotAccepted),
status: metav1.ConditionFalse,
message: fmt.Sprintf("Referenced HTTPRoute %s/%s not accepted by Gateway %s/%s: %s",
route.Namespace, route.Name, gatewayParent.Namespace, gatewayParent.Name, parentCondition.Message),
@@ -375,7 +386,7 @@ func calculateAcceptedStatus(
// If no Accepted condition found, treat as unknown (parent is listed in status)
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
reason: string(inferencev1.InferencePoolReasonAccepted),
status: metav1.ConditionUnknown,
message: "Referenced by an HTTPRoute unknown parentRef Gateway status",
}
@@ -386,7 +397,7 @@ func calculateAcceptedStatus(
// If we get here, no HTTPRoute was found that references this InferencePool with this gateway as parent
// This shouldn't happen in normal operation since we only call this for known gateway parents
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
reason: string(inferencev1.InferencePoolReasonHTTPRouteNotAccepted),
status: metav1.ConditionFalse,
message: fmt.Sprintf("No HTTPRoute found referencing this InferencePool with Gateway %s/%s as parent",
gatewayParent.Namespace, gatewayParent.Name),
@@ -398,42 +409,51 @@ func calculateAcceptedStatus(
// * if the extensionRef is defined
// * if the service exists in the same namespace as the InferencePool
func calculateResolvedRefsStatus(
pool *inferencev1alpha2.InferencePool,
pool *inferencev1.InferencePool,
services krt.Collection[*corev1.Service],
) *condition {
// defaults to service
if pool.Spec.ExtensionRef.Kind != nil && string(*pool.Spec.ExtensionRef.Kind) != gvk.Service.Kind {
// Default Kind to Service if unset
kind := string(pool.Spec.EndpointPickerRef.Kind)
if kind == "" {
kind = gvk.Service.Kind
}
if kind != gvk.Service.Kind {
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
reason: string(inferencev1.InferencePoolReasonInvalidExtensionRef),
status: metav1.ConditionFalse,
message: "Unsupported ExtensionRef kind " + string(*pool.Spec.ExtensionRef.Kind),
message: "Unsupported ExtensionRef kind " + kind,
}
}
if string(pool.Spec.ExtensionRef.Name) == "" {
name := string(pool.Spec.EndpointPickerRef.Name)
if name == "" {
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
reason: string(inferencev1.InferencePoolReasonInvalidExtensionRef),
status: metav1.ConditionFalse,
message: "ExtensionRef not defined",
}
}
svc := ptr.Flatten(services.GetKey(fmt.Sprintf("%s/%s", pool.Namespace, pool.Spec.ExtensionRef.Name)))
svc := ptr.Flatten(services.GetKey(fmt.Sprintf("%s/%s", pool.Namespace, name)))
if svc == nil {
return &condition{
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
reason: string(inferencev1.InferencePoolReasonInvalidExtensionRef),
status: metav1.ConditionFalse,
message: "Referenced ExtensionRef not found " + string(pool.Spec.ExtensionRef.Name),
message: "Referenced ExtensionRef not found " + name,
}
}
return &condition{
reason: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
reason: string(inferencev1.InferencePoolReasonResolvedRefs),
status: metav1.ConditionTrue,
message: "Referenced ExtensionRef resolved successfully",
}
}
// isDefaultStatusParent checks if this is a default status parent entry
func isDefaultStatusParent(parent inferencev1alpha2.PoolStatus) bool {
return string(ptr.OrEmpty(parent.GatewayRef.Kind)) == "Status" && parent.GatewayRef.Name == "default"
func isDefaultStatusParent(parent inferencev1.ParentStatus) bool {
return string(parent.ParentRef.Kind) == "Status" && parent.ParentRef.Name == "default"
}
// isOurManagedGateway checks if a Gateway is managed by one of our supported controllers
@@ -447,10 +467,10 @@ func isOurManagedGateway(gateways krt.Collection[*gateway.Gateway], namespace, n
return ok
}
func filterUsedConditions(conditions []metav1.Condition, usedConditions ...inferencev1alpha2.InferencePoolConditionType) []metav1.Condition {
func filterUsedConditions(conditions []metav1.Condition, usedConditions ...inferencev1.InferencePoolConditionType) []metav1.Condition {
var result []metav1.Condition
for _, condition := range conditions {
if slices.Contains(usedConditions, inferencev1alpha2.InferencePoolConditionType(condition.Type)) {
if slices.Contains(usedConditions, inferencev1.InferencePoolConditionType(condition.Type)) {
result = append(result, condition)
}
}
@@ -484,6 +504,18 @@ func InferencePoolServiceName(poolName string) (string, error) {
}
func translateShadowServiceToService(existingLabels map[string]string, shadow shadowServiceInfo, extRef extRefInfo) *corev1.Service {
// Create the ports used by the shadow service
ports := make([]corev1.ServicePort, 0, len(shadow.targetPorts))
dummyPort := int32(54321) // Dummy port, not used for anything
for i, port := range shadow.targetPorts {
ports = append(ports, corev1.ServicePort{
Name: "port" + strconv.Itoa(i),
Protocol: corev1.ProtocolTCP,
Port: dummyPort + int32(i),
TargetPort: intstr.FromInt(int(port.port)),
})
}
// Create a new service object based on the shadow service info
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -501,13 +533,7 @@ func translateShadowServiceToService(existingLabels map[string]string, shadow sh
Selector: shadow.selector,
Type: corev1.ServiceTypeClusterIP,
ClusterIP: corev1.ClusterIPNone, // Headless service
Ports: []corev1.ServicePort{ // adding dummy port, not used for anything
{
Protocol: "TCP",
Port: int32(54321),
TargetPort: intstr.FromInt(int(shadow.targetPort)),
},
},
Ports: ports,
},
}

View File

@@ -16,7 +16,6 @@ package istio
import (
"fmt"
"github.com/alibaba/higress/v2/pkg/config/constants"
"strings"
"testing"
"time"
@@ -28,7 +27,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -40,20 +39,21 @@ import (
)
const (
HigressController = constants.ManagedGatewayController
DefaultTestNS = "default"
GatewayTestNS = "gateway-ns"
AppTestNS = "app-ns"
EmptyTestNS = ""
IstioController = "higress.io/gateway-controller"
DefaultTestNS = "default"
GatewayTestNS = "gateway-ns"
AppTestNS = "app-ns"
EmptyTestNS = ""
infPoolPending = "Pending"
)
func TestInferencePoolStatusReconciliation(t *testing.T) {
test.SetForTest(t, &features.EnableGatewayAPIInferenceExtension, true)
testCases := []struct {
name string
givens []runtime.Object // Objects to create before the test
targetPool *inferencev1alpha2.InferencePool // The InferencePool to check
expectations func(t *testing.T, pool *inferencev1alpha2.InferencePoolStatus)
givens []runtime.Object // Objects to create before the test
targetPool *inferencev1.InferencePool // The InferencePool to check
expectations func(t *testing.T, pool *inferencev1.InferencePoolStatus)
}{
//
// Positive Test Scenarios
@@ -61,21 +61,21 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should add gateway parentRef to inferencepool status",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithRouteParentCondition(string(gatewayv1.RouteConditionAccepted), metav1.ConditionTrue, "Accepted", "Accepted"),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, DefaultTestNS, string(status.Parents[0].ParentRef.Namespace))
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
Type: string(inferencev1.InferencePoolConditionAccepted),
Status: metav1.ConditionTrue,
Reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
Reason: string(inferencev1.InferencePoolReasonAccepted),
Message: "Referenced by an HTTPRoute",
}, "Expected condition with Accepted")
},
@@ -83,136 +83,136 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should add only 1 gateway parentRef to status for multiple routes on different gateways with different controllers",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithParentRefAndStatus("gateway-2", DefaultTestNS, "other-controller"),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "gateway-1", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, DefaultTestNS, string(status.Parents[0].ParentRef.Namespace))
},
},
{
name: "should keep the status of the gateway parentRefs from antoher controller",
name: "should keep the status of the gateway parentRefs from another controller",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other-class")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
NewHTTPRoute("route-2", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-2", DefaultTestNS, "other-class"),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("gateway-2", DefaultTestNS, WithAcceptedConditions())),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 2, "Expected two parent references")
assert.ElementsMatch(t,
[]string{"gateway-1", "gateway-2"},
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
[]string{string(status.Parents[0].ParentRef.Name), string(status.Parents[1].ParentRef.Name)},
)
},
},
{
name: "should add multiple gateway parentRefs to status for multiple routes",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
NewHTTPRoute("route-2", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-2", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-2", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 2, "Expected two parent references")
assert.ElementsMatch(t,
[]string{"gateway-1", "gateway-2"},
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
[]string{string(status.Parents[0].ParentRef.Name), string(status.Parents[1].ParentRef.Name)},
)
},
},
{
name: "should remove our status from previous reconciliation that is no longer referenced by any HTTPRoute",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
WithParentStatus("gateway-2", DefaultTestNS,
WithAcceptedConditions(),
)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, "gateway-1", string(status.Parents[0].ParentRef.Name))
},
},
{
name: "should update/recreate our status from previous reconciliation",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
WithParentStatus("gateway-1", DefaultTestNS,
WithAcceptedConditions(),
)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, "gateway-1", string(status.Parents[0].ParentRef.Name))
require.Len(t, status.Parents[0].Conditions, 2, "Expected two conditions")
},
},
{
name: "should keep others status from previous reconciliation",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other-class")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("gateway-2", DefaultTestNS, WithAcceptedConditions())),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 2, "Expected two parent references")
assert.ElementsMatch(t,
[]string{"gateway-1", "gateway-2"},
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
[]string{string(status.Parents[0].ParentRef.Name), string(status.Parents[1].ParentRef.Name)},
)
},
},
{
name: "should remove default parent 'waiting for controller' status",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("default", DefaultTestNS, AsDefaultStatus())),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected two parent references")
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, "gateway-1", string(status.Parents[0].ParentRef.Name))
},
},
{
name: "should remove unknown condition types from controlled parents",
givens: []runtime.Object{
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
WithParentRefAndStatus("gateway-1", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
@@ -220,12 +220,12 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
WithAcceptedConditions(),
WithConditions(metav1.ConditionUnknown, "X", "Y", "Dummy"),
)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected two parent references")
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, "gateway-1", string(status.Parents[0].ParentRef.Name))
require.Len(t, status.Parents[0].Conditions, 2, "Expected two conditions")
assert.ElementsMatch(t,
[]string{string(inferencev1alpha2.InferencePoolConditionAccepted), string(inferencev1alpha2.InferencePoolConditionResolvedRefs)},
[]string{string(inferencev1.InferencePoolConditionAccepted), string(inferencev1.InferencePoolConditionResolvedRefs)},
[]string{status.Parents[0].Conditions[0].Type, status.Parents[0].Conditions[1].Type},
)
},
@@ -233,97 +233,97 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should handle cross-namespace gateway references correctly",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(AppTestNS),
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
WithParentRefAndStatus("main-gateway", GatewayTestNS, IstioController),
WithBackendRef("test-pool", AppTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, GatewayTestNS, string(status.Parents[0].ParentRef.Namespace))
},
},
{
name: "should handle cross-namespace httproute references correctly",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(AppTestNS),
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
WithParentRefAndStatus("main-gateway", GatewayTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, GatewayTestNS, string(status.Parents[0].ParentRef.Namespace))
},
},
{
name: "should handle HTTPRoute in same namespace (empty)",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(AppTestNS),
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
WithParentRefAndStatus("main-gateway", GatewayTestNS, IstioController),
WithBackendRef("test-pool", EmptyTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, GatewayTestNS, string(status.Parents[0].ParentRef.Namespace))
},
},
{
name: "should handle Gateway in same namespace (empty)",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(AppTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(AppTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(AppTestNS),
WithParentRefAndStatus("main-gateway", EmptyTestNS, HigressController),
WithParentRefAndStatus("main-gateway", EmptyTestNS, IstioController),
WithBackendRef("test-pool", AppTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, AppTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, AppTestNS, string(status.Parents[0].ParentRef.Namespace))
},
},
{
name: "should add only one parentRef for multiple routes on same gateway",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("route-a", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
NewHTTPRoute("route-b", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected only one parent reference for the same gateway")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
},
},
{
name: "should report ResolvedRef true when ExtensioNRef found",
givens: []runtime.Object{
NewService("test-epp", InNamespace(DefaultTestNS)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithExtensionRef("Service", "test-epp")),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
Type: string(inferencev1.InferencePoolConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: string(inferencev1alpha2.InferencePoolReasonResolvedRefs),
Reason: string(inferencev1.InferencePoolReasonResolvedRefs),
Message: "Referenced ExtensionRef resolved",
}, "Expected condition with InvalidExtensionRef")
},
@@ -331,21 +331,21 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should report HTTPRoute not accepted when parent gateway rejects HTTPRoute",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithRouteParentCondition(string(gatewayv1.RouteConditionAccepted), metav1.ConditionFalse, "GatewayNotReady", "Gateway not ready"),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, DefaultTestNS, string(status.Parents[0].ParentRef.Namespace))
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
Type: string(inferencev1.InferencePoolConditionAccepted),
Status: metav1.ConditionFalse,
Reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
Reason: string(inferencev1.InferencePoolReasonHTTPRouteNotAccepted),
Message: "Referenced HTTPRoute default/test-route not accepted by Gateway default/main-gateway",
}, "Expected condition with HTTPRouteNotAccepted")
},
@@ -353,21 +353,21 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should report unknown status when HTTPRoute parent status has no Accepted condition",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
// Note: No WithRouteParentCondition for Accepted - parent is listed but has no conditions
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
assert.Equal(t, "main-gateway", string(status.Parents[0].ParentRef.Name))
assert.Equal(t, DefaultTestNS, string(status.Parents[0].ParentRef.Namespace))
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
Type: string(inferencev1.InferencePoolConditionAccepted),
Status: metav1.ConditionUnknown,
Reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
Reason: string(inferencev1.InferencePoolReasonAccepted),
Message: "Referenced by an HTTPRoute unknown parentRef Gateway status",
}, "Expected condition with ConditionUnknown")
},
@@ -385,19 +385,19 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
assert.Empty(t, status.Parents, "ParentRefs should be empty")
},
},
{
name: "should not add parentRef if httproute has no backendref",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController)), // No BackendRef
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController)), // No BackendRef
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
assert.Empty(t, status.Parents, "ParentRefs should be empty")
},
},
@@ -408,26 +408,26 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
WithBackendRef("test-pool", DefaultTestNS)), // No ParentRef
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
assert.Empty(t, status.Parents, "ParentRefs should be empty")
},
},
{
name: "should report ExtensionRef not found if no matching service found",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
Type: string(inferencev1.InferencePoolConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
Reason: string(inferencev1.InferencePoolReasonInvalidExtensionRef),
Message: "Referenced ExtensionRef not found",
}, "Expected condition with InvalidExtensionRef")
},
@@ -435,19 +435,19 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
{
name: "should report unsupported ExtensionRef if kind is not service",
givens: []runtime.Object{
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass("higress")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
WithParentRefAndStatus("main-gateway", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS)),
},
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithExtensionRef("Gateway", "main-gateway")),
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
expectations: func(t *testing.T, status *inferencev1.InferencePoolStatus) {
require.Len(t, status.Parents, 1, "Expected one parent reference")
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
Type: string(inferencev1.InferencePoolConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
Reason: string(inferencev1.InferencePoolReasonInvalidExtensionRef),
Message: "Unsupported ExtensionRef kind",
}, "Expected condition with InvalidExtensionRef")
},
@@ -472,10 +472,10 @@ func TestInferencePoolStatusReconciliation(t *testing.T) {
dumpOnFailure(t, krt.GlobalDebugHandler)
getInferencePoolStatus := func() *inferencev1alpha2.InferencePoolStatus {
getInferencePoolStatus := func() *inferencev1.InferencePoolStatus {
statuses := sq.Statuses()
for _, status := range statuses {
if pool, ok := status.(*inferencev1alpha2.InferencePoolStatus); ok {
if pool, ok := status.(*inferencev1.InferencePoolStatus); ok {
return pool
}
}
@@ -511,7 +511,7 @@ func assertConditionContains(t *testing.T, conditions []metav1.Condition, expect
// Option is a function that mutates an object.
type Option func(client.Object)
type ParentOption func(*inferencev1alpha2.PoolStatus)
type ParentOption func(*inferencev1.ParentStatus)
// --- Helper functions to mutate objects ---
@@ -635,15 +635,15 @@ func WithBackendRef(name, namespace string) Option {
func WithParentStatus(gatewayName, namespace string, opt ...ParentOption) Option {
return func(obj client.Object) {
ip, ok := obj.(*inferencev1alpha2.InferencePool)
ip, ok := obj.(*inferencev1.InferencePool)
if ok {
if ip.Status.Parents == nil {
ip.Status.Parents = []inferencev1alpha2.PoolStatus{}
ip.Status.Parents = []inferencev1.ParentStatus{}
}
poolStatus := inferencev1alpha2.PoolStatus{
GatewayRef: inferencev1alpha2.ParentGatewayReference{
Name: inferencev1alpha2.ObjectName(gatewayName),
Namespace: (*inferencev1alpha2.Namespace)(&namespace),
poolStatus := inferencev1.ParentStatus{
ParentRef: inferencev1.ParentReference{
Name: inferencev1.ObjectName(gatewayName),
Namespace: inferencev1.Namespace(namespace),
},
}
for _, opt := range opt {
@@ -655,22 +655,22 @@ func WithParentStatus(gatewayName, namespace string, opt ...ParentOption) Option
}
func AsDefaultStatus() ParentOption {
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
return func(parentStatusRef *inferencev1.ParentStatus) {
dName := "default"
dKind := "Status"
parentStatusRef.GatewayRef.Name = inferencev1alpha2.ObjectName(dName)
parentStatusRef.GatewayRef.Kind = (*inferencev1alpha2.Kind)(&dKind)
parentStatusRef.ParentRef.Name = inferencev1.ObjectName(dName)
parentStatusRef.ParentRef.Kind = inferencev1.Kind(dKind)
WithConditions(
metav1.ConditionUnknown,
string(inferencev1alpha2.InferencePoolConditionAccepted),
string(inferencev1alpha2.InferencePoolReasonPending),
string(inferencev1.InferencePoolConditionAccepted),
infPoolPending,
"Waiting for controller",
)
}
}
func WithConditions(status metav1.ConditionStatus, conType, reason, message string) ParentOption {
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
return func(parentStatusRef *inferencev1.ParentStatus) {
if parentStatusRef.Conditions == nil {
parentStatusRef.Conditions = []metav1.Condition{}
}
@@ -688,17 +688,17 @@ func WithConditions(status metav1.ConditionStatus, conType, reason, message stri
}
func WithAcceptedConditions() ParentOption {
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
return func(parentStatusRef *inferencev1.ParentStatus) {
WithConditions(
metav1.ConditionTrue,
string(inferencev1alpha2.InferencePoolConditionAccepted),
string(inferencev1alpha2.InferencePoolReasonAccepted),
string(inferencev1.InferencePoolConditionAccepted),
string(inferencev1.InferencePoolReasonAccepted),
"Accepted by the parentRef Gateway",
)(parentStatusRef)
WithConditions(
metav1.ConditionTrue,
string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
string(inferencev1alpha2.InferencePoolReasonResolvedRefs),
string(inferencev1.InferencePoolConditionResolvedRefs),
string(inferencev1.InferencePoolReasonResolvedRefs),
"Resolved ExtensionRef",
)(parentStatusRef)
}
@@ -706,14 +706,12 @@ func WithAcceptedConditions() ParentOption {
func WithExtensionRef(kind, name string) Option {
return func(obj client.Object) {
ip, ok := obj.(*inferencev1alpha2.InferencePool)
ip, ok := obj.(*inferencev1.InferencePool)
if ok {
typedKind := inferencev1alpha2.Kind(kind)
ip.Spec.EndpointPickerConfig.ExtensionRef = &inferencev1alpha2.Extension{
ExtensionReference: inferencev1alpha2.ExtensionReference{
Name: inferencev1alpha2.ObjectName(name),
Kind: &typedKind,
},
typedKind := inferencev1.Kind(kind)
ip.Spec.EndpointPickerRef = inferencev1.EndpointPickerRef{
Name: inferencev1.ObjectName(name),
Kind: typedKind,
}
}
}
@@ -728,7 +726,7 @@ func NewGateway(name string, opts ...Option) *gateway.Gateway {
Namespace: DefaultTestNS,
},
Spec: gateway.GatewaySpec{
GatewayClassName: "istio",
GatewayClassName: "higress",
},
}
for _, opt := range opts {
@@ -750,23 +748,21 @@ func NewHTTPRoute(name string, opts ...Option) *gateway.HTTPRoute {
return hr
}
func NewInferencePool(name string, opts ...Option) *inferencev1alpha2.InferencePool {
ip := &inferencev1alpha2.InferencePool{
func NewInferencePool(name string, opts ...Option) *inferencev1.InferencePool {
ip := &inferencev1.InferencePool{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: DefaultTestNS,
},
Spec: inferencev1alpha2.InferencePoolSpec{
Selector: map[inferencev1alpha2.LabelKey]inferencev1alpha2.LabelValue{
"app": "test",
},
EndpointPickerConfig: inferencev1alpha2.EndpointPickerConfig{
ExtensionRef: &inferencev1alpha2.Extension{
ExtensionReference: inferencev1alpha2.ExtensionReference{
Name: "endpoint-picker",
},
Spec: inferencev1.InferencePoolSpec{
Selector: inferencev1.LabelSelector{
MatchLabels: map[inferencev1.LabelKey]inferencev1.LabelValue{
"app": "test",
},
},
EndpointPickerRef: inferencev1.EndpointPickerRef{
Name: "endpoint-picker",
},
},
}
for _, opt := range opts {

View File

@@ -19,45 +19,46 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
"istio.io/istio/pilot/pkg/features"
"istio.io/istio/pkg/config/constants"
"istio.io/istio/pkg/kube/krt"
"istio.io/istio/pkg/ptr"
"istio.io/istio/pkg/test"
"istio.io/istio/pkg/test/util/assert"
)
func TestReconcileInferencePool(t *testing.T) {
test.SetForTest(t, &features.EnableGatewayAPIInferenceExtension, true)
pool := &inferencev1alpha2.InferencePool{
pool := &inferencev1.InferencePool{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
Namespace: "default",
},
Spec: inferencev1alpha2.InferencePoolSpec{
TargetPortNumber: 8080,
Selector: map[inferencev1alpha2.LabelKey]inferencev1alpha2.LabelValue{
"app": "test",
Spec: inferencev1.InferencePoolSpec{
TargetPorts: []inferencev1.Port{
{
Number: inferencev1.PortNumber(8080),
},
},
EndpointPickerConfig: inferencev1alpha2.EndpointPickerConfig{
ExtensionRef: &inferencev1alpha2.Extension{
ExtensionReference: inferencev1alpha2.ExtensionReference{
Name: "dummy",
// Kind: &inferencev1alpha2.Kind(),
PortNumber: ptr.Of(inferencev1alpha2.PortNumber(5421)),
},
Selector: inferencev1.LabelSelector{
MatchLabels: map[inferencev1.LabelKey]inferencev1.LabelValue{
"app": "test",
},
},
EndpointPickerRef: inferencev1.EndpointPickerRef{
Name: "dummy",
Port: &inferencev1.Port{
Number: inferencev1.PortNumber(5421),
},
},
},
}
controller := setupController(t,
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}},
NewGateway("test-gw", InNamespace(DefaultTestNS), WithGatewayClass(higressconstants.DefaultGatewayClass)),
NewGateway("test-gw", InNamespace(DefaultTestNS), WithGatewayClass("istio")),
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
WithParentRefAndStatus("test-gw", DefaultTestNS, HigressController),
WithParentRefAndStatus("test-gw", DefaultTestNS, IstioController),
WithBackendRef("test-pool", DefaultTestNS),
),
pool,
@@ -82,4 +83,5 @@ func TestReconcileInferencePool(t *testing.T) {
assert.Equal(t, service.ObjectMeta.Labels[InferencePoolRefLabel], pool.Name)
assert.Equal(t, service.OwnerReferences[0].Name, pool.Name)
assert.Equal(t, service.Spec.Ports[0].TargetPort.IntVal, int32(8080))
assert.Equal(t, service.Spec.Ports[0].Port, int32(54321)) // dummyPort + i
}

View File

@@ -19,7 +19,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
"istio.io/istio/pkg/config"
schematypes "istio.io/istio/pkg/config/schema/kubetypes"
@@ -32,7 +32,11 @@ type ReferenceSet struct {
erasedCollections map[config.GroupVersionKind]func(name, namespace string) (any, bool)
}
func (s ReferenceSet) LocalPolicyTargetRef(ref gatewayalpha.LocalPolicyTargetReference, localNamespace string) (any, error) {
func (s ReferenceSet) LocalPolicyTargetRef(ref gatewayv1.LocalPolicyTargetReference, localNamespace string) (any, error) {
return s.internal(string(ref.Name), string(ref.Group), string(ref.Kind), localNamespace)
}
func (s ReferenceSet) XLocalPolicyTargetRef(ref gatewayx.LocalPolicyTargetReference, localNamespace string) (any, error) {
return s.internal(string(ref.Name), string(ref.Group), string(ref.Kind), localNamespace)
}

View File

@@ -22,6 +22,7 @@ import (
creds "istio.io/istio/pilot/pkg/model/credentials"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/config/schema/collections"
"istio.io/istio/pkg/config/schema/gvk"
"istio.io/istio/pkg/kube/krt"
)
@@ -72,7 +73,7 @@ func ReferenceGrantsCollection(referenceGrants krt.Collection[*gateway.Reference
ref := normalizeReference(&to.Group, &to.Kind, config.GroupVersionKind{})
switch ref {
case gvk.Secret, gvk.Service, gvk.InferencePool:
case gvk.ConfigMap, gvk.Secret, gvk.Service, gvk.InferencePool:
toKey.Kind = ref
default:
continue
@@ -127,8 +128,13 @@ func (refs ReferenceGrants) SecretAllowed(ctx krt.HandlerContext, kind config.Gr
log.Warnf("failed to parse resource name %q: %v", resourceName, err)
return false
}
resourceKind := config.GroupVersionKind{Kind: p.ResourceKind.String()}
resourceSchema, resourceSchemaFound := collections.All.FindByGroupKind(resourceKind)
if resourceSchemaFound {
resourceKind = resourceSchema.GroupVersionKind()
}
from := Reference{Kind: kind, Namespace: gateway.Namespace(namespace)}
to := Reference{Kind: gvk.Secret, Namespace: gateway.Namespace(p.Namespace)}
to := Reference{Kind: resourceKind, Namespace: gateway.Namespace(p.Namespace)}
pair := ReferencePair{From: from, To: to}
grants := krt.FetchOrList(ctx, refs.collection, krt.FilterIndex(refs.index, pair))
for _, g := range grants {

View File

@@ -22,7 +22,7 @@ import (
"go.uber.org/atomic"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -38,14 +38,33 @@ import (
"istio.io/istio/pkg/kube/krt"
"istio.io/istio/pkg/ptr"
"istio.io/istio/pkg/slices"
"istio.io/istio/pkg/util/sets"
)
type AncestorBackend struct {
Gateway types.NamespacedName
Backend TypedNamespacedName
}
func (a AncestorBackend) Equals(other AncestorBackend) bool {
return a.Gateway == other.Gateway && a.Backend == other.Backend
}
func (a AncestorBackend) ResourceName() string {
return a.Gateway.String() + "/" + a.Backend.String()
}
func HTTPRouteCollection(
httpRoutes krt.Collection[*gateway.HTTPRoute],
inputs RouteContextInputs,
opts krt.OptionsBuilder,
) RouteResult[*gateway.HTTPRoute, gateway.HTTPRouteStatus] {
routeCount := gatewayRouteAttachmentCountCollection(inputs, httpRoutes, gvk.HTTPRoute, opts)
ancestorBackends := krt.NewManyCollection(httpRoutes, func(krtctx krt.HandlerContext, obj *gateway.HTTPRoute) []AncestorBackend {
return extractAncestorBackends(obj.Namespace, obj.Spec.ParentRefs, obj.Spec.Rules, func(r gateway.HTTPRouteRule) []gateway.HTTPBackendRef {
return r.BackendRefs
})
}, opts.WithName("HTTPAncestors")...)
status, baseVirtualServices := krt.NewStatusManyCollection(httpRoutes, func(krtctx krt.HandlerContext, obj *gateway.HTTPRoute) (
*gateway.HTTPRouteStatus,
[]RouteWithKey,
@@ -145,7 +164,7 @@ func HTTPRouteCollection(
currentRouteInferenceConfigs[httpRule.Name] = kube.InferencePoolRouteRuleConfig{
FQDN: ipCfg.endpointPickerDst,
Port: ipCfg.endpointPickerPort,
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1alpha2.FailOpen),
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1.EndpointPickerFailOpen),
}
}
}
@@ -184,9 +203,54 @@ func HTTPRouteCollection(
VirtualServices: finalVirtualServices,
RouteAttachments: routeCount,
Status: status,
Ancestors: ancestorBackends,
}
}
func extractAncestorBackends[RT, BT any](ns string, prefs []gateway.ParentReference, rules []RT, extract func(RT) []BT) []AncestorBackend {
gateways := sets.Set[types.NamespacedName]{}
for _, r := range prefs {
ref := normalizeReference(r.Group, r.Kind, gvk.KubernetesGateway)
if ref != gvk.KubernetesGateway {
continue
}
gateways.Insert(types.NamespacedName{
Namespace: defaultString(r.Namespace, ns),
Name: string(r.Name),
})
}
backends := sets.Set[TypedNamespacedName]{}
for _, r := range rules {
for _, b := range extract(r) {
ref, refNs, refName := GetBackendRef(b)
k, ok := gvk.ToKind(ref)
if !ok {
continue
}
be := TypedNamespacedName{
NamespacedName: types.NamespacedName{
Namespace: defaultString(refNs, ns),
Name: string(refName),
},
Kind: k,
}
backends.Insert(be)
}
}
gtw := slices.SortBy(gateways.UnsortedList(), types.NamespacedName.String)
bes := slices.SortBy(backends.UnsortedList(), TypedNamespacedName.String)
res := make([]AncestorBackend, 0, len(gtw)*len(bes))
for _, gw := range gtw {
for _, be := range bes {
res = append(res, AncestorBackend{
Gateway: gw,
Backend: be,
})
}
}
return res
}
type conversionResult[O any] struct {
error *ConfigError
routes []O
@@ -198,6 +262,11 @@ func GRPCRouteCollection(
opts krt.OptionsBuilder,
) RouteResult[*gatewayv1.GRPCRoute, gatewayv1.GRPCRouteStatus] {
routeCount := gatewayRouteAttachmentCountCollection(inputs, grpcRoutes, gvk.GRPCRoute, opts)
ancestorBackends := krt.NewManyCollection(grpcRoutes, func(krtctx krt.HandlerContext, obj *gatewayv1.GRPCRoute) []AncestorBackend {
return extractAncestorBackends(obj.Namespace, obj.Spec.ParentRefs, obj.Spec.Rules, func(r gatewayv1.GRPCRouteRule) []gatewayv1.GRPCBackendRef {
return r.BackendRefs
})
}, opts.WithName("GRPCAncestors")...)
status, baseVirtualServices := krt.NewStatusManyCollection(grpcRoutes, func(krtctx krt.HandlerContext, obj *gatewayv1.GRPCRoute) (
*gatewayv1.GRPCRouteStatus,
[]RouteWithKey,
@@ -288,7 +357,7 @@ func GRPCRouteCollection(
currentRouteInferenceConfigs[httpRule.Name] = kube.InferencePoolRouteRuleConfig{
FQDN: ipCfg.endpointPickerDst,
Port: ipCfg.endpointPickerPort,
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1alpha2.FailOpen),
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1.EndpointPickerFailOpen),
}
}
}
@@ -327,6 +396,7 @@ func GRPCRouteCollection(
VirtualServices: finalVirtualServices,
RouteAttachments: routeCount,
Status: status,
Ancestors: ancestorBackends,
}
}
@@ -336,6 +406,11 @@ func TCPRouteCollection(
opts krt.OptionsBuilder,
) RouteResult[*gatewayalpha.TCPRoute, gatewayalpha.TCPRouteStatus] {
routeCount := gatewayRouteAttachmentCountCollection(inputs, tcpRoutes, gvk.TCPRoute, opts)
ancestorBackends := krt.NewManyCollection(tcpRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TCPRoute) []AncestorBackend {
return extractAncestorBackends(obj.Namespace, obj.Spec.ParentRefs, obj.Spec.Rules, func(r gatewayalpha.TCPRouteRule) []gateway.BackendRef {
return r.BackendRefs
})
}, opts.WithName("TCPAncestors")...)
status, virtualServices := krt.NewStatusManyCollection(tcpRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TCPRoute) (
*gatewayalpha.TCPRouteStatus,
[]*config.Config,
@@ -412,6 +487,7 @@ func TCPRouteCollection(
VirtualServices: virtualServices,
RouteAttachments: routeCount,
Status: status,
Ancestors: ancestorBackends,
}
}
@@ -421,6 +497,11 @@ func TLSRouteCollection(
opts krt.OptionsBuilder,
) RouteResult[*gatewayalpha.TLSRoute, gatewayalpha.TLSRouteStatus] {
routeCount := gatewayRouteAttachmentCountCollection(inputs, tlsRoutes, gvk.TLSRoute, opts)
ancestorBackends := krt.NewManyCollection(tlsRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TLSRoute) []AncestorBackend {
return extractAncestorBackends(obj.Namespace, obj.Spec.ParentRefs, obj.Spec.Rules, func(r gatewayalpha.TLSRouteRule) []gateway.BackendRef {
return r.BackendRefs
})
}, opts.WithName("TLSAncestors")...)
status, virtualServices := krt.NewStatusManyCollection(tlsRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TLSRoute) (
*gatewayalpha.TLSRouteStatus,
[]*config.Config,
@@ -496,6 +577,7 @@ func TLSRouteCollection(
VirtualServices: virtualServices,
RouteAttachments: routeCount,
Status: status,
Ancestors: ancestorBackends,
}
}
@@ -563,7 +645,7 @@ type RouteContextInputs struct {
Services krt.Collection[*corev1.Service]
Namespaces krt.Collection[*corev1.Namespace]
ServiceEntries krt.Collection[*networkingclient.ServiceEntry]
InferencePools krt.Collection[*inferencev1alpha2.InferencePool]
InferencePools krt.Collection[*inferencev1.InferencePool]
internalContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]]
}
@@ -608,6 +690,8 @@ type RouteResult[I controllers.Object, IStatus any] struct {
RouteAttachments krt.Collection[RouteAttachment]
// Status stores the status reports for the incoming object
Status krt.StatusCollection[I, IStatus]
// Ancestors stores information about Gateway --> Backend references
Ancestors krt.Collection[AncestorBackend]
}
type RouteAttachment struct {

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.x-k8s.io/v1alpha1
kind: XBackendTrafficPolicy
metadata:
creationTimestamp: null
name: lb-policy
namespace: default
spec: null
@@ -18,5 +17,5 @@ status:
reason: Accepted
status: "True"
type: Accepted
controllerName: istio.io/gateway-controller
controllerName: istio.io/mesh-controller
---

View File

@@ -3,8 +3,7 @@ kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: XBackendTrafficPolicy/default.lb-policy
creationTimestamp: null
name: echo-istio-autogenerated-k8s-gateway
name: echo~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: echo.default.svc.domain.suffix

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: bad-configmap-type
namespace: default
spec: null
@@ -14,15 +13,19 @@ status:
conditions:
- lastTransitionTime: fake
message: 'Certificate reference invalid: unsupported kind UnknownKind'
reason: Invalid
reason: NoValidCACertificate
status: "False"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: 'Certificate reference not supported: unsupported kind UnknownKind'
reason: InvalidKind
status: "False"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: bad-service
namespace: default
spec: null
@@ -39,12 +42,16 @@ status:
reason: TargetNotFound
status: "False"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: existing-status
namespace: default
spec: null
@@ -71,12 +78,16 @@ status:
reason: Accepted
status: "True"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: malformed-configmap
namespace: default
spec: null
@@ -90,15 +101,115 @@ status:
- lastTransitionTime: fake
message: 'Certificate reference invalid: found secret, but didn''t have expected
keys cacert or ca.crt; found: not-ca.crt'
reason: Invalid
reason: NoValidCACertificate
status: "False"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: 'Certificate invalid: found secret, but didn''t have expected keys
cacert or ca.crt; found: not-ca.crt'
reason: InvalidCACertificateRef
status: "False"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: multi-host-service-entry
namespace: default
spec: null
status:
ancestors:
- ancestorRef:
group: networking.istio.io
kind: ServiceEntry
name: multi-host-service
conditions:
- lastTransitionTime: fake
message: Configuration is valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: multi-host-service-entry-section-name
namespace: default
spec: null
status:
ancestors:
- ancestorRef:
group: networking.istio.io
kind: ServiceEntry
name: multi-host-service
sectionName: tls
conditions:
- lastTransitionTime: fake
message: Configuration is valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: tls-external-service-https
namespace: default
spec: null
status:
ancestors:
- ancestorRef:
group: networking.istio.io
kind: ServiceEntry
name: external-service
sectionName: https
conditions:
- lastTransitionTime: fake
message: Configuration is valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
- ancestorRef:
group: networking.istio.io
kind: ServiceEntry
name: external-service
sectionName: non-existing-port-name
conditions:
- lastTransitionTime: fake
message: 'targetRefs invalid: sectionName "non-existing-port-name" does not
exist in ServiceEntry default/external-service'
reason: TargetNotFound
status: "False"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: tls-upstream-echo
namespace: default
spec: null
@@ -114,12 +225,93 @@ status:
reason: Accepted
status: "True"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: tls-upstream-echo-https-merged-rules
namespace: default
spec: null
status:
ancestors:
- ancestorRef:
group: ""
kind: Service
name: echo-https
conditions:
- lastTransitionTime: fake
message: Configuration is valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
- ancestorRef:
group: ""
kind: Service
name: echo-https
sectionName: https
conditions:
- lastTransitionTime: fake
message: Configuration is valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
- ancestorRef:
group: ""
kind: Service
name: echo-https
sectionName: non-existing-port-name
conditions:
- lastTransitionTime: fake
message: 'targetRefs invalid: sectionName "non-existing-port-name" does not
exist in Service default/echo-https'
reason: TargetNotFound
status: "False"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway
conditions:
- lastTransitionTime: fake
message: 'targetRefs invalid: sectionName "non-existing-port-name" does not
exist in Service default/echo-https'
reason: TargetNotFound
status: "False"
type: Accepted
- lastTransitionTime: fake
message: Configuration is valid
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: higress.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: unknown-configmap
namespace: default
spec: null
@@ -133,8 +325,102 @@ status:
- lastTransitionTime: fake
message: 'Certificate reference invalid: reference default/does-not-exist (of
kind ConfigMap) not found'
reason: Invalid
reason: NoValidCACertificate
status: "False"
type: Accepted
controllerName: istio.io/gateway-controller
- lastTransitionTime: fake
message: 'Certificate reference not found: reference default/does-not-exist
(of kind ConfigMap) not found'
reason: InvalidCACertificateRef
status: "False"
type: ResolvedRefs
controllerName: istio.io/mesh-controller
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: higress
spec: null
status:
conditions:
- lastTransitionTime: fake
message: Handled by Higress controller
reason: Accepted
status: "True"
type: Accepted
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway
namespace: higress-system
spec: null
status:
addresses:
- type: Hostname
value: higress-gateway.higress-system.svc.domain.suffix
conditions:
- lastTransitionTime: fake
message: Resource accepted
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: Resource programmed, assigned to service(s) higress-gateway.higress-system.svc.domain.suffix:80
reason: Programmed
status: "True"
type: Programmed
listeners:
- attachedRoutes: 1
conditions:
- lastTransitionTime: fake
message: No errors found
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: No errors found
reason: NoConflicts
status: "False"
type: Conflicted
- lastTransitionTime: fake
message: No errors found
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: fake
message: No errors found
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: default
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: http
namespace: higress-system
spec: null
status:
parents:
- conditions:
- lastTransitionTime: fake
message: Route was valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: backendRef echo-https/default not accessible to a HTTPRoute in namespace
"higress-system" (missing a ReferenceGrant?)
reason: RefNotPermitted
status: "False"
type: ResolvedRefs
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
---

View File

@@ -1,4 +1,58 @@
apiVersion: gateway.networking.k8s.io/v1alpha3
# echo-https must be created by the kube-client, because it's used in a test
# that verifies `sectionName`, which is internally read from krt,
# so it could be just a `model.ServiceInstance`
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: higress
spec:
controllerName: higress.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway
namespace: higress-system
spec:
addresses:
- value: higress-gateway
type: Hostname
gatewayClassName: higress
listeners:
- name: default
hostname: "*.domain.example"
port: 80
protocol: HTTP
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: http
namespace: higress-system
spec:
parentRefs:
- name: gateway
rules:
- backendRefs:
- name: echo-https
namespace: default
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: echo-https
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
- name: https
port: 443
protocol: TCP
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: tls-upstream-echo
@@ -15,7 +69,32 @@ spec:
group: ""
hostname: auth.example.com
---
apiVersion: gateway.networking.k8s.io/v1alpha3
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: tls-upstream-echo-https-merged-rules
namespace: default
spec:
targetRefs:
- kind: Service
name: echo-https
group: ""
- kind: Service
name: echo-https
group: ""
sectionName: https
- kind: Service
name: echo-https
group: ""
sectionName: non-existing-port-name
validation:
caCertificateRefs:
- kind: ConfigMap
name: auth-cert
group: ""
hostname: auth.example.com
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: existing-status
@@ -33,19 +112,19 @@ spec:
hostname: auth.example.com
status:
ancestors:
- ancestorRef:
group: ""
kind: Service
name: httpbin
conditions:
- lastTransitionTime: 2000-01-01T01:01:01Z
message: hello
reason: Accepted
status: "True"
type: Accepted
controllerName: example.com/some-other-controller
- ancestorRef:
group: ""
kind: Service
name: httpbin
conditions:
- lastTransitionTime: 2000-01-01T01:01:01Z
message: hello
reason: Accepted
status: "True"
type: Accepted
controllerName: example.com/some-other-controller
---
apiVersion: gateway.networking.k8s.io/v1alpha3
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: bad-service
@@ -62,7 +141,7 @@ spec:
group: ""
hostname: auth.example.com
---
apiVersion: gateway.networking.k8s.io/v1alpha3
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: unknown-configmap
@@ -79,7 +158,7 @@ spec:
group: ""
hostname: auth.example.com
---
apiVersion: gateway.networking.k8s.io/v1alpha3
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: malformed-configmap
@@ -96,7 +175,7 @@ spec:
group: ""
hostname: auth.example.com
---
apiVersion: gateway.networking.k8s.io/v1alpha3
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: bad-configmap-type
@@ -112,3 +191,91 @@ spec:
name: blah
group: ""
hostname: auth.example.com
---
# ServiceEntry with multiple hosts for testing multiple DestinationRules
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: multi-host-service
namespace: default
spec:
hosts:
- api.example.com
- cdn.example.com
ports:
- number: 443
name: https
protocol: HTTPS
- number: 8443
name: tls
protocol: TLS
resolution: DNS
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: multi-host-service-entry
namespace: default
spec:
targetRefs:
- kind: ServiceEntry
name: multi-host-service
group: networking.istio.io
validation:
wellKnownCACertificates: System
hostname: cdn.example.com
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: multi-host-service-entry-section-name
namespace: default
spec:
targetRefs:
- kind: ServiceEntry
name: multi-host-service
group: networking.istio.io
sectionName: tls
validation:
caCertificateRefs:
- kind: ConfigMap
name: auth-cert
group: ""
hostname: api.example.com
---
# Simple ServiceEntry with 2 ports for testing sectionName
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-service
namespace: default
spec:
hosts:
- external.example.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: tls-external-service-https
namespace: default
spec:
targetRefs:
- kind: ServiceEntry
name: external-service
group: networking.istio.io
sectionName: https
- kind: ServiceEntry
name: external-service
group: networking.istio.io
sectionName: non-existing-port-name
validation:
wellKnownCACertificates: System
hostname: external.example.com

View File

@@ -1,10 +1,68 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
annotations:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
internal.istio.io/parents: Gateway/gateway/default.higress-system
internal.istio.io/service-account-name: ""
name: gateway-istio-autogenerated-k8s-gateway-default
namespace: higress-system
spec:
servers:
- hosts:
- higress-system/*.domain.example
port:
name: default
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http.higress-system
internal.istio.io/route-semantics: gateway
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~*
namespace: higress-system
spec:
gateways:
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
hosts:
- '*'
http:
- name: http
route:
- destination: {}
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.tls-upstream-echo-https-merged-rules
name: echo-https~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: echo-https.default.svc.domain.suffix
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: auth.example.com
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: auth.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.tls-upstream-echo
creationTimestamp: null
name: echo-istio-autogenerated-k8s-gateway
name: echo~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: echo.default.svc.domain.suffix
@@ -16,11 +74,27 @@ spec:
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.tls-external-service-https
name: external-service~external-example-com~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: external.example.com
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
sni: external.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.bad-configmap-type
creationTimestamp: null
name: foo-svc-istio-autogenerated-k8s-gateway
name: foo-svc~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: foo-svc.default.svc.domain.suffix
@@ -32,27 +106,10 @@ spec:
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.existing-status
creationTimestamp: null
name: httpbin-istio-autogenerated-k8s-gateway
namespace: default
spec:
host: httpbin.default.svc.domain.suffix
trafficPolicy:
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: auth.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.malformed-configmap
creationTimestamp: null
name: httpbin-other-istio-autogenerated-k8s-gateway
name: httpbin-other~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: httpbin-other.default.svc.domain.suffix
@@ -67,8 +124,7 @@ kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.unknown-configmap
creationTimestamp: null
name: httpbin-second-istio-autogenerated-k8s-gateway
name: httpbin-second~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: httpbin-second.default.svc.domain.suffix
@@ -78,3 +134,60 @@ spec:
mode: SIMPLE
sni: auth.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.existing-status
name: httpbin~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: httpbin.default.svc.domain.suffix
trafficPolicy:
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: auth.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.multi-host-service-entry,BackendTLSPolicy/default.multi-host-service-entry-section-name
name: multi-host-service~api-example-com~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: api.example.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: api.example.com
tls:
mode: SIMPLE
sni: cdn.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
annotations:
internal.istio.io/parents: BackendTLSPolicy/default.multi-host-service-entry,BackendTLSPolicy/default.multi-host-service-entry-section-name
name: multi-host-service~cdn-example-com~istio-autogenerated-k8s-gateway
namespace: default
spec:
host: cdn.example.com
trafficPolicy:
portLevelSettings:
- port:
number: 8443
tls:
credentialName: configmap://default/auth-cert
mode: SIMPLE
sni: api.example.com
tls:
mode: SIMPLE
sni: cdn.example.com
---

View File

@@ -4,7 +4,7 @@ kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
creationTimestamp: null
name: higress
spec: null
status:
@@ -15,7 +14,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway
namespace: higress-system
spec: null
@@ -95,7 +93,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http
namespace: apple
spec: null
@@ -112,7 +109,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -120,7 +117,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http
namespace: banana
spec: null
@@ -137,7 +133,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system

View File

@@ -5,7 +5,7 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
internal.istio.io/parents: Gateway/gateway/apple.higress-system
creationTimestamp: null
internal.istio.io/service-account-name: ""
name: gateway-istio-autogenerated-k8s-gateway-apple
namespace: higress-system
spec:
@@ -24,7 +24,7 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
internal.istio.io/parents: Gateway/gateway/banana.higress-system
creationTimestamp: null
internal.istio.io/service-account-name: ""
name: gateway-istio-autogenerated-k8s-gateway-banana
namespace: higress-system
spec:
@@ -42,7 +42,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http.apple
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-apple~*
namespace: apple
spec:
@@ -64,7 +63,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http.banana
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-banana~*
namespace: banana
spec:

View File

@@ -1,253 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
networking.istio.io/service-type: ClusterIP
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
networking.istio.io/service-type: ClusterIP
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
networking.istio.io/service-type: ClusterIP
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
networking.istio.io/service-type: ClusterIP
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: http
name: http
port: 80
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: ClusterIP
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,253 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
should: see-infra-annotation
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see-infra-label
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
should: see-infra-annotation
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see-infra-label
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
should: see-infra-annotation
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
should: see-infra-label
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
should: see-infra-annotation
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see-infra-label
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,253 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
should: see
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-custom
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-custom
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-custom
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-custom
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-custom
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-custom
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-custom
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,300 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
name: namespace-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
cm-annotation: cm-annotation-value
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
name: namespace-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
replicas: 4
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: namespace
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
service.istio.io/canonical-name: namespace-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: namespace-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 222m
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: namespace-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
name: namespace-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: namespace
type: LoadBalancer
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
annotations: {}
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
name: namespace-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
maxReplicas: 2
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: namespace-istio
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
annotations: {}
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
name: namespace-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
minAvailable: 1
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: namespace
---

View File

@@ -1,257 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
istio.io/enable-inference-extproc: "true"
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
istio.io/enable-inference-extproc: "true"
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
fizz: buzz
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
istio.io/enable-inference-extproc: "true"
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
istio.io/enable-inference-extproc: "true"
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,6 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---

View File

@@ -1,253 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
fizz: buzz
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
fizz: buzz
labels:
foo: bar
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,254 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-eastwest-controller
gateway.networking.k8s.io/gateway-name: eastwestgateway
topology.istio.io/network: network-1
name: eastwestgateway
namespace: istio-system
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: eastwestgateway
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-eastwest-controller
gateway.networking.k8s.io/gateway-name: eastwestgateway
topology.istio.io/network: network-1
name: eastwestgateway
namespace: istio-system
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: eastwestgateway
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: eastwestgateway
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-eastwest-controller
gateway.networking.k8s.io/gateway-name: eastwestgateway
istio.io/dataplane-mode: none
service.istio.io/canonical-name: eastwestgateway
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
topology.istio.io/network: network-1
spec:
containers:
- args:
- proxy
- waypoint
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --serviceCluster
- eastwestgateway.$(POD_NAMESPACE)
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: ISTIO_META_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NETWORK
value: network-1
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: eastwestgateway
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/istio-system/deployments/eastwestgateway
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
serviceAccountName: eastwestgateway
terminationGracePeriodSeconds: 2
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir:
medium: Memory
name: go-proxy-envoy
- emptyDir: {}
name: istio-data
- emptyDir: {}
name: go-proxy-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
- configMap:
name: istio-ca-root-cert
name: istiod-ca-cert
---
apiVersion: v1
kind: Service
metadata:
annotations:
networking.istio.io/traffic-distribution: PreferClose
labels:
gateway.istio.io/managed: istio.io-eastwest-controller
gateway.networking.k8s.io/gateway-name: eastwestgateway
topology.istio.io/network: network-1
name: eastwestgateway
namespace: istio-system
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: eastwestgateway
uid: ""
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: all
name: mesh
port: 15008
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: eastwestgateway
type: LoadBalancer
---

View File

@@ -1,256 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: test-upgrade
topology.istio.io/network: network-1
name: test-upgrade
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: test-upgrade
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: test-upgrade
topology.istio.io/network: network-1
name: test-upgrade
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: test-upgrade
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: test-upgrade
istio.io/gateway-name: test-upgrade
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: test-upgrade
istio.io/dataplane-mode: none
istio.io/gateway-name: test-upgrade
service.istio.io/canonical-name: test-upgrade
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
topology.istio.io/network: network-1
spec:
containers:
- args:
- proxy
- waypoint
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --serviceCluster
- test-upgrade.$(POD_NAMESPACE)
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: ISTIO_META_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NETWORK
value: network-1
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: test-upgrade
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/test-upgrade
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
serviceAccountName: test-upgrade
terminationGracePeriodSeconds: 2
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir:
medium: Memory
name: go-proxy-envoy
- emptyDir: {}
name: istio-data
- emptyDir: {}
name: go-proxy-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
- configMap:
name: istio-ca-root-cert
name: istiod-ca-cert
---
apiVersion: v1
kind: Service
metadata:
annotations:
networking.istio.io/traffic-distribution: PreferClose
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: test-upgrade
topology.istio.io/network: network-1
name: test-upgrade
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: test-upgrade
uid: ""
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: all
name: mesh
port: 15008
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: test-upgrade
type: ClusterIP
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: ambient
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,246 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
loadBalancerIP: 1.2.3.4
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: custom-sa
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: custom-sa
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,257 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
topology.istio.io/network: network-1
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
topology.istio.io/network: network-1
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
topology.istio.io/network: network-1
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_NETWORK
value: network-1
- name: ISTIO_META_WORKLOAD_NAME
value: default
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: network-1
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
topology.istio.io/network: network-1
name: default
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: http
name: http
port: 80
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,245 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{"image":{"imageType":"distroless"}}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test-distroless
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,253 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: default
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
service.istio.io/canonical-name: default-istio
service.istio.io/canonical-revision: latest
should: see
sidecar.istio.io/inject: "false"
spec:
containers:
- args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: ISTIO_META_POD_PORTS
value: '[]'
- name: ISTIO_META_APP_CONTAINERS
value: ""
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: default-istio
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/credential-uds
name: credential-socket
- mountPath: /var/run/secrets/workload-spiffe-credentials
name: workload-certs
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: default-istio
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
- emptyDir: {}
name: workload-certs
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir: {}
name: istio-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: <no value>
expirationSeconds: 43200
path: istio-token
---
apiVersion: v1
kind: Service
metadata:
annotations:
should: see
labels:
gateway.istio.io/managed: istio.io-gateway-controller
gateway.networking.k8s.io/gateway-name: default
istio.io/dataplane-mode: none
should: see
name: default-istio
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: default
uid: null
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: default
type: LoadBalancer
---

View File

@@ -1,254 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: namespace
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
service.istio.io/canonical-name: namespace
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
topology.istio.io/network: network-1
spec:
containers:
- args:
- proxy
- waypoint
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --serviceCluster
- namespace.$(POD_NAMESPACE)
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: ISTIO_META_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NETWORK
value: network-1
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: namespace
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
serviceAccountName: namespace
terminationGracePeriodSeconds: 2
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir:
medium: Memory
name: go-proxy-envoy
- emptyDir: {}
name: istio-data
- emptyDir: {}
name: go-proxy-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
- configMap:
name: istio-ca-root-cert
name: istiod-ca-cert
---
apiVersion: v1
kind: Service
metadata:
annotations:
networking.istio.io/traffic-distribution: PreferClose
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: all
name: mesh
port: 15008
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: namespace
type: ClusterIP
---

View File

@@ -1,254 +0,0 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
gateway.istio.io/controller-version: "5"
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: namespace
template:
metadata:
annotations:
istio.io/rev: default
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
istio.io/dataplane-mode: none
service.istio.io/canonical-name: namespace
service.istio.io/canonical-revision: latest
sidecar.istio.io/inject: "false"
topology.istio.io/network: network-1
spec:
containers:
- args:
- proxy
- waypoint
- --domain
- $(POD_NAMESPACE).svc.<no value>
- --serviceCluster
- namespace.$(POD_NAMESPACE)
- --proxyLogLevel
- <nil>
- --proxyComponentLogLevel
- <nil>
- --log_output_level
- <nil>
env:
- name: ISTIO_META_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: PILOT_CERT_PROVIDER
value: <no value>
- name: CA_ADDR
value: istiod-<no value>.<no value>.svc:15012
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{}
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: ISTIO_META_NETWORK
value: network-1
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_META_WORKLOAD_NAME
value: namespace
- name: ISTIO_META_OWNER
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace
- name: ISTIO_META_MESH_ID
value: cluster.local
- name: TRUST_DOMAIN
value: cluster.local
image: test/proxyv2:test
name: istio-proxy
ports:
- containerPort: 15020
name: metrics
protocol: TCP
- containerPort: 15021
name: status-port
protocol: TCP
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
readinessProbe:
failureThreshold: 4
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1337
runAsNonRoot: true
runAsUser: 1337
startupProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/run/secrets/workload-spiffe-uds
name: workload-socket
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
- mountPath: /var/lib/istio/data
name: istio-data
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
- mountPath: /etc/istio/pod
name: istio-podinfo
serviceAccountName: namespace
terminationGracePeriodSeconds: 2
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir:
medium: Memory
name: istio-envoy
- emptyDir:
medium: Memory
name: go-proxy-envoy
- emptyDir: {}
name: istio-data
- emptyDir: {}
name: go-proxy-data
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.labels
path: labels
- fieldRef:
fieldPath: metadata.annotations
path: annotations
name: istio-podinfo
- name: istio-token
projected:
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
- configMap:
name: istio-ca-root-cert
name: istiod-ca-cert
---
apiVersion: v1
kind: Service
metadata:
annotations:
networking.istio.io/traffic-distribution: PreferClose
labels:
gateway.istio.io/managed: istio.io-mesh-controller
gateway.networking.k8s.io/gateway-name: namespace
topology.istio.io/network: network-1
name: namespace
namespace: default
ownerReferences:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
name: namespace
uid: ""
spec:
ipFamilyPolicy: PreferDualStack
ports:
- appProtocol: tcp
name: status-port
port: 15021
protocol: TCP
- appProtocol: all
name: mesh
port: 15008
protocol: TCP
selector:
gateway.networking.k8s.io/gateway-name: namespace
type: ClusterIP
---

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: eastwestgateway
namespace: istio-system
spec: null
@@ -47,7 +46,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: invalid
namespace: istio-system
spec: null

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: eastwestgateway
namespace: istio-system
spec: null
@@ -101,7 +100,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-grpc
namespace: istio-system
spec: null
@@ -118,7 +116,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway
@@ -127,7 +125,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-webhook
namespace: istio-system
spec: null
@@ -144,7 +141,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway

View File

@@ -5,7 +5,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
namespace: istio-system
spec:
@@ -26,7 +25,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
namespace: istio-system
spec:
@@ -46,7 +44,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
namespace: istio-system
spec:
@@ -65,7 +62,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:
@@ -89,7 +85,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: eastwestgateway
namespace: istio-system
spec: null
@@ -24,7 +23,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-grpc
namespace: istio-system
spec: null
@@ -34,7 +32,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-webhook
namespace: istio-system
spec: null

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: eastwestgateway
namespace: istio-system
spec: null
@@ -101,7 +100,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-grpc
namespace: istio-system
spec: null
@@ -118,7 +116,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway
@@ -127,7 +125,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-webhook
namespace: istio-system
spec: null
@@ -144,7 +141,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway

View File

@@ -5,7 +5,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
namespace: istio-system
spec:
@@ -26,7 +25,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
namespace: istio-system
spec:
@@ -46,7 +44,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
namespace: istio-system
spec:
@@ -65,7 +62,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:
@@ -89,7 +85,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: eastwestgateway
namespace: istio-system
spec: null
@@ -101,7 +100,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-grpc
namespace: istio-system
spec: null
@@ -118,7 +116,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway
@@ -127,7 +125,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
creationTimestamp: null
name: eastwestgateway-webhook
namespace: istio-system
spec: null
@@ -144,7 +141,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
kind: Gateway
name: eastwestgateway

View File

@@ -5,7 +5,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
namespace: istio-system
spec:
@@ -26,7 +25,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
namespace: istio-system
spec:
@@ -46,7 +44,6 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
creationTimestamp: null
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
namespace: istio-system
spec:
@@ -65,7 +62,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:
@@ -89,7 +85,6 @@ metadata:
annotations:
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
namespace: istio-system
spec:

View File

@@ -1,7 +1,6 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
creationTimestamp: null
name: higress
spec: null
status:
@@ -15,7 +14,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway
namespace: higress-system
spec: null
@@ -65,7 +63,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
creationTimestamp: null
name: grpc
namespace: default
spec: null
@@ -82,7 +79,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system

View File

@@ -5,7 +5,7 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
internal.istio.io/parents: Gateway/gateway/default.higress-system
creationTimestamp: null
internal.istio.io/service-account-name: ""
name: gateway-istio-autogenerated-k8s-gateway-default
namespace: higress-system
spec:
@@ -23,7 +23,6 @@ metadata:
annotations:
internal.istio.io/parents: GRPCRoute/grpc.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~another.domain.example
namespace: default
spec:
@@ -66,7 +65,6 @@ metadata:
annotations:
internal.istio.io/parents: GRPCRoute/grpc.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~first.domain.example
namespace: default
spec:

View File

@@ -1,16 +1,14 @@
apiVersion: inference.networking.x-k8s.io/v1alpha2
apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
creationTimestamp: null
name: infpool-gen
namespace: default
spec: null
status: {}
---
apiVersion: inference.networking.x-k8s.io/v1alpha2
apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
creationTimestamp: null
name: infpool-gen2
namespace: default
spec: null
@@ -19,7 +17,6 @@ status: {}
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
creationTimestamp: null
name: higress
spec: null
status:
@@ -33,7 +30,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway
namespace: higress-system
spec: null
@@ -85,7 +81,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http
namespace: default
spec: null
@@ -102,7 +97,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -110,7 +105,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http-not-selected
namespace: default
spec: null
@@ -127,7 +121,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -135,7 +129,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http-retry-request
namespace: default
spec: null
@@ -152,7 +145,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -160,7 +153,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http-route-cors
namespace: default
spec: null
@@ -177,7 +169,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -185,7 +177,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http-timeout-backend-request
namespace: default
spec: null
@@ -202,7 +193,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -210,7 +201,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http-timeout-request
namespace: default
spec: null
@@ -227,7 +217,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -235,7 +225,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: http2
namespace: default
spec: null
@@ -252,7 +241,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -260,7 +249,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: mirror
namespace: default
spec: null
@@ -277,7 +265,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -285,7 +273,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: multiple-inferencepool-backend-refs
namespace: default
spec: null
@@ -302,7 +289,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -310,7 +297,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: redirect
namespace: default
spec: null
@@ -327,7 +313,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -335,7 +321,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: redirect-prefix-replace
namespace: default
spec: null
@@ -352,7 +337,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system
@@ -360,7 +345,6 @@ status:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: rewrite
namespace: default
spec: null
@@ -377,7 +361,7 @@ status:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
controllerName: higress.io/gateway-controller
parentRef:
name: gateway
namespace: higress-system

View File

@@ -12,17 +12,17 @@ metadata:
namespace: higress-system
spec:
addresses:
- value: higress-gateway
type: Hostname
- value: higress-gateway
type: Hostname
gatewayClassName: higress
listeners:
- name: default
hostname: "*.domain.example"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: default
hostname: "*.domain.example"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -31,34 +31,34 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["first.domain.example", "another.domain.example"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
headers:
- name: my-header
value: some-value
type: Exact
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-added-header
value: added-value
remove: [my-removed-header]
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: my-added-resp-header
value: added-resp-value
remove: [my-removed-header]
backendRefs:
- name: httpbin
port: 80
- matches:
- path:
type: PathPrefix
value: /get
headers:
- name: my-header
value: some-value
type: Exact
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-added-header
value: added-value
remove: [my-removed-header]
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: my-added-resp-header
value: added-resp-value
remove: [my-removed-header]
backendRefs:
- name: httpbin
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -67,24 +67,24 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["second.domain.example"]
rules:
- matches:
- path:
type: PathPrefix
value: /second
backendRefs:
- name: httpbin-second
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin-wildcard
port: 80
- matches:
- path:
type: PathPrefix
value: /second
backendRefs:
- name: httpbin-second
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin-wildcard
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -93,18 +93,18 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
rules:
- filters:
- type: RequestRedirect
requestRedirect:
port: 8080
statusCode: 302
scheme: https
path:
type: ReplaceFullPath
replaceFullPath: /replace-full
- filters:
- type: RequestRedirect
requestRedirect:
port: 8080
statusCode: 302
scheme: https
path:
type: ReplaceFullPath
replaceFullPath: /replace-full
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -113,23 +113,23 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["redirect.domain.example"]
rules:
- matches:
- path:
type: PathPrefix
value: /original
filters:
- type: RequestRedirect
requestRedirect:
port: 8080
statusCode: 302
scheme: https
path:
type: ReplacePrefixMatch
replacePrefixMatch: /replacement
- matches:
- path:
type: PathPrefix
value: /original
filters:
- type: RequestRedirect
requestRedirect:
port: 8080
statusCode: 302
scheme: https
path:
type: ReplacePrefixMatch
replacePrefixMatch: /replacement
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -138,51 +138,51 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
rules:
- name: route1
matches:
- path:
type: PathPrefix
value: /prefix-original
filters:
- type: URLRewrite
urlRewrite:
hostname: "new.example.com"
path:
type: ReplacePrefixMatch
replacePrefixMatch: "/replacement"
backendRefs:
- name: httpbin
port: 80
- matches:
- path:
type: PathPrefix
value: /prefix-to-be-removed
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: ""
backendRefs:
- name: httpbin
port: 80
- matches:
- path:
type: PathPrefix
value: /full-original
filters:
- type: URLRewrite
urlRewrite:
hostname: "new.example.com"
path:
type: ReplaceFullPath
replaceFullPath: "/replacement"
backendRefs:
- name: httpbin
port: 80
- name: route1
matches:
- path:
type: PathPrefix
value: /prefix-original
filters:
- type: URLRewrite
urlRewrite:
hostname: "new.example.com"
path:
type: ReplacePrefixMatch
replacePrefixMatch: "/replacement"
backendRefs:
- name: httpbin
port: 80
- matches:
- path:
type: PathPrefix
value: /prefix-to-be-removed
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: ""
backendRefs:
- name: httpbin
port: 80
- matches:
- path:
type: PathPrefix
value: /full-original
filters:
- type: URLRewrite
urlRewrite:
hostname: "new.example.com"
path:
type: ReplaceFullPath
replaceFullPath: "/replacement"
backendRefs:
- name: httpbin
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -191,27 +191,27 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
rules:
- filters:
- type: RequestMirror
requestMirror:
fraction:
numerator: 4
denominator: 8
backendRef:
name: httpbin-mirror
- filters:
- type: RequestMirror
requestMirror:
fraction:
numerator: 4
denominator: 8
backendRef:
name: httpbin-mirror
port: 80
- type: RequestMirror
requestMirror:
percent: 80
backendRef:
name: httpbin-second
port: 80
backendRefs:
- name: httpbin
port: 80
- type: RequestMirror
requestMirror:
percent: 80
backendRef:
name: httpbin-second
port: 80
backendRefs:
- name: httpbin
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -220,17 +220,17 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["should.not.select"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin-bad
port: 80
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin-bad
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -239,19 +239,19 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["timeout.domain.example"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 80
timeouts:
request: 1ms
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 80
timeouts:
request: 1ms
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -260,20 +260,20 @@ metadata:
namespace: default
spec:
parentRefs:
- name: gateway
namespace: higress-system
- name: gateway
namespace: higress-system
hostnames: ["timeout-backend.domain.example"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 80
timeouts:
request: 2ms
backendRequest: 1ms
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 80
timeouts:
request: 2ms
backendRequest: 1ms
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
@@ -297,8 +297,8 @@ spec:
attempts: 3
backoff: 3ms
codes:
- 503
- 429
- 503
- 429
- matches:
- path:
type: PathPrefix
@@ -324,7 +324,7 @@ metadata:
namespace: default
spec:
hostnames:
- "cors.domain.example"
- "cors.domain.example"
parentRefs:
- name: gateway
namespace: higress-system
@@ -337,8 +337,8 @@ spec:
- cors:
allowCredentials: true
allowOrigins:
# - '*' # This will be allowed in the future, probably https://github.com/kubernetes-sigs/gateway-api/issues/3648#issuecomment-2735208553
# - '*.com'
# - '*' # This will be allowed in the future, probably https://github.com/kubernetes-sigs/gateway-api/issues/3648#issuecomment-2735208553
# - '*.com'
- "https://example.com"
allowMethods:
- GET
@@ -368,12 +368,12 @@ spec:
type: PathPrefix
value: /infpool
headers:
- name: my-header
value: some-value
type: Exact
- name: my-header
value: some-value
type: Exact
backendRefs:
- name: infpool-gen
group: inference.networking.x-k8s.io
group: inference.networking.k8s.io
kind: InferencePool
port: 80
- matches:
@@ -381,35 +381,43 @@ spec:
type: PathPrefix
value: /infpool
headers:
- name: my-header
value: some-value-2
type: Exact
- name: my-header
value: some-value-2
type: Exact
backendRefs:
- name: infpool-gen2
group: inference.networking.x-k8s.io
group: inference.networking.k8s.io
kind: InferencePool
port: 80
---
apiVersion: inference.networking.x-k8s.io/v1alpha2
apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
name: infpool-gen
namespace: default
spec:
targetPortNumber: 8000
targetPorts:
- number: 8000
selector:
app: vllm-llama3-8b-instruct
extensionRef:
matchLabels:
app: vllm-llama3-8b-instruct
endpointPickerRef:
name: vllm-llama3-8b-instruct-epp
port:
number: 9002
---
apiVersion: inference.networking.x-k8s.io/v1alpha2
apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
name: infpool-gen2
namespace: default
spec:
targetPortNumber: 8000
targetPorts:
- number: 8000
selector:
app: vllm-llama3-8b-instruct
extensionRef:
matchLabels:
app: vllm-llama3-8b-instruct
endpointPickerRef:
name: vllm-llama3-8b-instruct-epp
port:
number: 9002

View File

@@ -5,7 +5,7 @@ metadata:
internal.istio.io/gateway-semantics: gateway
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
internal.istio.io/parents: Gateway/gateway/default.higress-system
creationTimestamp: null
internal.istio.io/service-account-name: ""
name: gateway-istio-autogenerated-k8s-gateway-default
namespace: higress-system
spec:
@@ -23,7 +23,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/mirror.default,HTTPRoute/redirect.default,HTTPRoute/rewrite.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~*
namespace: default
spec:
@@ -101,7 +100,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~another.domain.example
namespace: default
spec:
@@ -140,7 +138,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http-route-cors.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~cors.domain.example
namespace: default
spec:
@@ -176,7 +173,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~first.domain.example
namespace: default
spec:
@@ -215,7 +211,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/multiple-inferencepool-backend-refs.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~infpool-multi.domain.example
namespace: default
spec:
@@ -251,7 +246,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/redirect-prefix-replace.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~redirect.domain.example
namespace: default
spec:
@@ -276,7 +270,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http-retry-request.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~retry.domain.example
namespace: default
spec:
@@ -327,7 +320,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http2.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~second.domain.example
namespace: default
spec:
@@ -361,7 +353,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http-timeout-backend-request.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~timeout-backend.domain.example
namespace: default
spec:
@@ -387,7 +378,6 @@ metadata:
annotations:
internal.istio.io/parents: HTTPRoute/http-timeout-request.default
internal.istio.io/route-semantics: gateway
creationTimestamp: null
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~timeout.domain.example
namespace: default
spec:

Some files were not shown because too many files have changed in this diff Show More