You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by zh...@apache.org on 2025/10/05 05:47:29 UTC
(dubbo-kubernetes) branch master updated: [chore] discovery ads push completed (#800)
This is an automated email from the ASF dual-hosted git repository.
zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git
The following commit(s) were added to refs/heads/master by this push:
new 16a0738e [chore] discovery ads push completed (#800)
16a0738e is described below
commit 16a0738e586f252d172681b65e0d69375b99ed7b
Author: Jian Zhong <11...@qq.com>
AuthorDate: Sun Oct 5 13:47:24 2025 +0800
[chore] discovery ads push completed (#800)
---
Dockerfile | 2 +-
go.mod | 89 ++++++---
go.sum | 219 ++++++++++++++-------
.../{collections.go => collections.agent.go} | 79 +++++---
pkg/config/schema/collections/collections.go | 75 +++++--
pkg/config/schema/gvk/resources.go | 14 +-
pkg/config/schema/gvr/resources.go | 14 +-
.../schema/kind/{resource.go => resources.go} | 30 +--
.../kubeclient/{resource.go => resources.go} | 61 +++---
pkg/config/schema/kubetypes/resources.go | 2 +
pkg/ctrlz/options.go | 61 ++++++
pkg/kube/client.go | 4 +-
pkg/kube/collection/schemas.go | 81 --------
pkg/kube/collections/collections.go | 45 -----
pkg/kube/inject/webhook.go | 22 ++-
pkg/model/proxy.go | 8 +
pkg/webhooks/validation/controller/controller.go | 3 +-
pkg/webhooks/webhookpatch.go | 21 +-
pkg/xds/server.go | 35 +++-
sail/cmd/sail-agent/options/options.go | 3 -
sail/cmd/sail-discovery/app/cmd.go | 1 +
sail/pkg/bootstrap/configcontroller.go | 6 +
sail/pkg/bootstrap/options.go | 4 +
sail/pkg/bootstrap/proxylessinjector.go | 18 +-
sail/pkg/bootstrap/server.go | 57 +++++-
sail/pkg/bootstrap/servicecontroller.go | 3 +-
sail/pkg/bootstrap/validation.go | 2 +-
sail/pkg/config/kube/crdclient/types.go | 95 +++------
sail/pkg/features/tuning.go | 64 +++++-
sail/pkg/features/xds.go | 31 ---
sail/pkg/model/config.go | 11 ++
sail/pkg/model/context.go | 84 +++++++-
sail/pkg/model/endpointshards.go | 218 ++++++++++++++++++++
sail/pkg/model/push_context.go | 186 ++++++++---------
sail/pkg/model/service.go | 101 ++++++++++
sail/pkg/server/instance.go | 17 +-
sail/pkg/serviceregistry/aggregate/controller.go | 31 +++
.../serviceregistry/kube/controller/controller.go | 3 +-
sail/pkg/trustbundle/trustbundle.go | 2 -
sail/pkg/xds/ads.go | 121 +++++++++++-
sail/pkg/xds/delta.go | 5 +
sail/pkg/xds/discovery.go | 155 ++++++++++-----
sail/pkg/xds/eds.go | 20 ++
sail/pkg/xds/statusgen.go | 7 +
sail/pkg/xds/xdsgen.go | 79 ++++++++
45 files changed, 1565 insertions(+), 624 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 310b911d..63b52fd0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
FROM gcr.io/distroless/static:debug AS discovery
-COPY sail-discovery .
+COPY ../sail-discovery .
ENTRYPOINT ["./sail-discovery"]
FROM gcr.io/distroless/static:debug AS agent
diff --git a/go.mod b/go.mod
index 8691246f..f323b7b0 100644
--- a/go.mod
+++ b/go.mod
@@ -28,23 +28,23 @@ require (
github.com/chzyer/readline v1.5.1
github.com/containers/image/v5 v5.34.0
github.com/containers/storage v1.57.1
- github.com/coreos/go-oidc/v3 v3.12.0
+ github.com/coreos/go-oidc/v3 v3.15.0
github.com/docker/cli v28.3.3+incompatible
github.com/docker/docker v27.5.1+incompatible
github.com/docker/docker-credential-helpers v0.9.3
github.com/docker/go-connections v0.5.0
- github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250627145903-197b96a9c7f8
+ github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250921184633-9a6a6e1d1741
github.com/evanphx/json-patch/v5 v5.9.11
github.com/fatih/color v1.18.0
github.com/fsnotify/fsnotify v1.9.0
github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.13.1
- github.com/go-jose/go-jose/v4 v4.0.5
+ github.com/go-jose/go-jose/v4 v4.1.2
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.20.6
- github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
+ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/go-multierror v1.1.1
@@ -64,20 +64,20 @@ require (
golang.org/x/term v0.34.0
golang.org/x/time v0.12.0
gomodules.xyz/jsonpatch/v2 v2.5.0
- google.golang.org/grpc v1.74.2
- google.golang.org/protobuf v1.36.7
+ google.golang.org/grpc v1.75.1
+ google.golang.org/protobuf v1.36.9
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.18.6
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9
istio.io/client-go v1.27.1
- k8s.io/api v0.33.4
- k8s.io/apiextensions-apiserver v0.33.4
- k8s.io/apimachinery v0.33.4
- k8s.io/client-go v0.33.4
+ k8s.io/api v0.34.1
+ k8s.io/apiextensions-apiserver v0.34.1
+ k8s.io/apimachinery v0.34.1
+ k8s.io/client-go v0.34.1
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.130.1
k8s.io/kubectl v0.33.3
- k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
+ k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
sigs.k8s.io/yaml v1.6.0
)
@@ -102,6 +102,7 @@ require (
github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
+ github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/apex/log v1.9.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.12 // indirect
@@ -132,35 +133,42 @@ require (
github.com/containerd/typeurl v1.0.2 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/dgraph-io/ristretto v0.0.1 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
- github.com/emicklei/go-restful/v3 v3.12.2 // indirect
+ github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
+ github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250627145903-197b96a9c7f8 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
- github.com/fxamacker/cbor/v2 v2.8.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.6.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-logr/logr v1.4.3 // indirect
- github.com/go-openapi/jsonpointer v0.21.1 // indirect
+ github.com/go-logr/stdr v1.2.2 // 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
+ github.com/goccy/go-json v0.10.5 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/btree v1.1.3 // indirect
- github.com/google/gnostic-models v0.6.9 // indirect
- github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
+ github.com/google/cel-go v0.26.0 // indirect
+ github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/goph/emperror v0.17.2 // indirect
+ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
+ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -172,6 +180,12 @@ require (
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
+ github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
+ github.com/lestrrat-go/blackmagic v1.0.3 // indirect
+ github.com/lestrrat-go/httpcc v1.0.1 // indirect
+ github.com/lestrrat-go/iter v1.0.2 // indirect
+ github.com/lestrrat-go/jwx v1.2.31 // indirect
+ github.com/lestrrat-go/option v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
@@ -179,6 +193,7 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // 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/ioprogress v0.0.0-20180201004757-6a23b12fa88e // indirect
@@ -186,19 +201,19 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/buildkit v0.23.2 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
+ github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/capability v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/user v0.3.0 // indirect
github.com/moby/sys/userns v0.1.0 // 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/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nikolalohinski/gonja v1.5.3 // indirect
- github.com/onsi/ginkgo/v2 v2.24.0 // indirect
- github.com/onsi/gomega v1.38.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runc v1.1.7 // indirect
@@ -210,9 +225,11 @@ require (
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkoukk/tiktoken-go v0.1.6 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca // indirect
- github.com/prometheus/client_golang v1.23.0 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // 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/common v0.66.1 // indirect
+ github.com/prometheus/otlptranslator v0.0.0-20250717125610-8549f4ab4f8f // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
@@ -226,6 +243,7 @@ require (
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.8.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/stoewer/go-strcase v1.3.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
@@ -233,30 +251,43 @@ require (
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yargevad/filepathx v1.0.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
+ go.opentelemetry.io/otel/exporters/prometheus v0.59.1 // indirect
+ go.opentelemetry.io/otel/metric v1.37.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.37.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
+ go.opentelemetry.io/otel/trace v1.37.0 // indirect
+ go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.starlark.net v0.0.0-20230302034142-4b1e35fe2254 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
- go.yaml.in/yaml/v3 v3.0.3 // indirect
+ go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.27.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
- golang.org/x/sync v0.16.0 // indirect
+ golang.org/x/sync v0.17.0 // indirect
golang.org/x/text v0.28.0 // indirect
+ golang.org/x/tools v0.36.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
- gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect
+ gopkg.in/evanphx/json-patch.v4 v4.13.0 // 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.v2 v2.4.0 // indirect
+ k8s.io/apiserver v0.34.1 // indirect
k8s.io/cli-runtime v0.33.3 // indirect
- k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
- sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect
+ sigs.k8s.io/gateway-api v1.3.1-0.20250924180216-ab6b5a251c59 // indirect
+ sigs.k8s.io/gateway-api-inference-extension v0.0.0-20250917095812-173ad587b675 // 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.2.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
replace (
diff --git a/go.sum b/go.sum
index aa358fc3..0070e356 100644
--- a/go.sum
+++ b/go.sum
@@ -22,8 +22,8 @@ cloud.google.com/go/vertexai v0.12.0 h1:zTadEo/CtsoyRXNx3uGCncoWAP1H2HakGqwznt+i
cloud.google.com/go/vertexai v0.12.0/go.mod h1:8u+d0TsvBfAAd2x5R6GMgbYhsLgo3J7lmP4bR8g2ig8=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
github.com/AssemblyAI/assemblyai-go-sdk v1.3.0 h1:AtOVgGxUycvK4P4ypP+1ZupecvFgnfH+Jsum0o5ILoU=
@@ -89,6 +89,8 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
+github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
+github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0=
github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA=
github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
@@ -146,6 +148,7 @@ github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230522190001-
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
+github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
@@ -164,6 +167,8 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
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.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
+github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
@@ -201,8 +206,8 @@ github.com/containers/image/v5 v5.34.0 h1:HPqQaDUsox/3mC1pbOyLAIQEp0JhQqiUZ+6JiF
github.com/containers/image/v5 v5.34.0/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
github.com/containers/storage v1.57.1 h1:hKPoFsuBcB3qTzBxa4IFpZMRzUuL5Xhv/BE44W0XHx8=
github.com/containers/storage v1.57.1/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM=
-github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
-github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
+github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=
+github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
@@ -214,6 +219,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgraph-io/ristretto v0.0.1 h1:cJwdnj42uV8Jg4+KLrYovLiCgIfz9wtWm6E6KA+1tLs=
github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
@@ -243,15 +250,17 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
-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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250627145903-197b96a9c7f8 h1:/F9jLyfDeNr4iZxyibtKlZxCDqCFEhoYiLdc9VOZT2E=
-github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250627145903-197b96a9c7f8/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
+github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250627145903-197b96a9c7f8 h1:KXgXPtBofHkRHr+8dO058dGZnLHapW7m0yJEgSYdAFA=
+github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250627145903-197b96a9c7f8/go.mod h1:Nx/YcyEeIcgjT13QwKHdcPmS060urxZ835MeO8cLOrg=
+github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250921184633-9a6a6e1d1741 h1:cihocN3Y1vol5fNBh5Zxbk0s72PWbDL9WuKIVpCCkTI=
+github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250921184633-9a6a6e1d1741/go.mod h1:2LcmvJoXsDSrsGZIxGM0Gah9ykiwTn/kgjyQdnNH8Jc=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
@@ -270,8 +279,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/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1/go.mod h1:Az6Jt+M5idSED2YPGtwnfJV0kXohgdCBPmHGSYc1r04=
@@ -294,17 +303,19 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
-github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
-github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+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/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/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.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
@@ -316,6 +327,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
+github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@@ -344,10 +357,12 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
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.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
+github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/generative-ai-go v0.15.1 h1:n8aQUpvhPOlGVuM2DRkJ2jvx04zpp42B778AROJa+pQ=
github.com/google/generative-ai-go v0.15.1/go.mod h1:AAucpWZjXsDKhQYWvCYuP6d0yB1kX998pJlOW1rAesw=
-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=
@@ -355,7 +370,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
@@ -363,6 +377,8 @@ github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEva
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
@@ -383,19 +399,28 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+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/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.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+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/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/heroku/color v0.0.6 h1:UTFFMrmMLFcL3OweqP1lAdp8i1y/9oHqkeHjQ/b/Ny0=
@@ -441,8 +466,23 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
+github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
+github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
+github.com/lestrrat-go/blackmagic v1.0.3 h1:94HXkVLxkZO9vJI/w2u1T0DAoprShFd13xtnSINtDWs=
+github.com/lestrrat-go/blackmagic v1.0.3/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
+github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
+github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
+github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
+github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
+github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54=
+github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c=
+github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
+github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -466,6 +506,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
+github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
+github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -481,6 +523,8 @@ github.com/moby/buildkit v0.10.6 h1:DJlEuLIgnu34HQKF4n9Eg6q2YqQVC0eOpMb4p2eRS2w=
github.com/moby/buildkit v0.10.6/go.mod h1:tQuuyTWtOb9D+RE425cwOCUkX0/oZ+5iBZ+uWpWQ9bU=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
+github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
+github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
@@ -496,23 +540,27 @@ github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFL
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
+github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c=
github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo/v2 v2.24.0 h1:obZz8LAnHicNdbBqvG3ytAFx8fgza+i1IDpBVcHT2YE=
-github.com/onsi/ginkgo/v2 v2.24.0/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
+github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
-github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
+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/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@@ -546,13 +594,15 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca/go.mod h1
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
-github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
+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-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
-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.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
+github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
+github.com/prometheus/otlptranslator v0.0.0-20250717125610-8549f4ab4f8f h1:QQB6SuvGZjK8kdc2YaLJpYhV8fxauOsjE6jgcL6YJ8Q=
+github.com/prometheus/otlptranslator v0.0.0-20250717125610-8549f4ab4f8f/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI=
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/rivo/tview v0.0.0-20220307222120-9994674d60a8 h1:xe+mmCnDN82KhC010l3NfYlA8ZbOuzbXAzSYBa6wbMc=
@@ -610,6 +660,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
+github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -623,9 +675,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
@@ -669,12 +722,18 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
+go.opentelemetry.io/otel/exporters/prometheus v0.59.1 h1:HcpSkTkJbggT8bjYP+BjyqPWlD17BH9C5CYNKeDzmcA=
+go.opentelemetry.io/otel/exporters/prometheus v0.59.1/go.mod h1:0FJL+gjuUoM07xzik3KPBaN+nz/CoB15kV6WLMiXZag=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
@@ -683,21 +742,28 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+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.starlark.net v0.0.0-20230302034142-4b1e35fe2254 h1:Ss6D3hLXTM0KobyBYEAygXzFfGcjnmfEJOBgSbemCtg=
go.starlark.net v0.0.0-20230302034142-4b1e35fe2254/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+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=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
+go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+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/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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -717,6 +783,7 @@ golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aC
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -746,8 +813,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-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=
@@ -766,6 +833,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -800,6 +868,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -812,6 +881,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
+gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.183.0 h1:PNMeRDwo1pJdgNcFQ9GstuLe/noWKIc89pRWRLMvLwE=
google.golang.org/api v0.183.0/go.mod h1:q43adC5/pHoSZTx5h2mSmdF7NcyfW9JuDyIOJAgS9ZQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -824,15 +895,15 @@ google.golang.org/genproto v0.0.0-20240528184218-531527333157 h1:u7WMYrIrVvs0TF5
google.golang.org/genproto v0.0.0-20240528184218-531527333157/go.mod h1:ubQlAQnzejB8uZzszhrTCU2Fyp6Vi7ZE5nn0c3W8+qQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a h1:DMCgtIAIQGZqJXMVzJF4MV8BlWoJh2ZuFiRdAleyr58=
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a/go.mod h1:y2yVLIE/CSMCPXaHnSKXxu1spLPnglFLegmgdY23uuE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
-google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
+google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
+google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -841,20 +912,23 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
-google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
+google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
+google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
@@ -865,6 +939,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
@@ -878,39 +953,51 @@ istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9 h1:gVTxnhYGJ1pY+iqcz/mrbPSpdk
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9/go.mod h1:DTVGH6CLXj5W8FF9JUD3Tis78iRgT1WeuAnxfTz21Wg=
istio.io/client-go v1.27.1 h1:VWEtOzmv9gi4x3OPjN5wMFOBV1i95UIGcbYXoP4VVuA=
istio.io/client-go v1.27.1/go.mod h1:otQns/CCDd4EoyEFWp8w+ksTP0T05baYTIx5FxqS8eM=
-k8s.io/api v0.33.4 h1:oTzrFVNPXBjMu0IlpA2eDDIU49jsuEorGHB4cvKupkk=
-k8s.io/api v0.33.4/go.mod h1:VHQZ4cuxQ9sCUMESJV5+Fe8bGnqAARZ08tSTdHWfeAc=
-k8s.io/apiextensions-apiserver v0.33.4 h1:rtq5SeXiDbXmSwxsF0MLe2Mtv3SwprA6wp+5qh/CrOU=
-k8s.io/apiextensions-apiserver v0.33.4/go.mod h1:mWXcZQkQV1GQyxeIjYApuqsn/081hhXPZwZ2URuJeSs=
-k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s=
-k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
+istio.io/istio v0.0.0-20251004003413-450b9f38614f h1:Kdl3XP0a/zFHU8//DLlj+LjGFWg/+XHzG1Z7iUMMjwc=
+istio.io/istio v0.0.0-20251004003413-450b9f38614f/go.mod h1:rkwXkzAe+prvZU+JxLOJboEX44gr1ycbEPyl9k24CE8=
+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.4 h1:TNH+CSu8EmXfitntjUPwaKVPN0AYMbc9F1bBS8/ABpw=
-k8s.io/client-go v0.33.4/go.mod h1:LsA0+hBG2DPwovjd931L/AoaezMPX9CmBgyVyBZmbCY=
+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 v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
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-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
-k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/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=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
-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/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/gateway-api v1.3.1-0.20250924180216-ab6b5a251c59 h1:oemARIB7UxADVkfGavZazg/PLWSKmzbZhr7l4P0kCho=
+sigs.k8s.io/gateway-api v1.3.1-0.20250924180216-ab6b5a251c59/go.mod h1:eEPQfoYoowXAJ+/1RFugqZSanFd705bAPrIjB8Z8LdQ=
+sigs.k8s.io/gateway-api-inference-extension v0.0.0-20250917095812-173ad587b675 h1:CW+VWxazW54YzQnlHkyCE/WmAvF0YK7HOl+OK8IO3Ug=
+sigs.k8s.io/gateway-api-inference-extension v0.0.0-20250917095812-173ad587b675/go.mod h1:Tqmt4U654MNQkzC1lFYVa43wbUW7K8r8Lv6Sq2I3HCc=
+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/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/mcs-api v0.2.0 h1:F8o/nIpQmog494Qwe94srDWjS3ltEu4y5IL9i3dB938=
+sigs.k8s.io/mcs-api v0.2.0/go.mod h1:zZ5CK8uS6HaLkxY4HqsmcBHfzHuNMrY2uJy8T7jffK4=
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/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=
diff --git a/pkg/config/schema/collections/collections.go b/pkg/config/schema/collections/collections.agent.go
similarity index 68%
copy from pkg/config/schema/collections/collections.go
copy to pkg/config/schema/collections/collections.agent.go
index a93de7cc..21bd9682 100644
--- a/pkg/config/schema/collections/collections.go
+++ b/pkg/config/schema/collections/collections.agent.go
@@ -1,5 +1,5 @@
-//go:build !agent
-// +build !agent
+//go:build agent
+// +build agent
package collections
@@ -9,28 +9,11 @@ import (
istioioapimetav1alpha1 "istio.io/api/meta/v1alpha1"
istioioapinetworkingv1alpha3 "istio.io/api/networking/v1alpha3"
istioioapisecurityv1beta1 "istio.io/api/security/v1beta1"
+ k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"reflect"
)
var (
- DestinationRule = resource.Builder{
- Identifier: "DestinationRule",
- Group: "networking.istio.io",
- Kind: "DestinationRule",
- Plural: "destinationrules",
- Version: "v1",
- VersionAliases: []string{
- "v1alpha3",
- "v1beta1",
- },
- Proto: "istio.networking.v1alpha3.DestinationRule", StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType: reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(), StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3", StatusPackage: "istio.io/api/meta/v1alpha1",
- ClusterScoped: false,
- Synthetic: false,
- Builtin: false,
- }.MustBuild()
-
PeerAuthentication = resource.Builder{
Identifier: "PeerAuthentication",
Group: "security.istio.io",
@@ -47,7 +30,6 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
-
RequestAuthentication = resource.Builder{
Identifier: "RequestAuthentication",
Group: "security.istio.io",
@@ -64,7 +46,23 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
-
+ DestinationRule = resource.Builder{
+ Identifier: "DestinationRule",
+ Group: "networking.istio.io",
+ Kind: "DestinationRule",
+ Plural: "destinationrules",
+ Version: "v1",
+ VersionAliases: []string{
+ "v1alpha3",
+ "v1beta1",
+ },
+ Proto: "istio.networking.v1alpha3.DestinationRule", StatusProto: "istio.meta.v1alpha1.IstioStatus",
+ ReflectType: reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(), StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3", StatusPackage: "istio.io/api/meta/v1alpha1",
+ ClusterScoped: false,
+ Synthetic: false,
+ Builtin: false,
+ }.MustBuild()
VirtualService = resource.Builder{
Identifier: "VirtualService",
Group: "networking.istio.io",
@@ -82,11 +80,46 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
+ ValidatingWebhookConfiguration = resource.Builder{
+ Identifier: "ValidatingWebhookConfiguration",
+ Group: "admissionregistration.k8s.io",
+ Kind: "ValidatingWebhookConfiguration",
+ Plural: "validatingwebhookconfigurations",
+ Version: "v1",
+ Proto: "k8s.io.api.admissionregistration.v1.ValidatingWebhookConfiguration",
+ ReflectType: reflect.TypeOf(&k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration{}).Elem(),
+ ProtoPackage: "k8s.io/api/admissionregistration/v1",
+ ClusterScoped: true,
+ Synthetic: false,
+ Builtin: true,
+ }.MustBuild()
+ MutatingWebhookConfiguration = resource.Builder{
+ Identifier: "MutatingWebhookConfiguration",
+ Group: "admissionregistration.k8s.io",
+ Kind: "MutatingWebhookConfiguration",
+ Plural: "mutatingwebhookconfigurations",
+ Version: "v1",
+ Proto: "k8s.io.api.admissionregistration.v1.MutatingWebhookConfiguration",
+ ReflectType: reflect.TypeOf(&k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration{}).Elem(),
+ ProtoPackage: "k8s.io/api/admissionregistration/v1",
+ ClusterScoped: true,
+ Synthetic: false,
+ Builtin: true,
+ }.MustBuild()
- Sail = collection.NewSchemasBuilder().
+ All = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
MustAdd(RequestAuthentication).
+ MustAdd(DestinationRule).
MustAdd(VirtualService).
+ MustAdd(MutatingWebhookConfiguration).
+ MustAdd(ValidatingWebhookConfiguration).
+ Build()
+
+ Sail = collection.NewSchemasBuilder().
+ MustAdd(PeerAuthentication).
+ MustAdd(RequestAuthentication).
MustAdd(DestinationRule).
+ MustAdd(VirtualService).
Build()
)
diff --git a/pkg/config/schema/collections/collections.go b/pkg/config/schema/collections/collections.go
index a93de7cc..ace155e2 100644
--- a/pkg/config/schema/collections/collections.go
+++ b/pkg/config/schema/collections/collections.go
@@ -9,28 +9,11 @@ import (
istioioapimetav1alpha1 "istio.io/api/meta/v1alpha1"
istioioapinetworkingv1alpha3 "istio.io/api/networking/v1alpha3"
istioioapisecurityv1beta1 "istio.io/api/security/v1beta1"
+ k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"reflect"
)
var (
- DestinationRule = resource.Builder{
- Identifier: "DestinationRule",
- Group: "networking.istio.io",
- Kind: "DestinationRule",
- Plural: "destinationrules",
- Version: "v1",
- VersionAliases: []string{
- "v1alpha3",
- "v1beta1",
- },
- Proto: "istio.networking.v1alpha3.DestinationRule", StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType: reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(), StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3", StatusPackage: "istio.io/api/meta/v1alpha1",
- ClusterScoped: false,
- Synthetic: false,
- Builtin: false,
- }.MustBuild()
-
PeerAuthentication = resource.Builder{
Identifier: "PeerAuthentication",
Group: "security.istio.io",
@@ -47,7 +30,6 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
-
RequestAuthentication = resource.Builder{
Identifier: "RequestAuthentication",
Group: "security.istio.io",
@@ -64,7 +46,23 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
-
+ DestinationRule = resource.Builder{
+ Identifier: "DestinationRule",
+ Group: "networking.istio.io",
+ Kind: "DestinationRule",
+ Plural: "destinationrules",
+ Version: "v1",
+ VersionAliases: []string{
+ "v1alpha3",
+ "v1beta1",
+ },
+ Proto: "istio.networking.v1alpha3.DestinationRule", StatusProto: "istio.meta.v1alpha1.IstioStatus",
+ ReflectType: reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(), StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3", StatusPackage: "istio.io/api/meta/v1alpha1",
+ ClusterScoped: false,
+ Synthetic: false,
+ Builtin: false,
+ }.MustBuild()
VirtualService = resource.Builder{
Identifier: "VirtualService",
Group: "networking.istio.io",
@@ -82,11 +80,46 @@ var (
Synthetic: false,
Builtin: false,
}.MustBuild()
+ ValidatingWebhookConfiguration = resource.Builder{
+ Identifier: "ValidatingWebhookConfiguration",
+ Group: "admissionregistration.k8s.io",
+ Kind: "ValidatingWebhookConfiguration",
+ Plural: "validatingwebhookconfigurations",
+ Version: "v1",
+ Proto: "k8s.io.api.admissionregistration.v1.ValidatingWebhookConfiguration",
+ ReflectType: reflect.TypeOf(&k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration{}).Elem(),
+ ProtoPackage: "k8s.io/api/admissionregistration/v1",
+ ClusterScoped: true,
+ Synthetic: false,
+ Builtin: true,
+ }.MustBuild()
+ MutatingWebhookConfiguration = resource.Builder{
+ Identifier: "MutatingWebhookConfiguration",
+ Group: "admissionregistration.k8s.io",
+ Kind: "MutatingWebhookConfiguration",
+ Plural: "mutatingwebhookconfigurations",
+ Version: "v1",
+ Proto: "k8s.io.api.admissionregistration.v1.MutatingWebhookConfiguration",
+ ReflectType: reflect.TypeOf(&k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration{}).Elem(),
+ ProtoPackage: "k8s.io/api/admissionregistration/v1",
+ ClusterScoped: true,
+ Synthetic: false,
+ Builtin: true,
+ }.MustBuild()
- Sail = collection.NewSchemasBuilder().
+ All = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
MustAdd(RequestAuthentication).
+ MustAdd(DestinationRule).
MustAdd(VirtualService).
+ MustAdd(MutatingWebhookConfiguration).
+ MustAdd(ValidatingWebhookConfiguration).
+ Build()
+
+ Sail = collection.NewSchemasBuilder().
+ MustAdd(PeerAuthentication).
+ MustAdd(RequestAuthentication).
MustAdd(DestinationRule).
+ MustAdd(VirtualService).
Build()
)
diff --git a/pkg/config/schema/gvk/resources.go b/pkg/config/schema/gvk/resources.go
index a610009d..2a4af1fb 100644
--- a/pkg/config/schema/gvk/resources.go
+++ b/pkg/config/schema/gvk/resources.go
@@ -37,11 +37,11 @@ var (
Service = config.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"}
ServiceAccount = config.GroupVersionKind{Group: "", Version: "v1", Kind: "ServiceAccount"}
MeshConfig = config.GroupVersionKind{Group: "", Version: "v1alpha1", Kind: "MeshConfig"}
- RequestAuthentication = config.GroupVersionKind{Group: "security.dubbo.io", Version: "v1", Kind: "RequestAuthentication"}
- PeerAuthentication = config.GroupVersionKind{Group: "security.dubbo.io", Version: "v1", Kind: "PeerAuthentication"}
- AuthorizationPolicy = config.GroupVersionKind{Group: "security.dubbo.io", Version: "v1", Kind: "AuthorizationPolicy"}
- DestinationRule = config.GroupVersionKind{Group: "networking.dubbo.io", Version: "v1", Kind: "DestinationRule"}
- VirtualService = config.GroupVersionKind{Group: "networking.dubbo.io", Version: "v1", Kind: "VirtualService"}
+ RequestAuthentication = config.GroupVersionKind{Group: "security.istio.io", Version: "v1", Kind: "RequestAuthentication"}
+ PeerAuthentication = config.GroupVersionKind{Group: "security.istio.io", Version: "v1", Kind: "PeerAuthentication"}
+ AuthorizationPolicy = config.GroupVersionKind{Group: "security.istio.io", Version: "v1", Kind: "AuthorizationPolicy"}
+ DestinationRule = config.GroupVersionKind{Group: "networking.istio.io", Version: "v1", Kind: "DestinationRule"}
+ VirtualService = config.GroupVersionKind{Group: "networking.istio.io", Version: "v1", Kind: "VirtualService"}
)
func ToGVR(g config.GroupVersionKind) (schema.GroupVersionResource, bool) {
@@ -97,6 +97,10 @@ func FromGVR(g schema.GroupVersionResource) (config.GroupVersionKind, bool) {
switch g {
case gvr.CustomResourceDefinition:
return CustomResourceDefinition, true
+ // case gvr.MutatingWebhookConfiguration:
+ // return MutatingWebhookConfiguration, true
+ // case gvr.ValidatingWebhookConfiguration:
+ // return ValidatingWebhookConfiguration, true
case gvr.Namespace:
return Namespace, true
case gvr.Deployment:
diff --git a/pkg/config/schema/gvr/resources.go b/pkg/config/schema/gvr/resources.go
index ba4c933e..dd55ca6d 100644
--- a/pkg/config/schema/gvr/resources.go
+++ b/pkg/config/schema/gvr/resources.go
@@ -35,11 +35,11 @@ var (
Service = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"}
ServiceAccount = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"}
MeshConfig = schema.GroupVersionResource{Group: "", Version: "v1alpha1", Resource: "meshconfigs"}
- RequestAuthentication = schema.GroupVersionResource{Group: "security.dubbo.io", Version: "v1", Resource: "requestauthentications"}
- PeerAuthentication = schema.GroupVersionResource{Group: "security.dubbo.io", Version: "v1", Resource: "peerauthentications"}
- AuthorizationPolicy = schema.GroupVersionResource{Group: "security.dubbo.io", Version: "v1", Resource: "authorizationpolicies"}
- DestinationRule = schema.GroupVersionResource{Group: "networking.dubbo.io", Version: "v1", Resource: "destinationrules"}
- VirtualService = schema.GroupVersionResource{Group: "networking.dubbo.io", Version: "v1", Resource: "virtualservices"}
+ RequestAuthentication = schema.GroupVersionResource{Group: "security.istio.io", Version: "v1", Resource: "requestauthentications"}
+ PeerAuthentication = schema.GroupVersionResource{Group: "security.istio.io", Version: "v1", Resource: "peerauthentications"}
+ AuthorizationPolicy = schema.GroupVersionResource{Group: "security.istio.io", Version: "v1", Resource: "authorizationpolicies"}
+ DestinationRule = schema.GroupVersionResource{Group: "networking.istio.io", Version: "v1", Resource: "destinationrules"}
+ VirtualService = schema.GroupVersionResource{Group: "networking.istio.io", Version: "v1", Resource: "virtualservices"}
)
func IsClusterScoped(g schema.GroupVersionResource) bool {
@@ -70,6 +70,10 @@ func IsClusterScoped(g schema.GroupVersionResource) bool {
return false
case VirtualService:
return false
+ case MutatingWebhookConfiguration:
+ return true
+ case ValidatingWebhookConfiguration:
+ return true
}
return false
}
diff --git a/pkg/config/schema/kind/resource.go b/pkg/config/schema/kind/resources.go
similarity index 93%
rename from pkg/config/schema/kind/resource.go
rename to pkg/config/schema/kind/resources.go
index fdbb42ac..09d6606f 100644
--- a/pkg/config/schema/kind/resource.go
+++ b/pkg/config/schema/kind/resources.go
@@ -2,46 +2,38 @@ package kind
const (
Unknown Kind = iota
- AuthorizationPolicy
+ Address
CustomResourceDefinition
- DestinationRule
MeshConfig
MeshNetworks
- MutatingWebhookConfiguration
Namespace
- PeerAuthentication
Pod
- RequestAuthentication
Secret
Service
ServiceAccount
StatefulSet
ValidatingWebhookConfiguration
+ MutatingWebhookConfiguration
+ PeerAuthentication
+ RequestAuthentication
VirtualService
+ DestinationRule
)
func (k Kind) String() string {
switch k {
- case AuthorizationPolicy:
- return "AuthorizationPolicy"
+ case Address:
+ return "Address"
case CustomResourceDefinition:
return "CustomResourceDefinition"
- case DestinationRule:
- return "DestinationRule"
case MeshConfig:
return "MeshConfig"
case MeshNetworks:
return "MeshNetworks"
- case MutatingWebhookConfiguration:
- return "MutatingWebhookConfiguration"
case Namespace:
return "Namespace"
- case PeerAuthentication:
- return "PeerAuthentication"
case Pod:
return "Pod"
- case RequestAuthentication:
- return "RequestAuthentication"
case Secret:
return "Secret"
case Service:
@@ -52,8 +44,16 @@ func (k Kind) String() string {
return "StatefulSet"
case ValidatingWebhookConfiguration:
return "ValidatingWebhookConfiguration"
+ case MutatingWebhookConfiguration:
+ return "MutatingWebhookConfiguration"
+ case PeerAuthentication:
+ return "PeerAuthentication"
+ case RequestAuthentication:
+ return "RequestAuthentication"
case VirtualService:
return "VirtualService"
+ case DestinationRule:
+ return "DestinationRule"
default:
return "Unknown"
}
diff --git a/pkg/config/schema/kubeclient/resource.go b/pkg/config/schema/kubeclient/resources.go
similarity index 85%
rename from pkg/config/schema/kubeclient/resource.go
rename to pkg/config/schema/kubeclient/resources.go
index 12a9d02b..d06deac2 100644
--- a/pkg/config/schema/kubeclient/resource.go
+++ b/pkg/config/schema/kubeclient/resources.go
@@ -29,10 +29,7 @@ import (
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
k8sioapiappsv1 "k8s.io/api/apps/v1"
k8sioapicertificatesv1 "k8s.io/api/certificates/v1"
- k8sioapicoordinationv1 "k8s.io/api/coordination/v1"
k8sioapicorev1 "k8s.io/api/core/v1"
- k8sioapidiscoveryv1 "k8s.io/api/discovery/v1"
- k8sioapinetworkingv1 "k8s.io/api/networking/v1"
k8sioapipolicyv1 "k8s.io/api/policy/v1"
k8sioapiextensionsapiserverpkgapisapiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -54,18 +51,10 @@ func GetWriteClient[T runtime.Object](c ClientGetter, namespace string) ktypes.W
return c.Kube().AppsV1().DaemonSets(namespace).(ktypes.WriteAPI[T])
case *k8sioapiappsv1.Deployment:
return c.Kube().AppsV1().Deployments(namespace).(ktypes.WriteAPI[T])
- case *k8sioapidiscoveryv1.EndpointSlice:
- return c.Kube().DiscoveryV1().EndpointSlices(namespace).(ktypes.WriteAPI[T])
- case *k8sioapicorev1.Endpoints:
- return c.Kube().CoreV1().Endpoints(namespace).(ktypes.WriteAPI[T])
- case *k8sioapinetworkingv1.Ingress:
- return c.Kube().NetworkingV1().Ingresses(namespace).(ktypes.WriteAPI[T])
- case *k8sioapinetworkingv1.IngressClass:
- return c.Kube().NetworkingV1().IngressClasses().(ktypes.WriteAPI[T])
- case *k8sioapicoordinationv1.Lease:
- return c.Kube().CoordinationV1().Leases(namespace).(ktypes.WriteAPI[T])
case *k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration:
return c.Kube().AdmissionregistrationV1().MutatingWebhookConfigurations().(ktypes.WriteAPI[T])
+ case *k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration:
+ return c.Kube().AdmissionregistrationV1().ValidatingWebhookConfigurations().(ktypes.WriteAPI[T])
case *k8sioapicorev1.Namespace:
return c.Kube().CoreV1().Namespaces().(ktypes.WriteAPI[T])
case *k8sioapicorev1.Node:
@@ -104,8 +93,6 @@ func gvrToObject(g schema.GroupVersionResource) runtime.Object {
return &k8sioapiappsv1.DaemonSet{}
case gvr.Deployment:
return &k8sioapiappsv1.Deployment{}
- case gvr.MutatingWebhookConfiguration:
- return &k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration{}
case gvr.Namespace:
return &k8sioapicorev1.Namespace{}
case gvr.Secret:
@@ -116,6 +103,8 @@ func gvrToObject(g schema.GroupVersionResource) runtime.Object {
return &k8sioapicorev1.ServiceAccount{}
case gvr.StatefulSet:
return &k8sioapiappsv1.StatefulSet{}
+ case gvr.MutatingWebhookConfiguration:
+ return &k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration{}
case gvr.ValidatingWebhookConfiguration:
return &k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration{}
case gvr.RequestAuthentication:
@@ -164,13 +153,6 @@ func getInformerFiltered(c ClientGetter, opts ktypes.InformerOptions, g schema.G
w = func(options metav1.ListOptions) (watch.Interface, error) {
return c.Kube().AppsV1().Deployments(opts.Namespace).Watch(context.Background(), options)
}
- case gvr.MutatingWebhookConfiguration:
- l = func(options metav1.ListOptions) (runtime.Object, error) {
- return c.Kube().AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.Background(), options)
- }
- w = func(options metav1.ListOptions) (watch.Interface, error) {
- return c.Kube().AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(context.Background(), options)
- }
case gvr.Namespace:
l = func(options metav1.ListOptions) (runtime.Object, error) {
return c.Kube().CoreV1().Namespaces().List(context.Background(), options)
@@ -206,6 +188,13 @@ func getInformerFiltered(c ClientGetter, opts ktypes.InformerOptions, g schema.G
w = func(options metav1.ListOptions) (watch.Interface, error) {
return c.Kube().AppsV1().StatefulSets(opts.Namespace).Watch(context.Background(), options)
}
+ case gvr.MutatingWebhookConfiguration:
+ l = func(options metav1.ListOptions) (runtime.Object, error) {
+ return c.Kube().AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.Background(), options)
+ }
+ w = func(options metav1.ListOptions) (watch.Interface, error) {
+ return c.Kube().AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(context.Background(), options)
+ }
case gvr.ValidatingWebhookConfiguration:
l = func(options metav1.ListOptions) (runtime.Object, error) {
return c.Kube().AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.Background(), options)
@@ -213,6 +202,34 @@ func getInformerFiltered(c ClientGetter, opts ktypes.InformerOptions, g schema.G
w = func(options metav1.ListOptions) (watch.Interface, error) {
return c.Kube().AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(context.Background(), options)
}
+ case gvr.VirtualService:
+ l = func(options metav1.ListOptions) (runtime.Object, error) {
+ return c.Dubbo().NetworkingV1().VirtualServices(opts.Namespace).List(context.Background(), options)
+ }
+ w = func(options metav1.ListOptions) (watch.Interface, error) {
+ return c.Dubbo().NetworkingV1().VirtualServices(opts.Namespace).Watch(context.Background(), options)
+ }
+ case gvr.DestinationRule:
+ l = func(options metav1.ListOptions) (runtime.Object, error) {
+ return c.Dubbo().NetworkingV1().DestinationRules(opts.Namespace).List(context.Background(), options)
+ }
+ w = func(options metav1.ListOptions) (watch.Interface, error) {
+ return c.Dubbo().NetworkingV1().DestinationRules(opts.Namespace).Watch(context.Background(), options)
+ }
+ case gvr.PeerAuthentication:
+ l = func(options metav1.ListOptions) (runtime.Object, error) {
+ return c.Dubbo().SecurityV1().PeerAuthentications(opts.Namespace).List(context.Background(), options)
+ }
+ w = func(options metav1.ListOptions) (watch.Interface, error) {
+ return c.Dubbo().SecurityV1().PeerAuthentications(opts.Namespace).Watch(context.Background(), options)
+ }
+ case gvr.RequestAuthentication:
+ l = func(options metav1.ListOptions) (runtime.Object, error) {
+ return c.Dubbo().SecurityV1().RequestAuthentications(opts.Namespace).List(context.Background(), options)
+ }
+ w = func(options metav1.ListOptions) (watch.Interface, error) {
+ return c.Dubbo().SecurityV1().RequestAuthentications(opts.Namespace).Watch(context.Background(), options)
+ }
default:
panic(fmt.Sprintf("Unknown type %v", g))
}
diff --git a/pkg/config/schema/kubetypes/resources.go b/pkg/config/schema/kubetypes/resources.go
index 29962b0f..fd826128 100644
--- a/pkg/config/schema/kubetypes/resources.go
+++ b/pkg/config/schema/kubetypes/resources.go
@@ -45,6 +45,8 @@ func getGvk(obj any) (config.GroupVersionKind, bool) {
return gvk.MeshConfig, true
case *k8sioapicorev1.Namespace:
return gvk.Namespace, true
+ case *k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration:
+ return gvk.MutatingWebhookConfiguration, true
case *k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration:
return gvk.ValidatingWebhookConfiguration, true
default:
diff --git a/pkg/ctrlz/options.go b/pkg/ctrlz/options.go
index 75b8c33d..d5d295db 100644
--- a/pkg/ctrlz/options.go
+++ b/pkg/ctrlz/options.go
@@ -17,11 +17,26 @@
package ctrlz
+import (
+ "fmt"
+ "k8s.io/klog/v2"
+ "net"
+ "net/http"
+ "sync"
+ "time"
+)
+
type Options struct {
Port uint16
Address string
}
+type Server struct {
+ listener net.Listener
+ shutdown sync.WaitGroup
+ httpServer http.Server
+}
+
const DefaultControlZPort = 9876
func DefaultOptions() *Options {
@@ -30,3 +45,49 @@ func DefaultOptions() *Options {
Address: "localhost",
}
}
+
+func Run(o *Options) (*Server, error) {
+ addr := o.Address
+ if addr == "*" {
+ addr = ""
+ }
+
+ // Canonicalize the address and resolve a dynamic port if necessary
+ listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, o.Port))
+ if err != nil {
+ klog.Errorf("Unable to start ControlZ: %v", err)
+ return nil, err
+ }
+
+ s := &Server{
+ listener: listener,
+ httpServer: http.Server{
+ Addr: listener.Addr().(*net.TCPAddr).String(),
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: time.Minute, // High timeout to allow profiles to run
+ },
+ }
+
+ s.shutdown.Add(1)
+ go s.listen()
+
+ return s, nil
+}
+
+func (s *Server) listen() {
+ klog.Infof("ControlZ available at %s", s.httpServer.Addr)
+ err := s.httpServer.Serve(s.listener)
+ klog.Infof("ControlZ terminated: %v", err)
+ s.shutdown.Done()
+}
+
+func (s *Server) Close() {
+ klog.Info("Closing ControlZ")
+
+ if s.listener != nil {
+ if err := s.listener.Close(); err != nil {
+ klog.Warningf("Error closing ControlZ: %v", err)
+ }
+ s.shutdown.Wait()
+ }
+}
diff --git a/pkg/kube/client.go b/pkg/kube/client.go
index 7e5904f2..d83ab537 100644
--- a/pkg/kube/client.go
+++ b/pkg/kube/client.go
@@ -20,9 +20,9 @@ package kube
import (
"context"
"fmt"
- "github.com/apache/dubbo-kubernetes/operator/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/cluster"
- "github.com/apache/dubbo-kubernetes/pkg/kube/collections"
+ "github.com/apache/dubbo-kubernetes/pkg/config"
+ "github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
"github.com/apache/dubbo-kubernetes/pkg/kube/informerfactory"
"github.com/apache/dubbo-kubernetes/pkg/kube/kubetypes"
"github.com/apache/dubbo-kubernetes/pkg/lazy"
diff --git a/pkg/kube/collection/schemas.go b/pkg/kube/collection/schemas.go
deleted file mode 100644
index cc320234..00000000
--- a/pkg/kube/collection/schemas.go
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package collection
-
-import (
- "fmt"
- "github.com/apache/dubbo-kubernetes/operator/pkg/config"
- "github.com/apache/dubbo-kubernetes/operator/pkg/schema"
-)
-
-// Schemas contains metadata about configuration resources.
-type Schemas struct {
- byCollection map[config.GroupVersionKind]schema.Schema
- byAddOrder []schema.Schema
-}
-
-// FindByGroupVersionAliasesKind searches and returns the first schema with the given GVK,
-// if not found, it will search for version aliases for the schema to see if there is a match.
-func (s Schemas) FindByGroupVersionAliasesKind(gvk config.GroupVersionKind) (schema.Schema, bool) {
- for _, rs := range s.byAddOrder {
- for _, va := range rs.GroupVersionAliasKinds() {
- if va == gvk {
- return rs, true
- }
- }
- }
- return nil, false
-}
-
-// SchemasBuilder is a builder for the schemas type.
-type SchemasBuilder struct {
- schemas Schemas
-}
-
-// NewSchemasBuilder returns a new instance of SchemasBuilder.
-func NewSchemasBuilder() *SchemasBuilder {
- s := Schemas{
- byCollection: make(map[config.GroupVersionKind]schema.Schema),
- }
- return &SchemasBuilder{schemas: s}
-}
-
-// Add a new collection to the schemas.
-func (b *SchemasBuilder) Add(s schema.Schema) error {
- if _, found := b.schemas.byCollection[s.GroupVersionKind()]; found {
- return fmt.Errorf("collection already exists: %v", s.GroupVersionKind())
- }
- b.schemas.byCollection[s.GroupVersionKind()] = s
- b.schemas.byAddOrder = append(b.schemas.byAddOrder, s)
- return nil
-}
-
-// MustAdd calls Add and panics if it fails.
-func (b *SchemasBuilder) MustAdd(s schema.Schema) *SchemasBuilder {
- if err := b.Add(s); err != nil {
- panic(fmt.Sprintf("SchemasBuilder.MustAdd: %v", err))
- }
- return b
-}
-
-// Build a new schemas from this SchemasBuilder.
-func (b *SchemasBuilder) Build() Schemas {
- s := b.schemas
- b.schemas = Schemas{}
- return s
-}
diff --git a/pkg/kube/collections/collections.go b/pkg/kube/collections/collections.go
deleted file mode 100644
index 9916e6e0..00000000
--- a/pkg/kube/collections/collections.go
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package collections
-
-import (
- "github.com/apache/dubbo-kubernetes/operator/pkg/schema"
- "github.com/apache/dubbo-kubernetes/pkg/kube/collection"
- k8sioapiextensionsapiserverpkgapisapiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
- "reflect"
-)
-
-var (
- CustomResourceDefinition = schema.Builder{
- Identifier: "CustomResourceDefinition",
- Group: "apiextensions.k8s.io",
- Kind: "CustomResourceDefinition",
- Plural: "customresourcedefinitions",
- Version: "v1",
- Proto: "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.CustomResourceDefinition",
- ReflectType: reflect.TypeOf(&k8sioapiextensionsapiserverpkgapisapiextensionsv1.CustomResourceDefinition{}).Elem(),
- ProtoPackage: "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1",
- ClusterScoped: true,
- Synthetic: false,
- Builtin: true,
- }.MustBuild()
-
- All = collection.NewSchemasBuilder().
- MustAdd(CustomResourceDefinition).
- Build()
-)
diff --git a/pkg/kube/inject/webhook.go b/pkg/kube/inject/webhook.go
index 372ea741..134074b9 100644
--- a/pkg/kube/inject/webhook.go
+++ b/pkg/kube/inject/webhook.go
@@ -50,6 +50,7 @@ type Webhook struct {
env *model.Environment
Config *Config
valuesConfig ValuesConfig
+ revision string
}
func NewWebhook(p WebhookParameters) (*Webhook, error) {
@@ -61,13 +62,14 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) {
watcher: p.Watcher,
meshConfig: p.Env.Mesh(),
env: p.Env,
+ revision: p.Revision,
}
- sidecarConfig, valuesConfig, err := p.Watcher.Get()
+ proxylessConfig, valuesConfig, err := p.Watcher.Get()
if err != nil {
return nil, fmt.Errorf("failed to get initial configuration: %v", err)
}
- if err := wh.updateConfig(sidecarConfig, valuesConfig); err != nil {
+ if err := wh.updateConfig(proxylessConfig, valuesConfig); err != nil {
return nil, fmt.Errorf("failed to process webhook config: %v", err)
}
@@ -84,10 +86,11 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) {
}
type WebhookParameters struct {
- Watcher Watcher
- Port int
- Env *model.Environment
- Mux *http.ServeMux
+ Watcher Watcher
+ Port int
+ Env *model.Environment
+ Mux *http.ServeMux
+ Revision string
}
type ValuesConfig struct {
@@ -221,7 +224,6 @@ type InjectionParameters struct {
pod *corev1.Pod
deployMeta types.NamespacedName
namespace *corev1.Namespace
- nativeSidecar bool
typeMeta metav1.TypeMeta
templates map[string]*template.Template
defaultTemplate []string
@@ -346,6 +348,11 @@ func (wh *Webhook) inject(ar *kube.AdmissionReview, path string) *kube.Admission
pod.ManagedFields = nil
+ potentialPodName(pod.ObjectMeta)
+ if pod.ObjectMeta.Namespace == "" {
+ pod.ObjectMeta.Namespace = req.Namespace
+ }
+
klog.Infof("Process proxyless injection request")
proxyConfig := wh.env.GetProxyConfigOrDefault(pod.Namespace, pod.Labels, pod.Annotations, wh.meshConfig)
@@ -362,6 +369,7 @@ func (wh *Webhook) inject(ar *kube.AdmissionReview, path string) *kube.Admission
valuesConfig: wh.valuesConfig,
injectedAnnotations: wh.Config.InjectedAnnotations,
proxyEnvs: parseInjectEnvs(path),
+ revision: wh.revision,
}
patchBytes, err := injectPod(params)
diff --git a/pkg/model/proxy.go b/pkg/model/proxy.go
new file mode 100644
index 00000000..e9924c6d
--- /dev/null
+++ b/pkg/model/proxy.go
@@ -0,0 +1,8 @@
+package model
+
+import "github.com/apache/dubbo-kubernetes/pkg/cluster"
+
+type NodeMetadata struct {
+ Generator string `json:"GENERATOR,omitempty"`
+ ClusterID cluster.ID `json:"CLUSTER_ID,omitempty"`
+}
diff --git a/pkg/webhooks/validation/controller/controller.go b/pkg/webhooks/validation/controller/controller.go
index 01208422..4745ffcf 100644
--- a/pkg/webhooks/validation/controller/controller.go
+++ b/pkg/webhooks/validation/controller/controller.go
@@ -43,8 +43,9 @@ type Controller struct {
webhooks kclient.Client[*kubeApiAdmission.ValidatingWebhookConfiguration]
}
-func NewValidatingWebhookController(client kube.Client, ns string, caBundleWatcher *keycertbundle.Watcher) *Controller {
+func NewValidatingWebhookController(client kube.Client, revision, ns string, caBundleWatcher *keycertbundle.Watcher) *Controller {
o := Options{
+ Revision: revision,
WatchedNamespace: ns,
CABundleWatcher: caBundleWatcher,
ServiceName: "dubbod",
diff --git a/pkg/webhooks/webhookpatch.go b/pkg/webhooks/webhookpatch.go
index 71c7b7b4..9a7d5522 100644
--- a/pkg/webhooks/webhookpatch.go
+++ b/pkg/webhooks/webhookpatch.go
@@ -40,8 +40,9 @@ type WebhookCertPatcher struct {
webhooks kclient.Client[*v1.MutatingWebhookConfiguration]
}
-func NewWebhookCertPatcher(client kubelib.Client, webhookName string, caBundleWatcher *keycertbundle.Watcher) (*WebhookCertPatcher, error) {
+func NewWebhookCertPatcher(client kubelib.Client, webhookName, revision string, caBundleWatcher *keycertbundle.Watcher) (*WebhookCertPatcher, error) {
p := &WebhookCertPatcher{
+ revision: revision,
webhookName: webhookName,
CABundleWatcher: caBundleWatcher,
}
@@ -119,13 +120,6 @@ func (w *WebhookCertPatcher) patchMutatingWebhookConfig(webhookConfigName string
return err
}
-func (w *WebhookCertPatcher) Run(stopChan <-chan struct{}) {
- go w.startCaBundleWatcher(stopChan)
- w.webhooks.Start(stopChan)
- kubelib.WaitForCacheSync("webhook patcher", stopChan, w.webhooks.HasSynced)
- w.queue.Run(stopChan)
-}
-
func (w *WebhookCertPatcher) startCaBundleWatcher(stop <-chan struct{}) {
id, watchCh := w.CABundleWatcher.AddWatcher()
defer w.CABundleWatcher.RemoveWatcher(id)
@@ -140,3 +134,14 @@ func (w *WebhookCertPatcher) startCaBundleWatcher(stop <-chan struct{}) {
}
}
}
+
+func (w *WebhookCertPatcher) Run(stopChan <-chan struct{}) {
+ go w.startCaBundleWatcher(stopChan)
+ w.webhooks.Start(stopChan)
+ kubelib.WaitForCacheSync("webhook patcher", stopChan, w.webhooks.HasSynced)
+ w.queue.Run(stopChan)
+}
+
+func (w *WebhookCertPatcher) HasSynced() bool {
+ return w.queue.HasSynced()
+}
diff --git a/pkg/xds/server.go b/pkg/xds/server.go
index f0aa72ab..1527bf97 100644
--- a/pkg/xds/server.go
+++ b/pkg/xds/server.go
@@ -25,7 +25,9 @@ import (
discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
+ "google.golang.org/protobuf/types/known/anypb"
"k8s.io/klog/v2"
+ "strings"
"time"
)
@@ -69,13 +71,9 @@ type Watcher interface {
type ConnectionContext interface {
XdsConnection() *Connection
Watcher() Watcher
- // Initialize checks the first request.
Initialize(node *core.Node) error
- // Close discards the connection.
Close()
- // Process responds to a discovery request.
Process(req *discovery.DiscoveryRequest) error
- // Push responds to a push event queue
Push(ev any) error
}
@@ -290,8 +288,35 @@ func ShouldRespond(w Watcher, id string, request *discovery.DiscoveryRequest) (b
}
}
+func ResourcesToAny(r Resources) []*anypb.Any {
+ a := make([]*anypb.Any, 0, len(r))
+ for _, rr := range r {
+ a = append(a, rr.Resource)
+ }
+ return a
+}
+
func Send(ctx ConnectionContext, res *discovery.DiscoveryResponse) error {
- return nil
+ conn := ctx.XdsConnection()
+ sendResponse := func() error {
+ return conn.stream.Send(res)
+ }
+ err := sendResponse()
+ if err == nil {
+ if res.Nonce != "" && !strings.HasPrefix(res.TypeUrl, model.DebugType) {
+ ctx.Watcher().UpdateWatchedResource(res.TypeUrl, func(wr *WatchedResource) *WatchedResource {
+ if wr == nil {
+ wr = &WatchedResource{TypeUrl: res.TypeUrl}
+ }
+ wr.NonceSent = res.Nonce
+ wr.LastSendTime = time.Now()
+ return wr
+ })
+ }
+ } else if status.Convert(err).Code() == codes.DeadlineExceeded {
+ klog.Infof("Timeout writing %s: %v", conn.conID, model.GetShortType(res.TypeUrl))
+ }
+ return err
}
type ResourceDelta struct {
diff --git a/sail/cmd/sail-agent/options/options.go b/sail/cmd/sail-agent/options/options.go
index 6088635a..d5360fb6 100644
--- a/sail/cmd/sail-agent/options/options.go
+++ b/sail/cmd/sail-agent/options/options.go
@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/apache/dubbo-kubernetes/pkg/config/constants"
"github.com/apache/dubbo-kubernetes/pkg/env"
- "github.com/apache/dubbo-kubernetes/pkg/jwt"
"github.com/apache/dubbo-kubernetes/pkg/security"
"path/filepath"
)
@@ -13,8 +12,6 @@ var (
dubbodSAN = env.Register("DUBBOD_SAN", "",
"Override the ServerName used to validate Dubbod certificate. "+
"Can be used as an alternative to setting /etc/hosts for VMs - discovery address will be an IP:port")
- jwtPolicy = env.Register("JWT_POLICY", jwt.PolicyThirdParty,
- "The JWT validation policy.")
workloadIdentitySocketFile = env.Register("WORKLOAD_IDENTITY_SOCKET_FILE", security.DefaultWorkloadIdentitySocketFile,
fmt.Sprintf("SPIRE workload identity SDS socket filename. If set, an SDS socket with this name must exist at %s", security.WorkloadIdentityPath)).Get()
grpcBootstrapEnv = env.Register("GRPC_XDS_BOOTSTRAP", filepath.Join(constants.ConfigPathDir, "grpc-bootstrap.json"),
diff --git a/sail/cmd/sail-discovery/app/cmd.go b/sail/cmd/sail-discovery/app/cmd.go
index 2b0f24dd..59dd2fce 100644
--- a/sail/cmd/sail-discovery/app/cmd.go
+++ b/sail/cmd/sail-discovery/app/cmd.go
@@ -81,6 +81,7 @@ func newDiscoveryCommand() *cobra.Command {
cmd.WaitSignal(stop)
+ discoveryServer.WaitUntilCompletion()
return nil
},
}
diff --git a/sail/pkg/bootstrap/configcontroller.go b/sail/pkg/bootstrap/configcontroller.go
index c77a9825..a6d8e35d 100644
--- a/sail/pkg/bootstrap/configcontroller.go
+++ b/sail/pkg/bootstrap/configcontroller.go
@@ -31,6 +31,7 @@ import (
"github.com/apache/dubbo-kubernetes/sail/pkg/config/memory"
dubboCredentials "github.com/apache/dubbo-kubernetes/sail/pkg/credentials"
"github.com/apache/dubbo-kubernetes/sail/pkg/credentials/kube"
+ "github.com/apache/dubbo-kubernetes/sail/pkg/model"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
@@ -193,6 +194,11 @@ func (s *Server) initK8SConfigStore(args *SailArgs) error {
}
configController := s.makeKubeConfigController(args)
s.ConfigStores = append(s.ConfigStores, configController)
+ s.XDSServer.ConfigUpdate(&model.PushRequest{
+ Full: true,
+ Reason: model.NewReasonStats(model.GlobalUpdate),
+ Forced: true,
+ })
return nil
}
diff --git a/sail/pkg/bootstrap/options.go b/sail/pkg/bootstrap/options.go
index d262d4b3..f1c99bb5 100644
--- a/sail/pkg/bootstrap/options.go
+++ b/sail/pkg/bootstrap/options.go
@@ -56,6 +56,7 @@ type SailArgs struct {
KeepaliveOptions *keepalive.Options
KrtDebugger *krt.DebugHandler `json:"-"`
JwtRule string
+ Revision string
}
type DiscoveryServerOptions struct {
@@ -89,9 +90,12 @@ func NewSailArgs(initFuncs ...func(*SailArgs)) *SailArgs {
return p
}
+var Revision = env.Register("REVISION", "", "").Get()
+
func (p *SailArgs) applyDefaults() {
p.Namespace = PodNamespace
p.PodName = PodName
+ p.Revision = Revision
p.KeepaliveOptions = keepalive.DefaultOption()
p.RegistryOptions.ClusterRegistriesNamespace = p.Namespace
}
diff --git a/sail/pkg/bootstrap/proxylessinjector.go b/sail/pkg/bootstrap/proxylessinjector.go
index e8f0e9df..5297d263 100644
--- a/sail/pkg/bootstrap/proxylessinjector.go
+++ b/sail/pkg/bootstrap/proxylessinjector.go
@@ -39,7 +39,7 @@ func (s *Server) initProxylessInjector(args *SailArgs) (*inject.Webhook, error)
return nil, err
}
} else if s.kubeClient != nil {
- configMapName := getInjectorConfigMapName()
+ configMapName := getInjectorConfigMapName(args.Revision)
cms := s.kubeClient.Kube().CoreV1().ConfigMaps(args.Namespace)
if _, err := cms.Get(context.TODO(), configMapName, metav1.GetOptions{}); err != nil {
if errors.IsNotFound(err) {
@@ -57,9 +57,10 @@ func (s *Server) initProxylessInjector(args *SailArgs) (*inject.Webhook, error)
klog.Info("initializing proxyless injector")
parameters := inject.WebhookParameters{
- Watcher: watcher,
- Env: s.environment,
- Mux: s.httpsMux,
+ Watcher: watcher,
+ Env: s.environment,
+ Mux: s.httpsMux,
+ Revision: args.Revision,
}
wh, err := inject.NewWebhook(parameters)
@@ -69,7 +70,7 @@ func (s *Server) initProxylessInjector(args *SailArgs) (*inject.Webhook, error)
if features.InjectionWebhookConfigName != "" {
s.addStartFunc("injection patcher", func(stop <-chan struct{}) error {
- patcher, err := webhooks.NewWebhookCertPatcher(s.kubeClient, webhookName, s.dubbodCertBundleWatcher)
+ patcher, err := webhooks.NewWebhookCertPatcher(s.kubeClient, webhookName, args.Revision, s.dubbodCertBundleWatcher)
if err != nil {
klog.Errorf("failed to create webhook cert patcher: %v", err)
return nil
@@ -87,7 +88,10 @@ func (s *Server) initProxylessInjector(args *SailArgs) (*inject.Webhook, error)
return wh, nil
}
-func getInjectorConfigMapName() string {
+func getInjectorConfigMapName(revision string) string {
name := defaultInjectorConfigMapName
- return name
+ if revision == "" || revision == "default" {
+ return name
+ }
+ return name + "-" + revision
}
diff --git a/sail/pkg/bootstrap/server.go b/sail/pkg/bootstrap/server.go
index 927fabeb..3812cb02 100644
--- a/sail/pkg/bootstrap/server.go
+++ b/sail/pkg/bootstrap/server.go
@@ -23,8 +23,11 @@ import (
"crypto/x509"
"fmt"
"github.com/apache/dubbo-kubernetes/pkg/cluster"
+ "github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/constants"
"github.com/apache/dubbo-kubernetes/pkg/config/mesh"
+ "github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
+ "github.com/apache/dubbo-kubernetes/pkg/ctrlz"
"github.com/apache/dubbo-kubernetes/pkg/filewatcher"
"github.com/apache/dubbo-kubernetes/pkg/h2c"
dubbokeepalive "github.com/apache/dubbo-kubernetes/pkg/keepalive"
@@ -157,7 +160,8 @@ func NewServer(args *SailArgs, initFuncs ...func(*Server)) (*Server, error) {
s.XDSServer = xds.NewDiscoveryServer(e, args.RegistryOptions.KubeOptions.ClusterAliases, args.KrtDebugger)
// TODO xds cache
- // TODO initReadinessProbes
+
+ s.initReadinessProbes()
s.initServers(args)
@@ -239,12 +243,16 @@ func NewServer(args *SailArgs, initFuncs ...func(*Server)) (*Server, error) {
}
}
- // TODO initRegistryEventHandlers?
+ s.initRegistryEventHandlers()
s.initDiscoveryService()
s.startCA(caOpts)
+ if args.CtrlZOptions != nil {
+ _, _ = ctrlz.Run(args.CtrlZOptions)
+ }
+
if s.kubeClient != nil {
s.addStartFunc("kube client", func(stop <-chan struct{}) error {
s.kubeClient.RunAndWait(stop)
@@ -321,6 +329,39 @@ func (s *Server) initDiscoveryService() {
})
}
+func (s *Server) initRegistryEventHandlers() {
+ klog.Info("initializing registry event handlers")
+
+ if s.configController != nil {
+ configHandler := func(prev config.Config, curr config.Config, event model.Event) {}
+ schemas := collections.Sail.All()
+ for _, schema := range schemas {
+ s.configController.RegisterEventHandler(schema.GroupVersionKind(), configHandler)
+ }
+ }
+}
+
+func (s *Server) initReadinessProbes() {
+ probes := map[string]readinessProbe{
+ "discovery": func() bool {
+ return s.XDSServer.IsServerReady()
+ },
+ "proxyless injector": func() bool {
+ return s.readinessFlags.proxylessInjectorReady.Load()
+ },
+ "config validation": func() bool {
+ return s.readinessFlags.configValidationReady.Load()
+ },
+ }
+ for name, probe := range probes {
+ s.addReadinessProbe(name, probe)
+ }
+}
+
+func (s *Server) addReadinessProbe(name string, fn readinessProbe) {
+ s.readinessProbes[name] = fn
+}
+
func (s *Server) startCA(caOpts *caOptions) {
if s.CA == nil && s.RA == nil {
return
@@ -559,6 +600,10 @@ func (s *Server) getDubbodCertificate(*tls.ClientHelloInfo) (*tls.Certificate, e
return nil, fmt.Errorf("cert not initialized")
}
+func (s *Server) WaitUntilCompletion() {
+ s.server.Wait()
+}
+
func (s *Server) serveHTTP() error {
// At this point we are ready - start Http Listener so that it can respond to readiness events.
httpListener, err := net.Listen("tcp", s.httpServer.Addr)
@@ -626,6 +671,12 @@ func (s *Server) initSDSServer() {
if !features.EnableXDSIdentityCheck {
// Make sure we have security
klog.Warningf("skipping Kubernetes credential reader; SAIL_ENABLE_XDS_IDENTITY_CHECK must be set to true for this feature.")
+ } else {
+ // s.XDSServer.ConfigUpdate(&model.PushRequest{
+ // Full: false,
+ // ConfigsUpdated: sets.New(model.ConfigKey{Kind: k, Name: name, Namespace: namespace}),
+ // Reason: model.NewReasonStats(model.SecretTrigger),
+ // })
}
}
@@ -718,7 +769,7 @@ func (s *Server) waitForCacheSync(stop <-chan struct{}) bool {
start := time.Now()
klog.Info("Waiting for caches to be synced")
if !kubelib.WaitForCacheSync("server", stop, s.cachesSynced) {
- klog.Info("Failed waiting for cache sync")
+ klog.Errorf("Failed waiting for cache sync")
return false
}
klog.Infof("All controller caches have been synced up in %v", time.Since(start))
diff --git a/sail/pkg/bootstrap/servicecontroller.go b/sail/pkg/bootstrap/servicecontroller.go
index f324fc9c..70cac1bd 100644
--- a/sail/pkg/bootstrap/servicecontroller.go
+++ b/sail/pkg/bootstrap/servicecontroller.go
@@ -47,7 +47,7 @@ func (s *Server) initServiceControllers(args *SailArgs) error {
// initKubeRegistry creates all the k8s service controllers under this pilot
func (s *Server) initKubeRegistry(args *SailArgs) (err error) {
args.RegistryOptions.KubeOptions.ClusterID = s.clusterID
- // TODO reversion
+ args.RegistryOptions.KubeOptions.Revision = args.Revision
args.RegistryOptions.KubeOptions.KrtDebugger = args.KrtDebugger
// TODO metrics
args.RegistryOptions.KubeOptions.XDSUpdater = s.XDSServer
@@ -55,6 +55,5 @@ func (s *Server) initKubeRegistry(args *SailArgs) (err error) {
args.RegistryOptions.KubeOptions.MeshWatcher = s.environment.Watcher
args.RegistryOptions.KubeOptions.SystemNamespace = args.Namespace
args.RegistryOptions.KubeOptions.MeshServiceController = s.ServiceController()
- // TODO NewMulticluster
return
}
diff --git a/sail/pkg/bootstrap/validation.go b/sail/pkg/bootstrap/validation.go
index 5de2ae57..bbe41c69 100644
--- a/sail/pkg/bootstrap/validation.go
+++ b/sail/pkg/bootstrap/validation.go
@@ -26,7 +26,7 @@ func (s *Server) initConfigValidation(args *SailArgs) error {
s.addStartFunc("validation controller", func(stop <-chan struct{}) error {
klog.Infof("Starting validation controller")
go controller.NewValidatingWebhookController(
- s.kubeClient, args.Namespace, s.dubbodCertBundleWatcher).Run(stop)
+ s.kubeClient, args.Revision, args.Namespace, s.dubbodCertBundleWatcher).Run(stop)
return nil
})
}
diff --git a/sail/pkg/config/kube/crdclient/types.go b/sail/pkg/config/kube/crdclient/types.go
index 7bf590f5..778b833d 100644
--- a/sail/pkg/config/kube/crdclient/types.go
+++ b/sail/pkg/config/kube/crdclient/types.go
@@ -22,11 +22,6 @@ import (
func create(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.AuthorizationPolicy:
- return c.Dubbo().SecurityV1().AuthorizationPolicies(cfg.Namespace).Create(context.TODO(), &apiistioioapisecurityv1.AuthorizationPolicy{
- ObjectMeta: objMeta,
- Spec: *(cfg.Spec.(*istioioapisecurityv1beta1.AuthorizationPolicy)),
- }, metav1.CreateOptions{})
case gvk.DestinationRule:
return c.Dubbo().NetworkingV1().DestinationRules(cfg.Namespace).Create(context.TODO(), &apiistioioapinetworkingv1.DestinationRule{
ObjectMeta: objMeta,
@@ -54,11 +49,6 @@ func create(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1
func update(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.AuthorizationPolicy:
- return c.Dubbo().SecurityV1().AuthorizationPolicies(cfg.Namespace).Update(context.TODO(), &apiistioioapisecurityv1.AuthorizationPolicy{
- ObjectMeta: objMeta,
- Spec: *(cfg.Spec.(*istioioapisecurityv1beta1.AuthorizationPolicy)),
- }, metav1.UpdateOptions{})
case gvk.DestinationRule:
return c.Dubbo().NetworkingV1().DestinationRules(cfg.Namespace).Update(context.TODO(), &apiistioioapinetworkingv1.DestinationRule{
ObjectMeta: objMeta,
@@ -86,11 +76,6 @@ func update(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1
func updateStatus(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.AuthorizationPolicy:
- return c.Dubbo().SecurityV1().AuthorizationPolicies(cfg.Namespace).UpdateStatus(context.TODO(), &apiistioioapisecurityv1.AuthorizationPolicy{
- ObjectMeta: objMeta,
- Status: *(cfg.Status.(*istioioapimetav1alpha1.IstioStatus)),
- }, metav1.UpdateOptions{})
case gvk.DestinationRule:
return c.Dubbo().NetworkingV1().DestinationRules(cfg.Namespace).UpdateStatus(context.TODO(), &apiistioioapinetworkingv1.DestinationRule{
ObjectMeta: objMeta,
@@ -121,21 +106,6 @@ func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod co
return nil, fmt.Errorf("gvk mismatch: %v, modified: %v", orig.GroupVersionKind, mod.GroupVersionKind)
}
switch orig.GroupVersionKind {
- case gvk.AuthorizationPolicy:
- oldRes := &apiistioioapisecurityv1.AuthorizationPolicy{
- ObjectMeta: origMeta,
- Spec: *(orig.Spec.(*istioioapisecurityv1beta1.AuthorizationPolicy)),
- }
- modRes := &apiistioioapisecurityv1.AuthorizationPolicy{
- ObjectMeta: modMeta,
- Spec: *(mod.Spec.(*istioioapisecurityv1beta1.AuthorizationPolicy)),
- }
- patchBytes, err := genPatchBytes(oldRes, modRes, typ)
- if err != nil {
- return nil, err
- }
- return c.Dubbo().SecurityV1().AuthorizationPolicies(orig.Namespace).
- Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
case gvk.DestinationRule:
oldRes := &apiistioioapinetworkingv1.DestinationRule{
ObjectMeta: origMeta,
@@ -150,7 +120,7 @@ func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod co
return nil, err
}
return c.Dubbo().NetworkingV1().DestinationRules(orig.Namespace).
- Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
+ Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "sail-discovery"})
case gvk.PeerAuthentication:
oldRes := &apiistioioapisecurityv1.PeerAuthentication{
ObjectMeta: origMeta,
@@ -165,7 +135,7 @@ func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod co
return nil, err
}
return c.Dubbo().SecurityV1().PeerAuthentications(orig.Namespace).
- Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
+ Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "sail-discovery"})
case gvk.RequestAuthentication:
oldRes := &apiistioioapisecurityv1.RequestAuthentication{
ObjectMeta: origMeta,
@@ -180,7 +150,7 @@ func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod co
return nil, err
}
return c.Dubbo().SecurityV1().RequestAuthentications(orig.Namespace).
- Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
+ Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "sail-discovery"})
case gvk.VirtualService:
oldRes := &apiistioioapinetworkingv1.VirtualService{
ObjectMeta: origMeta,
@@ -195,7 +165,7 @@ func patch(c kube.Client, orig config.Config, origMeta metav1.ObjectMeta, mod co
return nil, err
}
return c.Dubbo().NetworkingV1().VirtualServices(orig.Namespace).
- Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "pilot-discovery"})
+ Patch(context.TODO(), orig.Name, typ, patchBytes, metav1.PatchOptions{FieldManager: "sail-discovery"})
default:
return nil, fmt.Errorf("unsupported type: %v", orig.GroupVersionKind)
}
@@ -207,8 +177,6 @@ func delete(c kube.Client, typ config.GroupVersionKind, name, namespace string,
deleteOptions.Preconditions = &metav1.Preconditions{ResourceVersion: resourceVersion}
}
switch typ {
- case gvk.AuthorizationPolicy:
- return c.Dubbo().SecurityV1().AuthorizationPolicies(namespace).Delete(context.TODO(), name, deleteOptions)
case gvk.DestinationRule:
return c.Dubbo().NetworkingV1().DestinationRules(namespace).Delete(context.TODO(), name, deleteOptions)
case gvk.PeerAuthentication:
@@ -223,25 +191,6 @@ func delete(c kube.Client, typ config.GroupVersionKind, name, namespace string,
}
var translationMap = map[config.GroupVersionKind]func(r runtime.Object) config.Config{
- gvk.AuthorizationPolicy: func(r runtime.Object) config.Config {
- obj := r.(*apiistioioapisecurityv1.AuthorizationPolicy)
- return config.Config{
- Meta: config.Meta{
- GroupVersionKind: gvk.AuthorizationPolicy,
- Name: obj.Name,
- Namespace: obj.Namespace,
- Labels: obj.Labels,
- Annotations: obj.Annotations,
- ResourceVersion: obj.ResourceVersion,
- CreationTimestamp: obj.CreationTimestamp.Time,
- OwnerReferences: obj.OwnerReferences,
- UID: string(obj.UID),
- Generation: obj.Generation,
- },
- Spec: &obj.Spec,
- Status: &obj.Status,
- }
- },
gvk.ConfigMap: func(r runtime.Object) config.Config {
obj := r.(*k8sioapicorev1.ConfigMap)
return config.Config{
@@ -333,24 +282,6 @@ var translationMap = map[config.GroupVersionKind]func(r runtime.Object) config.C
Status: &obj.Status,
}
},
- gvk.MutatingWebhookConfiguration: func(r runtime.Object) config.Config {
- obj := r.(*k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration)
- return config.Config{
- Meta: config.Meta{
- GroupVersionKind: gvk.MutatingWebhookConfiguration,
- Name: obj.Name,
- Namespace: obj.Namespace,
- Labels: obj.Labels,
- Annotations: obj.Annotations,
- ResourceVersion: obj.ResourceVersion,
- CreationTimestamp: obj.CreationTimestamp.Time,
- OwnerReferences: obj.OwnerReferences,
- UID: string(obj.UID),
- Generation: obj.Generation,
- },
- Spec: obj,
- }
- },
gvk.Namespace: func(r runtime.Object) config.Config {
obj := r.(*k8sioapicorev1.Namespace)
return config.Config{
@@ -480,6 +411,24 @@ var translationMap = map[config.GroupVersionKind]func(r runtime.Object) config.C
Spec: &obj.Spec,
}
},
+ gvk.MutatingWebhookConfiguration: func(r runtime.Object) config.Config {
+ obj := r.(*k8sioapiadmissionregistrationv1.MutatingWebhookConfiguration)
+ return config.Config{
+ Meta: config.Meta{
+ GroupVersionKind: gvk.MutatingWebhookConfiguration,
+ Name: obj.Name,
+ Namespace: obj.Namespace,
+ Labels: obj.Labels,
+ Annotations: obj.Annotations,
+ ResourceVersion: obj.ResourceVersion,
+ CreationTimestamp: obj.CreationTimestamp.Time,
+ OwnerReferences: obj.OwnerReferences,
+ UID: string(obj.UID),
+ Generation: obj.Generation,
+ },
+ Spec: obj,
+ }
+ },
gvk.ValidatingWebhookConfiguration: func(r runtime.Object) config.Config {
obj := r.(*k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration)
return config.Config{
diff --git a/sail/pkg/features/tuning.go b/sail/pkg/features/tuning.go
index 1b29b630..1faf9a8d 100644
--- a/sail/pkg/features/tuning.go
+++ b/sail/pkg/features/tuning.go
@@ -19,6 +19,7 @@ package features
import (
"github.com/apache/dubbo-kubernetes/pkg/env"
+ "runtime"
"time"
)
@@ -36,8 +37,63 @@ var (
"Sets the max receive buffer size of gRPC stream in bytes.",
).Get()
- XDSCacheMaxSize = env.Register("SAIL_XDS_CACHE_SIZE", 60000,
- "The maximum number of cache entries for the XDS cache.").Get()
- XDSCacheIndexClearInterval = env.Register("SAIL_XDS_CACHE_INDEX_CLEAR_INTERVAL", 5*time.Second,
- "The interval for xds cache index clearing.").Get()
+ RequestLimit = func() float64 {
+ v := env.Register(
+ "SAIL_MAX_REQUESTS_PER_SECOND",
+ 0.0,
+ "Limits the number of incoming XDS requests per second. On larger machines this can be increased to handle more proxies concurrently. "+
+ "If set to 0 or unset, the max will be automatically determined based on the machine size",
+ ).Get()
+ if v > 0 {
+ return v
+ }
+ procs := runtime.GOMAXPROCS(0)
+ // Heuristic to scale with cores. We end up with...
+ // 1: 20
+ // 2: 25
+ // 4: 35
+ // 32: 100
+ return min(float64(15+5*procs), 100.0)
+ }()
+
+ DebounceAfter = env.Register(
+ "SAIL_DEBOUNCE_AFTER",
+ 100*time.Millisecond,
+ "The delay added to config/registry events for debouncing. This will delay the push by "+
+ "at least this interval. If no change is detected within this period, the push will happen, "+
+ " otherwise we'll keep delaying until things settle, up to a max of PILOT_DEBOUNCE_MAX.",
+ ).Get()
+
+ DebounceMax = env.Register(
+ "SAIL_DEBOUNCE_MAX",
+ 10*time.Second,
+ "The maximum amount of time to wait for events while debouncing. If events keep showing up with no breaks "+
+ "for this time, we'll trigger a push.",
+ ).Get()
+
+ EnableEDSDebounce = env.Register(
+ "SAIL_ENABLE_EDS_DEBOUNCE",
+ true,
+ "If enabled, Sail will include EDS pushes in the push debouncing, configured by PILOT_DEBOUNCE_AFTER and PILOT_DEBOUNCE_MAX."+
+ " EDS pushes may be delayed, but there will be fewer pushes. By default this is enabled",
+ ).Get()
+
+ PushThrottle = func() int {
+ v := env.Register(
+ "PILOT_PUSH_THROTTLE",
+ 0,
+ "Limits the number of concurrent pushes allowed. On larger machines this can be increased for faster pushes. "+
+ "If set to 0 or unset, the max will be automatically determined based on the machine size",
+ ).Get()
+ if v > 0 {
+ return v
+ }
+ procs := runtime.GOMAXPROCS(0)
+ // Heuristic to scale with cores. We end up with...
+ // 1: 20
+ // 2: 25
+ // 4: 35
+ // 32: 100
+ return min(15+5*procs, 100)
+ }()
)
diff --git a/sail/pkg/features/xds.go b/sail/pkg/features/xds.go
deleted file mode 100644
index 1d44dd4a..00000000
--- a/sail/pkg/features/xds.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package features
-
-import "github.com/apache/dubbo-kubernetes/pkg/env"
-
-var (
- EnableXDSCaching = env.Register("NAVIGATOR_ENABLE_XDS_CACHE", true,
- "If true, Navigator will cache XDS responses.").Get()
-
- EnableCDSCaching = env.Register("NAVIGATOR_ENABLE_CDS_CACHE", true,
- "If true, Navigator will cache CDS responses. Note: this depends on NAVIGATOR_ENABLE_XDS_CACHE.").Get()
-
- EnableRDSCaching = env.Register("NAVIGATOR_ENABLE_RDS_CACHE", true,
- "If true, Navigator will cache RDS responses. Note: this depends on NAVIGATOR_ENABLE_XDS_CACHE.").Get()
-)
diff --git a/sail/pkg/model/config.go b/sail/pkg/model/config.go
index eead713c..be9a607b 100644
--- a/sail/pkg/model/config.go
+++ b/sail/pkg/model/config.go
@@ -4,7 +4,9 @@ import (
"cmp"
"github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collection"
+ "github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
"github.com/apache/dubbo-kubernetes/pkg/util/hash"
+ "github.com/apache/dubbo-kubernetes/pkg/util/sets"
"sort"
)
@@ -61,3 +63,12 @@ func (key ConfigKey) HashCode() ConfigHash {
h.WriteString(key.Name)
return ConfigHash(h.Sum64())
}
+
+func HasConfigsOfKind(configs sets.Set[ConfigKey], kind kind.Kind) bool {
+ for c := range configs {
+ if c.Kind == kind {
+ return true
+ }
+ }
+ return false
+}
diff --git a/sail/pkg/model/context.go b/sail/pkg/model/context.go
index 4a1ad939..f86b60a3 100644
--- a/sail/pkg/model/context.go
+++ b/sail/pkg/model/context.go
@@ -23,13 +23,20 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/host"
"github.com/apache/dubbo-kubernetes/pkg/config/mesh"
"github.com/apache/dubbo-kubernetes/pkg/config/mesh/meshwatcher"
+ pm "github.com/apache/dubbo-kubernetes/pkg/model"
+ "github.com/apache/dubbo-kubernetes/pkg/util/sets"
"github.com/apache/dubbo-kubernetes/pkg/xds"
+ discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
meshconfig "istio.io/api/mesh/v1alpha1"
"net"
"strconv"
"sync"
+ "time"
)
+type (
+ NodeMetadata = pm.NodeMetadata
+)
type Watcher = meshwatcher.WatcherCollection
type WatchedResource = xds.WatchedResource
@@ -44,11 +51,19 @@ type Environment struct {
NetworkManager *NetworkManager
clusterLocalServices ClusterLocalProvider
DomainSuffix string
+ EndpointIndex *EndpointIndex
}
func NewEnvironment() *Environment {
return &Environment{
- pushContext: NewPushContext(),
+ pushContext: NewPushContext(),
+ EndpointIndex: NewEndpointIndex(),
+ }
+}
+
+func NewEndpointIndex() *EndpointIndex {
+ return &EndpointIndex{
+ shardsBySvc: make(map[string]map[string]*EndpointShards),
}
}
@@ -123,4 +138,69 @@ func (e *Environment) InitNetworksManager(updater XDSUpdater) (err error) {
return
}
-type Proxy struct{}
+type Proxy struct {
+ sync.RWMutex
+ XdsResourceGenerator XdsResourceGenerator
+ LastPushContext *PushContext
+ LastPushTime time.Time
+ WatchedResources map[string]*WatchedResource
+ ID string
+ Metadata *NodeMetadata
+ IPAddresses []string
+}
+
+func (node *Proxy) GetWatchedResource(typeURL string) *WatchedResource {
+ node.RLock()
+ defer node.RUnlock()
+
+ return node.WatchedResources[typeURL]
+}
+
+func (node *Proxy) DeleteWatchedResource(typeURL string) {
+ node.Lock()
+ defer node.Unlock()
+
+ delete(node.WatchedResources, typeURL)
+}
+
+func (node *Proxy) NewWatchedResource(typeURL string, names []string) {
+ node.Lock()
+ defer node.Unlock()
+
+ node.WatchedResources[typeURL] = &WatchedResource{TypeUrl: typeURL, ResourceNames: sets.New(names...)}
+}
+
+func (node *Proxy) GetID() string {
+ if node == nil {
+ return ""
+ }
+ return node.ID
+}
+
+func (node *Proxy) UpdateWatchedResource(typeURL string, updateFn func(*WatchedResource) *WatchedResource) {
+ node.Lock()
+ defer node.Unlock()
+ r := node.WatchedResources[typeURL]
+ r = updateFn(r)
+ if r != nil {
+ node.WatchedResources[typeURL] = r
+ } else {
+ delete(node.WatchedResources, typeURL)
+ }
+}
+
+func (node *Proxy) IsProxylessGrpc() bool {
+ return node.Metadata != nil && node.Metadata.Generator == "grpc"
+}
+
+type XdsLogDetails struct {
+ Incremental bool
+ AdditionalInfo string
+}
+
+type Resources = []*discovery.Resource
+
+type XdsResourceGenerator interface {
+ // Generate generates the Sotw resources for Xds.
+ Generate(proxy *Proxy, w *WatchedResource, req *PushRequest) (Resources, XdsLogDetails, error)
+}
diff --git a/sail/pkg/model/endpointshards.go b/sail/pkg/model/endpointshards.go
new file mode 100644
index 00000000..43e4cbfe
--- /dev/null
+++ b/sail/pkg/model/endpointshards.go
@@ -0,0 +1,218 @@
+package model
+
+import (
+ "github.com/apache/dubbo-kubernetes/pkg/cluster"
+ "github.com/apache/dubbo-kubernetes/pkg/util/sets"
+ "github.com/apache/dubbo-kubernetes/sail/pkg/serviceregistry/provider"
+ "k8s.io/klog/v2"
+ "sync"
+)
+
+type ShardKey struct {
+ Cluster cluster.ID
+ Provider provider.ID
+}
+
+type EndpointShards struct {
+ sync.RWMutex
+ Shards map[ShardKey][]*DubboEndpoint
+ ServiceAccounts sets.String
+}
+
+type EndpointIndex struct {
+ mu sync.RWMutex
+ shardsBySvc map[string]map[string]*EndpointShards
+}
+
+type PushType int
+
+const (
+ // NoPush does not push any thing.
+ NoPush PushType = iota
+ // IncrementalPush just pushes endpoints.
+ IncrementalPush
+ // FullPush triggers full push - typically used for new services.
+ FullPush
+)
+
+func endpointUpdateRequiresPush(oldDubboEndpoints []*DubboEndpoint, incomingEndpoints []*DubboEndpoint) ([]*DubboEndpoint, bool) {
+ if oldDubboEndpoints == nil {
+ // If there are no old endpoints, we should push with incoming endpoints as there is nothing to compare.
+ return incomingEndpoints, true
+ }
+ needPush := false
+ newDubboEndpoints := make([]*DubboEndpoint, 0, len(incomingEndpoints))
+ // Check if new Endpoints are ready to be pushed. This check
+ // will ensure that if a new pod comes with a non ready endpoint,
+ // we do not unnecessarily push that config to Envoy.
+ omap := make(map[string]*DubboEndpoint, len(oldDubboEndpoints))
+ nmap := make(map[string]*DubboEndpoint, len(newDubboEndpoints))
+ // Add new endpoints only if they are ever ready once to shards
+ // so that full push does not send them from shards.
+ for _, oie := range oldDubboEndpoints {
+ omap[oie.Key()] = oie
+ }
+ for _, nie := range incomingEndpoints {
+ nmap[nie.Key()] = nie
+ }
+ for _, nie := range incomingEndpoints {
+ if oie, exists := omap[nie.Key()]; exists {
+ // If endpoint exists already, we should push if it's changed.
+ // Skip this check if we already decide we need to push to avoid expensive checks
+ if !needPush && !oie.Equals(nie) {
+ needPush = true
+ }
+ newDubboEndpoints = append(newDubboEndpoints, nie)
+ } else {
+ // If the endpoint does not exist in shards that means it is a
+ // new endpoint. Always send new healthy endpoints.
+ // Also send new unhealthy endpoints when SendUnhealthyEndpoints is enabled.
+ // This is OK since we disable panic threshold when SendUnhealthyEndpoints is enabled.
+ if nie.HealthStatus != UnHealthy || nie.SendUnhealthyEndpoints {
+ needPush = true
+ }
+ newDubboEndpoints = append(newDubboEndpoints, nie)
+ }
+ }
+ // Next, check for endpoints that were in old but no longer exist. If there are any, there is a
+ // removal so we need to push an update.
+ if !needPush {
+ for _, oie := range oldDubboEndpoints {
+ if _, f := nmap[oie.Key()]; !f {
+ needPush = true
+ break
+ }
+ }
+ }
+
+ return newDubboEndpoints, needPush
+}
+
+func (e *EndpointIndex) UpdateServiceEndpoints(
+ shard ShardKey,
+ hostname string,
+ namespace string,
+ dubboEndpoints []*DubboEndpoint,
+ logPushType bool,
+) PushType {
+ if len(dubboEndpoints) == 0 {
+ // Should delete the service EndpointShards when endpoints become zero to prevent memory leak,
+ // but we should not delete the keys from EndpointIndex map - that will trigger
+ // unnecessary full push which can become a real problem if a pod is in crashloop and thus endpoints
+ // flip flopping between 1 and 0.
+ e.DeleteServiceShard(shard, hostname, namespace, true)
+ if logPushType {
+ klog.Infof("Incremental push, service %s at shard %v has no endpoints", hostname, shard)
+ } else {
+ klog.Infof("Cache Update, Service %s at shard %v has no endpoints", hostname, shard)
+ }
+ return IncrementalPush
+ }
+
+ pushType := IncrementalPush
+ // Find endpoint shard for this service, if it is available - otherwise create a new one.
+ ep, created := e.GetOrCreateEndpointShard(hostname, namespace)
+ // If we create a new endpoint shard, that means we have not seen the service earlier. We should do a full push.
+ if created {
+ if logPushType {
+ klog.Infof("Full push, new service %s/%s", namespace, hostname)
+ } else {
+ klog.Infof("Cache Update, new service %s/%s", namespace, hostname)
+ }
+ pushType = FullPush
+ }
+
+ ep.Lock()
+ defer ep.Unlock()
+ oldDubboEndpoints := ep.Shards[shard]
+ newDubboEndpoints, needPush := endpointUpdateRequiresPush(oldDubboEndpoints, dubboEndpoints)
+
+ if pushType != FullPush && !needPush {
+ klog.V(2).Infof("No push, either old endpoint health status did not change or new endpoint came with unhealthy status, %v", hostname)
+ pushType = NoPush
+ }
+
+ ep.Shards[shard] = newDubboEndpoints
+
+ // Check if ServiceAccounts have changed. We should do a full push if they have changed.
+ saUpdated := updateShardServiceAccount(ep, hostname)
+
+ // For existing endpoints, we need to do full push if service accounts change.
+ if saUpdated && pushType != FullPush {
+ // Avoid extra logging if already a full push
+ if logPushType {
+ klog.Infof("Full push, service accounts changed, %v", hostname)
+ } else {
+ klog.Infof("Cache Update, service accounts changed, %v", hostname)
+ }
+ pushType = FullPush
+ }
+ return pushType
+}
+
+func (e *EndpointIndex) GetOrCreateEndpointShard(serviceName, namespace string) (*EndpointShards, bool) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+
+ if _, exists := e.shardsBySvc[serviceName]; !exists {
+ e.shardsBySvc[serviceName] = map[string]*EndpointShards{}
+ }
+ if ep, exists := e.shardsBySvc[serviceName][namespace]; exists {
+ return ep, false
+ }
+ // This endpoint is for a service that was not previously loaded.
+ ep := &EndpointShards{
+ Shards: map[ShardKey][]*DubboEndpoint{},
+ ServiceAccounts: sets.String{},
+ }
+ e.shardsBySvc[serviceName][namespace] = ep
+ // TODO clearCacheForService
+ return ep, true
+}
+
+func (e *EndpointIndex) DeleteServiceShard(shard ShardKey, serviceName, namespace string, preserveKeys bool) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ e.deleteServiceInner(shard, serviceName, namespace, preserveKeys)
+}
+
+func updateShardServiceAccount(shards *EndpointShards, serviceName string) bool {
+ oldServiceAccount := shards.ServiceAccounts
+ serviceAccounts := sets.String{}
+ for _, epShards := range shards.Shards {
+ for _, ep := range epShards {
+ if ep.ServiceAccount != "" {
+ serviceAccounts.Insert(ep.ServiceAccount)
+ }
+ }
+ }
+
+ if !oldServiceAccount.Equals(serviceAccounts) {
+ shards.ServiceAccounts = serviceAccounts
+ klog.V(2).Infof("Updating service accounts now, svc %v, before service account %v, after %v",
+ serviceName, oldServiceAccount, serviceAccounts)
+ return true
+ }
+
+ return false
+}
+
+func (e *EndpointIndex) deleteServiceInner(shard ShardKey, serviceName, namespace string, preserveKeys bool) {
+ if e.shardsBySvc[serviceName] == nil ||
+ e.shardsBySvc[serviceName][namespace] == nil {
+ return
+ }
+ epShards := e.shardsBySvc[serviceName][namespace]
+ epShards.Lock()
+ delete(epShards.Shards, shard)
+ // TODO clearCacheForService
+ if !preserveKeys {
+ if len(epShards.Shards) == 0 {
+ delete(e.shardsBySvc[serviceName], namespace)
+ }
+ if len(e.shardsBySvc[serviceName]) == 0 {
+ delete(e.shardsBySvc, serviceName)
+ }
+ }
+ epShards.Unlock()
+}
diff --git a/sail/pkg/model/push_context.go b/sail/pkg/model/push_context.go
index e1e48814..8efbe55e 100644
--- a/sail/pkg/model/push_context.go
+++ b/sail/pkg/model/push_context.go
@@ -23,6 +23,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
"github.com/apache/dubbo-kubernetes/pkg/config/visibility"
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
+ "github.com/apache/dubbo-kubernetes/pkg/xds"
"go.uber.org/atomic"
meshconfig "istio.io/api/mesh/v1alpha1"
"k8s.io/apimachinery/pkg/types"
@@ -30,26 +31,40 @@ import (
"time"
)
+var (
+ LastPushStatus *PushContext
+ // LastPushMutex will protect the LastPushStatus
+ LastPushMutex sync.Mutex
+)
+
type TriggerReason string
const (
+ EndpointUpdate TriggerReason = "endpoint"
UnknownTrigger TriggerReason = "unknown"
+ ProxyRequest TriggerReason = "proxyrequest"
+ GlobalUpdate TriggerReason = "global"
+ SecretTrigger TriggerReason = "secret"
)
+type ProxyPushStatus struct {
+ Proxy string `json:"proxy,omitempty"`
+ Message string `json:"message,omitempty"`
+}
+
type PushContext struct {
- Mesh *meshconfig.MeshConfig `json:"-"`
- initializeMutex sync.Mutex
- InitDone atomic.Bool
- Networks *meshconfig.MeshNetworks
- networkMgr *NetworkManager
- clusterLocalHosts ClusterLocalHosts
- exportToDefaults exportToDefaults
- AuthnPolicies *AuthenticationPolicies `json:"-"`
- AuthzPolicies *AuthorizationPolicies `json:"-"`
- virtualServiceIndex virtualServiceIndex
- destinationRuleIndex destinationRuleIndex
- ServiceIndex serviceIndex
- serviceAccounts map[serviceAccountKey][]string
+ Mesh *meshconfig.MeshConfig `json:"-"`
+ initializeMutex sync.Mutex
+ InitDone atomic.Bool
+ Networks *meshconfig.MeshNetworks
+ networkMgr *NetworkManager
+ clusterLocalHosts ClusterLocalHosts
+ exportToDefaults exportToDefaults
+ ServiceIndex serviceIndex
+ serviceAccounts map[serviceAccountKey][]string
+ PushVersion string
+ ProxyStatus map[string]map[string]ProxyPushStatus
+ proxyStatusMutex sync.RWMutex
}
type serviceAccountKey struct {
@@ -57,22 +72,12 @@ type serviceAccountKey struct {
namespace string
}
-type virtualServiceIndex struct {
-}
-
-type destinationRuleIndex struct {
-}
-
-type consolidatedDestRules struct {
- specificDestRules map[host.Name][]*ConsolidatedDestRule
- wildcardDestRules map[host.Name][]*ConsolidatedDestRule
-}
-
type serviceIndex struct {
privateByNamespace map[string][]*Service
public []*Service
exportedToNamespace map[string][]*Service
HostnameAndNamespace map[host.Name]map[string]*Service `json:"-"`
+ instancesByPort map[string]map[int][]*DubboEndpoint
}
type ConsolidatedDestRule struct {
@@ -86,16 +91,32 @@ type ReasonStats map[TriggerReason]int
type PushRequest struct {
Reason ReasonStats
ConfigsUpdated sets.Set[ConfigKey]
+ AddressesUpdated sets.Set[string]
Forced bool
Full bool
Push *PushContext
- LastPushContext *PushContext
- AddressesUpdated sets.Set[string]
Start time.Time
+ Delta ResourceDelta
}
+type ResourceDelta = xds.ResourceDelta
+
func NewPushContext() *PushContext {
- return &PushContext{}
+ return &PushContext{
+ // ServiceIndex: serviceIndex{},
+ // ProxyStatus: map[string]map[string]ProxyPushStatus{},
+ // serviceAccounts: map[serviceAccountKey][]string{},
+ }
+}
+
+func newServiceIndex() serviceIndex {
+ return serviceIndex{
+ public: []*Service{},
+ privateByNamespace: map[string][]*Service{},
+ exportedToNamespace: map[string][]*Service{},
+ HostnameAndNamespace: map[host.Name]map[string]*Service{},
+ instancesByPort: map[string]map[int][]*DubboEndpoint{},
+ }
}
type ConfigKey struct {
@@ -122,7 +143,10 @@ func (pr *PushRequest) CopyMerge(other *PushRequest) *PushRequest {
return merged
}
-type XDSUpdater interface{}
+type XDSUpdater interface {
+ EDSUpdate(shard ShardKey, hostname string, namespace string, entry []*DubboEndpoint)
+ ConfigUpdate(req *PushRequest)
+}
func (ps *PushContext) InitContext(env *Environment, oldPushContext *PushContext, pushReq *PushRequest) {
ps.initializeMutex.Lock()
@@ -179,86 +203,9 @@ func (ps *PushContext) initDefaultExportMaps() {
}
}
-func (ps *PushContext) initServiceRegistry(env *Environment, configsUpdate sets.Set[ConfigKey]) {
-
-}
-
-func (ps *PushContext) initServiceAccounts(env *Environment, services []*Service) {
-}
-
-func (ps *PushContext) initVirtualServices(env *Environment) {
-}
-
-func (ps *PushContext) initDestinationRules(env *Environment) {
-}
-
-func (ps *PushContext) initAuthnPolicies(env *Environment) {
- ps.AuthnPolicies = initAuthenticationPolicies(env)
-}
-
-func (ps *PushContext) initAuthorizationPolicies(env *Environment) {
- ps.AuthzPolicies = GetAuthorizationPolicies(env)
-}
-
-func (ps *PushContext) createNewContext(env *Environment) {
- ps.initServiceRegistry(env, nil)
- ps.initVirtualServices(env)
- ps.initDestinationRules(env)
- ps.initAuthnPolicies(env)
- ps.initAuthorizationPolicies(env)
-}
+func (ps *PushContext) createNewContext(env *Environment) {}
func (ps *PushContext) updateContext(env *Environment, oldPushContext *PushContext, pushReq *PushRequest) {
- var servicesChanged, virtualServicesChanged, destinationRulesChanged, authnChanged, authzChanged bool
-
- // We do not need to watch Ingress or Gateway API changes. Both of these have their own controllers which will send
- // events for Istio types (Gateway and VirtualService).
- for conf := range pushReq.ConfigsUpdated {
- switch conf.Kind {
- case kind.DestinationRule:
- destinationRulesChanged = true
- case kind.VirtualService:
- virtualServicesChanged = true
- case kind.AuthorizationPolicy:
- authzChanged = true
- case kind.RequestAuthentication,
- kind.PeerAuthentication:
- authnChanged = true
- }
- }
-
- if servicesChanged {
- // Services have changed. initialize service registry
- ps.initServiceRegistry(env, pushReq.ConfigsUpdated)
- } else {
- // make sure we copy over things that would be generated in initServiceRegistry
- ps.ServiceIndex = oldPushContext.ServiceIndex
- ps.serviceAccounts = oldPushContext.serviceAccounts
- }
-
- if virtualServicesChanged {
- ps.initVirtualServices(env)
- } else {
- ps.virtualServiceIndex = oldPushContext.virtualServiceIndex
- }
-
- if destinationRulesChanged {
- ps.initDestinationRules(env)
- } else {
- ps.destinationRuleIndex = oldPushContext.destinationRuleIndex
- }
-
- if authnChanged {
- ps.initAuthnPolicies(env)
- } else {
- ps.AuthnPolicies = oldPushContext.AuthnPolicies
- }
-
- if authzChanged {
- ps.initAuthorizationPolicies(env)
- } else {
- ps.AuthzPolicies = oldPushContext.AuthzPolicies
- }
}
func (pr *PushRequest) Merge(other *PushRequest) *PushRequest {
@@ -305,6 +252,33 @@ func (pr *PushRequest) Merge(other *PushRequest) *PushRequest {
return pr
}
+func (r ReasonStats) Has(reason TriggerReason) bool {
+ return r[reason] > 0
+}
+
+func (pr *PushRequest) IsRequest() bool {
+ return len(pr.Reason) == 1 && pr.Reason.Has(ProxyRequest)
+}
+
+func (pr *PushRequest) PushReason() string {
+ if pr.IsRequest() {
+ return " request"
+ }
+ return ""
+}
+
+func (ps *PushContext) OnConfigChange() {
+ LastPushMutex.Lock()
+ LastPushStatus = ps
+ LastPushMutex.Unlock()
+ ps.UpdateMetrics()
+}
+
+func (ps *PushContext) UpdateMetrics() {
+ ps.proxyStatusMutex.RLock()
+ defer ps.proxyStatusMutex.RUnlock()
+}
+
func NewReasonStats(reasons ...TriggerReason) ReasonStats {
ret := make(ReasonStats)
for _, reason := range reasons {
diff --git a/sail/pkg/model/service.go b/sail/pkg/model/service.go
index 7b6c26de..004793cd 100644
--- a/sail/pkg/model/service.go
+++ b/sail/pkg/model/service.go
@@ -3,16 +3,117 @@ package model
import (
"github.com/apache/dubbo-kubernetes/pkg/cluster"
"github.com/apache/dubbo-kubernetes/pkg/config/host"
+ "github.com/apache/dubbo-kubernetes/pkg/config/labels"
"github.com/apache/dubbo-kubernetes/pkg/config/protocol"
"github.com/apache/dubbo-kubernetes/pkg/config/visibility"
"github.com/apache/dubbo-kubernetes/pkg/maps"
"github.com/apache/dubbo-kubernetes/pkg/slices"
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
"github.com/apache/dubbo-kubernetes/sail/pkg/serviceregistry/provider"
+ "github.com/google/go-cmp/cmp"
"sync"
"time"
)
+type EndpointDiscoverabilityPolicy interface {
+ String() string
+}
+
+type endpointDiscoverabilityPolicyImpl struct {
+ name string
+ f func(*DubboEndpoint, *Proxy) bool
+}
+
+func (p *endpointDiscoverabilityPolicyImpl) String() string {
+ return p.name
+}
+
+var endpointDiscoverabilityPolicyImplCmpOpt = cmp.Comparer(func(x, y endpointDiscoverabilityPolicyImpl) bool {
+ return x.String() == y.String()
+})
+
+func (p *endpointDiscoverabilityPolicyImpl) CmpOpts() []cmp.Option {
+ return []cmp.Option{endpointDiscoverabilityPolicyImplCmpOpt}
+}
+
+type HealthStatus int32
+
+const (
+ // Healthy indicates an endpoint is ready to accept traffic
+ Healthy HealthStatus = 1
+ // UnHealthy indicates an endpoint is not ready to accept traffic
+ UnHealthy HealthStatus = 2
+ // Draining is a special case, which is used only when persistent sessions are enabled. This indicates an endpoint
+ // was previously healthy, but is now shutting down.
+ // Without persistent sessions, an endpoint that is shutting down will be marked as Terminating.
+ Draining HealthStatus = 3
+ // Terminating marks an endpoint as shutting down. Similar to "unhealthy", this means we should not send it traffic.
+ // But unlike "unhealthy", this means we do not consider it when calculating failover.
+ Terminating HealthStatus = 4
+)
+
+type DubboEndpoint struct {
+ ServiceAccount string
+ Addresses []string
+ WorkloadName string
+ ServicePortName string
+ Labels labels.Instance
+ HealthStatus HealthStatus
+ SendUnhealthyEndpoints bool
+ DiscoverabilityPolicy EndpointDiscoverabilityPolicy `json:"-"`
+}
+
+func (ep *DubboEndpoint) FirstAddressOrNil() string {
+ if ep == nil || len(ep.Addresses) == 0 {
+ return ""
+ }
+ return ep.Addresses[0]
+}
+
+func (ep *DubboEndpoint) Key() string {
+ return ep.FirstAddressOrNil() + "/" + ep.WorkloadName + "/" + ep.ServicePortName
+}
+
+func (ep *DubboEndpoint) Equals(other *DubboEndpoint) bool {
+ if ep == nil {
+ return other == nil
+ }
+ if other == nil {
+ return ep == nil
+ }
+
+ // Check things we can directly compare...
+ eq := ep.ServicePortName == other.ServicePortName &&
+ ep.ServiceAccount == other.ServiceAccount &&
+ ep.WorkloadName == other.WorkloadName
+ if !eq {
+ return false
+ }
+
+ // check everything else
+ if !slices.EqualUnordered(ep.Addresses, other.Addresses) {
+ return false
+ }
+ if !maps.Equal(ep.Labels, other.Labels) {
+ return false
+ }
+
+ // Compare discoverability by name
+ var epp string
+ if ep.DiscoverabilityPolicy != nil {
+ epp = ep.DiscoverabilityPolicy.String()
+ }
+ var op string
+ if other.DiscoverabilityPolicy != nil {
+ op = other.DiscoverabilityPolicy.String()
+ }
+ if epp != op {
+ return false
+ }
+
+ return true
+}
+
type NamespacedHostname struct {
Hostname host.Name
Namespace string
diff --git a/sail/pkg/server/instance.go b/sail/pkg/server/instance.go
index 1ac26f66..e8e5906e 100644
--- a/sail/pkg/server/instance.go
+++ b/sail/pkg/server/instance.go
@@ -19,6 +19,7 @@ package server
import (
"k8s.io/klog/v2"
+ "sync"
"time"
)
@@ -32,11 +33,13 @@ type task struct {
type Instance interface {
Start(stop <-chan struct{}) error
RunComponent(name string, t Component)
+ Wait()
}
type instance struct {
- components chan task
- done chan struct{}
+ components chan task
+ done chan struct{}
+ requiredTerminations sync.WaitGroup
}
var _ Instance = &instance{}
@@ -64,6 +67,7 @@ func (i *instance) Start(stop <-chan struct{}) error {
}
runtime := time.Since(t0)
if runtime > time.Second {
+ klog.Warningf("slow startup task")
}
default:
startupDone = true
@@ -74,6 +78,7 @@ func (i *instance) Start(stop <-chan struct{}) error {
for {
select {
case <-stop:
+ i.requiredTerminations.Wait()
shutdown()
return
case next := <-i.components:
@@ -82,6 +87,8 @@ func (i *instance) Start(stop <-chan struct{}) error {
}
runtime := time.Since(t0)
if runtime > time.Second {
+ klog.Warningf("slow post-start task")
+
}
}
}
@@ -93,8 +100,12 @@ func (i *instance) Start(stop <-chan struct{}) error {
func (i *instance) RunComponent(name string, t Component) {
select {
case <-i.done:
- klog.Infof("attempting to run a new component %q after the server was shutdown", name)
+ klog.Warningf("attempting to run a new component %q after the server was shutdown", name)
default:
i.components <- task{name, t}
}
}
+
+func (i *instance) Wait() {
+ <-i.done
+}
diff --git a/sail/pkg/serviceregistry/aggregate/controller.go b/sail/pkg/serviceregistry/aggregate/controller.go
index 2179a5b7..528de8e7 100644
--- a/sail/pkg/serviceregistry/aggregate/controller.go
+++ b/sail/pkg/serviceregistry/aggregate/controller.go
@@ -4,6 +4,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/cluster"
"github.com/apache/dubbo-kubernetes/pkg/config/host"
"github.com/apache/dubbo-kubernetes/pkg/config/mesh"
+ "github.com/apache/dubbo-kubernetes/pkg/slices"
"github.com/apache/dubbo-kubernetes/sail/pkg/model"
"github.com/apache/dubbo-kubernetes/sail/pkg/serviceregistry"
"github.com/apache/dubbo-kubernetes/sail/pkg/serviceregistry/provider"
@@ -144,6 +145,36 @@ func (c *Controller) GetRegistries() []serviceregistry.Instance {
return out
}
+func (c *Controller) AddRegistryAndRun(registry serviceregistry.Instance, stop <-chan struct{}) {
+ if stop == nil {
+ klog.Warningf("nil stop channel passed to AddRegistryAndRun for registry %s/%s", registry.Provider(), registry.Cluster())
+ }
+ c.storeLock.Lock()
+ defer c.storeLock.Unlock()
+ c.addRegistry(registry, stop)
+ if c.running {
+ go registry.Run(stop)
+ }
+}
+
+func (c *Controller) addRegistry(registry serviceregistry.Instance, stop <-chan struct{}) {
+ added := false
+ if registry.Provider() == provider.Kubernetes {
+ for i, r := range c.registries {
+ if r.Provider() != provider.Kubernetes {
+ // insert the registry in the position of the first non kubernetes registry
+ c.registries = slices.Insert(c.registries, i, ®istryEntry{Instance: registry, stop: stop})
+ added = true
+ break
+ }
+ }
+ }
+ if !added {
+ c.registries = append(c.registries, ®istryEntry{Instance: registry, stop: stop})
+ }
+
+}
+
func mergeService(dst, src *model.Service, srcRegistry serviceregistry.Instance) {
if !src.Ports.Equals(dst.Ports) {
klog.V(2).Infof("service %s defined from cluster %s is different from others", src.Hostname, srcRegistry.Cluster())
diff --git a/sail/pkg/serviceregistry/kube/controller/controller.go b/sail/pkg/serviceregistry/kube/controller/controller.go
index 893ec60f..3dd79905 100644
--- a/sail/pkg/serviceregistry/kube/controller/controller.go
+++ b/sail/pkg/serviceregistry/kube/controller/controller.go
@@ -62,6 +62,7 @@ type Options struct {
MeshServiceController *aggregate.Controller
KrtDebugger *krt.DebugHandler
SyncTimeout time.Duration
+ Revision string
}
func (c *Controller) Services() []*model.Service {
@@ -118,5 +119,5 @@ func (c *Controller) HasSynced() bool {
}
func (c *Controller) informersSynced() bool {
- return false
+ return true
}
diff --git a/sail/pkg/trustbundle/trustbundle.go b/sail/pkg/trustbundle/trustbundle.go
index 33964cf1..55b57ec4 100644
--- a/sail/pkg/trustbundle/trustbundle.go
+++ b/sail/pkg/trustbundle/trustbundle.go
@@ -42,8 +42,6 @@ const (
SourceMeshConfig
SourceDubboRA
sourceSpiffeEndpoints
-
- RemoteDefaultPollPeriod = 30 * time.Minute
)
func (s Source) String() string {
diff --git a/sail/pkg/xds/ads.go b/sail/pkg/xds/ads.go
index 79d5fa9d..9d287319 100644
--- a/sail/pkg/xds/ads.go
+++ b/sail/pkg/xds/ads.go
@@ -23,9 +23,14 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
"github.com/apache/dubbo-kubernetes/pkg/xds"
"github.com/apache/dubbo-kubernetes/sail/pkg/model"
+ v3 "github.com/apache/dubbo-kubernetes/sail/pkg/xds/v3"
core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/peer"
+ "google.golang.org/grpc/status"
"k8s.io/klog/v2"
+ "strings"
"time"
)
@@ -91,7 +96,6 @@ func (s *DiscoveryServer) AdsPushAll(req *model.PushRequest) {
req.ConfigsUpdated = make(sets.Set[model.ConfigKey])
}
}
-
s.StartPush(req)
}
@@ -116,7 +120,37 @@ func (s *DiscoveryServer) closeConnection(con *Connection) {
}
func (s *DiscoveryServer) Stream(stream DiscoveryStream) error {
- return nil
+ if !s.IsServerReady() {
+ return status.Error(codes.Unavailable, "server is not ready to serve discovery information")
+ }
+
+ ctx := stream.Context()
+ peerAddr := "0.0.0.0"
+ if peerInfo, ok := peer.FromContext(ctx); ok {
+ peerAddr = peerInfo.Addr.String()
+ }
+ // TODO WaitForRequestLimit?
+
+ if err := s.WaitForRequestLimit(stream.Context()); err != nil {
+ klog.Warningf("ADS: %q exceeded rate limit: %v", peerAddr, err)
+ return status.Errorf(codes.ResourceExhausted, "request rate limit exceeded: %v", err)
+ }
+
+ ids, err := s.authenticate(ctx)
+ if err != nil {
+ return status.Error(codes.Unauthenticated, err.Error())
+ }
+
+ if ids != nil {
+ klog.V(2).Infof("Authenticated XDS: %v with identity %v", peerAddr, ids)
+ } else {
+ klog.V(2).Infof("Unauthenticated XDS: %s", peerAddr)
+ }
+ s.globalPushContext().InitContext(s.Env, nil, nil)
+ con := newConnection(peerAddr, stream)
+ con.ids = ids
+ con.s = s
+ return xds.Stream(con)
}
func (s *DiscoveryServer) WaitForRequestLimit(ctx context.Context) error {
@@ -140,3 +174,86 @@ func newConnection(peerAddr string, stream DiscoveryStream) *Connection {
func (conn *Connection) watchedResourcesByOrder() []*model.WatchedResource {
return nil
}
+
+func (conn *Connection) Initialize(node *core.Node) error {
+ return conn.s.initConnection(node, conn, conn.ids)
+}
+
+func (conn *Connection) Close() {
+ conn.s.closeConnection(conn)
+}
+
+func (s *DiscoveryServer) pushConnection(con *Connection, pushEv *Event) error {
+ pushRequest := pushEv.pushRequest
+
+ if pushRequest.Full {
+ // Update Proxy with current information.
+ s.computeProxyState(con.proxy, pushRequest)
+ }
+
+ pushRequest, needsPush := s.ProxyNeedsPush(con.proxy, pushRequest)
+ if !needsPush {
+ klog.V(2).Infof("Skipping push to %v, no updates required", con.ID())
+ return nil
+ }
+
+ // Send pushes to all generators
+ // Each Generator is responsible for determining if the push event requires a push
+ wrl := con.watchedResourcesByOrder()
+ for _, w := range wrl {
+ if err := s.pushXds(con, w, pushRequest); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (s *DiscoveryServer) processRequest(req *discovery.DiscoveryRequest, con *Connection) error {
+ stype := v3.GetShortType(req.TypeUrl)
+ klog.V(2).Infof("ADS:%s: REQ %s resources:%d nonce:%s ", stype,
+ con.ID(), len(req.ResourceNames), req.ResponseNonce)
+ if req.TypeUrl == v3.HealthInfoType {
+ return nil
+ }
+
+ // For now, don't let xDS piggyback debug requests start watchers.
+ if strings.HasPrefix(req.TypeUrl, v3.DebugType) {
+ return s.pushXds(con,
+ &model.WatchedResource{TypeUrl: req.TypeUrl, ResourceNames: sets.New(req.ResourceNames...)},
+ &model.PushRequest{Full: true, Push: con.proxy.LastPushContext, Forced: true})
+ }
+
+ shouldRespond, delta := xds.ShouldRespond(con.proxy, con.ID(), req)
+ if !shouldRespond {
+ return nil
+ }
+
+ request := &model.PushRequest{
+ Full: true,
+ Push: con.proxy.LastPushContext,
+ Reason: model.NewReasonStats(model.ProxyRequest),
+
+ // The usage of LastPushTime (rather than time.Now()), is critical here for correctness; This time
+ // is used by the XDS cache to determine if a entry is stale. If we use Now() with an old push context,
+ // we may end up overriding active cache entries with stale ones.
+ Start: con.proxy.LastPushTime,
+ Delta: delta,
+ Forced: true,
+ }
+ return s.pushXds(con, con.proxy.GetWatchedResource(req.TypeUrl), request)
+}
+
+func (conn *Connection) Push(ev any) error {
+ pushEv := ev.(*Event)
+ err := conn.s.pushConnection(conn, pushEv)
+ pushEv.done()
+ return err
+}
+
+func (conn *Connection) Process(req *discovery.DiscoveryRequest) error {
+ return conn.s.processRequest(req, conn)
+}
+
+func (conn *Connection) Watcher() xds.Watcher {
+ return conn.proxy
+}
diff --git a/sail/pkg/xds/delta.go b/sail/pkg/xds/delta.go
index 82064a64..71b36305 100644
--- a/sail/pkg/xds/delta.go
+++ b/sail/pkg/xds/delta.go
@@ -1,6 +1,7 @@
package xds
import (
+ "errors"
"github.com/apache/dubbo-kubernetes/pkg/xds"
dubbogrpc "github.com/apache/dubbo-kubernetes/sail/pkg/grpc"
"github.com/apache/dubbo-kubernetes/sail/pkg/model"
@@ -13,6 +14,10 @@ import (
)
func (s *DiscoveryServer) StreamDeltas(stream DeltaDiscoveryStream) error {
+ if !s.IsServerReady() {
+ return errors.New("server is not ready to serve discovery information")
+ }
+
ctx := stream.Context()
peerAddr := "0.0.0.0"
if peerInfo, ok := peer.FromContext(ctx); ok {
diff --git a/sail/pkg/xds/discovery.go b/sail/pkg/xds/discovery.go
index 7b00ce4f..822bf218 100644
--- a/sail/pkg/xds/discovery.go
+++ b/sail/pkg/xds/discovery.go
@@ -20,7 +20,9 @@ package xds
import (
"fmt"
"github.com/apache/dubbo-kubernetes/pkg/cluster"
+ "github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
"github.com/apache/dubbo-kubernetes/pkg/kube/krt"
+ "github.com/apache/dubbo-kubernetes/sail/pkg/features"
"github.com/apache/dubbo-kubernetes/sail/pkg/model"
discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
"go.uber.org/atomic"
@@ -54,15 +56,32 @@ type DiscoveryServer struct {
concurrentPushLimit chan struct{}
adsClientsMutex sync.RWMutex
adsClients map[string]*Connection
+ Generators map[string]model.XdsResourceGenerator
+ pushVersion atomic.Uint64
}
+var processStartTime = time.Now()
+
func NewDiscoveryServer(env *model.Environment, clusterAliases map[string]string, debugger *krt.DebugHandler) *DiscoveryServer {
out := &DiscoveryServer{
- Env: env,
- krtDebugger: debugger,
- InboundUpdates: atomic.NewInt64(0),
- CommittedUpdates: atomic.NewInt64(0),
+ Env: env,
+ Generators: map[string]model.XdsResourceGenerator{},
+ krtDebugger: debugger,
+ InboundUpdates: atomic.NewInt64(0),
+ CommittedUpdates: atomic.NewInt64(0),
+ concurrentPushLimit: make(chan struct{}, features.PushThrottle),
+ RequestRateLimit: rate.NewLimiter(rate.Limit(features.RequestLimit), 1),
+ pushChannel: make(chan *model.PushRequest, 10),
+ pushQueue: NewPushQueue(),
+ DebounceOptions: DebounceOptions{
+ DebounceAfter: features.DebounceAfter,
+ debounceMax: features.DebounceMax,
+ enableEDSDebounce: features.EnableEDSDebounce,
+ },
+ adsClients: map[string]*Connection{},
+ DiscoveryStartTime: processStartTime,
}
+
out.ClusterAliases = make(map[cluster.ID]cluster.ID)
for alias := range clusterAliases {
out.ClusterAliases[cluster.ID(alias)] = cluster.ID(clusterAliases[alias])
@@ -92,9 +111,32 @@ func (s *DiscoveryServer) Shutdown() {
func (s *DiscoveryServer) Push(req *model.PushRequest) {
if !req.Full {
req.Push = s.globalPushContext()
- s.AdsPushAll(req)
+ // s.AdsPushAll(req)
return
}
+
+ // Reset the status during the push.
+ oldPushContext := s.globalPushContext()
+ if oldPushContext != nil {
+ oldPushContext.OnConfigChange()
+ }
+ // PushContext is reset after a config change. Previous status is
+ // saved.
+ versionLocal := s.NextVersion()
+ push := s.initPushContext(req, oldPushContext, versionLocal)
+ req.Push = push
+ // s.AdsPushAll(req)
+}
+
+func (s *DiscoveryServer) initPushContext(req *model.PushRequest, oldPushContext *model.PushContext, version string) *model.PushContext {
+ push := model.NewPushContext()
+ push.InitContext(s.Env, oldPushContext, req)
+ s.Env.SetPushContext(push)
+ return push
+}
+
+func (s *DiscoveryServer) NextVersion() string {
+ return time.Now().Format(time.RFC3339) + "/" + strconv.FormatUint(s.pushVersion.Inc(), 10)
}
func (s *DiscoveryServer) globalPushContext() *model.PushContext {
@@ -109,6 +151,64 @@ func (s *DiscoveryServer) sendPushes(stopCh <-chan struct{}) {
doSendPushes(stopCh, s.concurrentPushLimit, s.pushQueue)
}
+func (s *DiscoveryServer) ConfigUpdate(req *model.PushRequest) {
+ if model.HasConfigsOfKind(req.ConfigsUpdated, kind.Address) {
+ // TODO ClearAll
+ }
+ s.InboundUpdates.Inc()
+
+ klog.Infof("this is req: %v", req)
+
+ s.pushChannel <- req
+}
+
+func (s *DiscoveryServer) IsServerReady() bool {
+ return s.serverReady.Load()
+}
+
+func reasonsUpdated(req *model.PushRequest) string {
+ var (
+ reason0, reason1 model.TriggerReason
+ reason0Cnt, reason1Cnt, idx int
+ )
+ for r, cnt := range req.Reason {
+ if idx == 0 {
+ reason0, reason0Cnt = r, cnt
+ } else if idx == 1 {
+ reason1, reason1Cnt = r, cnt
+ } else {
+ break
+ }
+ idx++
+ }
+
+ switch len(req.Reason) {
+ case 0:
+ return "unknown"
+ case 1:
+ return fmt.Sprintf("%s:%d", reason0, reason0Cnt)
+ case 2:
+ return fmt.Sprintf("%s:%d and %s:%d", reason0, reason0Cnt, reason1, reason1Cnt)
+ default:
+ return fmt.Sprintf("%s:%d and %d(%d) more reasons", reason0, reason0Cnt, len(req.Reason)-1,
+ req.Reason.Count()-reason0Cnt)
+ }
+}
+
+func configsUpdated(req *model.PushRequest) string {
+ configs := ""
+ for key := range req.ConfigsUpdated {
+ configs += key.String()
+ break
+ }
+ if len(req.ConfigsUpdated) > 1 {
+ more := " and " + strconv.Itoa(len(req.ConfigsUpdated)-1) + " more configs"
+ configs += more
+ }
+
+ return configs
+}
+
func debounce(ch chan *model.PushRequest, stopCh <-chan struct{}, opts DebounceOptions, pushFn func(req *model.PushRequest), updateSent *atomic.Int64) {
var timeChan <-chan time.Time
var startDebounce time.Time
@@ -118,17 +218,18 @@ func debounce(ch chan *model.PushRequest, stopCh <-chan struct{}, opts DebounceO
debouncedEvents := 0
var req *model.PushRequest
-
free := true
freeCh := make(chan struct{}, 1)
push := func(req *model.PushRequest, debouncedEvents int, startDebounce time.Time) {
+ klog.Info("This is push func")
pushFn(req)
updateSent.Add(int64(debouncedEvents))
freeCh <- struct{}{}
}
pushWorker := func() {
+ klog.Info("This is pushWorker func")
eventDelay := time.Since(startDebounce)
quietTime := time.Since(lastConfigUpdateTime)
// it has been too long or quiet enough
@@ -191,48 +292,6 @@ func debounce(ch chan *model.PushRequest, stopCh <-chan struct{}, opts DebounceO
}
}
-func reasonsUpdated(req *model.PushRequest) string {
- var (
- reason0, reason1 model.TriggerReason
- reason0Cnt, reason1Cnt, idx int
- )
- for r, cnt := range req.Reason {
- if idx == 0 {
- reason0, reason0Cnt = r, cnt
- } else if idx == 1 {
- reason1, reason1Cnt = r, cnt
- } else {
- break
- }
- idx++
- }
-
- switch len(req.Reason) {
- case 0:
- return "unknown"
- case 1:
- return fmt.Sprintf("%s:%d", reason0, reason0Cnt)
- case 2:
- return fmt.Sprintf("%s:%d and %s:%d", reason0, reason0Cnt, reason1, reason1Cnt)
- default:
- return fmt.Sprintf("%s:%d and %d(%d) more reasons", reason0, reason0Cnt, len(req.Reason)-1,
- req.Reason.Count()-reason0Cnt)
- }
-}
-
-func configsUpdated(req *model.PushRequest) string {
- configs := ""
- for key := range req.ConfigsUpdated {
- configs += key.String()
- break
- }
- if len(req.ConfigsUpdated) > 1 {
- more := " and " + strconv.Itoa(len(req.ConfigsUpdated)-1) + " more configs"
- configs += more
- }
- return configs
-}
-
func doSendPushes(stopCh <-chan struct{}, semaphore chan struct{}, queue *PushQueue) {
for {
select {
diff --git a/sail/pkg/xds/eds.go b/sail/pkg/xds/eds.go
new file mode 100644
index 00000000..21fe09b8
--- /dev/null
+++ b/sail/pkg/xds/eds.go
@@ -0,0 +1,20 @@
+package xds
+
+import (
+ "github.com/apache/dubbo-kubernetes/sail/pkg/model"
+)
+
+func (s *DiscoveryServer) EDSUpdate(shard model.ShardKey, serviceName string, namespace string,
+ dubboEndpoints []*model.DubboEndpoint,
+) {
+ // Update the endpoint shards
+ pushType := s.Env.EndpointIndex.UpdateServiceEndpoints(shard, serviceName, namespace, dubboEndpoints, true)
+ if pushType == model.IncrementalPush || pushType == model.FullPush {
+ // Trigger a push
+ s.ConfigUpdate(&model.PushRequest{
+ Full: pushType == model.FullPush,
+ ConfigsUpdated: nil,
+ Reason: model.NewReasonStats(model.EndpointUpdate),
+ })
+ }
+}
diff --git a/sail/pkg/xds/statusgen.go b/sail/pkg/xds/statusgen.go
new file mode 100644
index 00000000..aa3a0321
--- /dev/null
+++ b/sail/pkg/xds/statusgen.go
@@ -0,0 +1,7 @@
+package xds
+
+import v3 "github.com/apache/dubbo-kubernetes/sail/pkg/xds/v3"
+
+const (
+ TypeDebugPrefix = v3.DebugType + "/"
+)
diff --git a/sail/pkg/xds/xdsgen.go b/sail/pkg/xds/xdsgen.go
new file mode 100644
index 00000000..b3c7986c
--- /dev/null
+++ b/sail/pkg/xds/xdsgen.go
@@ -0,0 +1,79 @@
+package xds
+
+import (
+ "github.com/apache/dubbo-kubernetes/sail/pkg/model"
+ discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
+ "strings"
+
+ "github.com/apache/dubbo-kubernetes/pkg/xds"
+ "strconv"
+)
+
+func (s *DiscoveryServer) pushXds(con *Connection, w *model.WatchedResource, req *model.PushRequest) error {
+ if w == nil {
+ return nil
+ }
+ gen := s.findGenerator(w.TypeUrl, con)
+ if gen == nil {
+ return nil
+ }
+
+ // If delta is set, client is requesting new resources or removing old ones. We should just generate the
+ // new resources it needs, rather than the entire set of known resources.
+ // Note: we do not need to account for unsubscribed resources as these are handled by parent removal;
+ // See https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol#deleting-resources.
+ // This means if there are only removals, we will not respond.
+ var logFiltered string
+ if !req.Delta.IsEmpty() && !con.proxy.IsProxylessGrpc() {
+ logFiltered = " filtered:" + strconv.Itoa(len(w.ResourceNames)-len(req.Delta.Subscribed))
+ w = &model.WatchedResource{
+ TypeUrl: w.TypeUrl,
+ ResourceNames: req.Delta.Subscribed,
+ }
+ }
+ res, logdata, err := gen.Generate(con.proxy, w, req)
+ info := ""
+ if len(logdata.AdditionalInfo) > 0 {
+ info = " " + logdata.AdditionalInfo
+ }
+ if len(logFiltered) > 0 {
+ info += logFiltered
+ }
+ if err != nil || res == nil {
+ return err
+ }
+
+ resp := &discovery.DiscoveryResponse{
+ TypeUrl: w.TypeUrl,
+ Resources: xds.ResourcesToAny(res),
+ }
+
+ if err := xds.Send(con, resp); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (s *DiscoveryServer) findGenerator(typeURL string, con *Connection) model.XdsResourceGenerator {
+ if g, f := s.Generators[con.proxy.Metadata.Generator+"/"+typeURL]; f {
+ return g
+ }
+
+ if g, f := s.Generators[typeURL]; f {
+ return g
+ }
+
+ // XdsResourceGenerator is the default generator for this connection. We want to allow
+ // some types to use custom generators - for example EDS.
+ g := con.proxy.XdsResourceGenerator
+ if g == nil {
+ if strings.HasPrefix(typeURL, TypeDebugPrefix) {
+ g = s.Generators["event"]
+ } else {
+ // TODO move this to just directly using the resource TypeUrl
+ g = s.Generators["api"] // default to "MCP" generators - any type supported by store
+ }
+ }
+ return g
+}