diff --git a/go.mod b/go.mod index d98cf25b81..bd9f85ee59 100644 --- a/go.mod +++ b/go.mod @@ -24,10 +24,10 @@ require ( github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.6 github.com/tektoncd/chains v0.25.1 - github.com/tektoncd/hub v1.21.0 - github.com/tektoncd/pipeline v1.2.0 + github.com/tektoncd/hub v1.22.2 + github.com/tektoncd/pipeline v1.3.1 github.com/tektoncd/plumbing v0.0.0-20250430145243-3b7cd59879c1 - github.com/tektoncd/triggers v0.32.0 + github.com/tektoncd/triggers v0.33.0 github.com/theupdateframework/go-tuf v0.7.0 go.opencensus.io v0.24.0 go.uber.org/multierr v1.11.0 @@ -40,13 +40,13 @@ require ( k8s.io/cli-runtime v0.29.15 k8s.io/client-go v0.33.3 knative.dev/pkg v0.0.0-20250415155312-ed3e2158b883 - sigs.k8s.io/yaml v1.4.0 + sigs.k8s.io/yaml v1.6.0 ) replace github.com/alibabacloud-go/cr-20160607 => github.com/vdemeester/cr-20160607 v1.0.1 require ( - cel.dev/expr v0.23.1 // indirect + cel.dev/expr v0.24.0 // indirect cloud.google.com/go v0.121.1 // indirect cloud.google.com/go/auth v0.16.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -77,7 +77,7 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect - github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 // indirect + github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect @@ -125,7 +125,7 @@ require ( github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/cloudevents/sdk-go/v2 v2.16.1 // indirect - github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect + github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/coreos/go-oidc/v3 v3.14.1 // indirect @@ -179,7 +179,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/cel-go v0.25.0 // indirect + github.com/google/cel-go v0.26.0 // indirect github.com/google/certificate-transparency-go v1.3.2 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240108195214-a0658aa1d0cc // indirect @@ -325,7 +325,8 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - goa.design/goa/v3 v3.20.1 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + goa.design/goa/v3 v3.21.1 // indirect gocloud.dev v0.40.0 // indirect gocloud.dev/docstore/mongodocstore v0.40.0 // indirect gocloud.dev/pubsub/kafkapubsub v0.40.0 // indirect @@ -344,14 +345,14 @@ require ( google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.73.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/grpc v1.74.2 // indirect + google.golang.org/protobuf v1.36.7 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.32.6 // indirect + k8s.io/apiextensions-apiserver v0.32.7 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect diff --git a/go.sum b/go.sum index f04bb0ecd9..80ec0a655e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.23.1 h1:K4KOtPCJQjVggkARsjG9RWXP6O4R73aHeJMa/dmCQQg= -cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -703,8 +703,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJ github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 h1:DBjmt6/otSdULyJdVg2BlG0qGZO5tKL4VzOs0jpvw5Q= -github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0= +github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 h1:2afWGsMzkIcN8Qm4mgPJKZWyroE5QBszMiDMYEBrnfw= +github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= @@ -914,8 +914,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= -github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= @@ -1246,8 +1246,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY= -github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI= +github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= +github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/certificate-transparency-go v1.3.2 h1:9ahSNZF2o7SYMaKaXhAumVEzXB2QaayzII9C8rv7v+A= github.com/google/certificate-transparency-go v1.3.2/go.mod h1:H5FpMUaGa5Ab2+KCYsxg6sELw3Flkl7pGZzWdBoYLXs= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= @@ -1496,8 +1496,8 @@ github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc= github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw= -github.com/jenkins-x/go-scm v1.14.58 h1:R7ZxZySGkvz7UxPdvAeQxUy9esUwrrseSPoTbxmXNt8= -github.com/jenkins-x/go-scm v1.14.58/go.mod h1:1RPxLZndnvu31XhFZ+RTvXiHmMX70HkQ17bRupTQxGs= +github.com/jenkins-x/go-scm v1.15.4 h1:xjWTbIzoTDnOwXeNcbzZLPoqn3yPWAVhz8UIa5jncSk= +github.com/jenkins-x/go-scm v1.15.4/go.mod h1:1RPxLZndnvu31XhFZ+RTvXiHmMX70HkQ17bRupTQxGs= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -1903,8 +1903,8 @@ github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= -github.com/spiffe/spire-api-sdk v1.12.0 h1:xx6PAsoBTvMtNe7h5dGS+/SyVZccudAQg/vB9P/XPec= -github.com/spiffe/spire-api-sdk v1.12.0/go.mod h1:4uuhFlN6KBWjACRP3xXwrOTNnvaLp1zJs8Lribtr4fI= +github.com/spiffe/spire-api-sdk v1.12.4 h1:RFMW7aPylHrJOPWY+w+YjElKCRUJPOUAMEyn7w4wLTU= +github.com/spiffe/spire-api-sdk v1.12.4/go.mod h1:4uuhFlN6KBWjACRP3xXwrOTNnvaLp1zJs8Lribtr4fI= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= @@ -1942,14 +1942,14 @@ github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/ github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/tektoncd/chains v0.25.1 h1:FBALaY1uGVDFbS198eUUfbLCSQ2PI5i98Ft2UnEw6vg= github.com/tektoncd/chains v0.25.1/go.mod h1:NtobmZ8Sn8XPWnY+CNtVBSqJtxk2RrEiabILD7pe0M0= -github.com/tektoncd/hub v1.21.0 h1:O9Q2N8poCXUHus6FV79mIPcuKPPJdzXRm1pPIXeWzIo= -github.com/tektoncd/hub v1.21.0/go.mod h1:N9QdNJyvMfFJ5aVg9MBLXVbsrk8mlbe9wu3jGmdk2Xs= -github.com/tektoncd/pipeline v1.2.0 h1:A/vNvfcXCfmtduwSYowEvoxW77HVBHsh5BPflVtwrUI= -github.com/tektoncd/pipeline v1.2.0/go.mod h1:am+EgEYjPVclhZpum04YUM7yzkggyWq40vp8T3U9UxU= +github.com/tektoncd/hub v1.22.2 h1:YqGs+c1umB7mZ3TlAiiwXNUxCBgn8zrIbHtNTMJlu0E= +github.com/tektoncd/hub v1.22.2/go.mod h1:ZDTBuF/etOTcNBb2TNKhhLfTUErND6hd258owacg1sM= +github.com/tektoncd/pipeline v1.3.1 h1:GOp49pAMPCXYX1E/cSc2JAm7j4vEB68DOOhGkSoaAmI= +github.com/tektoncd/pipeline v1.3.1/go.mod h1:924mFZJC0FXYruna4kDisnfFnRowJQgRgLpJuGbjNPQ= github.com/tektoncd/plumbing v0.0.0-20250430145243-3b7cd59879c1 h1:nv7BsOAZ1ifQX9Lw1hYFo1f7e62dTDyyVPJBuljgZKw= github.com/tektoncd/plumbing v0.0.0-20250430145243-3b7cd59879c1/go.mod h1:eDs4O8vTNkyKZ/+AEuo4nYDfpyn1AzbgIcQ1QMQaKJk= -github.com/tektoncd/triggers v0.32.0 h1:aUo2ePkbvwJaUC8+S66gLuryF17O+I2K/gzQaXjlsm8= -github.com/tektoncd/triggers v0.32.0/go.mod h1:dfJ0Dnp4vl/PflXO3cSgs4aYLxdU5DMAY/BCKI2oUmM= +github.com/tektoncd/triggers v0.33.0 h1:pG2Kz/2FHjysGG4GGhiGp9hHdwA8BLZI3H7m9U9sj4M= +github.com/tektoncd/triggers v0.33.0/go.mod h1:V2CTUxZB6zwymfeUnsZqFEwtkN6ClT+chtxr03N3L7c= github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg= github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= @@ -2128,8 +2128,12 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -goa.design/goa/v3 v3.20.1 h1:NpGdgRjaXUMOvb4dIfkUwAJOrLf1Jz0K0ggYj4Q7DFM= -goa.design/goa/v3 v3.20.1/go.mod h1:cLX3Y1JvnCabMWDAZxmfnjxM1f1l9g7Zf0C9CD9GIAQ= +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= +goa.design/goa/v3 v3.21.1 h1:tLwhbcNoEBJm1CcJc3ks6oZ8BHYl6vFuxEBnl2kC428= +goa.design/goa/v3 v3.21.1/go.mod h1:E+97AYffVIvDi6LkuNdfdvMZb8UFb/+ie3V0/WBBdgc= gocloud.dev v0.40.0 h1:f8LgP+4WDqOG/RXoUcyLpeIAGOcAbZrZbDQCUee10ng= gocloud.dev v0.40.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ= gocloud.dev/docstore/mongodocstore v0.40.0 h1:KTwP9Wr3PNPxN3bItxtK/RHiF4D6cTYjE5GDkPKcJrI= @@ -2900,8 +2904,8 @@ google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= +google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -2920,8 +2924,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= +google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2979,8 +2983,8 @@ k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= k8s.io/apiextensions-apiserver v0.22.5/go.mod h1:tIXeZ0BrDxUb1PoAz+tgOz43Zi1Bp4BEEqVtUccMJbE= -k8s.io/apiextensions-apiserver v0.32.6 h1:B9zv1tpW+090Prav3GP53A4W2Bv908AAouZYJWp0fy8= -k8s.io/apiextensions-apiserver v0.32.6/go.mod h1:3lAgylV3582qpXg8NWW4NOLdzxLC8mTcfPqqjAzOSTs= +k8s.io/apiextensions-apiserver v0.32.7 h1:w7IzqA3SZG9KNm5YMtrrqY3ipPgt13rZevDaZSubARA= +k8s.io/apiextensions-apiserver v0.32.7/go.mod h1:CelzsiBUTLZeJ+MxBEcuDEgu9Qr3LQkZqmydvA/W9UA= k8s.io/apimachinery v0.19.7/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= @@ -3084,7 +3088,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vt sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= diff --git a/vendor/cel.dev/expr/eval.pb.go b/vendor/cel.dev/expr/eval.pb.go index 8f651f9cc6..a7aae0900c 100644 --- a/vendor/cel.dev/expr/eval.pb.go +++ b/vendor/cel.dev/expr/eval.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.3 +// protoc v5.27.1 // source: cel/expr/eval.proto package expr import ( - status "google.golang.org/genproto/googleapis/rpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -22,21 +22,18 @@ const ( ) type EvalState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState) Reset() { *x = EvalState{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState) String() string { @@ -47,7 +44,7 @@ func (*EvalState) ProtoMessage() {} func (x *EvalState) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,25 +74,22 @@ func (x *EvalState) GetResults() []*EvalState_Result { } type ExprValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Kind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: // // *ExprValue_Value // *ExprValue_Error // *ExprValue_Unknown - Kind isExprValue_Kind `protobuf_oneof:"kind"` + Kind isExprValue_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExprValue) Reset() { *x = ExprValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExprValue) String() string { @@ -106,7 +100,7 @@ func (*ExprValue) ProtoMessage() {} func (x *ExprValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -121,30 +115,36 @@ func (*ExprValue) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{1} } -func (m *ExprValue) GetKind() isExprValue_Kind { - if m != nil { - return m.Kind +func (x *ExprValue) GetKind() isExprValue_Kind { + if x != nil { + return x.Kind } return nil } func (x *ExprValue) GetValue() *Value { - if x, ok := x.GetKind().(*ExprValue_Value); ok { - return x.Value + if x != nil { + if x, ok := x.Kind.(*ExprValue_Value); ok { + return x.Value + } } return nil } func (x *ExprValue) GetError() *ErrorSet { - if x, ok := x.GetKind().(*ExprValue_Error); ok { - return x.Error + if x != nil { + if x, ok := x.Kind.(*ExprValue_Error); ok { + return x.Error + } } return nil } func (x *ExprValue) GetUnknown() *UnknownSet { - if x, ok := x.GetKind().(*ExprValue_Unknown); ok { - return x.Unknown + if x != nil { + if x, ok := x.Kind.(*ExprValue_Unknown); ok { + return x.Unknown + } } return nil } @@ -172,20 +172,17 @@ func (*ExprValue_Error) isExprValue_Kind() {} func (*ExprValue_Unknown) isExprValue_Kind() {} type ErrorSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Errors []*Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` unknownFields protoimpl.UnknownFields - - Errors []*status.Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ErrorSet) Reset() { *x = ErrorSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ErrorSet) String() string { @@ -196,7 +193,7 @@ func (*ErrorSet) ProtoMessage() {} func (x *ErrorSet) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -211,28 +208,85 @@ func (*ErrorSet) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{2} } -func (x *ErrorSet) GetErrors() []*status.Status { +func (x *ErrorSet) GetErrors() []*Status { if x != nil { return x.Errors } return nil } -type UnknownSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Status struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Details []*anypb.Any `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} - Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` +func (x *Status) Reset() { + *x = Status{} + mi := &file_cel_expr_eval_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *UnknownSet) Reset() { - *x = UnknownSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[3] +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_cel_expr_eval_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} +} + +func (x *Status) GetCode() int32 { + if x != nil { + return x.Code } + return 0 +} + +func (x *Status) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Status) GetDetails() []*anypb.Any { + if x != nil { + return x.Details + } + return nil +} + +type UnknownSet struct { + state protoimpl.MessageState `protogen:"open.v1"` + Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UnknownSet) Reset() { + *x = UnknownSet{} + mi := &file_cel_expr_eval_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnknownSet) String() string { @@ -242,8 +296,8 @@ func (x *UnknownSet) String() string { func (*UnknownSet) ProtoMessage() {} func (x *UnknownSet) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -255,7 +309,7 @@ func (x *UnknownSet) ProtoReflect() protoreflect.Message { // Deprecated: Use UnknownSet.ProtoReflect.Descriptor instead. func (*UnknownSet) Descriptor() ([]byte, []int) { - return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} + return file_cel_expr_eval_proto_rawDescGZIP(), []int{4} } func (x *UnknownSet) GetExprs() []int64 { @@ -266,21 +320,18 @@ func (x *UnknownSet) GetExprs() []int64 { } type EvalState_Result struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` - Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState_Result) Reset() { *x = EvalState_Result{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState_Result) String() string { @@ -290,8 +341,8 @@ func (x *EvalState_Result) String() string { func (*EvalState_Result) ProtoMessage() {} func (x *EvalState_Result) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -325,39 +376,45 @@ var File_cel_expr_eval_proto protoreflect.FileDescriptor var file_cel_expr_eval_proto_rawDesc = []byte{ 0x0a, 0x13, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, - 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, - 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x06, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, - 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x22, 0x36, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x06, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, - 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, - 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, - 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, + 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xa2, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, + 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x1a, 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, + 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, + 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, + 0x65, 0x78, 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x22, 0x34, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x28, + 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x66, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2e, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, + 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, + 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, + 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -372,28 +429,30 @@ func file_cel_expr_eval_proto_rawDescGZIP() []byte { return file_cel_expr_eval_proto_rawDescData } -var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cel_expr_eval_proto_goTypes = []interface{}{ +var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cel_expr_eval_proto_goTypes = []any{ (*EvalState)(nil), // 0: cel.expr.EvalState (*ExprValue)(nil), // 1: cel.expr.ExprValue (*ErrorSet)(nil), // 2: cel.expr.ErrorSet - (*UnknownSet)(nil), // 3: cel.expr.UnknownSet - (*EvalState_Result)(nil), // 4: cel.expr.EvalState.Result - (*Value)(nil), // 5: cel.expr.Value - (*status.Status)(nil), // 6: google.rpc.Status + (*Status)(nil), // 3: cel.expr.Status + (*UnknownSet)(nil), // 4: cel.expr.UnknownSet + (*EvalState_Result)(nil), // 5: cel.expr.EvalState.Result + (*Value)(nil), // 6: cel.expr.Value + (*anypb.Any)(nil), // 7: google.protobuf.Any } var file_cel_expr_eval_proto_depIdxs = []int32{ 1, // 0: cel.expr.EvalState.values:type_name -> cel.expr.ExprValue - 4, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result - 5, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value + 5, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result + 6, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value 2, // 3: cel.expr.ExprValue.error:type_name -> cel.expr.ErrorSet - 3, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet - 6, // 5: cel.expr.ErrorSet.errors:type_name -> google.rpc.Status - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 4, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet + 3, // 5: cel.expr.ErrorSet.errors:type_name -> cel.expr.Status + 7, // 6: cel.expr.Status.details:type_name -> google.protobuf.Any + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_cel_expr_eval_proto_init() } @@ -402,69 +461,7 @@ func file_cel_expr_eval_proto_init() { return } file_cel_expr_value_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_eval_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExprValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnknownSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState_Result); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []any{ (*ExprValue_Value)(nil), (*ExprValue_Error)(nil), (*ExprValue_Unknown)(nil), @@ -475,7 +472,7 @@ func file_cel_expr_eval_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cel_expr_eval_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/gcp_balancer.go b/vendor/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/gcp_balancer.go index 6fdac53d62..293cffb6d5 100644 --- a/vendor/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/gcp_balancer.go +++ b/vendor/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/gcp_balancer.go @@ -574,3 +574,8 @@ func (gb *gcpBalancer) refresh(ref *subConnRef) { func (gb *gcpBalancer) Close() { } + +// ExitIdle is a no-op because the gcpBalancer will always try to reconnect and +// never enter "Idle" state after it's built. When a SubConn enters Idle, the +// balancer will immediately call sc.Connect() begin re-connecting it. +func (gb *gcpBalancer) ExitIdle() {} diff --git a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go index ac8dd4f19e..1d1607b9c9 100644 --- a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go +++ b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go @@ -120,7 +120,8 @@ type Matcher_OnMatch struct { // // *Matcher_OnMatch_Matcher // *Matcher_OnMatch_Action - OnMatch isMatcher_OnMatch_OnMatch `protobuf_oneof:"on_match"` + OnMatch isMatcher_OnMatch_OnMatch `protobuf_oneof:"on_match"` + KeepMatching bool `protobuf:"varint,3,opt,name=keep_matching,json=keepMatching,proto3" json:"keep_matching,omitempty"` } func (x *Matcher_OnMatch) Reset() { @@ -176,6 +177,13 @@ func (x *Matcher_OnMatch) GetAction() *v3.TypedExtensionConfig { return nil } +func (x *Matcher_OnMatch) GetKeepMatching() bool { + if x != nil { + return x.KeepMatching + } + return false +} + type isMatcher_OnMatch_OnMatch interface { isMatcher_OnMatch_OnMatch() } @@ -703,7 +711,7 @@ var file_xds_type_matcher_v3_matcher_proto_rawDesc = []byte{ 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xf6, 0x0f, 0x0a, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0c, + 0x22, 0x9b, 0x10, 0x0a, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, @@ -718,7 +726,7 @@ var file_xds_type_matcher_v3_matcher_proto_rawDesc = []byte{ 0x24, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x09, 0x6f, 0x6e, 0x4e, 0x6f, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x1a, 0x91, 0x01, 0x0a, 0x07, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x38, 0x0a, 0x07, + 0x1a, 0xb6, 0x01, 0x0a, 0x07, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x38, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x6d, @@ -726,117 +734,120 @@ var file_xds_type_matcher_v3_matcher_proto_rawDesc = []byte{ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x42, 0x0f, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, - 0x03, 0xf8, 0x42, 0x01, 0x1a, 0xb6, 0x08, 0x0a, 0x0b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x08, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x08, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x73, 0x1a, 0x91, 0x06, 0x0a, 0x09, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, - 0x6f, 0x0a, 0x10, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x78, 0x64, 0x73, 0x2e, + 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x65, 0x70, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x42, 0x0f, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0xb6, 0x08, 0x0a, 0x0b, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x08, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x78, 0x64, + 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, + 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x08, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x73, 0x1a, 0x91, 0x06, 0x0a, 0x09, 0x50, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x12, 0x6f, 0x0a, 0x10, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x70, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, + 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x64, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x61, 0x0a, 0x0a, 0x6f, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x69, - 0x6e, 0x67, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, - 0x0f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x12, 0x61, 0x0a, 0x0a, 0x6f, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, - 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x72, 0x12, 0x63, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, - 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6e, - 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x55, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, + 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x6f, + 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x63, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x5f, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x1a, - 0xf3, 0x01, 0x0a, 0x0f, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, - 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x45, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x64, - 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, - 0x33, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x48, - 0x00, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x46, 0x0a, - 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, - 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x0e, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0x6b, 0x0a, 0x0d, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x64, 0x73, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x42, 0x11, 0x0a, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0xb5, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x64, 0x73, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, - 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0xa9, 0x04, - 0x0a, 0x0b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, 0x72, 0x65, 0x65, 0x12, 0x41, 0x0a, - 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, - 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, - 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x64, 0x73, 0x2e, + 0x65, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x00, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x55, 0x0a, + 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x1a, 0xf3, 0x01, 0x0a, 0x0f, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x50, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, + 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x45, 0x0a, 0x0b, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x0e, 0x0a, 0x07, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0x6b, 0x0a, 0x0d, 0x50, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x09, 0x70, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x09, 0x70, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x11, 0x0a, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0xb5, 0x01, 0x0a, 0x0c, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x09, 0x70, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x70, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, - 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x0d, - 0x65, 0x78, 0x61, 0x63, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x12, 0x5d, 0x0a, - 0x10, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6d, 0x61, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, 0x72, 0x65, - 0x65, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x12, 0x46, 0x0a, 0x0c, - 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x1a, 0xc0, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, - 0x70, 0x12, 0x56, 0x0a, 0x03, 0x6d, 0x61, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x6f, 0x6e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x1a, 0xa9, 0x04, 0x0a, 0x0b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, 0x72, + 0x65, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, - 0x70, 0x2e, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x9a, - 0x01, 0x02, 0x08, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x70, 0x1a, 0x5c, 0x0a, 0x08, 0x4d, 0x61, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x10, 0x0a, 0x09, 0x74, 0x72, 0x65, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x5c, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, - 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x0c, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6e, 0x63, 0x66, 0x2f, 0x78, 0x64, 0x73, - 0x2f, 0x67, 0x6f, 0x2f, 0x78, 0x64, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x78, 0x61, 0x63, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, + 0x61, 0x70, 0x12, 0x5d, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, + 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, + 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x54, 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x48, + 0x00, 0x52, 0x0e, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, + 0x70, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0xc0, 0x01, 0x0a, 0x08, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x12, 0x56, 0x0a, 0x03, 0x6d, 0x61, 0x70, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x54, 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x4d, 0x61, 0x70, 0x2e, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x9a, 0x01, 0x02, 0x08, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x70, 0x1a, 0x5c, + 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3a, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x64, + 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, + 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x10, 0x0a, 0x09, + 0x74, 0x72, 0x65, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x0e, + 0x0a, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x5c, + 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x78, 0x64, 0x73, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, + 0x42, 0x0c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6e, 0x63, + 0x66, 0x2f, 0x78, 0x64, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x78, 0x64, 0x73, 0x2f, 0x74, 0x79, 0x70, + 0x65, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go index 60b721f5f5..edd1dd8aa0 100644 --- a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go +++ b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go @@ -271,6 +271,8 @@ func (m *Matcher_OnMatch) validate(all bool) error { var errors []error + // no validation rules for KeepMatching + oneofOnMatchPresent := false switch v := m.OnMatch.(type) { case *Matcher_OnMatch_Matcher: diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index 4a0425a8e5..c12e4904da 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -11,8 +11,8 @@ go_library( "decls.go", "env.go", "folding.go", - "io.go", "inlining.go", + "io.go", "library.go", "macro.go", "optimizer.go", @@ -64,8 +64,8 @@ go_test( "decls_test.go", "env_test.go", "folding_test.go", - "io_test.go", "inlining_test.go", + "io_test.go", "optimizer_test.go", "prompt_test.go", "validator_test.go", @@ -90,8 +90,8 @@ go_test( "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", - "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//encoding/prototext:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/cel/folding.go b/vendor/github.com/google/cel-go/cel/folding.go index 0c7ecc616f..40d843ecea 100644 --- a/vendor/github.com/google/cel-go/cel/folding.go +++ b/vendor/github.com/google/cel-go/cel/folding.go @@ -38,6 +38,23 @@ func MaxConstantFoldIterations(limit int) ConstantFoldingOption { } } +// Adds an Activation which provides known values for the folding evaluator +// +// Any values the activation provides will be used by the constant folder and turned into +// literals in the AST. +// +// Defaults to the NoVars() Activation +func FoldKnownValues(knownValues Activation) ConstantFoldingOption { + return func(opt *constantFoldingOptimizer) (*constantFoldingOptimizer, error) { + if knownValues != nil { + opt.knownValues = knownValues + } else { + opt.knownValues = NoVars() + } + return opt, nil + } +} + // NewConstantFoldingOptimizer creates an optimizer which inlines constant scalar an aggregate // literal values within function calls and select statements with their evaluated result. func NewConstantFoldingOptimizer(opts ...ConstantFoldingOption) (ASTOptimizer, error) { @@ -56,6 +73,7 @@ func NewConstantFoldingOptimizer(opts ...ConstantFoldingOption) (ASTOptimizer, e type constantFoldingOptimizer struct { maxFoldIterations int + knownValues Activation } // Optimize queries the expression graph for scalar and aggregate literal expressions within call and @@ -68,7 +86,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // Walk the list of foldable expression and continue to fold until there are no more folds left. // All of the fold candidates returned by the constantExprMatcher should succeed unless there's // a logic bug with the selection of expressions. - constantExprMatcherCapture := func(e ast.NavigableExpr) bool { return constantExprMatcher(ctx, a, e) } + constantExprMatcherCapture := func(e ast.NavigableExpr) bool { return opt.constantExprMatcher(ctx, a, e) } foldableExprs := ast.MatchDescendants(root, constantExprMatcherCapture) foldCount := 0 for len(foldableExprs) != 0 && foldCount < opt.maxFoldIterations { @@ -83,8 +101,10 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) continue } // Otherwise, assume all context is needed to evaluate the expression. - err := tryFold(ctx, a, fold) - if err != nil { + err := opt.tryFold(ctx, a, fold) + // Ignore errors for identifiers, since there is no guarantee that the environment + // has a value for them. + if err != nil && fold.Kind() != ast.IdentKind { ctx.ReportErrorAtID(fold.ID(), "constant-folding evaluation failed: %v", err.Error()) return a } @@ -96,7 +116,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // one last time. In this case, there's no guarantee they'll run, so we only update the // target comprehension node with the literal value if the evaluation succeeds. for _, compre := range ast.MatchDescendants(root, ast.KindMatcher(ast.ComprehensionKind)) { - tryFold(ctx, a, compre) + opt.tryFold(ctx, a, compre) } // If the output is a list, map, or struct which contains optional entries, then prune it @@ -126,7 +146,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // // If the evaluation succeeds, the input expr value will be modified to become a literal, otherwise // the method will return an error. -func tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { +func (opt *constantFoldingOptimizer) tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { // Assume all context is needed to evaluate the expression. subAST := &Ast{ impl: ast.NewCheckedAST(ast.NewAST(expr, a.SourceInfo()), a.TypeMap(), a.ReferenceMap()), @@ -135,7 +155,11 @@ func tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { if err != nil { return err } - out, _, err := prg.Eval(NoVars()) + activation := opt.knownValues + if activation == nil { + activation = NoVars() + } + out, _, err := prg.Eval(activation) if err != nil { return err } @@ -469,13 +493,15 @@ func adaptLiteral(ctx *OptimizerContext, val ref.Val) (ast.Expr, error) { // Only comprehensions which are not nested are included as possible constant folds, and only // if all variables referenced in the comprehension stack exist are only iteration or // accumulation variables. -func constantExprMatcher(ctx *OptimizerContext, a *ast.AST, e ast.NavigableExpr) bool { +func (opt *constantFoldingOptimizer) constantExprMatcher(ctx *OptimizerContext, a *ast.AST, e ast.NavigableExpr) bool { switch e.Kind() { case ast.CallKind: return constantCallMatcher(e) case ast.SelectKind: sel := e.AsSelect() // guaranteed to be a navigable value return constantMatcher(sel.Operand().(ast.NavigableExpr)) + case ast.IdentKind: + return opt.knownValues != nil && a.ReferenceMap()[e.ID()] != nil case ast.ComprehensionKind: if isNestedComprehension(e) { return false diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go index 7b1a4bed28..2e611228d9 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -126,6 +126,55 @@ func ValueAsAlphaProto(res ref.Val) (*exprpb.Value, error) { return alpha, err } +// RefValToExprValue converts between ref.Val and google.api.expr.v1alpha1.ExprValue. +// The result ExprValue is the serialized proto form. +func RefValToExprValue(res ref.Val) (*exprpb.ExprValue, error) { + return ExprValueAsAlphaProto(res) +} + +// ExprValueAsAlphaProto converts between ref.Val and google.api.expr.v1alpha1.ExprValue. +// The result ExprValue is the serialized proto form. +func ExprValueAsAlphaProto(res ref.Val) (*exprpb.ExprValue, error) { + canonical, err := ExprValueAsProto(res) + if err != nil { + return nil, err + } + alpha := &exprpb.ExprValue{} + err = convertProto(canonical, alpha) + return alpha, err +} + +// ExprValueAsProto converts between ref.Val and cel.expr.ExprValue. +// The result ExprValue is the serialized proto form. +func ExprValueAsProto(res ref.Val) (*celpb.ExprValue, error) { + switch res := res.(type) { + case *types.Unknown: + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Unknown{ + Unknown: &celpb.UnknownSet{ + Exprs: res.IDs(), + }, + }}, nil + case *types.Err: + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Error{ + Error: &celpb.ErrorSet{ + // Keeping the error code as UNKNOWN since there's no error codes associated with + // Cel-Go runtime errors. + Errors: []*celpb.Status{{Code: 2, Message: res.Error()}}, + }, + }, + }, nil + default: + val, err := ValueAsProto(res) + if err != nil { + return nil, err + } + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Value{Value: val}}, nil + } +} + // ValueAsProto converts between ref.Val and cel.expr.Value. // The result Value is the serialized proto form. The ref.Val must not be error or unknown. func ValueAsProto(res ref.Val) (*celpb.Value, error) { diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go index a9e04fc262..0057c16ccb 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/github.com/google/cel-go/checker/checker.go @@ -152,7 +152,7 @@ func (c *checker) checkOptSelect(e ast.Expr) { } c.errors.notAnOptionalFieldSelectionCall(e.ID(), c.location(e), fmt.Sprintf( - "incorrect signature.%s argument count: %d%s", t, len(call.Args()))) + "incorrect signature.%s argument count: %d", t, len(call.Args()))) return } diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go index 59be751c97..5bc6318ed0 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/github.com/google/cel-go/checker/cost.go @@ -545,16 +545,17 @@ func (c *coster) costCall(e ast.Expr) CostEstimate { if len(overloadIDs) == 0 { return CostEstimate{} } - var targetType AstNode + var targetType *AstNode if call.IsMemberFunction() { sum = sum.Add(c.cost(call.Target())) - targetType = c.newAstNode(call.Target()) + var t AstNode = c.newAstNode(call.Target()) + targetType = &t } // Pick a cost estimate range that covers all the overload cost estimation ranges fnCost := CostEstimate{Min: uint64(math.MaxUint64), Max: 0} var resultSize *SizeEstimate for _, overload := range overloadIDs { - overloadCost := c.functionCost(e, call.FunctionName(), overload, &targetType, argTypes, argCosts) + overloadCost := c.functionCost(e, call.FunctionName(), overload, targetType, argTypes, argCosts) fnCost = fnCost.Union(overloadCost.CostEstimate) if overloadCost.ResultSize != nil { if resultSize == nil { diff --git a/vendor/github.com/google/cel-go/common/decls/decls.go b/vendor/github.com/google/cel-go/common/decls/decls.go index 759b1d16b2..a4a51c3f28 100644 --- a/vendor/github.com/google/cel-go/common/decls/decls.go +++ b/vendor/github.com/google/cel-go/common/decls/decls.go @@ -303,7 +303,7 @@ func (f *FunctionDecl) OverloadDecls() []*OverloadDecl { return overloads } -// Returns true if the function has late bindings. A function cannot mix late bindings with other bindings. +// HasLateBinding returns true if the function has late bindings. A function cannot mix late bindings with other bindings. func (f *FunctionDecl) HasLateBinding() bool { if f == nil { return false diff --git a/vendor/github.com/google/cel-go/ext/BUILD.bazel b/vendor/github.com/google/cel-go/ext/BUILD.bazel index 24066b864f..ef4f4ec3db 100644 --- a/vendor/github.com/google/cel-go/ext/BUILD.bazel +++ b/vendor/github.com/google/cel-go/ext/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "math.go", "native.go", "protos.go", + "regex.go", "sets.go", "strings.go", ], @@ -26,6 +27,7 @@ go_library( deps = [ "//cel:go_default_library", "//checker:go_default_library", + "//common:go_default_library", "//common/ast:go_default_library", "//common/decls:go_default_library", "//common/env:go_default_library", @@ -59,6 +61,7 @@ go_test( "math_test.go", "native_test.go", "protos_test.go", + "regex_test.go", "sets_test.go", "strings_test.go", ], @@ -68,6 +71,7 @@ go_test( deps = [ "//cel:go_default_library", "//checker:go_default_library", + "//common:go_default_library", "//common/env:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", diff --git a/vendor/github.com/google/cel-go/ext/README.md b/vendor/github.com/google/cel-go/ext/README.md index 4620204fc2..41ae6a3143 100644 --- a/vendor/github.com/google/cel-go/ext/README.md +++ b/vendor/github.com/google/cel-go/ext/README.md @@ -356,6 +356,23 @@ Examples: math.isFinite(0.0/0.0) // returns false math.isFinite(1.2) // returns true +### Math.Sqrt + +Introduced at version: 2 + +Returns the square root of the given input as double +Throws error for negative or non-numeric inputs + + math.sqrt() -> + math.sqrt() -> + math.sqrt() -> + +Examples: + + math.sqrt(81) // returns 9.0 + math.sqrt(985.25) // returns 31.388692231439016 + math.sqrt(-15) // returns NaN + ## Protos Protos configure extended macros and functions for proto manipulation. @@ -395,7 +412,7 @@ zero-based. ### Distinct -**Introduced in version 2** +**Introduced in version 2 (cost support in version 3)** Returns the distinct elements of a list. @@ -409,7 +426,7 @@ Examples: ### Flatten -**Introduced in version 1** +**Introduced in version 1 (cost support in version 3)** Flattens a list recursively. If an optional depth is provided, the list is flattened to a the specificied level. @@ -428,7 +445,7 @@ Examples: ### Range -**Introduced in version 2** +**Introduced in version 2 (cost support in version 3)** Returns a list of integers from 0 to n-1. @@ -441,7 +458,7 @@ Examples: ### Reverse -**Introduced in version 2** +**Introduced in version 2 (cost support in version 3)** Returns the elements of a list in reverse order. @@ -454,6 +471,7 @@ Examples: ### Slice +**Introduced in version 0 (cost support in version 3)** Returns a new sub-list using the indexes provided. @@ -466,7 +484,7 @@ Examples: ### Sort -**Introduced in version 2** +**Introduced in version 2 (cost support in version 3)** Sorts a list with comparable elements. If the element type is not comparable or the element types are not the same, the function will produce an error. @@ -483,7 +501,7 @@ Examples: ### SortBy -**Introduced in version 2** +**Introduced in version 2 (cost support in version 3)** Sorts a list by a key value, i.e., the order is determined by the result of an expression applied to each element of the list. diff --git a/vendor/github.com/google/cel-go/ext/extension_option_factory.go b/vendor/github.com/google/cel-go/ext/extension_option_factory.go index 4906227a55..cebf0d760d 100644 --- a/vendor/github.com/google/cel-go/ext/extension_option_factory.go +++ b/vendor/github.com/google/cel-go/ext/extension_option_factory.go @@ -69,4 +69,7 @@ var extFactories = map[string]extensionFactory{ "two-var-comprehensions": func(version uint32) cel.EnvOption { return TwoVarComprehensions(TwoVarComprehensionsVersion(version)) }, + "regex": func(version uint32) cel.EnvOption { + return Regex(RegexVersion(version)) + }, } diff --git a/vendor/github.com/google/cel-go/ext/lists.go b/vendor/github.com/google/cel-go/ext/lists.go index 9a3cce37ed..b27ddf22f5 100644 --- a/vendor/github.com/google/cel-go/ext/lists.go +++ b/vendor/github.com/google/cel-go/ext/lists.go @@ -20,11 +20,14 @@ import ( "sort" "github.com/google/cel-go/cel" + "github.com/google/cel-go/checker" + "github.com/google/cel-go/common" "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/common/types/traits" + "github.com/google/cel-go/interpreter" "github.com/google/cel-go/parser" ) @@ -44,7 +47,7 @@ var comparableTypes = []*cel.Type{ // // # Distinct // -// Introduced in version: 2 +// Introduced in version: 2 (cost support in version 3) // // Returns the distinct elements of a list. // @@ -58,7 +61,7 @@ var comparableTypes = []*cel.Type{ // // # Range // -// Introduced in version: 2 +// Introduced in version: 2 (cost support in version 3) // // Returns a list of integers from 0 to n-1. // @@ -70,7 +73,7 @@ var comparableTypes = []*cel.Type{ // // # Reverse // -// Introduced in version: 2 +// Introduced in version: 2 (cost support in version 3) // // Returns the elements of a list in reverse order. // @@ -82,6 +85,8 @@ var comparableTypes = []*cel.Type{ // // # Slice // +// Introduced in version: 0 (cost support in version 3) +// // Returns a new sub-list using the indexes provided. // // .slice(, ) -> @@ -93,12 +98,14 @@ var comparableTypes = []*cel.Type{ // // # Flatten // +// Introduced in version: 1 (cost support in version 3) +// // Flattens a list recursively. -// If an optional depth is provided, the list is flattened to a the specificied level. +// If an optional depth is provided, the list is flattened to a the specified level. // A negative depth value will result in an error. // -// .flatten() -> -// .flatten(, ) -> +// .flatten() -> +// .flatten() -> // // Examples: // @@ -110,7 +117,7 @@ var comparableTypes = []*cel.Type{ // // # Sort // -// Introduced in version: 2 +// Introduced in version: 2 (cost support in version 3) // // Sorts a list with comparable elements. If the element type is not comparable // or the element types are not the same, the function will produce an error. @@ -127,6 +134,8 @@ var comparableTypes = []*cel.Type{ // // # SortBy // +// Introduced in version: 2 (cost support in version 3) +// // Sorts a list by a key value, i.e., the order is determined by the result of // an expression applied to each element of the list. // The output of the key expression must be a comparable type, otherwise the @@ -303,9 +312,8 @@ func (lib listsLib) CompileOptions() []cel.EnvOption { opts = append(opts, cel.Function("lists.range", cel.Overload("lists_range", []*cel.Type{cel.IntType}, cel.ListType(cel.IntType), - cel.FunctionBinding(func(args ...ref.Val) ref.Val { - n := args[0].(types.Int) - result, err := genRange(n) + cel.UnaryBinding(func(n ref.Val) ref.Val { + result, err := genRange(n.(types.Int)) if err != nil { return types.WrapErr(err) } @@ -316,9 +324,8 @@ func (lib listsLib) CompileOptions() []cel.EnvOption { opts = append(opts, cel.Function("reverse", cel.MemberOverload("list_reverse", []*cel.Type{listType}, listType, - cel.FunctionBinding(func(args ...ref.Val) ref.Val { - list := args[0].(traits.Lister) - result, err := reverseList(list) + cel.UnaryBinding(func(list ref.Val) ref.Val { + result, err := reverseList(list.(traits.Lister)) if err != nil { return types.WrapErr(err) } @@ -339,13 +346,61 @@ func (lib listsLib) CompileOptions() []cel.EnvOption { ), )) } + if lib.version >= 3 { + estimators := []checker.CostOption{ + checker.OverloadCostEstimate("list_slice", estimateListSlice), + checker.OverloadCostEstimate("list_flatten", estimateListFlatten), + checker.OverloadCostEstimate("list_flatten_int", estimateListFlatten), + checker.OverloadCostEstimate("lists_range", estimateListsRange), + checker.OverloadCostEstimate("list_reverse", estimateListReverse), + checker.OverloadCostEstimate("list_distinct", estimateListDistinct), + } + for _, t := range comparableTypes { + estimators = append(estimators, + checker.OverloadCostEstimate( + fmt.Sprintf("list_%s_sort", t.TypeName()), + estimateListSort(t), + ), + checker.OverloadCostEstimate( + fmt.Sprintf("list_%s_sortByAssociatedKeys", t.TypeName()), + estimateListSortBy(t), + ), + ) + } + opts = append(opts, cel.CostEstimatorOptions(estimators...)) + } return opts } // ProgramOptions implements the Library interface method. -func (listsLib) ProgramOptions() []cel.ProgramOption { - return []cel.ProgramOption{} +func (lib *listsLib) ProgramOptions() []cel.ProgramOption { + var opts []cel.ProgramOption + if lib.version >= 3 { + // TODO: Add cost trackers for list operations + trackers := []interpreter.CostTrackerOption{ + interpreter.OverloadCostTracker("list_slice", trackListOutputSize), + interpreter.OverloadCostTracker("list_flatten", trackListFlatten), + interpreter.OverloadCostTracker("list_flatten_int", trackListFlatten), + interpreter.OverloadCostTracker("lists_range", trackListOutputSize), + interpreter.OverloadCostTracker("list_reverse", trackListOutputSize), + interpreter.OverloadCostTracker("list_distinct", trackListDistinct), + } + for _, t := range comparableTypes { + trackers = append(trackers, + interpreter.OverloadCostTracker( + fmt.Sprintf("list_%s_sort", t.TypeName()), + trackListSort, + ), + interpreter.OverloadCostTracker( + fmt.Sprintf("list_%s_sortByAssociatedKeys", t.TypeName()), + trackListSortBy, + ), + ) + } + opts = append(opts, cel.CostTrackerOptions(trackers...)) + } + return opts } func genRange(n types.Int) (ref.Val, error) { @@ -450,20 +505,24 @@ func sortListByAssociatedKeys(list, keys traits.Lister) (ref.Val, error) { sortedIndices := make([]ref.Val, 0, listLength) for i := types.IntZero; i < listLength; i++ { - if keys.Get(i).Type() != elem.Type() { - return nil, fmt.Errorf("list elements must have the same type") - } sortedIndices = append(sortedIndices, i) } + var err error sort.Slice(sortedIndices, func(i, j int) bool { iKey := keys.Get(sortedIndices[i]) jKey := keys.Get(sortedIndices[j]) + if iKey.Type() != elem.Type() || jKey.Type() != elem.Type() { + err = fmt.Errorf("list elements must have the same type") + return false + } return iKey.(traits.Comparer).Compare(jKey) == types.IntNegOne }) + if err != nil { + return nil, err + } sorted := make([]ref.Val, 0, listLength) - for _, sortedIdx := range sortedIndices { sorted = append(sorted, list.Get(sortedIdx)) } @@ -550,3 +609,171 @@ func templatedOverloads(types []*cel.Type, template func(t *cel.Type) cel.Functi } return overloads } + +// estimateListSlice computes an O(n) slice operation with a cost factor of 1. +func estimateListSlice(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) != 2 { + return nil + } + sz := estimateSize(estimator, *target) + start := nodeAsIntValue(args[0], 0) + end := nodeAsIntValue(args[1], sz.Max) + return estimateAllocatingListCall(1, checker.FixedSizeEstimate(end-start)) +} + +// estimateListsRange computes an O(n) range operation with a cost factor of 1. +func estimateListsRange(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target != nil || len(args) != 1 { + return nil + } + return estimateAllocatingListCall(1, checker.FixedSizeEstimate(nodeAsIntValue(args[0], math.MaxUint))) +} + +// estimateListReverse computes an O(n) reverse operation with a cost factor of 1. +func estimateListReverse(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) != 0 { + return nil + } + return estimateAllocatingListCall(1, estimateSize(estimator, *target)) +} + +// estimateListFlatten computes an O(n) flatten operation with a cost factor proportional to the flatten depth. +func estimateListFlatten(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) > 1 { + return nil + } + depth := uint64(1) + if len(args) == 1 { + depth = nodeAsIntValue(args[0], math.MaxUint) + } + return estimateAllocatingListCall(float64(depth), estimateSize(estimator, *target)) +} + +// Compute an O(n^2) with a cost factor of 2, equivalent to sets.contains with a result list +// which can vary in size from 1 element to the original list size. +func estimateListDistinct(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) != 0 { + return nil + } + sz := estimateSize(estimator, *target) + costFactor := 2.0 + return estimateAllocatingListCall(costFactor, sz.Multiply(sz)) +} + +// estimateListSort computes an O(n^2) sort operation with a cost factor of 2 for the equality +// operations against the elements in the list against themselves which occur during the sort computation. +func estimateListSort(t *types.Type) checker.FunctionEstimator { + return func(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) != 0 { + return nil + } + return estimateListSortCost(estimator, *target, t) + } +} + +// estimateListSortBy computes an O(n^2) sort operation with a cost factor of 2 for the equality +// operations against the sort index list which occur during the sort computation. +func estimateListSortBy(u *types.Type) checker.FunctionEstimator { + return func(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if target == nil || len(args) != 1 { + return nil + } + // Estimate the size of the list used as the sort index + return estimateListSortCost(estimator, args[0], u) + } +} + +// estimateListSortCost estimates an O(n^2) sort operation with a cost factor of 2 for the equality +// operations which occur during the sort computation. +func estimateListSortCost(estimator checker.CostEstimator, node checker.AstNode, elemType *types.Type) *checker.CallEstimate { + sz := estimateSize(estimator, node) + costFactor := 2.0 + switch elemType { + case types.StringType, types.BytesType: + costFactor += common.StringTraversalCostFactor + } + return estimateAllocatingListCall(costFactor, sz.Multiply(sz)) +} + +// estimateAllocatingListCall computes cost as a function of the size of the result list with a +// baseline cost for the call dispatch and the associated list allocation. +func estimateAllocatingListCall(costFactor float64, listSize checker.SizeEstimate) *checker.CallEstimate { + return estimateListCall(costFactor, listSize, true) +} + +// estimateListCall computes cost as a function of the size of the target list and whether the +// call allocates memory. +func estimateListCall(costFactor float64, listSize checker.SizeEstimate, allocates bool) *checker.CallEstimate { + cost := listSize.MultiplyByCostFactor(costFactor).Add(callCostEstimate) + if allocates { + cost = cost.Add(checker.FixedCostEstimate(common.ListCreateBaseCost)) + } + return &checker.CallEstimate{CostEstimate: cost, ResultSize: &listSize} +} + +// trackListOutputSize computes cost as a function of the size of the result list. +func trackListOutputSize(_ []ref.Val, result ref.Val) *uint64 { + return trackAllocatingListCall(1, actualSize(result)) +} + +// trackListFlatten computes cost as a function of the size of the result list and the depth of +// the flatten operation. +func trackListFlatten(args []ref.Val, _ ref.Val) *uint64 { + depth := 1.0 + if len(args) == 2 { + depth = float64(args[1].(types.Int)) + } + inputSize := actualSize(args[0]) + return trackAllocatingListCall(depth, inputSize) +} + +// trackListDistinct computes costs as a worst-case O(n^2) operation over the input list. +func trackListDistinct(args []ref.Val, _ ref.Val) *uint64 { + return trackListSelfCompare(args[0].(traits.Lister)) +} + +// trackListSort computes costs as a worst-case O(n^2) operation over the input list. +func trackListSort(args []ref.Val, result ref.Val) *uint64 { + return trackListSelfCompare(args[0].(traits.Lister)) +} + +// trackListSortBy computes costs as a worst-case O(n^2) operation over the sort index list. +func trackListSortBy(args []ref.Val, result ref.Val) *uint64 { + return trackListSelfCompare(args[1].(traits.Lister)) +} + +// trackListSelfCompare computes costs as a worst-case O(n^2) operation over the input list. +func trackListSelfCompare(l traits.Lister) *uint64 { + sz := actualSize(l) + costFactor := 2.0 + if sz == 0 { + return trackAllocatingListCall(costFactor, 0) + } + elem := l.Get(types.IntZero) + if elem.Type() == types.StringType || elem.Type() == types.BytesType { + costFactor += common.StringTraversalCostFactor + } + return trackAllocatingListCall(costFactor, sz*sz) +} + +// trackAllocatingListCall computes costs as a function of the size of the result list with a baseline cost +// for the call dispatch and the associated list allocation. +func trackAllocatingListCall(costFactor float64, size uint64) *uint64 { + cost := uint64(float64(size)*costFactor) + callCost + common.ListCreateBaseCost + return &cost +} + +func nodeAsIntValue(node checker.AstNode, defaultVal uint64) uint64 { + if node.Expr().Kind() != ast.LiteralKind { + return defaultVal + } + lit := node.Expr().AsLiteral() + if lit.Type() != types.IntType { + return defaultVal + } + val := lit.(types.Int) + if val < types.IntZero { + return 0 + } + return uint64(lit.(types.Int)) +} diff --git a/vendor/github.com/google/cel-go/ext/math.go b/vendor/github.com/google/cel-go/ext/math.go index 250246db15..6df8e37736 100644 --- a/vendor/github.com/google/cel-go/ext/math.go +++ b/vendor/github.com/google/cel-go/ext/math.go @@ -325,6 +325,23 @@ import ( // // math.isFinite(0.0/0.0) // returns false // math.isFinite(1.2) // returns true +// +// # Math.Sqrt +// +// Introduced at version: 2 +// +// Returns the square root of the given input as double +// Throws error for negative or non-numeric inputs +// +// math.sqrt() -> +// math.sqrt() -> +// math.sqrt() -> +// +// Examples: +// +// math.sqrt(81) // returns 9.0 +// math.sqrt(985.25) // returns 31.388692231439016 +// math.sqrt(-15) // returns NaN func Math(options ...MathOption) cel.EnvOption { m := &mathLib{version: math.MaxUint32} for _, o := range options { @@ -357,6 +374,9 @@ const ( absFunc = "math.abs" signFunc = "math.sign" + // SquareRoot function + sqrtFunc = "math.sqrt" + // Bitwise functions bitAndFunc = "math.bitAnd" bitOrFunc = "math.bitOr" @@ -548,6 +568,18 @@ func (lib *mathLib) CompileOptions() []cel.EnvOption { ), ) } + if lib.version >= 2 { + opts = append(opts, + cel.Function(sqrtFunc, + cel.Overload("math_sqrt_double", []*cel.Type{cel.DoubleType}, cel.DoubleType, + cel.UnaryBinding(sqrt)), + cel.Overload("math_sqrt_int", []*cel.Type{cel.IntType}, cel.DoubleType, + cel.UnaryBinding(sqrt)), + cel.Overload("math_sqrt_uint", []*cel.Type{cel.UintType}, cel.DoubleType, + cel.UnaryBinding(sqrt)), + ), + ) + } return opts } @@ -691,6 +723,21 @@ func sign(val ref.Val) ref.Val { } } + +func sqrt(val ref.Val) ref.Val { + switch v := val.(type) { + case types.Double: + return types.Double(math.Sqrt(float64(v))) + case types.Int: + return types.Double(math.Sqrt(float64(v))) + case types.Uint: + return types.Double(math.Sqrt(float64(v))) + default: + return types.NewErr("no such overload: sqrt") + } +} + + func bitAndPairInt(first, second ref.Val) ref.Val { l := first.(types.Int) r := second.(types.Int) diff --git a/vendor/github.com/google/cel-go/ext/regex.go b/vendor/github.com/google/cel-go/ext/regex.go new file mode 100644 index 0000000000..1a66f65d0a --- /dev/null +++ b/vendor/github.com/google/cel-go/ext/regex.go @@ -0,0 +1,332 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ext + +import ( + "errors" + "fmt" + "math" + "regexp" + "strconv" + "strings" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +const ( + regexReplace = "regex.replace" + regexExtract = "regex.extract" + regexExtractAll = "regex.extractAll" +) + +// Regex returns a cel.EnvOption to configure extended functions for regular +// expression operations. +// +// Note: all functions use the 'regex' namespace. If you are +// currently using a variable named 'regex', the functions will likely work as +// intended, however there is some chance for collision. +// +// This library depends on the CEL optional type. Please ensure that the +// cel.OptionalTypes() is enabled when using regex extensions. +// +// # Replace +// +// The `regex.replace` function replaces all non-overlapping substring of a regex +// pattern in the target string with a replacement string. Optionally, you can +// limit the number of replacements by providing a count argument. When the count +// is a negative number, the function acts as replace all. Only numeric (\N) +// capture group references are supported in the replacement string, with +// validation for correctness. Backslashed-escaped digits (\1 to \9) within the +// replacement argument can be used to insert text matching the corresponding +// parenthesized group in the regexp pattern. An error will be thrown for invalid +// regex or replace string. +// +// regex.replace(target: string, pattern: string, replacement: string) -> string +// regex.replace(target: string, pattern: string, replacement: string, count: int) -> string +// +// Examples: +// +// regex.replace('hello world hello', 'hello', 'hi') == 'hi world hi' +// regex.replace('banana', 'a', 'x', 0) == 'banana' +// regex.replace('banana', 'a', 'x', 1) == 'bxnana' +// regex.replace('banana', 'a', 'x', 2) == 'bxnxna' +// regex.replace('banana', 'a', 'x', -12) == 'bxnxnx' +// regex.replace('foo bar', '(fo)o (ba)r', r'\2 \1') == 'ba fo' +// regex.replace('test', '(.)', r'\2') \\ Runtime Error invalid replace string +// regex.replace('foo bar', '(', '$2 $1') \\ Runtime Error invalid regex string +// regex.replace('id=123', r'id=(?P\d+)', r'value: \values') \\ Runtime Error invalid replace string +// +// # Extract +// +// The `regex.extract` function returns the first match of a regex pattern in a +// string. If no match is found, it returns an optional none value. An error will +// be thrown for invalid regex or for multiple capture groups. +// +// regex.extract(target: string, pattern: string) -> optional +// +// Examples: +// +// regex.extract('hello world', 'hello(.*)') == optional.of(' world') +// regex.extract('item-A, item-B', 'item-(\\w+)') == optional.of('A') +// regex.extract('HELLO', 'hello') == optional.empty() +// regex.extract('testuser@testdomain', '(.*)@([^.]*)') // Runtime Error multiple capture group +// +// # Extract All +// +// The `regex.extractAll` function returns a list of all matches of a regex +// pattern in a target string. If no matches are found, it returns an empty list. An error will +// be thrown for invalid regex or for multiple capture groups. +// +// regex.extractAll(target: string, pattern: string) -> list +// +// Examples: +// +// regex.extractAll('id:123, id:456', 'id:\\d+') == ['id:123', 'id:456'] +// regex.extractAll('id:123, id:456', 'assa') == [] +// regex.extractAll('testuser@testdomain', '(.*)@([^.]*)') // Runtime Error multiple capture group +func Regex(options ...RegexOptions) cel.EnvOption { + s := ®exLib{ + version: math.MaxUint32, + } + for _, o := range options { + s = o(s) + } + return cel.Lib(s) +} + +// RegexOptions declares a functional operator for configuring regex extension. +type RegexOptions func(*regexLib) *regexLib + +// RegexVersion configures the version of the Regex library definitions to use. See [Regex] for supported values. +func RegexVersion(version uint32) RegexOptions { + return func(lib *regexLib) *regexLib { + lib.version = version + return lib + } +} + +type regexLib struct { + version uint32 +} + +// LibraryName implements that SingletonLibrary interface method. +func (r *regexLib) LibraryName() string { + return "cel.lib.ext.regex" +} + +// CompileOptions implements the cel.Library interface method. +func (r *regexLib) CompileOptions() []cel.EnvOption { + optionalTypesEnabled := func(env *cel.Env) (*cel.Env, error) { + if !env.HasLibrary("cel.lib.optional") { + return nil, errors.New("regex library requires the optional library") + } + return env, nil + } + opts := []cel.EnvOption{ + cel.Function(regexExtract, + cel.Overload("regex_extract_string_string", []*cel.Type{cel.StringType, cel.StringType}, cel.OptionalType(cel.StringType), + cel.BinaryBinding(extract))), + + cel.Function(regexExtractAll, + cel.Overload("regex_extractAll_string_string", []*cel.Type{cel.StringType, cel.StringType}, cel.ListType(cel.StringType), + cel.BinaryBinding(extractAll))), + + cel.Function(regexReplace, + cel.Overload("regex_replace_string_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, cel.StringType, + cel.FunctionBinding(regReplace)), + cel.Overload("regex_replace_string_string_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.StringType, cel.IntType}, cel.StringType, + cel.FunctionBinding((regReplaceN))), + ), + cel.EnvOption(optionalTypesEnabled), + } + return opts +} + +// ProgramOptions implements the cel.Library interface method +func (r *regexLib) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func compileRegex(regexStr string) (*regexp.Regexp, error) { + re, err := regexp.Compile(regexStr) + if err != nil { + return nil, fmt.Errorf("given regex is invalid: %w", err) + } + return re, nil +} + +func regReplace(args ...ref.Val) ref.Val { + target := args[0].(types.String) + regexStr := args[1].(types.String) + replaceStr := args[2].(types.String) + + return regReplaceN(target, regexStr, replaceStr, types.Int(-1)) +} + +func regReplaceN(args ...ref.Val) ref.Val { + target := string(args[0].(types.String)) + regexStr := string(args[1].(types.String)) + replaceStr := string(args[2].(types.String)) + replaceCount := int64(args[3].(types.Int)) + + if replaceCount == 0 { + return types.String(target) + } + + if replaceCount > math.MaxInt32 { + return types.NewErr("integer overflow") + } + + // If replaceCount is negative, just do a replaceAll. + if replaceCount < 0 { + replaceCount = -1 + } + + re, err := regexp.Compile(regexStr) + if err != nil { + return types.WrapErr(err) + } + + var resultBuilder strings.Builder + var lastIndex int + counter := int64(0) + + matches := re.FindAllStringSubmatchIndex(target, -1) + + for _, match := range matches { + if replaceCount != -1 && counter >= replaceCount { + break + } + + processedReplacement, err := replaceStrValidator(target, re, match, replaceStr) + if err != nil { + return types.WrapErr(err) + } + + resultBuilder.WriteString(target[lastIndex:match[0]]) + resultBuilder.WriteString(processedReplacement) + lastIndex = match[1] + counter++ + } + + resultBuilder.WriteString(target[lastIndex:]) + return types.String(resultBuilder.String()) +} + +func replaceStrValidator(target string, re *regexp.Regexp, match []int, replacement string) (string, error) { + groupCount := re.NumSubexp() + var sb strings.Builder + runes := []rune(replacement) + + for i := 0; i < len(runes); i++ { + c := runes[i] + + if c != '\\' { + sb.WriteRune(c) + continue + } + + if i+1 >= len(runes) { + return "", fmt.Errorf("invalid replacement string: '%s' \\ not allowed at end", replacement) + } + + i++ + nextChar := runes[i] + + if nextChar == '\\' { + sb.WriteRune('\\') + continue + } + + groupNum, err := strconv.Atoi(string(nextChar)) + if err != nil { + return "", fmt.Errorf("invalid replacement string: '%s' \\ must be followed by a digit or \\", replacement) + } + + if groupNum > groupCount { + return "", fmt.Errorf("replacement string references group %d but regex has only %d group(s)", groupNum, groupCount) + } + + if match[2*groupNum] != -1 { + sb.WriteString(target[match[2*groupNum]:match[2*groupNum+1]]) + } + } + return sb.String(), nil +} + +func extract(target, regexStr ref.Val) ref.Val { + t := string(target.(types.String)) + r := string(regexStr.(types.String)) + re, err := compileRegex(r) + if err != nil { + return types.WrapErr(err) + } + + if len(re.SubexpNames())-1 > 1 { + return types.WrapErr(fmt.Errorf("regular expression has more than one capturing group: %q", r)) + } + + matches := re.FindStringSubmatch(t) + if len(matches) == 0 { + return types.OptionalNone + } + + // If there is a capturing group, return the first match; otherwise, return the whole match. + if len(matches) > 1 { + capturedGroup := matches[1] + // If optional group is empty, return OptionalNone. + if capturedGroup == "" { + return types.OptionalNone + } + return types.OptionalOf(types.String(capturedGroup)) + } + return types.OptionalOf(types.String(matches[0])) +} + +func extractAll(target, regexStr ref.Val) ref.Val { + t := string(target.(types.String)) + r := string(regexStr.(types.String)) + re, err := compileRegex(r) + if err != nil { + return types.WrapErr(err) + } + + groupCount := len(re.SubexpNames()) - 1 + if groupCount > 1 { + return types.WrapErr(fmt.Errorf("regular expression has more than one capturing group: %q", r)) + } + + matches := re.FindAllStringSubmatch(t, -1) + result := make([]string, 0, len(matches)) + if len(matches) == 0 { + return types.NewStringList(types.DefaultTypeAdapter, result) + } + + if groupCount != 1 { + for _, match := range matches { + result = append(result, match[0]) + } + return types.NewStringList(types.DefaultTypeAdapter, result) + } + + for _, match := range matches { + if match[1] != "" { + result = append(result, match[1]) + } + } + return types.NewStringList(types.DefaultTypeAdapter, result) +} diff --git a/vendor/github.com/google/cel-go/ext/sets.go b/vendor/github.com/google/cel-go/ext/sets.go index 9a9ef6eef6..ecac4bf9d0 100644 --- a/vendor/github.com/google/cel-go/ext/sets.go +++ b/vendor/github.com/google/cel-go/ext/sets.go @@ -236,13 +236,13 @@ func setsEquivalent(listA, listB ref.Val) ref.Val { func estimateSetsCost(costFactor float64) checker.FunctionEstimator { return func(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { - if len(args) == 2 { - arg0Size := estimateSize(estimator, args[0]) - arg1Size := estimateSize(estimator, args[1]) - costEstimate := arg0Size.Multiply(arg1Size).MultiplyByCostFactor(costFactor).Add(callCostEstimate) - return &checker.CallEstimate{CostEstimate: costEstimate} + if len(args) != 2 { + return nil } - return nil + arg0Size := estimateSize(estimator, args[0]) + arg1Size := estimateSize(estimator, args[1]) + costEstimate := arg0Size.Multiply(arg1Size).MultiplyByCostFactor(costFactor).Add(callCostEstimate) + return &checker.CallEstimate{CostEstimate: costEstimate} } } @@ -273,6 +273,6 @@ func actualSize(value ref.Val) uint64 { } var ( - callCostEstimate = checker.CostEstimate{Min: 1, Max: 1} + callCostEstimate = checker.FixedCostEstimate(1) callCost = uint64(1) ) diff --git a/vendor/github.com/google/cel-go/ext/strings.go b/vendor/github.com/google/cel-go/ext/strings.go index 88b4d7f037..de65421f6d 100644 --- a/vendor/github.com/google/cel-go/ext/strings.go +++ b/vendor/github.com/google/cel-go/ext/strings.go @@ -607,6 +607,10 @@ func lastIndexOf(str, substr string) (int64, error) { if substr == "" { return int64(len(runes)), nil } + + if len(str) < len(substr) { + return -1, nil + } return lastIndexOfOffset(str, substr, int64(len(runes)-1)) } diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/client.go b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/client.go index 076b356442..553425ee0b 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/client.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/client.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog client // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/endpoints.go b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/endpoints.go index 590f4b53a3..e19ae3be2f 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/endpoints.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/endpoints.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog endpoints // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/service.go b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/service.go index 13af9d2d6d..3516f24fa7 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/service.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/service.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog service // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/views/view.go b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/views/view.go index ba9df2b29a..6a2bc9a0c3 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/views/view.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/catalog/views/view.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog views // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/cli.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/cli.go index efc43b8e7e..21ea31e40b 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/cli.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/cli.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog HTTP client CLI support package // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/client.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/client.go index 231b55ba91..aa7e5b5470 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/client.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/client.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog client HTTP transport // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/encode_decode.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/encode_decode.go index d493e852de..49510ee390 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/encode_decode.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/encode_decode.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog HTTP client encoders and decoders // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/paths.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/paths.go index 22b9427e07..5462d1eba4 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/paths.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/paths.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // HTTP request path constructors for the catalog service. // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/types.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/types.go index c32b51e029..0a776f8f4c 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/types.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/catalog/client/types.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // catalog HTTP client types // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/cli.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/cli.go index 47cc13f62f..233eb3b170 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/cli.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/cli.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource HTTP client CLI support package // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/client.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/client.go index d55edfff78..4a4c3b2432 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/client.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/client.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource client HTTP transport // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/encode_decode.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/encode_decode.go index 0a1c99aaee..8051815027 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/encode_decode.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/encode_decode.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource HTTP client encoders and decoders // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/paths.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/paths.go index 21f53af19e..00062def33 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/paths.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/paths.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // HTTP request path constructors for the resource service. // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/types.go b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/types.go index f7318f64c1..f76d3de821 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/types.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/http/resource/client/types.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource HTTP client types // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/client.go b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/client.go index b7df3f8f96..e3e9b3f9e0 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/client.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/client.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource client // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/endpoints.go b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/endpoints.go index 3639e1c1c6..8ae1e4ffa7 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/endpoints.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/endpoints.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource endpoints // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/service.go b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/service.go index 441d6b1b55..36816cf464 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/service.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/service.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource service // diff --git a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/views/view.go b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/views/view.go index 2715e7d633..ad15438846 100644 --- a/vendor/github.com/tektoncd/hub/api/v1/gen/resource/views/view.go +++ b/vendor/github.com/tektoncd/hub/api/v1/gen/resource/views/view.go @@ -1,4 +1,4 @@ -// Code generated by goa v3.20.0, DO NOT EDIT. +// Code generated by goa v3.21.1, DO NOT EDIT. // // resource views // diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/default.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/default.go index 3bb5e02ab5..435f33f32c 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/default.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/default.go @@ -54,6 +54,8 @@ const ( // Default maximum resolution timeout used by the resolution controller before timing out when exceeded DefaultMaximumResolutionTimeout = 1 * time.Minute + DefaultSidecarLogPollingInterval = 100 * time.Millisecond + defaultTimeoutMinutesKey = "default-timeout-minutes" defaultServiceAccountKey = "default-service-account" defaultManagedByLabelValueKey = "default-managed-by-label-value" @@ -67,6 +69,7 @@ const ( defaultContainerResourceRequirementsKey = "default-container-resource-requirements" defaultImagePullBackOffTimeout = "default-imagepullbackoff-timeout" defaultMaximumResolutionTimeout = "default-maximum-resolution-timeout" + defaultSidecarLogPollingIntervalKey = "default-sidecar-log-polling-interval" ) // DefaultConfig holds all the default configurations for the config. @@ -88,6 +91,10 @@ type Defaults struct { DefaultContainerResourceRequirements map[string]corev1.ResourceRequirements DefaultImagePullBackOffTimeout time.Duration DefaultMaximumResolutionTimeout time.Duration + // DefaultSidecarLogPollingInterval specifies how frequently (as a time.Duration) the Tekton sidecar log results container polls for step completion files. + // This value is loaded from the 'sidecar-log-polling-interval' key in the config-defaults ConfigMap. + // It is used to control the responsiveness and resource usage of the sidecar in both production and test environments. + DefaultSidecarLogPollingInterval time.Duration } // GetDefaultsConfigName returns the name of the configmap containing all @@ -120,6 +127,7 @@ func (cfg *Defaults) Equals(other *Defaults) bool { other.DefaultResolverType == cfg.DefaultResolverType && other.DefaultImagePullBackOffTimeout == cfg.DefaultImagePullBackOffTimeout && other.DefaultMaximumResolutionTimeout == cfg.DefaultMaximumResolutionTimeout && + other.DefaultSidecarLogPollingInterval == cfg.DefaultSidecarLogPollingInterval && reflect.DeepEqual(other.DefaultForbiddenEnv, cfg.DefaultForbiddenEnv) } @@ -134,6 +142,7 @@ func NewDefaultsFromMap(cfgMap map[string]string) (*Defaults, error) { DefaultResolverType: DefaultResolverTypeValue, DefaultImagePullBackOffTimeout: DefaultImagePullBackOffTimeout, DefaultMaximumResolutionTimeout: DefaultMaximumResolutionTimeout, + DefaultSidecarLogPollingInterval: DefaultSidecarLogPollingInterval, } if defaultTimeoutMin, ok := cfgMap[defaultTimeoutMinutesKey]; ok { @@ -220,6 +229,14 @@ func NewDefaultsFromMap(cfgMap map[string]string) (*Defaults, error) { tc.DefaultMaximumResolutionTimeout = timeout } + if defaultSidecarPollingInterval, ok := cfgMap[defaultSidecarLogPollingIntervalKey]; ok { + interval, err := time.ParseDuration(defaultSidecarPollingInterval) + if err != nil { + return nil, fmt.Errorf("failed parsing default config %q", defaultSidecarPollingInterval) + } + tc.DefaultSidecarLogPollingInterval = interval + } + return &tc, nil } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go index 0c19d487cc..bac9a55dc0 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go @@ -107,6 +107,11 @@ const ( EnableKubernetesSidecar = "enable-kubernetes-sidecar" // DefaultEnableKubernetesSidecar is the default value for EnableKubernetesSidecar DefaultEnableKubernetesSidecar = false + // EnableWaitExponentialBackoff is the flag to enable exponential backoff strategy + EnableWaitExponentialBackoff = "enable-wait-exponential-backoff" + // DefaultEnableWaitExponentialBackoff is the default value for EnableWaitExponentialBackoff + DefaultEnableWaitExponentialBackoff = false + // EnableStepActions is the flag to enable step actions (no-op since it's stable) EnableStepActions = "enable-step-actions" @@ -198,12 +203,13 @@ type FeatureFlags struct { Coschedule string `json:"coschedule,omitempty"` EnableCELInWhenExpression bool `json:"enableCELInWhenExpression,omitempty"` // EnableStepActions is a no-op flag since StepActions are stable - EnableStepActions bool `json:"enableStepActions,omitempty"` - EnableParamEnum bool `json:"enableParamEnum,omitempty"` - EnableArtifacts bool `json:"enableArtifacts,omitempty"` - DisableInlineSpec string `json:"disableInlineSpec,omitempty"` - EnableConciseResolverSyntax bool `json:"enableConciseResolverSyntax,omitempty"` - EnableKubernetesSidecar bool `json:"enableKubernetesSidecar,omitempty"` + EnableStepActions bool `json:"enableStepActions,omitempty"` + EnableParamEnum bool `json:"enableParamEnum,omitempty"` + EnableArtifacts bool `json:"enableArtifacts,omitempty"` + DisableInlineSpec string `json:"disableInlineSpec,omitempty"` + EnableConciseResolverSyntax bool `json:"enableConciseResolverSyntax,omitempty"` + EnableKubernetesSidecar bool `json:"enableKubernetesSidecar,omitempty"` + EnableWaitExponentialBackoff bool `json:"enableWaitExponentialBackoff,omitempty"` } // GetFeatureFlagsConfigName returns the name of the configmap containing all @@ -308,6 +314,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) { if err := setFeature(EnableKubernetesSidecar, DefaultEnableKubernetesSidecar, &tc.EnableKubernetesSidecar); err != nil { return nil, err } + if err := setFeature(EnableWaitExponentialBackoff, DefaultEnableWaitExponentialBackoff, &tc.EnableWaitExponentialBackoff); err != nil { + return nil, err + } return &tc, nil } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/store.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/store.go index 65e9e99895..c2bc7e4673 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/store.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/store.go @@ -30,12 +30,13 @@ type cfgKey struct{} // Config holds the collection of configurations that we attach to contexts. // +k8s:deepcopy-gen=false type Config struct { - Defaults *Defaults - FeatureFlags *FeatureFlags - Metrics *Metrics - SpireConfig *sc.SpireConfig - Events *Events - Tracing *Tracing + Defaults *Defaults + FeatureFlags *FeatureFlags + Metrics *Metrics + SpireConfig *sc.SpireConfig + Events *Events + Tracing *Tracing + WaitExponentialBackoff *WaitExponentialBackoff } // FromContext extracts a Config from the provided context. @@ -55,12 +56,13 @@ func FromContextOrDefaults(ctx context.Context) *Config { } return &Config{ - Defaults: DefaultConfig.DeepCopy(), - FeatureFlags: DefaultFeatureFlags.DeepCopy(), - Metrics: DefaultMetrics.DeepCopy(), - SpireConfig: DefaultSpire.DeepCopy(), - Events: DefaultEvents.DeepCopy(), - Tracing: DefaultTracing.DeepCopy(), + Defaults: DefaultConfig.DeepCopy(), + FeatureFlags: DefaultFeatureFlags.DeepCopy(), + Metrics: DefaultMetrics.DeepCopy(), + SpireConfig: DefaultSpire.DeepCopy(), + Events: DefaultEvents.DeepCopy(), + Tracing: DefaultTracing.DeepCopy(), + WaitExponentialBackoff: DefaultWaitExponentialBackoff.DeepCopy(), } } @@ -83,12 +85,13 @@ func NewStore(logger configmap.Logger, onAfterStore ...func(name string, value i "defaults/features/artifacts", logger, configmap.Constructors{ - GetDefaultsConfigName(): NewDefaultsFromConfigMap, - GetFeatureFlagsConfigName(): NewFeatureFlagsFromConfigMap, - GetMetricsConfigName(): NewMetricsFromConfigMap, - GetSpireConfigName(): NewSpireConfigFromConfigMap, - GetEventsConfigName(): NewEventsFromConfigMap, - GetTracingConfigName(): NewTracingFromConfigMap, + GetDefaultsConfigName(): NewDefaultsFromConfigMap, + GetFeatureFlagsConfigName(): NewFeatureFlagsFromConfigMap, + GetMetricsConfigName(): NewMetricsFromConfigMap, + GetSpireConfigName(): NewSpireConfigFromConfigMap, + GetEventsConfigName(): NewEventsFromConfigMap, + GetTracingConfigName(): NewTracingFromConfigMap, + GetWaitExponentialBackoffConfigName(): NewWaitExponentialBackoffFromConfigMap, }, onAfterStore..., ), @@ -129,13 +132,18 @@ func (s *Store) Load() *Config { if events == nil { events = DefaultEvents.DeepCopy() } + waitExponentialBackoff := s.UntypedLoad(GetWaitExponentialBackoffConfigName()) + if waitExponentialBackoff == nil { + waitExponentialBackoff = DefaultWaitExponentialBackoff.DeepCopy() + } return &Config{ - Defaults: defaults.(*Defaults).DeepCopy(), - FeatureFlags: featureFlags.(*FeatureFlags).DeepCopy(), - Metrics: metrics.(*Metrics).DeepCopy(), - Tracing: tracing.(*Tracing).DeepCopy(), - SpireConfig: spireconfig.(*sc.SpireConfig).DeepCopy(), - Events: events.(*Events).DeepCopy(), + Defaults: defaults.(*Defaults).DeepCopy(), + FeatureFlags: featureFlags.(*FeatureFlags).DeepCopy(), + Metrics: metrics.(*Metrics).DeepCopy(), + Tracing: tracing.(*Tracing).DeepCopy(), + SpireConfig: spireconfig.(*sc.SpireConfig).DeepCopy(), + Events: events.(*Events).DeepCopy(), + WaitExponentialBackoff: waitExponentialBackoff.(*WaitExponentialBackoff).DeepCopy(), } } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/wait_exponential_backoff.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/wait_exponential_backoff.go new file mode 100644 index 0000000000..69f4cdc62b --- /dev/null +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/wait_exponential_backoff.go @@ -0,0 +1,138 @@ +/* +Copyright 2025 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "fmt" + "os" + "strconv" + "time" + + corev1 "k8s.io/api/core/v1" +) + +const ( + waitExponentialBackoffDurationKey = "duration" + waitExponentialBackoffFactorKey = "factor" + waitExponentialBackoffJitterKey = "jitter" + waitExponentialBackoffStepsKey = "steps" + waitExponentialBackoffCapKey = "cap" + + DefaultWaitExponentialBackoffDuration = "1s" + DefaultWaitExponentialBackoffFactor = 2.0 + DefaultWaitExponentialBackoffJitter = 0.0 + DefaultWaitExponentialBackoffSteps = 10 + DefaultWaitExponentialBackoffCap = "60s" +) + +// DefaultWaitExponentialBackoff holds all the default configurations for wait-exponential-backoff +var DefaultWaitExponentialBackoff, _ = newWaitExponentialBackoffFromMap(map[string]string{}) + +// WaitExponentialBackoff holds the configurations for exponential backoff +// +k8s:deepcopy-gen=true +type WaitExponentialBackoff struct { + Duration time.Duration + Factor float64 + Jitter float64 + Steps int + Cap time.Duration +} + +// Equals returns true if two Configs are identical +func (cfg *WaitExponentialBackoff) Equals(other *WaitExponentialBackoff) bool { + if cfg == nil && other == nil { + return true + } + if cfg == nil || other == nil { + return false + } + return other.Duration == cfg.Duration && + other.Factor == cfg.Factor && + other.Jitter == cfg.Jitter && + other.Steps == cfg.Steps && + other.Cap == cfg.Cap +} + +// GetWaitExponentialBackoffConfigName returns the name of the configmap containing all customizations for wait-exponential-backoff +func GetWaitExponentialBackoffConfigName() string { + if e := os.Getenv("CONFIG_WAIT_EXPONENTIAL_BACKOFF_NAME"); e != "" { + return e + } + return "config-wait-exponential-backoff" +} + +// newWaitExponentialBackoffFromMap returns a Config given a map from ConfigMap +func newWaitExponentialBackoffFromMap(config map[string]string) (*WaitExponentialBackoff, error) { + w := WaitExponentialBackoff{} + + durationStr := DefaultWaitExponentialBackoffDuration + if v, ok := config[waitExponentialBackoffDurationKey]; ok { + durationStr = v + } + dur, err := time.ParseDuration(durationStr) + if err != nil { + return nil, fmt.Errorf("failed parsing duration %q: %w", durationStr, err) + } + w.Duration = dur + + factor := DefaultWaitExponentialBackoffFactor + if v, ok := config[waitExponentialBackoffFactorKey]; ok { + f, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, fmt.Errorf("failed parsing factor %q: %w", v, err) + } + factor = f + } + w.Factor = factor + + jitter := DefaultWaitExponentialBackoffJitter + if v, ok := config[waitExponentialBackoffJitterKey]; ok { + j, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, fmt.Errorf("failed parsing jitter %q: %w", v, err) + } + jitter = j + } + w.Jitter = jitter + + steps := DefaultWaitExponentialBackoffSteps + if v, ok := config[waitExponentialBackoffStepsKey]; ok { + s, err := strconv.Atoi(v) + if err != nil { + return nil, fmt.Errorf("failed parsing steps %q: %w", v, err) + } + steps = s + } + w.Steps = steps + + capStr := DefaultWaitExponentialBackoffCap + if v, ok := config[waitExponentialBackoffCapKey]; ok { + capStr = v + } + capDur, err := time.ParseDuration(capStr) + if err != nil { + return nil, fmt.Errorf("failed parsing cap %q: %w", capStr, err) + } + w.Cap = capDur + + return &w, nil +} + +// NewWaitExponentialBackoffFromConfigMap returns a Config given a ConfigMap +func NewWaitExponentialBackoffFromConfigMap(config *corev1.ConfigMap) (*WaitExponentialBackoff, error) { + return newWaitExponentialBackoffFromMap(config.Data) +} diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/zz_generated.deepcopy.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/zz_generated.deepcopy.go index b670e28058..12ceac0433 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/zz_generated.deepcopy.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/zz_generated.deepcopy.go @@ -134,3 +134,19 @@ func (in *Tracing) DeepCopy() *Tracing { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WaitExponentialBackoff) DeepCopyInto(out *WaitExponentialBackoff) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WaitExponentialBackoff. +func (in *WaitExponentialBackoff) DeepCopy() *WaitExponentialBackoff { + if in == nil { + return nil + } + out := new(WaitExponentialBackoff) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go index d5b8738a5d..f8c9053b8f 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go @@ -2359,7 +2359,7 @@ func schema_pkg_apis_pipeline_v1_RefSource(ref common.ReferenceCallback) common. }, "entryPoint": { SchemaProps: spec.SchemaProps{ - Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", Type: []string{"string"}, Format: "", }, diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/provenance.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/provenance.go index de9f2a5c5d..ea1234335d 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/provenance.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/provenance.go @@ -41,6 +41,6 @@ type RefSource struct { // EntryPoint identifies the entry point into the build. This is often a path to a // build definition file and/or a target label within that file. - // Example: "task/git-clone/0.8/git-clone.yaml" + // Example: "task/git-clone/0.10/git-clone.yaml" EntryPoint string `json:"entryPoint,omitempty"` } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json index 607bc82480..5f8710cf24 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json @@ -1185,7 +1185,7 @@ } }, "entryPoint": { - "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", "type": "string" }, "uri": { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go index 5cfe8d8580..f0c68b778e 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -712,7 +712,7 @@ func schema_pkg_apis_pipeline_v1beta1_ConfigSource(ref common.ReferenceCallback) }, "entryPoint": { SchemaProps: spec.SchemaProps{ - Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", Type: []string{"string"}, Format: "", }, @@ -3122,7 +3122,7 @@ func schema_pkg_apis_pipeline_v1beta1_RefSource(ref common.ReferenceCallback) co }, "entryPoint": { SchemaProps: spec.SchemaProps{ - Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + Description: "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", Type: []string{"string"}, Format: "", }, diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go index b8345db6b2..e0c9b7365e 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -195,15 +195,7 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { NamespacedTaskKind: true, } - if pt.OnError != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.BetaAPIFields)) - if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { - errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) - } - if pt.OnError == PipelineTaskContinue && pt.Retries > 0 { - errs = errs.Also(apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0")) - } - } + errs = errs.Also(pt.ValidateOnError(ctx)) // Pipeline task having taskRef/taskSpec with APIVersion is classified as custom task switch { @@ -221,6 +213,20 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { return //nolint:nakedret } +// ValidateOnError validates the OnError field of a PipelineTask +func (pt PipelineTask) ValidateOnError(ctx context.Context) (errs *apis.FieldError) { + if pt.OnError != "" && !isParamRefs(string(pt.OnError)) { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.BetaAPIFields)) + if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { + errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) + } + if pt.OnError == PipelineTaskContinue && pt.Retries > 0 { + errs = errs.Also(apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0")) + } + } + return errs +} + // validateEnabledInlineSpec validates that pipelineSpec or taskSpec is allowed by checking // disable-inline-spec field func (pt PipelineTask) validateEnabledInlineSpec(ctx context.Context) (errs *apis.FieldError) { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/provenance.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/provenance.go index 3ae27eb55d..7fadd2c9e0 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/provenance.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/provenance.go @@ -44,7 +44,7 @@ type RefSource struct { // EntryPoint identifies the entry point into the build. This is often a path to a // build definition file and/or a target label within that file. - // Example: "task/git-clone/0.8/git-clone.yaml" + // Example: "task/git-clone/0.10/git-clone.yaml" EntryPoint string `json:"entryPoint,omitempty"` } @@ -62,6 +62,6 @@ type ConfigSource struct { // EntryPoint identifies the entry point into the build. This is often a path to a // build definition file and/or a target label within that file. - // Example: "task/git-clone/0.8/git-clone.yaml" + // Example: "task/git-clone/0.10/git-clone.yaml" EntryPoint string `json:"entryPoint,omitempty"` } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json index 8b087ba435..4340e77451 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json @@ -306,7 +306,7 @@ } }, "entryPoint": { - "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", "type": "string" }, "uri": { @@ -1592,7 +1592,7 @@ } }, "entryPoint": { - "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", + "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.10/git-clone.yaml\"", "type": "string" }, "uri": { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1alpha1/resolution_request_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1alpha1/resolution_request_validation.go index 7dbbac8cdf..cae911baa4 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1alpha1/resolution_request_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1alpha1/resolution_request_validation.go @@ -20,9 +20,21 @@ import ( "context" "github.com/tektoncd/pipeline/pkg/resolution/common" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" "knative.dev/pkg/apis" + "knative.dev/pkg/webhook/resourcesemantics" ) +var ( + _ apis.Validatable = (*ResolutionRequest)(nil) + _ resourcesemantics.VerbLimited = (*ResolutionRequest)(nil) +) + +// SupportedVerbs returns the operations that validation should be called for +func (rr *ResolutionRequest) SupportedVerbs() []admissionregistrationv1.OperationType { + return []admissionregistrationv1.OperationType{admissionregistrationv1.Create, admissionregistrationv1.Update} +} + // Validate checks that a submitted ResolutionRequest is structurally // sound before the controller receives it. func (rr *ResolutionRequest) Validate(ctx context.Context) (errs *apis.FieldError) { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1/resolution_request_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1/resolution_request_validation.go index b8f3e312db..6b29ac06a4 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1/resolution_request_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1/resolution_request_validation.go @@ -20,9 +20,21 @@ import ( "context" "github.com/tektoncd/pipeline/pkg/resolution/common" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" "knative.dev/pkg/apis" + "knative.dev/pkg/webhook/resourcesemantics" ) +var ( + _ apis.Validatable = (*ResolutionRequest)(nil) + _ resourcesemantics.VerbLimited = (*ResolutionRequest)(nil) +) + +// SupportedVerbs returns the operations that validation should be called for +func (rr *ResolutionRequest) SupportedVerbs() []admissionregistrationv1.OperationType { + return []admissionregistrationv1.OperationType{admissionregistrationv1.Create, admissionregistrationv1.Update} +} + // Validate checks that a submitted ResolutionRequest is structurally // sound before the controller receives it. func (rr *ResolutionRequest) Validate(ctx context.Context) (errs *apis.FieldError) { diff --git a/vendor/github.com/tektoncd/pipeline/pkg/reconciler/testing/configmap.go b/vendor/github.com/tektoncd/pipeline/pkg/reconciler/testing/configmap.go index e41b36d525..3a50a7d5a7 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/reconciler/testing/configmap.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/reconciler/testing/configmap.go @@ -17,16 +17,23 @@ limitations under the License. package testing import ( - "context" "fmt" "os" + "strconv" "testing" "github.com/tektoncd/pipeline/pkg/apis/config" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/system" "sigs.k8s.io/yaml" ) +const ( + apiFieldsFeatureFlag = "enable-api-fields" + maxMatrixCombinationsCountFlag = "default-max-matrix-combinations-count" +) + // ConfigMapFromTestFile creates a v1.ConfigMap from a YAML file // It loads the YAML file from the testdata folder. func ConfigMapFromTestFile(t *testing.T, name string) *corev1.ConfigMap { @@ -48,19 +55,60 @@ func ConfigMapFromTestFile(t *testing.T, name string) *corev1.ConfigMap { return &cm } -// EnableFeatureFlagField enables a boolean feature flag in an existing context (for use in testing). -func EnableFeatureFlagField(ctx context.Context, t *testing.T, flagName string) context.Context { - t.Helper() - featureFlags, err := config.NewFeatureFlagsFromMap(map[string]string{ - flagName: "true", - }) +func NewFeatureFlagsConfigMapInSlice() []*corev1.ConfigMap { + return []*corev1.ConfigMap{newFeatureFlagsConfigMap()} +} - if err != nil { - t.Fatalf("Fail to create a feature config: %v", err) +func newFeatureFlagsConfigMap() *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetFeatureFlagsConfigName(), + Namespace: system.Namespace(), + }, + Data: make(map[string]string), } +} + +func NewAlphaFeatureFlagsConfigMapInSlice() []*corev1.ConfigMap { + return []*corev1.ConfigMap{withEnabledAlphaAPIFields(newFeatureFlagsConfigMap())} +} + +func withEnabledAlphaAPIFields(cm *corev1.ConfigMap) *corev1.ConfigMap { + newCM := cm.DeepCopy() + newCM.Data[apiFieldsFeatureFlag] = config.AlphaAPIFields + return newCM +} + +func NewFeatureFlagsConfigMapWithMatrixInSlice(count int) []*corev1.ConfigMap { + return append( + NewFeatureFlagsConfigMapInSlice(), + withMaxMatrixCombinationsCount(newDefaultsConfigMap(), count), + ) +} + +func withMaxMatrixCombinationsCount(cm *corev1.ConfigMap, count int) *corev1.ConfigMap { + newCM := cm.DeepCopy() + newCM.Data[maxMatrixCombinationsCountFlag] = strconv.Itoa(count) + return newCM +} - cfg := &config.Config{ - FeatureFlags: featureFlags, +func newDefaultsConfigMap() *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetDefaultsConfigName(), + Namespace: system.Namespace(), + }, + Data: make(map[string]string), } - return config.ToContext(ctx, cfg) +} + +func NewAlphaFeatureFlagsConfigMapWithMatrixInSlice(count int) []*corev1.ConfigMap { + return append( + NewAlphaFeatureFlagsConfigMapInSlice(), + withMaxMatrixCombinationsCount(newDefaultsConfigMap(), count), + ) +} + +func NewDefaultsCofigMapInSlice() []*corev1.ConfigMap { + return []*corev1.ConfigMap{newDefaultsConfigMap()} } diff --git a/vendor/github.com/tektoncd/pipeline/test/controller.go b/vendor/github.com/tektoncd/pipeline/test/controller.go index 80e5ba7061..fd34ed003d 100644 --- a/vendor/github.com/tektoncd/pipeline/test/controller.go +++ b/vendor/github.com/tektoncd/pipeline/test/controller.go @@ -342,7 +342,7 @@ func PrependResourceVersionReactor(f *ktesting.Fake) { // EnsureConfigurationConfigMapsExist makes sure all the configmaps exists. func EnsureConfigurationConfigMapsExist(d *Data) { - var defaultsExists, featureFlagsExists, metricsExists, spireconfigExists, eventsExists, tracingExists bool + var defaultsExists, featureFlagsExists, metricsExists, spireconfigExists, eventsExists, tracingExists, backoffExists bool for _, cm := range d.ConfigMaps { if cm.Name == config.GetDefaultsConfigName() { defaultsExists = true @@ -362,6 +362,9 @@ func EnsureConfigurationConfigMapsExist(d *Data) { if cm.Name == config.GetTracingConfigName() { tracingExists = true } + if cm.Name == config.GetWaitExponentialBackoffConfigName() { + backoffExists = true + } } if !defaultsExists { d.ConfigMaps = append(d.ConfigMaps, &corev1.ConfigMap{ @@ -399,4 +402,10 @@ func EnsureConfigurationConfigMapsExist(d *Data) { Data: map[string]string{}, }) } + if !backoffExists { + d.ConfigMaps = append(d.ConfigMaps, &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Name: config.GetWaitExponentialBackoffConfigName(), Namespace: system.Namespace()}, + Data: map[string]string{}, + }) + } } diff --git a/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh b/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh index d67138c27c..4ddd15ac88 100644 --- a/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh +++ b/vendor/github.com/tektoncd/pipeline/test/e2e-tests.sh @@ -158,6 +158,13 @@ function set_enable_kubernetes_sidecar() { kubectl patch configmap feature-flags -n tekton-pipelines -p "$jsonpatch" } +function set_default_sidecar_log_polling_interval() { + # Sets the default-sidecar-log-polling-interval in the config-defaults ConfigMap to 0ms for e2e tests + echo "Patching config-defaults ConfigMap: setting default-sidecar-log-polling-interval to 0ms" + jsonpatch='{"data": {"default-sidecar-log-polling-interval": "0ms"}}' + kubectl patch configmap config-defaults -n tekton-pipelines -p "$jsonpatch" +} + function run_e2e() { # Run the integration tests header "Running Go e2e tests" @@ -187,6 +194,7 @@ set_enable_param_enum "$ENABLE_PARAM_ENUM" set_enable_artifacts "$ENABLE_ARTIFACTS" set_enable_concise_resolver_syntax "$ENABLE_CONCISE_RESOLVER_SYNTAX" set_enable_kubernetes_sidecar "$ENABLE_KUBERNETES_SIDECAR" +set_default_sidecar_log_polling_interval run_e2e (( failed )) && fail_test diff --git a/vendor/github.com/tektoncd/pipeline/test/presubmit-tests.sh b/vendor/github.com/tektoncd/pipeline/test/presubmit-tests.sh index a3049db116..076c62d3f7 100644 --- a/vendor/github.com/tektoncd/pipeline/test/presubmit-tests.sh +++ b/vendor/github.com/tektoncd/pipeline/test/presubmit-tests.sh @@ -55,7 +55,7 @@ function ko_resolve() { github.com/tektoncd/pipeline/cmd/nop: ghcr.io/tektoncd/pipeline/github.com/tektoncd/pipeline/combined-base-image:latest github.com/tektoncd/pipeline/cmd/workingdirinit: ghcr.io/tektoncd/pipeline/github.com/tektoncd/pipeline/combined-base-image:latest - github.com/tektoncd/pipeline/cmd/resolvers: cgr.dev/chainguard/git@sha256:566235a8ef752f37d285042ee05fc37dbb04293e50f116a231984080fb835693 + github.com/tektoncd/pipeline/cmd/resolvers: ghcr.io/tektoncd/plumbing/tini-git@sha256:2c18f0b3ed4394e27068b5c70bb55419797e8fc743d8ea9e0c2766001b36b5b4 EOF KO_DOCKER_REPO=example.com ko resolve -l 'app.kubernetes.io/component!=resolvers' --platform=all --push=false -R -f config 1>/dev/null diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/config/default.go b/vendor/github.com/tektoncd/triggers/pkg/apis/config/default.go index b03ce742d1..0db1b7f2b3 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/config/default.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/config/default.go @@ -142,7 +142,6 @@ func NewDefaultsFromMap(cfgMap map[string]string) (*Defaults, error) { // if "" value is provided via configmap set back to default value which is true tc.DefaultRunAsNonRoot = defaultRunAsNonRootValue } - } return &tc, nil diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/config/feature_flags.go b/vendor/github.com/tektoncd/triggers/pkg/apis/config/feature_flags.go index f6d84cbd9f..76920d6469 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/config/feature_flags.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/config/feature_flags.go @@ -73,7 +73,6 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) { // If the feature gate is not defined then we ignore it, if the pattern is not // valid regex then we return error func getLabelsExclusionPattern(cfgMap map[string]string) (string, error) { - if pattern, ok := cfgMap[labelsExclusionPattern]; ok { if _, err := regexp.Compile(pattern); err != nil { return "", fmt.Errorf("invalid value for feature flag %q: %q", labelsExclusionPattern, pattern) diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_types.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_types.go index 9994fbbb48..91f267baed 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_types.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_types.go @@ -137,7 +137,7 @@ type EventListenerStatus struct { duckv1.Status `json:",inline"` // EventListener is Addressable. It currently exposes the service DNS - // address of the the EventListener sink + // address of the EventListener sink duckv1alpha1.AddressStatus `json:",inline"` // Configuration stores configuration for the EventListener service diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_validation.go index 18dcfdf743..125594693f 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/event_listener_validation.go @@ -152,7 +152,7 @@ func validateEnv(envVars []corev1.EnvVar) (errs *apis.FieldError) { // This is to make sure both TLS_CERT and TLS_KEY is set for tls connection if count == 1 { errs = errs.Also(&apis.FieldError{ - Message: fmt.Sprintf("Expected env's are TLS_CERT and TLS_KEY, but got only one env %s", envValue), + Message: "Expected env's are TLS_CERT and TLS_KEY, but got only one env " + envValue, }) } return errs diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_binding_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_binding_validation.go index ac0dcb9109..dd7f60a088 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_binding_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_binding_validation.go @@ -96,5 +96,4 @@ func validateParamValue(in string) *apis.FieldError { } } return nil - } diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_types.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_types.go index ecf2ff921e..95dc1c2e80 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_types.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_types.go @@ -205,7 +205,7 @@ func addToParams(params *[]InterceptorParams, name string, val interface{}) erro func toV1JSON(v interface{}) (apiextensionsv1.JSON, error) { b, err := json.Marshal(v) if err != nil { - return apiextensionsv1.JSON{}, fmt.Errorf("json.Marshal() failed: %s", err) + return apiextensionsv1.JSON{}, fmt.Errorf("json.Marshal() failed: %w", err) } return apiextensionsv1.JSON{ Raw: b, diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_validation.go index 1917a879dc..1c53d5ac25 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1alpha1/trigger_validation.go @@ -18,6 +18,7 @@ package v1alpha1 import ( "context" + "errors" "fmt" "net/http" @@ -57,7 +58,7 @@ func (t TriggerSpecTemplate) validate(ctx context.Context) (errs *apis.FieldErro // Optional explicit match if t.APIVersion != "" { if t.APIVersion != "v1alpha1" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid apiVersion"), "template.apiVersion")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid apiVersion"), "template.apiVersion")) } } @@ -82,7 +83,7 @@ func (t triggerSpecBindingArray) validate(ctx context.Context) (errs *apis.Field case b.Name != "": // Cannot specify both Ref and Name errs = errs.Also(apis.ErrMultipleOneOf(fmt.Sprintf("bindings[%d].Ref", i), fmt.Sprintf("bindings[%d].Name", i))) case b.Kind != NamespacedTriggerBindingKind && b.Kind != ClusterTriggerBindingKind: // Kind must be valid - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid kind"), fmt.Sprintf("bindings[%d].kind", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid kind"), fmt.Sprintf("bindings[%d].kind", i))) } case b.Name != "": if b.Value == nil { // Value is mandatory if Name is specified @@ -127,26 +128,26 @@ func (i *TriggerInterceptor) validate(ctx context.Context) (errs *apis.FieldErro } w := i.Webhook if w.ObjectRef.Kind != "Service" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid kind"), "interceptor.webhook.objectRef.kind")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid kind"), "interceptor.webhook.objectRef.kind")) } // Optional explicit match if w.ObjectRef.APIVersion != "v1" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid apiVersion"), "interceptor.webhook.objectRef.apiVersion")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid apiVersion"), "interceptor.webhook.objectRef.apiVersion")) } for i, header := range w.Header { // Enforce non-empty canonical header keys if len(header.Name) == 0 || http.CanonicalHeaderKey(header.Name) != header.Name { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header name"), fmt.Sprintf("interceptor.webhook.header[%d].name", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header name"), fmt.Sprintf("interceptor.webhook.header[%d].name", i))) } // Enforce non-empty header values if header.Value.Type == pipelinev1.ParamTypeString { if len(header.Value.StringVal) == 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) } } else if len(header.Value.ArrayVal) == 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) } } } @@ -157,16 +158,16 @@ func (i *TriggerInterceptor) validate(ctx context.Context) (errs *apis.FieldErro } env, err := cel.NewEnv() if err != nil { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to create a DeprecatedCEL env: %s", err), "cel.filter")) + errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to create a DeprecatedCEL env: %w", err), "cel.filter")) } if i.DeprecatedCEL.Filter != "" { if _, issues := env.Parse(i.DeprecatedCEL.Filter); issues != nil && issues.Err() != nil { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to parse the DeprecatedCEL filter: %s", issues.Err()), "cel.filter")) + errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to parse the DeprecatedCEL filter: %w", issues.Err()), "cel.filter")) } } for _, v := range i.DeprecatedCEL.Overlays { if _, issues := env.Parse(v.Expression); issues != nil && issues.Err() != nil { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to parse the DeprecatedCEL overlay: %s", issues.Err()), "cel.overlay")) + errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("failed to parse the DeprecatedCEL overlay: %w", issues.Err()), "cel.overlay")) } } } diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_types.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_types.go index 58e5bb8d63..7967a4defc 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_types.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_types.go @@ -156,7 +156,7 @@ type EventListenerStatus struct { duckv1.Status `json:",inline"` // EventListener is Addressable. It currently exposes the service DNS - // address of the the EventListener sink + // address of the EventListener sink v1beta1.AddressStatus `json:",inline"` // Configuration stores configuration for the EventListener service diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_validation.go index af4a97ecc6..e38149e3c6 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/event_listener_validation.go @@ -171,7 +171,7 @@ func validateEnv(envVars []corev1.EnvVar) (errs *apis.FieldError) { // This is to make sure both TLS_CERT and TLS_KEY is set for tls connection if count == 1 { errs = errs.Also(&apis.FieldError{ - Message: fmt.Sprintf("Expected env's are TLS_CERT and TLS_KEY, but got only one env %s", envValue), + Message: "Expected env's are TLS_CERT and TLS_KEY, but got only one env " + envValue, }) } return errs diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/swagger.json b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/swagger.json index e0e88eb977..e69de29bb2 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/swagger.json +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/swagger.json @@ -1,3498 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "Tekton Pipeline", - "title": "Tekton", - "version": "v0.17.2" - }, - "paths": {}, - "definitions": { - "github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequest": { - "description": "ResolutionRequest is an object for requesting the content of a Tekton resource like a pipeline.yaml.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "description": "Spec holds the information for the request part of the resource request.", - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestSpec" - }, - "status": { - "description": "Status communicates the state of the request and, ultimately, the content of the resolved resource.", - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestStatus" - } - } - }, - "github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestList": { - "description": "ResolutionRequestList is a list of ResolutionRequests.", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequest" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestSpec": { - "description": "ResolutionRequestSpec are all the fields in the spec of the ResolutionRequest CRD.", - "type": "object", - "properties": { - "params": { - "description": "Parameters are the runtime attributes passed to the resolver to help it figure out how to resolve the resource being requested. For example: repo URL, commit SHA, path to file, the kind of authentication to leverage, etc.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "url": { - "description": "URL is the runtime url passed to the resolver to help it figure out how to resolver the resource being requested. This is currently at an ALPHA stability level and subject to alpha API compatibility policies.", - "type": "string" - } - } - }, - "github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestStatus": { - "description": "ResolutionRequestStatus are all the fields in a ResolutionRequest's status subresource.", - "type": "object", - "required": [ - "data", - "source", - "refSource" - ], - "properties": { - "annotations": { - "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "conditions": { - "description": "Conditions the latest available observations of a resource's current state.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/knative.Condition" - }, - "x-kubernetes-patch-merge-key": "type", - "x-kubernetes-patch-strategy": "merge" - }, - "data": { - "description": "Data is a string representation of the resolved content of the requested resource in-lined into the ResolutionRequest object.", - "type": "string", - "default": "" - }, - "observedGeneration": { - "description": "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", - "type": "integer", - "format": "int64" - }, - "refSource": { - "description": "RefSource is the source reference of the remote data that records the url, digest and the entrypoint.", - "$ref": "#/definitions/v1.RefSource" - }, - "source": { - "description": "Deprecated: Use RefSource instead", - "$ref": "#/definitions/v1.RefSource" - } - } - }, - "github.com.tektoncd.pipeline.pkg.apis.resolution.v1beta1.ResolutionRequestStatusFields": { - "description": "ResolutionRequestStatusFields are the ResolutionRequest-specific fields for the status subresource.", - "type": "object", - "required": [ - "data", - "source", - "refSource" - ], - "properties": { - "data": { - "description": "Data is a string representation of the resolved content of the requested resource in-lined into the ResolutionRequest object.", - "type": "string", - "default": "" - }, - "refSource": { - "description": "RefSource is the source reference of the remote data that records the url, digest and the entrypoint.", - "$ref": "#/definitions/v1.RefSource" - }, - "source": { - "description": "Deprecated: Use RefSource instead", - "$ref": "#/definitions/v1.RefSource" - } - } - }, - "pod.AffinityAssistantTemplate": { - "description": "AffinityAssistantTemplate holds pod specific configuration and is a subset of the generic pod Template", - "type": "object", - "properties": { - "imagePullSecrets": { - "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.LocalObjectReference" - }, - "x-kubernetes-list-type": "atomic" - }, - "nodeSelector": { - "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "priorityClassName": { - "description": "If specified, indicates the pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.", - "type": "string" - }, - "securityContext": { - "description": "SecurityContext sets the security context for the pod", - "$ref": "#/definitions/v1.PodSecurityContext" - }, - "tolerations": { - "description": "If specified, the pod's tolerations.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Toleration" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "pod.Template": { - "description": "Template holds pod specific configuration", - "type": "object", - "properties": { - "affinity": { - "description": "If specified, the pod's scheduling constraints. See Pod.spec.affinity (API version: v1)", - "$ref": "#/definitions/v1.Affinity" - }, - "automountServiceAccountToken": { - "description": "AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted.", - "type": "boolean" - }, - "dnsConfig": { - "description": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.", - "$ref": "#/definitions/v1.PodDNSConfig" - }, - "dnsPolicy": { - "description": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.", - "type": "string" - }, - "enableServiceLinks": { - "description": "EnableServiceLinks indicates whether information about services should be injected into pod's environment variables, matching the syntax of Docker links. Optional: Defaults to true.", - "type": "boolean" - }, - "env": { - "description": "List of environment variables that can be provided to the containers belonging to the pod.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvVar" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge" - }, - "hostAliases": { - "description": "HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.HostAlias" - }, - "x-kubernetes-list-type": "atomic" - }, - "hostNetwork": { - "description": "HostNetwork specifies whether the pod may use the node network namespace", - "type": "boolean" - }, - "imagePullSecrets": { - "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.LocalObjectReference" - }, - "x-kubernetes-list-type": "atomic" - }, - "nodeSelector": { - "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "priorityClassName": { - "description": "If specified, indicates the pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.", - "type": "string" - }, - "runtimeClassName": { - "description": "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md This is a beta feature as of Kubernetes v1.14.", - "type": "string" - }, - "schedulerName": { - "description": "SchedulerName specifies the scheduler to be used to dispatch the Pod", - "type": "string" - }, - "securityContext": { - "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. See Pod.spec.securityContext (API version: v1)", - "$ref": "#/definitions/v1.PodSecurityContext" - }, - "tolerations": { - "description": "If specified, the pod's tolerations.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Toleration" - }, - "x-kubernetes-list-type": "atomic" - }, - "topologySpreadConstraints": { - "description": "TopologySpreadConstraints controls how Pods are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.TopologySpreadConstraint" - }, - "x-kubernetes-list-type": "atomic" - }, - "volumes": { - "description": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes See Pod.spec.volumes (API version: v1)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Volume" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge,retainKeys" - } - } - }, - "v1beta1.Artifact": { - "description": "TaskRunStepArtifact represents an artifact produced or used by a step within a task run. It directly uses the Artifact type for its structure.", - "type": "object", - "properties": { - "buildOutput": { - "description": "Indicate if the artifact is a build output or a by-product", - "type": "boolean" - }, - "name": { - "description": "The artifact's identifying category name", - "type": "string" - }, - "values": { - "description": "A collection of values related to the artifact", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ArtifactValue" - } - } - } - }, - "v1beta1.ArtifactValue": { - "description": "ArtifactValue represents a specific value or data element within an Artifact.", - "type": "object", - "properties": { - "digest": { - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "uri": { - "description": "Algorithm-specific digests for verifying the content (e.g., SHA256)", - "type": "string" - } - } - }, - "v1beta1.Artifacts": { - "description": "Artifacts represents the collection of input and output artifacts associated with a task run or a similar process. Artifacts in this context are units of data or resources that the process either consumes as input or produces as output.", - "type": "object", - "properties": { - "inputs": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Artifact" - } - }, - "outputs": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Artifact" - } - } - } - }, - "v1beta1.ChildStatusReference": { - "description": "ChildStatusReference is used to point to the statuses of individual TaskRuns and Runs within this PipelineRun.", - "type": "object", - "properties": { - "apiVersion": { - "type": "string" - }, - "displayName": { - "description": "DisplayName is a user-facing name of the pipelineTask that may be used to populate a UI.", - "type": "string" - }, - "kind": { - "type": "string" - }, - "name": { - "description": "Name is the name of the TaskRun or Run this is referencing.", - "type": "string" - }, - "pipelineTaskName": { - "description": "PipelineTaskName is the name of the PipelineTask this is referencing.", - "type": "string" - }, - "whenExpressions": { - "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.CloudEventDelivery": { - "description": "CloudEventDelivery is the target of a cloud event along with the state of delivery.", - "type": "object", - "properties": { - "status": { - "default": {}, - "$ref": "#/definitions/v1beta1.CloudEventDeliveryState" - }, - "target": { - "description": "Target points to an addressable", - "type": "string" - } - } - }, - "v1beta1.CloudEventDeliveryState": { - "description": "CloudEventDeliveryState reports the state of a cloud event to be sent.", - "type": "object", - "required": [ - "message", - "retryCount" - ], - "properties": { - "condition": { - "description": "Current status", - "type": "string" - }, - "message": { - "description": "Error is the text of error (if any)", - "type": "string", - "default": "" - }, - "retryCount": { - "description": "RetryCount is the number of attempts of sending the cloud event", - "type": "integer", - "format": "int32", - "default": 0 - }, - "sentAt": { - "description": "SentAt is the time at which the last attempt to send the event was made", - "$ref": "#/definitions/v1.Time" - } - } - }, - "v1beta1.ConfigSource": { - "description": "ConfigSource contains the information that can uniquely identify where a remote built definition came from i.e. Git repositories, Tekton Bundles in OCI registry and hub.", - "type": "object", - "properties": { - "digest": { - "description": "Digest is a collection of cryptographic digests for the contents of the artifact specified by URI. Example: {\"sha1\": \"f99d13e554ffcb696dee719fa85b695cb5b0f428\"}", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "entryPoint": { - "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", - "type": "string" - }, - "uri": { - "description": "URI indicates the identity of the source of the build definition. Example: \"https://github.com/tektoncd/catalog\"", - "type": "string" - } - } - }, - "v1beta1.CustomRun": { - "description": "CustomRun represents a single execution of a Custom Task.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "default": {}, - "$ref": "#/definitions/v1beta1.CustomRunSpec" - }, - "status": { - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.run.v1beta1.CustomRunStatus" - } - } - }, - "v1beta1.CustomRunList": { - "description": "CustomRunList contains a list of CustomRun", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.CustomRun" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.CustomRunSpec": { - "description": "CustomRunSpec defines the desired state of CustomRun", - "type": "object", - "properties": { - "customRef": { - "$ref": "#/definitions/v1beta1.TaskRef" - }, - "customSpec": { - "description": "Spec is a specification of a custom task", - "$ref": "#/definitions/v1beta1.EmbeddedCustomRunSpec" - }, - "params": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "retries": { - "description": "Used for propagating retries count to custom tasks", - "type": "integer", - "format": "int32" - }, - "serviceAccountName": { - "type": "string", - "default": "" - }, - "status": { - "description": "Used for cancelling a customrun (and maybe more later on)", - "type": "string" - }, - "statusMessage": { - "description": "Status message for cancellation.", - "type": "string" - }, - "timeout": { - "description": "Time after which the custom-task times out. Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration", - "$ref": "#/definitions/v1.Duration" - }, - "workspaces": { - "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.EmbeddedCustomRunSpec": { - "description": "EmbeddedCustomRunSpec allows custom task definitions to be embedded", - "type": "object", - "properties": { - "apiVersion": { - "type": "string" - }, - "kind": { - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTaskMetadata" - }, - "spec": { - "description": "Spec is a specification of a custom task", - "$ref": "#/definitions/k8s.io.apimachinery.pkg.runtime.RawExtension" - } - } - }, - "v1beta1.EmbeddedTask": { - "description": "EmbeddedTask is used to define a Task inline within a Pipeline's PipelineTasks.", - "type": "object", - "properties": { - "apiVersion": { - "type": "string" - }, - "description": { - "description": "Description is a user-facing description of the task that may be used to populate a UI.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is a user-facing name of the task that may be used to populate a UI.", - "type": "string" - }, - "kind": { - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTaskMetadata" - }, - "params": { - "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ParamSpec" - }, - "x-kubernetes-list-type": "atomic" - }, - "resources": { - "description": "Resources is a list input and output resource to run the task Resources are represented in TaskRuns as bindings to instances of PipelineResources.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "$ref": "#/definitions/v1beta1.TaskResources" - }, - "results": { - "description": "Results are values that this Task can output", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "sidecars": { - "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Sidecar" - }, - "x-kubernetes-list-type": "atomic" - }, - "spec": { - "description": "Spec is a specification of a custom task", - "$ref": "#/definitions/k8s.io.apimachinery.pkg.runtime.RawExtension" - }, - "stepTemplate": { - "description": "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - "$ref": "#/definitions/v1beta1.StepTemplate" - }, - "steps": { - "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Step" - }, - "x-kubernetes-list-type": "atomic" - }, - "volumes": { - "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Volume" - }, - "x-kubernetes-list-type": "atomic" - }, - "workspaces": { - "description": "Workspaces are the volumes that this Task requires.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceDeclaration" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.IncludeParams": { - "description": "IncludeParams allows passing in a specific combinations of Parameters into the Matrix.", - "type": "object", - "properties": { - "name": { - "description": "Name the specified combination", - "type": "string" - }, - "params": { - "description": "Params takes only `Parameters` of type `\"string\"` The names of the `params` must match the names of the `params` in the underlying `Task`", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.InternalTaskModifier": { - "description": "InternalTaskModifier implements TaskModifier for resources that are built-in to Tekton Pipelines.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "required": [ - "stepsToPrepend", - "stepsToAppend", - "volumes" - ], - "properties": { - "stepsToAppend": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Step" - }, - "x-kubernetes-list-type": "atomic" - }, - "stepsToPrepend": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Step" - }, - "x-kubernetes-list-type": "atomic" - }, - "volumes": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Volume" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.Matrix": { - "description": "Matrix is used to fan out Tasks in a Pipeline", - "type": "object", - "properties": { - "include": { - "description": "Include is a list of IncludeParams which allows passing in specific combinations of Parameters into the Matrix.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.IncludeParams" - }, - "x-kubernetes-list-type": "atomic" - }, - "params": { - "description": "Params is a list of parameters used to fan out the pipelineTask Params takes only `Parameters` of type `\"array\"` Each array element is supplied to the `PipelineTask` by substituting `params` of type `\"string\"` in the underlying `Task`. The names of the `params` in the `Matrix` must match the names of the `params` in the underlying `Task` that they will be substituting.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.Param": { - "description": "Param declares an ParamValues to use for the parameter called name.", - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string", - "default": "" - }, - "value": { - "$ref": "#/definitions/v1beta1.ParamValue" - } - } - }, - "v1beta1.ParamSpec": { - "description": "ParamSpec defines arbitrary parameters needed beyond typed inputs (such as resources). Parameter values are provided by users as inputs on a TaskRun or PipelineRun.", - "type": "object", - "required": [ - "name" - ], - "properties": { - "default": { - "description": "Default is the value a parameter takes if no input value is supplied. If default is set, a Task may be executed without a supplied value for the parameter.", - "$ref": "#/definitions/v1beta1.ParamValue" - }, - "description": { - "description": "Description is a user-facing description of the parameter that may be used to populate a UI.", - "type": "string" - }, - "enum": { - "description": "Enum declares a set of allowed param input values for tasks/pipelines that can be validated. If Enum is not set, no input validation is performed for the param.", - "type": "array", - "items": { - "type": "string", - "default": "" - } - }, - "name": { - "description": "Name declares the name by which a parameter is referenced.", - "type": "string", - "default": "" - }, - "properties": { - "description": "Properties is the JSON Schema properties to support key-value pairs parameter.", - "type": "object", - "additionalProperties": { - "default": {}, - "$ref": "#/definitions/v1beta1.PropertySpec" - } - }, - "type": { - "description": "Type is the user-specified type of the parameter. The possible types are currently \"string\", \"array\" and \"object\", and \"string\" is the default.", - "type": "string" - } - } - }, - "v1beta1.ParamValue": { - "description": "ResultValue is a type alias of ParamValue", - "type": "object", - "required": [ - "Type", - "StringVal", - "ArrayVal", - "ObjectVal" - ], - "properties": { - "ArrayVal": { - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "ObjectVal": { - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "StringVal": { - "description": "Represents the stored type of ParamValues.", - "type": "string", - "default": "" - }, - "Type": { - "type": "string", - "default": "" - } - } - }, - "v1beta1.Pipeline": { - "description": "Pipeline describes a list of Tasks to execute. It expresses how outputs of tasks feed into inputs of subsequent tasks.\n\nDeprecated: Please use v1.Pipeline instead.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "description": "Spec holds the desired state of the Pipeline from the client", - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineSpec" - } - } - }, - "v1beta1.PipelineDeclaredResource": { - "description": "PipelineDeclaredResource is used by a Pipeline to declare the types of the PipelineResources that it will required to run and names which can be used to refer to these PipelineResources in PipelineTaskResourceBindings.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "description": "Name is the name that will be used by the Pipeline to refer to this resource. It does not directly correspond to the name of any PipelineResources Task inputs or outputs, and it does not correspond to the actual names of the PipelineResources that will be bound in the PipelineRun.", - "type": "string", - "default": "" - }, - "optional": { - "description": "Optional declares the resource as optional. optional: true - the resource is considered optional optional: false - the resource is considered required (default/equivalent of not specifying it)", - "type": "boolean" - }, - "type": { - "description": "Type is the type of the PipelineResource.", - "type": "string", - "default": "" - } - } - }, - "v1beta1.PipelineList": { - "description": "PipelineList contains a list of Pipeline", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Pipeline" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.PipelineRef": { - "description": "PipelineRef can be used to refer to a specific instance of a Pipeline.", - "type": "object", - "properties": { - "apiVersion": { - "description": "API version of the referent", - "type": "string" - }, - "bundle": { - "description": "Bundle url reference to a Tekton Bundle.\n\nDeprecated: Please use ResolverRef with the bundles resolver instead. The field is staying there for go client backward compatibility, but is not used/allowed anymore.", - "type": "string" - }, - "name": { - "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "type": "string" - } - } - }, - "v1beta1.PipelineResourceBinding": { - "description": "PipelineResourceBinding connects a reference to an instance of a PipelineResource with a PipelineResource dependency that the Pipeline has declared\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "name": { - "description": "Name is the name of the PipelineResource in the Pipeline's declaration", - "type": "string" - }, - "resourceRef": { - "description": "ResourceRef is a reference to the instance of the actual PipelineResource that should be used", - "$ref": "#/definitions/v1beta1.PipelineResourceRef" - }, - "resourceSpec": { - "description": "ResourceSpec is specification of a resource that should be created and consumed by the task", - "$ref": "#/definitions/v1alpha1.PipelineResourceSpec" - } - } - }, - "v1beta1.PipelineResourceRef": { - "description": "PipelineResourceRef can be used to refer to a specific instance of a Resource\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "apiVersion": { - "description": "API version of the referent", - "type": "string" - }, - "name": { - "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "type": "string" - } - } - }, - "v1beta1.PipelineResult": { - "description": "PipelineResult used to describe the results of a pipeline", - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "description": { - "description": "Description is a human-readable description of the result", - "type": "string", - "default": "" - }, - "name": { - "description": "Name the given name", - "type": "string", - "default": "" - }, - "type": { - "description": "Type is the user-specified type of the result. The possible types are 'string', 'array', and 'object', with 'string' as the default. 'array' and 'object' types are alpha features.", - "type": "string" - }, - "value": { - "description": "Value the expression used to retrieve the value", - "$ref": "#/definitions/v1beta1.ParamValue" - } - } - }, - "v1beta1.PipelineRun": { - "description": "PipelineRun represents a single execution of a Pipeline. PipelineRuns are how the graph of Tasks declared in a Pipeline are executed; they specify inputs to Pipelines such as parameter values and capture operational aspects of the Tasks execution such as service account and tolerations. Creating a PipelineRun creates TaskRuns for Tasks in the referenced Pipeline.\n\nDeprecated: Please use v1.PipelineRun instead.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineRunSpec" - }, - "status": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineRunStatus" - } - } - }, - "v1beta1.PipelineRunList": { - "description": "PipelineRunList contains a list of PipelineRun", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineRun" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.PipelineRunResult": { - "description": "PipelineRunResult used to describe the results of a pipeline", - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "description": "Name is the result's name as declared by the Pipeline", - "type": "string", - "default": "" - }, - "value": { - "description": "Value is the result returned from the execution of this PipelineRun", - "$ref": "#/definitions/v1beta1.ParamValue" - } - } - }, - "v1beta1.PipelineRunRunStatus": { - "description": "PipelineRunRunStatus contains the name of the PipelineTask for this CustomRun or Run and the CustomRun or Run's Status", - "type": "object", - "properties": { - "pipelineTaskName": { - "description": "PipelineTaskName is the name of the PipelineTask.", - "type": "string" - }, - "status": { - "description": "Status is the CustomRunStatus for the corresponding CustomRun or Run", - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.run.v1beta1.CustomRunStatus" - }, - "whenExpressions": { - "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineRunSpec": { - "description": "PipelineRunSpec defines the desired state of PipelineRun", - "type": "object", - "properties": { - "params": { - "description": "Params is a list of parameter names and values.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "pipelineRef": { - "$ref": "#/definitions/v1beta1.PipelineRef" - }, - "pipelineSpec": { - "description": "Specifying PipelineSpec can be disabled by setting `disable-inline-spec` feature flag. See Pipeline.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.PipelineSpec" - }, - "podTemplate": { - "description": "PodTemplate holds pod specific configuration", - "$ref": "#/definitions/pod.Template" - }, - "resources": { - "description": "Resources is a list of bindings specifying which actual instances of PipelineResources to use for the resources the Pipeline has declared it needs.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineResourceBinding" - }, - "x-kubernetes-list-type": "atomic" - }, - "serviceAccountName": { - "type": "string" - }, - "status": { - "description": "Used for cancelling a pipelinerun (and maybe more later on)", - "type": "string" - }, - "taskRunSpecs": { - "description": "TaskRunSpecs holds a set of runtime specs", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTaskRunSpec" - }, - "x-kubernetes-list-type": "atomic" - }, - "timeout": { - "description": "Timeout is the Time after which the Pipeline times out. Defaults to never. Refer to Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration\n\nDeprecated: use pipelineRunSpec.Timeouts.Pipeline instead", - "$ref": "#/definitions/v1.Duration" - }, - "timeouts": { - "description": "Time after which the Pipeline times out. Currently three keys are accepted in the map pipeline, tasks and finally with Timeouts.pipeline \u003e= Timeouts.tasks + Timeouts.finally", - "$ref": "#/definitions/v1beta1.TimeoutFields" - }, - "workspaces": { - "description": "Workspaces holds a set of workspace bindings that must match names with those declared in the pipeline.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineRunStatus": { - "description": "PipelineRunStatus defines the observed state of PipelineRun", - "type": "object", - "properties": { - "annotations": { - "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "childReferences": { - "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ChildStatusReference" - }, - "x-kubernetes-list-type": "atomic" - }, - "completionTime": { - "description": "CompletionTime is the time the PipelineRun completed.", - "$ref": "#/definitions/v1.Time" - }, - "conditions": { - "description": "Conditions the latest available observations of a resource's current state.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/knative.Condition" - }, - "x-kubernetes-patch-merge-key": "type", - "x-kubernetes-patch-strategy": "merge" - }, - "finallyStartTime": { - "description": "FinallyStartTime is when all non-finally tasks have been completed and only finally tasks are being executed.", - "$ref": "#/definitions/v1.Time" - }, - "observedGeneration": { - "description": "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", - "type": "integer", - "format": "int64" - }, - "pipelineResults": { - "description": "PipelineResults are the list of results written out by the pipeline task's containers", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineRunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "pipelineSpec": { - "description": "PipelineSpec contains the exact spec used to instantiate the run. See Pipeline.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.PipelineSpec" - }, - "provenance": { - "description": "Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.).", - "$ref": "#/definitions/v1beta1.Provenance" - }, - "runs": { - "description": "Runs is a map of PipelineRunRunStatus with the run name as the key\n\nDeprecated: use ChildReferences instead. As of v0.45.0, this field is no longer populated and is only included for backwards compatibility with older server versions.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1beta1.PipelineRunRunStatus" - } - }, - "skippedTasks": { - "description": "list of tasks that were skipped due to when expressions evaluating to false", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.SkippedTask" - }, - "x-kubernetes-list-type": "atomic" - }, - "spanContext": { - "description": "SpanContext contains tracing span context fields", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "startTime": { - "description": "StartTime is the time the PipelineRun is actually started.", - "$ref": "#/definitions/v1.Time" - }, - "taskRuns": { - "description": "TaskRuns is a map of PipelineRunTaskRunStatus with the taskRun name as the key.\n\nDeprecated: use ChildReferences instead. As of v0.45.0, this field is no longer populated and is only included for backwards compatibility with older server versions.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1beta1.PipelineRunTaskRunStatus" - } - } - } - }, - "v1beta1.PipelineRunStatusFields": { - "description": "PipelineRunStatusFields holds the fields of PipelineRunStatus' status. This is defined separately and inlined so that other types can readily consume these fields via duck typing.", - "type": "object", - "properties": { - "childReferences": { - "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ChildStatusReference" - }, - "x-kubernetes-list-type": "atomic" - }, - "completionTime": { - "description": "CompletionTime is the time the PipelineRun completed.", - "$ref": "#/definitions/v1.Time" - }, - "finallyStartTime": { - "description": "FinallyStartTime is when all non-finally tasks have been completed and only finally tasks are being executed.", - "$ref": "#/definitions/v1.Time" - }, - "pipelineResults": { - "description": "PipelineResults are the list of results written out by the pipeline task's containers", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineRunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "pipelineSpec": { - "description": "PipelineSpec contains the exact spec used to instantiate the run. See Pipeline.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.PipelineSpec" - }, - "provenance": { - "description": "Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.).", - "$ref": "#/definitions/v1beta1.Provenance" - }, - "runs": { - "description": "Runs is a map of PipelineRunRunStatus with the run name as the key\n\nDeprecated: use ChildReferences instead. As of v0.45.0, this field is no longer populated and is only included for backwards compatibility with older server versions.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1beta1.PipelineRunRunStatus" - } - }, - "skippedTasks": { - "description": "list of tasks that were skipped due to when expressions evaluating to false", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.SkippedTask" - }, - "x-kubernetes-list-type": "atomic" - }, - "spanContext": { - "description": "SpanContext contains tracing span context fields", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "startTime": { - "description": "StartTime is the time the PipelineRun is actually started.", - "$ref": "#/definitions/v1.Time" - }, - "taskRuns": { - "description": "TaskRuns is a map of PipelineRunTaskRunStatus with the taskRun name as the key.\n\nDeprecated: use ChildReferences instead. As of v0.45.0, this field is no longer populated and is only included for backwards compatibility with older server versions.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1beta1.PipelineRunTaskRunStatus" - } - } - } - }, - "v1beta1.PipelineRunTaskRunStatus": { - "description": "PipelineRunTaskRunStatus contains the name of the PipelineTask for this TaskRun and the TaskRun's Status", - "type": "object", - "properties": { - "pipelineTaskName": { - "description": "PipelineTaskName is the name of the PipelineTask.", - "type": "string" - }, - "status": { - "description": "Status is the TaskRunStatus for the corresponding TaskRun", - "$ref": "#/definitions/v1beta1.TaskRunStatus" - }, - "whenExpressions": { - "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineSpec": { - "description": "PipelineSpec defines the desired state of Pipeline.", - "type": "object", - "properties": { - "description": { - "description": "Description is a user-facing description of the pipeline that may be used to populate a UI.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is a user-facing name of the pipeline that may be used to populate a UI.", - "type": "string" - }, - "finally": { - "description": "Finally declares the list of Tasks that execute just before leaving the Pipeline i.e. either after all Tasks are finished executing successfully or after a failure which would result in ending the Pipeline", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTask" - }, - "x-kubernetes-list-type": "atomic" - }, - "params": { - "description": "Params declares a list of input parameters that must be supplied when this Pipeline is run.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ParamSpec" - }, - "x-kubernetes-list-type": "atomic" - }, - "resources": { - "description": "Deprecated: Unused, preserved only for backwards compatibility", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineDeclaredResource" - }, - "x-kubernetes-list-type": "atomic" - }, - "results": { - "description": "Results are values that this pipeline can output once run", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "tasks": { - "description": "Tasks declares the graph of Tasks that execute when this Pipeline is run.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTask" - }, - "x-kubernetes-list-type": "atomic" - }, - "workspaces": { - "description": "Workspaces declares a set of named workspaces that are expected to be provided by a PipelineRun.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineWorkspaceDeclaration" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineTask": { - "description": "PipelineTask defines a task in a Pipeline, passing inputs from both Params and from the output of previous tasks.", - "type": "object", - "properties": { - "description": { - "description": "Description is the description of this task within the context of a Pipeline. This description may be used to populate a UI.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is the display name of this task within the context of a Pipeline. This display name may be used to populate a UI.", - "type": "string" - }, - "matrix": { - "description": "Matrix declares parameters used to fan out this task.", - "$ref": "#/definitions/v1beta1.Matrix" - }, - "name": { - "description": "Name is the name of this task within the context of a Pipeline. Name is used as a coordinate with the `from` and `runAfter` fields to establish the execution order of tasks relative to one another.", - "type": "string" - }, - "onError": { - "description": "OnError defines the exiting behavior of a PipelineRun on error can be set to [ continue | stopAndFail ]", - "type": "string" - }, - "params": { - "description": "Parameters declares parameters passed to this task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "pipelineRef": { - "description": "PipelineRef is a reference to a pipeline definition Note: PipelineRef is in preview mode and not yet supported", - "$ref": "#/definitions/v1beta1.PipelineRef" - }, - "pipelineSpec": { - "description": "PipelineSpec is a specification of a pipeline Note: PipelineSpec is in preview mode and not yet supported Specifying PipelineSpec can be disabled by setting `disable-inline-spec` feature flag. See Pipeline.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.PipelineSpec" - }, - "resources": { - "description": "Deprecated: Unused, preserved only for backwards compatibility", - "$ref": "#/definitions/v1beta1.PipelineTaskResources" - }, - "retries": { - "description": "Retries represents how many times this task should be retried in case of task failure: ConditionSucceeded set to False", - "type": "integer", - "format": "int32" - }, - "runAfter": { - "description": "RunAfter is the list of PipelineTask names that should be executed before this Task executes. (Used to force a specific ordering in graph execution.)", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskRef": { - "description": "TaskRef is a reference to a task definition.", - "$ref": "#/definitions/v1beta1.TaskRef" - }, - "taskSpec": { - "description": "TaskSpec is a specification of a task Specifying TaskSpec can be disabled by setting `disable-inline-spec` feature flag. See Task.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.EmbeddedTask" - }, - "timeout": { - "description": "Time after which the TaskRun times out. Defaults to 1 hour. Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration", - "$ref": "#/definitions/v1.Duration" - }, - "when": { - "description": "WhenExpressions is a list of when expressions that need to be true for the task to run", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - } - }, - "workspaces": { - "description": "Workspaces maps workspaces from the pipeline spec to the workspaces declared in the Task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspacePipelineTaskBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineTaskInputResource": { - "description": "PipelineTaskInputResource maps the name of a declared PipelineResource input dependency in a Task to the resource in the Pipeline's DeclaredPipelineResources that should be used. This input may come from a previous task.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "required": [ - "name", - "resource" - ], - "properties": { - "from": { - "description": "From is the list of PipelineTask names that the resource has to come from. (Implies an ordering in the execution graph.)", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "name": { - "description": "Name is the name of the PipelineResource as declared by the Task.", - "type": "string", - "default": "" - }, - "resource": { - "description": "Resource is the name of the DeclaredPipelineResource to use.", - "type": "string", - "default": "" - } - } - }, - "v1beta1.PipelineTaskMetadata": { - "description": "PipelineTaskMetadata contains the labels or annotations for an EmbeddedTask", - "type": "object", - "properties": { - "annotations": { - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "labels": { - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - } - } - }, - "v1beta1.PipelineTaskOutputResource": { - "description": "PipelineTaskOutputResource maps the name of a declared PipelineResource output dependency in a Task to the resource in the Pipeline's DeclaredPipelineResources that should be used.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "required": [ - "name", - "resource" - ], - "properties": { - "name": { - "description": "Name is the name of the PipelineResource as declared by the Task.", - "type": "string", - "default": "" - }, - "resource": { - "description": "Resource is the name of the DeclaredPipelineResource to use.", - "type": "string", - "default": "" - } - } - }, - "v1beta1.PipelineTaskParam": { - "description": "PipelineTaskParam is used to provide arbitrary string parameters to a Task.", - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "type": "string", - "default": "" - }, - "value": { - "type": "string", - "default": "" - } - } - }, - "v1beta1.PipelineTaskResources": { - "description": "PipelineTaskResources allows a Pipeline to declare how its DeclaredPipelineResources should be provided to a Task as its inputs and outputs.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "inputs": { - "description": "Inputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTaskInputResource" - }, - "x-kubernetes-list-type": "atomic" - }, - "outputs": { - "description": "Outputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.PipelineTaskOutputResource" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.PipelineTaskRun": { - "description": "PipelineTaskRun reports the results of running a step in the Task. Each task has the potential to succeed or fail (based on the exit code) and produces logs.", - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - }, - "v1beta1.PipelineTaskRunSpec": { - "description": "PipelineTaskRunSpec can be used to configure specific specs for a concrete Task", - "type": "object", - "properties": { - "computeResources": { - "description": "Compute resources to use for this TaskRun", - "$ref": "#/definitions/v1.ResourceRequirements" - }, - "metadata": { - "$ref": "#/definitions/v1beta1.PipelineTaskMetadata" - }, - "pipelineTaskName": { - "type": "string" - }, - "sidecarOverrides": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunSidecarOverride" - }, - "x-kubernetes-list-type": "atomic" - }, - "stepOverrides": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunStepOverride" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskPodTemplate": { - "$ref": "#/definitions/pod.Template" - }, - "taskServiceAccountName": { - "type": "string" - } - } - }, - "v1beta1.PipelineWorkspaceDeclaration": { - "description": "WorkspacePipelineDeclaration creates a named slot in a Pipeline that a PipelineRun is expected to populate with a workspace binding.\n\nDeprecated: use PipelineWorkspaceDeclaration type instead", - "type": "object", - "required": [ - "name" - ], - "properties": { - "description": { - "description": "Description is a human readable string describing how the workspace will be used in the Pipeline. It can be useful to include a bit of detail about which tasks are intended to have access to the data on the workspace.", - "type": "string" - }, - "name": { - "description": "Name is the name of a workspace to be provided by a PipelineRun.", - "type": "string", - "default": "" - }, - "optional": { - "description": "Optional marks a Workspace as not being required in PipelineRuns. By default this field is false and so declared workspaces are required.", - "type": "boolean" - } - } - }, - "v1beta1.PropertySpec": { - "description": "PropertySpec defines the struct for object keys", - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - }, - "v1beta1.Provenance": { - "description": "Provenance contains metadata about resources used in the TaskRun/PipelineRun such as the source from where a remote build definition was fetched. This field aims to carry minimum amoumt of metadata in *Run status so that Tekton Chains can capture them in the provenance.", - "type": "object", - "properties": { - "configSource": { - "description": "Deprecated: Use RefSource instead", - "$ref": "#/definitions/v1beta1.ConfigSource" - }, - "featureFlags": { - "description": "FeatureFlags identifies the feature flags that were used during the task/pipeline run", - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.apis.config.FeatureFlags" - }, - "refSource": { - "description": "RefSource identifies the source where a remote task/pipeline came from.", - "$ref": "#/definitions/v1beta1.RefSource" - } - } - }, - "v1beta1.Ref": { - "description": "Ref can be used to refer to a specific instance of a StepAction.", - "type": "object", - "properties": { - "name": { - "description": "Name of the referenced step", - "type": "string" - } - } - }, - "v1beta1.RefSource": { - "description": "RefSource contains the information that can uniquely identify where a remote built definition came from i.e. Git repositories, Tekton Bundles in OCI registry and hub.", - "type": "object", - "properties": { - "digest": { - "description": "Digest is a collection of cryptographic digests for the contents of the artifact specified by URI. Example: {\"sha1\": \"f99d13e554ffcb696dee719fa85b695cb5b0f428\"}", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "entryPoint": { - "description": "EntryPoint identifies the entry point into the build. This is often a path to a build definition file and/or a target label within that file. Example: \"task/git-clone/0.8/git-clone.yaml\"", - "type": "string" - }, - "uri": { - "description": "URI indicates the identity of the source of the build definition. Example: \"https://github.com/tektoncd/catalog\"", - "type": "string" - } - } - }, - "v1beta1.ResolverRef": { - "description": "ResolverRef can be used to refer to a Pipeline or Task in a remote location like a git repo.", - "type": "object", - "properties": { - "params": { - "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "resolver": { - "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", - "type": "string" - } - } - }, - "v1beta1.ResultRef": { - "description": "ResultRef is a type that represents a reference to a task run result", - "type": "object", - "required": [ - "pipelineTask", - "result", - "resultsIndex", - "property" - ], - "properties": { - "pipelineTask": { - "type": "string", - "default": "" - }, - "property": { - "type": "string", - "default": "" - }, - "result": { - "type": "string", - "default": "" - }, - "resultsIndex": { - "type": "integer", - "format": "int32" - } - } - }, - "v1beta1.Sidecar": { - "description": "Sidecar has nearly the same data structure as Step but does not have the ability to timeout.", - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "command": { - "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Sidecar's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "env": { - "description": "List of environment variables to set in the Sidecar. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvVar" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge" - }, - "envFrom": { - "description": "List of sources to populate environment variables in the Sidecar. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the Sidecar is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvFromSource" - }, - "x-kubernetes-list-type": "atomic" - }, - "image": { - "description": "Image name to be used by the Sidecar. More info: https://kubernetes.io/docs/concepts/containers/images", - "type": "string" - }, - "imagePullPolicy": { - "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", - "type": "string" - }, - "lifecycle": { - "description": "Actions that the management system should take in response to Sidecar lifecycle events. Cannot be updated.", - "$ref": "#/definitions/v1.Lifecycle" - }, - "livenessProbe": { - "description": "Periodic probe of Sidecar liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", - "$ref": "#/definitions/v1.Probe" - }, - "name": { - "description": "Name of the Sidecar specified as a DNS_LABEL. Each Sidecar in a Task must have a unique name (DNS_LABEL). Cannot be updated.", - "type": "string", - "default": "" - }, - "ports": { - "description": "List of ports to expose from the Sidecar. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.ContainerPort" - }, - "x-kubernetes-list-map-keys": [ - "containerPort", - "protocol" - ], - "x-kubernetes-list-type": "map", - "x-kubernetes-patch-merge-key": "containerPort", - "x-kubernetes-patch-strategy": "merge" - }, - "readinessProbe": { - "description": "Periodic probe of Sidecar service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", - "$ref": "#/definitions/v1.Probe" - }, - "resources": { - "description": "Compute Resources required by this Sidecar. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", - "default": {}, - "$ref": "#/definitions/v1.ResourceRequirements" - }, - "restartPolicy": { - "description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.", - "type": "string" - }, - "script": { - "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.", - "type": "string" - }, - "securityContext": { - "description": "SecurityContext defines the security options the Sidecar should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", - "$ref": "#/definitions/v1.SecurityContext" - }, - "startupProbe": { - "description": "StartupProbe indicates that the Pod the Sidecar is running in has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", - "$ref": "#/definitions/v1.Probe" - }, - "stdin": { - "description": "Whether this Sidecar should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the Sidecar will always result in EOF. Default is false.", - "type": "boolean" - }, - "stdinOnce": { - "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on Sidecar start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the Sidecar is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", - "type": "boolean" - }, - "terminationMessagePath": { - "description": "Optional: Path at which the file to which the Sidecar's termination message will be written is mounted into the Sidecar's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", - "type": "string" - }, - "terminationMessagePolicy": { - "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the Sidecar status message on both success and failure. FallbackToLogsOnError will use the last chunk of Sidecar log output if the termination message file is empty and the Sidecar exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", - "type": "string" - }, - "tty": { - "description": "Whether this Sidecar should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", - "type": "boolean" - }, - "volumeDevices": { - "description": "volumeDevices is the list of block devices to be used by the Sidecar.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeDevice" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "devicePath", - "x-kubernetes-patch-strategy": "merge" - }, - "volumeMounts": { - "description": "Volumes to mount into the Sidecar's filesystem. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeMount" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "mountPath", - "x-kubernetes-patch-strategy": "merge" - }, - "workingDir": { - "description": "Sidecar's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "type": "string" - }, - "workspaces": { - "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceUsage" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.SidecarState": { - "description": "SidecarState reports the results of running a sidecar in a Task.", - "type": "object", - "properties": { - "container": { - "type": "string" - }, - "imageID": { - "type": "string" - }, - "name": { - "type": "string" - }, - "running": { - "description": "Details about a running container", - "$ref": "#/definitions/v1.ContainerStateRunning" - }, - "terminated": { - "description": "Details about a terminated container", - "$ref": "#/definitions/v1.ContainerStateTerminated" - }, - "waiting": { - "description": "Details about a waiting container", - "$ref": "#/definitions/v1.ContainerStateWaiting" - } - } - }, - "v1beta1.SkippedTask": { - "description": "SkippedTask is used to describe the Tasks that were skipped due to their When Expressions evaluating to False. This is a struct because we are looking into including more details about the When Expressions that caused this Task to be skipped.", - "type": "object", - "required": [ - "name", - "reason" - ], - "properties": { - "name": { - "description": "Name is the Pipeline Task name", - "type": "string", - "default": "" - }, - "reason": { - "description": "Reason is the cause of the PipelineTask being skipped.", - "type": "string", - "default": "" - }, - "whenExpressions": { - "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.Step": { - "description": "Step runs a subcomponent of a Task", - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "command": { - "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "env": { - "description": "List of environment variables to set in the container. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvVar" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge" - }, - "envFrom": { - "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvFromSource" - }, - "x-kubernetes-list-type": "atomic" - }, - "image": { - "description": "Image reference name to run for this Step. More info: https://kubernetes.io/docs/concepts/containers/images", - "type": "string" - }, - "imagePullPolicy": { - "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", - "type": "string" - }, - "lifecycle": { - "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Lifecycle" - }, - "livenessProbe": { - "description": "Periodic probe of container liveness. Step will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "name": { - "description": "Name of the Step specified as a DNS_LABEL. Each Step in a Task must have a unique name.", - "type": "string", - "default": "" - }, - "onError": { - "description": "OnError defines the exiting behavior of a container on error can be set to [ continue | stopAndFail ]", - "type": "string" - }, - "params": { - "description": "Params declares parameters passed to this step action.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "ports": { - "description": "List of ports to expose from the Step's container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.ContainerPort" - }, - "x-kubernetes-list-map-keys": [ - "containerPort", - "protocol" - ], - "x-kubernetes-list-type": "map", - "x-kubernetes-patch-merge-key": "containerPort", - "x-kubernetes-patch-strategy": "merge" - }, - "readinessProbe": { - "description": "Periodic probe of container service readiness. Step will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "ref": { - "description": "Contains the reference to an existing StepAction.", - "$ref": "#/definitions/v1beta1.Ref" - }, - "resources": { - "description": "Compute Resources required by this Step. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", - "default": {}, - "$ref": "#/definitions/v1.ResourceRequirements" - }, - "results": { - "description": "Results declares StepResults produced by the Step.\n\nIt can be used in an inlined Step when used to store Results to $(step.results.resultName.path). It cannot be used when referencing StepActions using [v1beta1.Step.Ref]. The Results declared by the StepActions will be stored here instead.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.StepResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "script": { - "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.", - "type": "string" - }, - "securityContext": { - "description": "SecurityContext defines the security options the Step should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", - "$ref": "#/definitions/v1.SecurityContext" - }, - "startupProbe": { - "description": "DeprecatedStartupProbe indicates that the Pod this Step runs in has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "stderrConfig": { - "description": "Stores configuration for the stderr stream of the step.", - "$ref": "#/definitions/v1beta1.StepOutputConfig" - }, - "stdin": { - "description": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "stdinOnce": { - "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "stdoutConfig": { - "description": "Stores configuration for the stdout stream of the step.", - "$ref": "#/definitions/v1beta1.StepOutputConfig" - }, - "terminationMessagePath": { - "description": "Deprecated: This field will be removed in a future release and can't be meaningfully used.", - "type": "string" - }, - "terminationMessagePolicy": { - "description": "Deprecated: This field will be removed in a future release and can't be meaningfully used.", - "type": "string" - }, - "timeout": { - "description": "Timeout is the time after which the step times out. Defaults to never. Refer to Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration", - "$ref": "#/definitions/v1.Duration" - }, - "tty": { - "description": "Whether this container should allocate a DeprecatedTTY for itself, also requires 'stdin' to be true. Default is false.\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "volumeDevices": { - "description": "volumeDevices is the list of block devices to be used by the Step.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeDevice" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "devicePath", - "x-kubernetes-patch-strategy": "merge" - }, - "volumeMounts": { - "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeMount" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "mountPath", - "x-kubernetes-patch-strategy": "merge" - }, - "when": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WhenExpression" - } - }, - "workingDir": { - "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "type": "string" - }, - "workspaces": { - "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Step wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceUsage" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.StepAction": { - "description": "StepAction represents the actionable components of Step. The Step can only reference it from the cluster or using remote resolution.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "description": "Spec holds the desired state of the Step from the client", - "default": {}, - "$ref": "#/definitions/v1beta1.StepActionSpec" - } - } - }, - "v1beta1.StepActionList": { - "description": "StepActionList contains a list of StepActions", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.StepAction" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.StepActionSpec": { - "description": "StepActionSpec contains the actionable components of a step.", - "type": "object", - "properties": { - "args": { - "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "command": { - "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "description": { - "description": "Description is a user-facing description of the stepaction that may be used to populate a UI.", - "type": "string" - }, - "env": { - "description": "List of environment variables to set in the container. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvVar" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge" - }, - "image": { - "description": "Image reference name to run for this StepAction. More info: https://kubernetes.io/docs/concepts/containers/images", - "type": "string" - }, - "params": { - "description": "Params is a list of input parameters required to run the stepAction. Params must be supplied as inputs in Steps unless they declare a defaultvalue.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.ParamSpec" - }, - "x-kubernetes-list-type": "atomic" - }, - "results": { - "description": "Results are values that this StepAction can output", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.StepResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "script": { - "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.", - "type": "string" - }, - "securityContext": { - "description": "SecurityContext defines the security options the Step should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ The value set in StepAction will take precedence over the value from Task.", - "$ref": "#/definitions/v1.SecurityContext" - }, - "volumeMounts": { - "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeMount" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "mountPath", - "x-kubernetes-patch-strategy": "merge" - }, - "workingDir": { - "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "type": "string" - } - } - }, - "v1beta1.StepOutputConfig": { - "description": "StepOutputConfig stores configuration for a step output stream.", - "type": "object", - "properties": { - "path": { - "description": "Path to duplicate stdout stream to on container's local filesystem.", - "type": "string" - } - } - }, - "v1beta1.StepState": { - "description": "StepState reports the results of running a step in a Task.", - "type": "object", - "properties": { - "container": { - "type": "string" - }, - "imageID": { - "type": "string" - }, - "inputs": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Artifact" - } - }, - "name": { - "type": "string" - }, - "outputs": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Artifact" - } - }, - "provenance": { - "$ref": "#/definitions/v1beta1.Provenance" - }, - "results": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunResult" - } - }, - "running": { - "description": "Details about a running container", - "$ref": "#/definitions/v1.ContainerStateRunning" - }, - "terminated": { - "description": "Details about a terminated container", - "$ref": "#/definitions/v1.ContainerStateTerminated" - }, - "waiting": { - "description": "Details about a waiting container", - "$ref": "#/definitions/v1.ContainerStateWaiting" - } - } - }, - "v1beta1.StepTemplate": { - "description": "StepTemplate is a template for a Step", - "type": "object", - "required": [ - "name" - ], - "properties": { - "args": { - "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "command": { - "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "env": { - "description": "List of environment variables to set in the container. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvVar" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "name", - "x-kubernetes-patch-strategy": "merge" - }, - "envFrom": { - "description": "List of sources to populate environment variables in the Step. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.EnvFromSource" - }, - "x-kubernetes-list-type": "atomic" - }, - "image": { - "description": "Default image name to use for each Step. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", - "type": "string" - }, - "imagePullPolicy": { - "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", - "type": "string" - }, - "lifecycle": { - "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Lifecycle" - }, - "livenessProbe": { - "description": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "name": { - "description": "Default name for each Step specified as a DNS_LABEL. Each Step in a Task must have a unique name. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", - "type": "string", - "default": "" - }, - "ports": { - "description": "List of ports to expose from the Step's container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.ContainerPort" - }, - "x-kubernetes-list-map-keys": [ - "containerPort", - "protocol" - ], - "x-kubernetes-list-type": "map", - "x-kubernetes-patch-merge-key": "containerPort", - "x-kubernetes-patch-strategy": "merge" - }, - "readinessProbe": { - "description": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "resources": { - "description": "Compute Resources required by this Step. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", - "default": {}, - "$ref": "#/definitions/v1.ResourceRequirements" - }, - "securityContext": { - "description": "SecurityContext defines the security options the Step should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", - "$ref": "#/definitions/v1.SecurityContext" - }, - "startupProbe": { - "description": "DeprecatedStartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n\nDeprecated: This field will be removed in a future release.", - "$ref": "#/definitions/v1.Probe" - }, - "stdin": { - "description": "Whether this Step should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the Step will always result in EOF. Default is false.\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "stdinOnce": { - "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "terminationMessagePath": { - "description": "Deprecated: This field will be removed in a future release and cannot be meaningfully used.", - "type": "string" - }, - "terminationMessagePolicy": { - "description": "Deprecated: This field will be removed in a future release and cannot be meaningfully used.", - "type": "string" - }, - "tty": { - "description": "Whether this Step should allocate a DeprecatedTTY for itself, also requires 'stdin' to be true. Default is false.\n\nDeprecated: This field will be removed in a future release.", - "type": "boolean" - }, - "volumeDevices": { - "description": "volumeDevices is the list of block devices to be used by the Step.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeDevice" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "devicePath", - "x-kubernetes-patch-strategy": "merge" - }, - "volumeMounts": { - "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.VolumeMount" - }, - "x-kubernetes-list-type": "atomic", - "x-kubernetes-patch-merge-key": "mountPath", - "x-kubernetes-patch-strategy": "merge" - }, - "workingDir": { - "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "type": "string" - } - } - }, - "v1beta1.Task": { - "description": "Task represents a collection of sequential steps that are run as part of a Pipeline using a set of inputs and producing a set of outputs. Tasks execute when TaskRuns are created that provide the input parameters and resources and output resources the Task requires.\n\nDeprecated: Please use v1.Task instead.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "description": "Spec holds the desired state of the Task from the client", - "default": {}, - "$ref": "#/definitions/v1beta1.TaskSpec" - } - } - }, - "v1beta1.TaskBreakpoints": { - "description": "TaskBreakpoints defines the breakpoint config for a particular Task", - "type": "object", - "properties": { - "beforeSteps": { - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "onFailure": { - "description": "if enabled, pause TaskRun on failure of a step failed step will not exit", - "type": "string" - } - } - }, - "v1beta1.TaskList": { - "description": "TaskList contains a list of Task", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Task" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.TaskRef": { - "description": "TaskRef can be used to refer to a specific instance of a task.", - "type": "object", - "properties": { - "apiVersion": { - "description": "API version of the referent Note: A Task with non-empty APIVersion and Kind is considered a Custom Task", - "type": "string" - }, - "bundle": { - "description": "Bundle url reference to a Tekton Bundle.\n\nDeprecated: Please use ResolverRef with the bundles resolver instead. The field is staying there for go client backward compatibility, but is not used/allowed anymore.", - "type": "string" - }, - "kind": { - "description": "TaskKind indicates the Kind of the Task: 1. Namespaced Task when Kind is set to \"Task\". If Kind is \"\", it defaults to \"Task\". 2. Custom Task when Kind is non-empty and APIVersion is non-empty", - "type": "string" - }, - "name": { - "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "type": "string" - } - } - }, - "v1beta1.TaskResource": { - "description": "TaskResource defines an input or output Resource declared as a requirement by a Task. The Name field will be used to refer to these Resources within the Task definition, and when provided as an Input, the Name will be the path to the volume mounted containing this Resource as an input (e.g. an input Resource named `workspace` will be mounted at `/workspace`).\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "description": { - "description": "Description is a user-facing description of the declared resource that may be used to populate a UI.", - "type": "string" - }, - "name": { - "description": "Name declares the name by which a resource is referenced in the definition. Resources may be referenced by name in the definition of a Task's steps.", - "type": "string", - "default": "" - }, - "optional": { - "description": "Optional declares the resource as optional. By default optional is set to false which makes a resource required. optional: true - the resource is considered optional optional: false - the resource is considered required (equivalent of not specifying it)", - "type": "boolean" - }, - "targetPath": { - "description": "TargetPath is the path in workspace directory where the resource will be copied.", - "type": "string" - }, - "type": { - "description": "Type is the type of this resource;", - "type": "string", - "default": "" - } - } - }, - "v1beta1.TaskResourceBinding": { - "description": "TaskResourceBinding points to the PipelineResource that will be used for the Task input or output called Name.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "name": { - "description": "Name is the name of the PipelineResource in the Pipeline's declaration", - "type": "string" - }, - "paths": { - "description": "Paths will probably be removed in #1284, and then PipelineResourceBinding can be used instead. The optional Path field corresponds to a path on disk at which the Resource can be found (used when providing the resource via mounted volume, overriding the default logic to fetch the Resource).", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - }, - "resourceRef": { - "description": "ResourceRef is a reference to the instance of the actual PipelineResource that should be used", - "$ref": "#/definitions/v1beta1.PipelineResourceRef" - }, - "resourceSpec": { - "description": "ResourceSpec is specification of a resource that should be created and consumed by the task", - "$ref": "#/definitions/v1alpha1.PipelineResourceSpec" - } - } - }, - "v1beta1.TaskResources": { - "description": "TaskResources allows a Pipeline to declare how its DeclaredPipelineResources should be provided to a Task as its inputs and outputs.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "inputs": { - "description": "Inputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResource" - }, - "x-kubernetes-list-type": "atomic" - }, - "outputs": { - "description": "Outputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResource" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TaskResult": { - "description": "TaskResult used to describe the results of a task", - "type": "object", - "required": [ - "name" - ], - "properties": { - "description": { - "description": "Description is a human-readable description of the result", - "type": "string" - }, - "name": { - "description": "Name the given name", - "type": "string", - "default": "" - }, - "properties": { - "description": "Properties is the JSON Schema properties to support key-value pairs results.", - "type": "object", - "additionalProperties": { - "default": {}, - "$ref": "#/definitions/v1beta1.PropertySpec" - } - }, - "type": { - "description": "Type is the user-specified type of the result. The possible type is currently \"string\" and will support \"array\" in following work.", - "type": "string" - }, - "value": { - "description": "Value the expression used to retrieve the value of the result from an underlying Step.", - "$ref": "#/definitions/v1beta1.ParamValue" - } - } - }, - "v1beta1.TaskRun": { - "description": "TaskRun represents a single execution of a Task. TaskRuns are how the steps specified in a Task are executed; they specify the parameters and resources used to run the steps in a Task.\n\nDeprecated: Please use v1.TaskRun instead.", - "type": "object", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ObjectMeta" - }, - "spec": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunSpec" - }, - "status": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunStatus" - } - } - }, - "v1beta1.TaskRunDebug": { - "description": "TaskRunDebug defines the breakpoint config for a particular TaskRun", - "type": "object", - "properties": { - "breakpoints": { - "$ref": "#/definitions/v1beta1.TaskBreakpoints" - } - } - }, - "v1beta1.TaskRunInputs": { - "description": "TaskRunInputs holds the input values that this task was invoked with.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "params": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "resources": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResourceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TaskRunList": { - "description": "TaskRunList contains a list of TaskRun", - "type": "object", - "required": [ - "items" - ], - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRun" - } - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "default": {}, - "$ref": "#/definitions/v1.ListMeta" - } - } - }, - "v1beta1.TaskRunOutputs": { - "description": "TaskRunOutputs holds the output values that this task was invoked with.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "resources": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResourceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TaskRunResources": { - "description": "TaskRunResources allows a TaskRun to declare inputs and outputs TaskResourceBinding\n\nDeprecated: Unused, preserved only for backwards compatibility", - "type": "object", - "properties": { - "inputs": { - "description": "Inputs holds the inputs resources this task was invoked with", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResourceBinding" - }, - "x-kubernetes-list-type": "atomic" - }, - "outputs": { - "description": "Outputs holds the inputs resources this task was invoked with", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResourceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TaskRunResult": { - "description": "TaskRunStepResult is a type alias of TaskRunResult", - "type": "object", - "required": [ - "name", - "value" - ], - "properties": { - "name": { - "description": "Name the given name", - "type": "string", - "default": "" - }, - "type": { - "description": "Type is the user-specified type of the result. The possible type is currently \"string\" and will support \"array\" in following work.", - "type": "string" - }, - "value": { - "description": "Value the given value of the result", - "$ref": "#/definitions/v1beta1.ParamValue" - } - } - }, - "v1beta1.TaskRunSidecarOverride": { - "description": "TaskRunSidecarOverride is used to override the values of a Sidecar in the corresponding Task.", - "type": "object", - "required": [ - "name", - "resources" - ], - "properties": { - "name": { - "description": "The name of the Sidecar to override.", - "type": "string", - "default": "" - }, - "resources": { - "description": "The resource requirements to apply to the Sidecar.", - "default": {}, - "$ref": "#/definitions/v1.ResourceRequirements" - } - } - }, - "v1beta1.TaskRunSpec": { - "description": "TaskRunSpec defines the desired state of TaskRun", - "type": "object", - "properties": { - "computeResources": { - "description": "Compute resources to use for this TaskRun", - "$ref": "#/definitions/v1.ResourceRequirements" - }, - "debug": { - "$ref": "#/definitions/v1beta1.TaskRunDebug" - }, - "params": { - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Param" - }, - "x-kubernetes-list-type": "atomic" - }, - "podTemplate": { - "description": "PodTemplate holds pod specific configuration", - "$ref": "#/definitions/pod.Template" - }, - "resources": { - "description": "Deprecated: Unused, preserved only for backwards compatibility", - "$ref": "#/definitions/v1beta1.TaskRunResources" - }, - "retries": { - "description": "Retries represents how many times this TaskRun should be retried in the event of Task failure.", - "type": "integer", - "format": "int32" - }, - "serviceAccountName": { - "type": "string", - "default": "" - }, - "sidecarOverrides": { - "description": "Overrides to apply to Sidecars in this TaskRun. If a field is specified in both a Sidecar and a SidecarOverride, the value from the SidecarOverride will be used. This field is only supported when the alpha feature gate is enabled.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunSidecarOverride" - }, - "x-kubernetes-list-type": "atomic" - }, - "status": { - "description": "Used for cancelling a TaskRun (and maybe more later on)", - "type": "string" - }, - "statusMessage": { - "description": "Status message for cancellation.", - "type": "string" - }, - "stepOverrides": { - "description": "Overrides to apply to Steps in this TaskRun. If a field is specified in both a Step and a StepOverride, the value from the StepOverride will be used. This field is only supported when the alpha feature gate is enabled.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunStepOverride" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskRef": { - "description": "no more than one of the TaskRef and TaskSpec may be specified.", - "$ref": "#/definitions/v1beta1.TaskRef" - }, - "taskSpec": { - "description": "Specifying TaskSpec can be disabled by setting `disable-inline-spec` feature flag. See Task.spec (API version: tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.TaskSpec" - }, - "timeout": { - "description": "Time after which one retry attempt times out. Defaults to 1 hour. Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration", - "$ref": "#/definitions/v1.Duration" - }, - "workspaces": { - "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceBinding" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TaskRunStatus": { - "description": "TaskRunStatus defines the observed state of TaskRun", - "type": "object", - "required": [ - "podName" - ], - "properties": { - "annotations": { - "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "cloudEvents": { - "description": "CloudEvents describe the state of each cloud event requested via a CloudEventResource.\n\nDeprecated: Removed in v0.44.0.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.CloudEventDelivery" - }, - "x-kubernetes-list-type": "atomic" - }, - "completionTime": { - "description": "CompletionTime is the time the build completed.", - "$ref": "#/definitions/v1.Time" - }, - "conditions": { - "description": "Conditions the latest available observations of a resource's current state.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/knative.Condition" - }, - "x-kubernetes-patch-merge-key": "type", - "x-kubernetes-patch-strategy": "merge" - }, - "observedGeneration": { - "description": "ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.", - "type": "integer", - "format": "int64" - }, - "podName": { - "description": "PodName is the name of the pod responsible for executing this task's steps.", - "type": "string", - "default": "" - }, - "provenance": { - "description": "Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.).", - "$ref": "#/definitions/v1beta1.Provenance" - }, - "resourcesResult": { - "description": "Results from Resources built during the TaskRun. This is tomb-stoned along with the removal of pipelineResources Deprecated: this field is not populated and is preserved only for backwards compatibility", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.result.RunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "retriesStatus": { - "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. See TaskRun.status (API version: tekton.dev/v1beta1)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunStatus" - }, - "x-kubernetes-list-type": "atomic" - }, - "sidecars": { - "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.SidecarState" - }, - "x-kubernetes-list-type": "atomic" - }, - "spanContext": { - "description": "SpanContext contains tracing span context fields", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "startTime": { - "description": "StartTime is the time the build is actually started.", - "$ref": "#/definitions/v1.Time" - }, - "steps": { - "description": "Steps describes the state of each build step container.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.StepState" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskResults": { - "description": "TaskRunResults are the list of results written out by the task's containers", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskSpec": { - "description": "TaskSpec contains the Spec from the dereferenced Task definition used to instantiate this TaskRun. See Task.spec (API version tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.TaskSpec" - } - } - }, - "v1beta1.TaskRunStatusFields": { - "description": "TaskRunStatusFields holds the fields of TaskRun's status. This is defined separately and inlined so that other types can readily consume these fields via duck typing.", - "type": "object", - "required": [ - "podName" - ], - "properties": { - "cloudEvents": { - "description": "CloudEvents describe the state of each cloud event requested via a CloudEventResource.\n\nDeprecated: Removed in v0.44.0.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.CloudEventDelivery" - }, - "x-kubernetes-list-type": "atomic" - }, - "completionTime": { - "description": "CompletionTime is the time the build completed.", - "$ref": "#/definitions/v1.Time" - }, - "podName": { - "description": "PodName is the name of the pod responsible for executing this task's steps.", - "type": "string", - "default": "" - }, - "provenance": { - "description": "Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.).", - "$ref": "#/definitions/v1beta1.Provenance" - }, - "resourcesResult": { - "description": "Results from Resources built during the TaskRun. This is tomb-stoned along with the removal of pipelineResources Deprecated: this field is not populated and is preserved only for backwards compatibility", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.result.RunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "retriesStatus": { - "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. See TaskRun.status (API version: tekton.dev/v1beta1)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunStatus" - }, - "x-kubernetes-list-type": "atomic" - }, - "sidecars": { - "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.SidecarState" - }, - "x-kubernetes-list-type": "atomic" - }, - "spanContext": { - "description": "SpanContext contains tracing span context fields", - "type": "object", - "additionalProperties": { - "type": "string", - "default": "" - } - }, - "startTime": { - "description": "StartTime is the time the build is actually started.", - "$ref": "#/definitions/v1.Time" - }, - "steps": { - "description": "Steps describes the state of each build step container.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.StepState" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskResults": { - "description": "TaskRunResults are the list of results written out by the task's containers", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskRunResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "taskSpec": { - "description": "TaskSpec contains the Spec from the dereferenced Task definition used to instantiate this TaskRun. See Task.spec (API version tekton.dev/v1beta1)", - "$ref": "#/definitions/v1beta1.TaskSpec" - } - } - }, - "v1beta1.TaskRunStepOverride": { - "description": "TaskRunStepOverride is used to override the values of a Step in the corresponding Task.", - "type": "object", - "required": [ - "name", - "resources" - ], - "properties": { - "name": { - "description": "The name of the Step to override.", - "type": "string", - "default": "" - }, - "resources": { - "description": "The resource requirements to apply to the Step.", - "default": {}, - "$ref": "#/definitions/v1.ResourceRequirements" - } - } - }, - "v1beta1.TaskSpec": { - "description": "TaskSpec defines the desired state of Task.", - "type": "object", - "properties": { - "description": { - "description": "Description is a user-facing description of the task that may be used to populate a UI.", - "type": "string" - }, - "displayName": { - "description": "DisplayName is a user-facing name of the task that may be used to populate a UI.", - "type": "string" - }, - "params": { - "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.ParamSpec" - }, - "x-kubernetes-list-type": "atomic" - }, - "resources": { - "description": "Resources is a list input and output resource to run the task Resources are represented in TaskRuns as bindings to instances of PipelineResources.\n\nDeprecated: Unused, preserved only for backwards compatibility", - "$ref": "#/definitions/v1beta1.TaskResources" - }, - "results": { - "description": "Results are values that this Task can output", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.TaskResult" - }, - "x-kubernetes-list-type": "atomic" - }, - "sidecars": { - "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Sidecar" - }, - "x-kubernetes-list-type": "atomic" - }, - "stepTemplate": { - "description": "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - "$ref": "#/definitions/v1beta1.StepTemplate" - }, - "steps": { - "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.Step" - }, - "x-kubernetes-list-type": "atomic" - }, - "volumes": { - "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1.Volume" - }, - "x-kubernetes-list-type": "atomic" - }, - "workspaces": { - "description": "Workspaces are the volumes that this Task requires.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/v1beta1.WorkspaceDeclaration" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.TimeoutFields": { - "description": "TimeoutFields allows granular specification of pipeline, task, and finally timeouts", - "type": "object", - "properties": { - "finally": { - "description": "Finally sets the maximum allowed duration of this pipeline's finally", - "$ref": "#/definitions/v1.Duration" - }, - "pipeline": { - "description": "Pipeline sets the maximum allowed duration for execution of the entire pipeline. The sum of individual timeouts for tasks and finally must not exceed this value.", - "$ref": "#/definitions/v1.Duration" - }, - "tasks": { - "description": "Tasks sets the maximum allowed duration of this pipeline's tasks", - "$ref": "#/definitions/v1.Duration" - } - } - }, - "v1beta1.WhenExpression": { - "description": "WhenExpression allows a PipelineTask to declare expressions to be evaluated before the Task is run to determine whether the Task should be executed or skipped", - "type": "object", - "properties": { - "cel": { - "description": "CEL is a string of Common Language Expression, which can be used to conditionally execute the task based on the result of the expression evaluation More info about CEL syntax: https://github.com/google/cel-spec/blob/master/doc/langdef.md", - "type": "string" - }, - "input": { - "description": "Input is the string for guard checking which can be a static input or an output from a parent Task", - "type": "string" - }, - "operator": { - "description": "Operator that represents an Input's relationship to the values", - "type": "string" - }, - "values": { - "description": "Values is an array of strings, which is compared against the input, for guard checking It must be non-empty", - "type": "array", - "items": { - "type": "string", - "default": "" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, - "v1beta1.WorkspaceBinding": { - "description": "WorkspaceBinding maps a Task's declared workspace to a Volume.", - "type": "object", - "required": [ - "name" - ], - "properties": { - "configMap": { - "description": "ConfigMap represents a configMap that should populate this workspace.", - "$ref": "#/definitions/v1.ConfigMapVolumeSource" - }, - "csi": { - "description": "CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.", - "$ref": "#/definitions/v1.CSIVolumeSource" - }, - "emptyDir": { - "description": "EmptyDir represents a temporary directory that shares a Task's lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir Either this OR PersistentVolumeClaim can be used.", - "$ref": "#/definitions/v1.EmptyDirVolumeSource" - }, - "name": { - "description": "Name is the name of the workspace populated by the volume.", - "type": "string", - "default": "" - }, - "persistentVolumeClaim": { - "description": "PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. Either this OR EmptyDir can be used.", - "$ref": "#/definitions/v1.PersistentVolumeClaimVolumeSource" - }, - "projected": { - "description": "Projected represents a projected volume that should populate this workspace.", - "$ref": "#/definitions/v1.ProjectedVolumeSource" - }, - "secret": { - "description": "Secret represents a secret that should populate this workspace.", - "$ref": "#/definitions/v1.SecretVolumeSource" - }, - "subPath": { - "description": "SubPath is optionally a directory on the volume which should be used for this binding (i.e. the volume will be mounted at this sub directory).", - "type": "string" - }, - "volumeClaimTemplate": { - "description": "VolumeClaimTemplate is a template for a claim that will be created in the same namespace. The PipelineRun controller is responsible for creating a unique claim for each instance of PipelineRun. See PersistentVolumeClaim (API version: v1)", - "$ref": "#/definitions/v1.PersistentVolumeClaim" - } - } - }, - "v1beta1.WorkspaceDeclaration": { - "description": "WorkspaceDeclaration is a declaration of a volume that a Task requires.", - "type": "object", - "required": [ - "name" - ], - "properties": { - "description": { - "description": "Description is an optional human readable description of this volume.", - "type": "string" - }, - "mountPath": { - "description": "MountPath overrides the directory that the volume will be made available at.", - "type": "string" - }, - "name": { - "description": "Name is the name by which you can bind the volume at runtime.", - "type": "string", - "default": "" - }, - "optional": { - "description": "Optional marks a Workspace as not being required in TaskRuns. By default this field is false and so declared workspaces are required.", - "type": "boolean" - }, - "readOnly": { - "description": "ReadOnly dictates whether a mounted volume is writable. By default this field is false and so mounted volumes are writable.", - "type": "boolean" - } - } - }, - "v1beta1.WorkspacePipelineTaskBinding": { - "description": "WorkspacePipelineTaskBinding describes how a workspace passed into the pipeline should be mapped to a task's declared workspace.", - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "description": "Name is the name of the workspace as declared by the task", - "type": "string", - "default": "" - }, - "subPath": { - "description": "SubPath is optionally a directory on the volume which should be used for this binding (i.e. the volume will be mounted at this sub directory).", - "type": "string" - }, - "workspace": { - "description": "Workspace is the name of the workspace declared by the pipeline", - "type": "string" - } - } - }, - "v1beta1.WorkspaceUsage": { - "description": "WorkspaceUsage is used by a Step or Sidecar to declare that it wants isolated access to a Workspace defined in a Task.", - "type": "object", - "required": [ - "name", - "mountPath" - ], - "properties": { - "mountPath": { - "description": "MountPath is the path that the workspace should be mounted to inside the Step or Sidecar, overriding any MountPath specified in the Task's WorkspaceDeclaration.", - "type": "string", - "default": "" - }, - "name": { - "description": "Name is the name of the workspace this Step or Sidecar wants access to.", - "type": "string", - "default": "" - } - } - } - } -} diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_binding_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_binding_validation.go index d13c5a0c37..acc12687f1 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_binding_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_binding_validation.go @@ -101,5 +101,4 @@ func validateParamValue(in string) *apis.FieldError { } } return nil - } diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_validation.go index c97e1f5d9f..0c3d4290eb 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1/trigger_validation.go @@ -18,6 +18,7 @@ package v1beta1 import ( "context" + "errors" "fmt" "net/http" @@ -59,7 +60,7 @@ func (t TriggerSpecTemplate) validate(ctx context.Context) (errs *apis.FieldErro // Optional explicit match if t.APIVersion != "" { if t.APIVersion != "v1alpha1" && t.APIVersion != "v1beta1" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid apiVersion"), "template.apiVersion")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid apiVersion"), "template.apiVersion")) } } @@ -86,7 +87,7 @@ func (t triggerSpecBindingArray) validate(ctx context.Context) (errs *apis.Field case b.Name != "": // Cannot specify both Ref and Name errs = errs.Also(apis.ErrMultipleOneOf(fmt.Sprintf("bindings[%d].ref", i), fmt.Sprintf("bindings[%d].name", i))) case b.Kind != NamespacedTriggerBindingKind && b.Kind != ClusterTriggerBindingKind: // Kind must be valid - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid kind"), fmt.Sprintf("bindings[%d].kind", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid kind"), fmt.Sprintf("bindings[%d].kind", i))) } case b.Name != "": if b.Value == nil { // Value is mandatory if Name is specified @@ -114,29 +115,29 @@ func (i *TriggerInterceptor) validate(ctx context.Context) (errs *apis.FieldErro if w.ObjectRef.Kind == "" { errs = errs.Also(apis.ErrMissingField("interceptor.webhook.objectRef.kind")) } else if w.ObjectRef.Kind != "Service" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid kind"), "interceptor.webhook.objectRef.kind")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid kind"), "interceptor.webhook.objectRef.kind")) } // Optional explicit match if w.ObjectRef.APIVersion == "" { errs = errs.Also(apis.ErrMissingField("interceptor.webhook.objectRef.apiVersion")) } else if w.ObjectRef.APIVersion != "v1" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid apiVersion"), "interceptor.webhook.objectRef.apiVersion")) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid apiVersion"), "interceptor.webhook.objectRef.apiVersion")) } } for i, header := range w.Header { // Enforce non-empty canonical header keys if len(header.Name) == 0 || http.CanonicalHeaderKey(header.Name) != header.Name { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header name"), fmt.Sprintf("interceptor.webhook.header[%d].name", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header name"), fmt.Sprintf("interceptor.webhook.header[%d].name", i))) } // Enforce non-empty header values if header.Value.Type == pipelinev1.ParamTypeString { if len(header.Value.StringVal) == 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) } } else if len(header.Value.ArrayVal) == 0 { - errs = errs.Also(apis.ErrInvalidValue(fmt.Errorf("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) + errs = errs.Also(apis.ErrInvalidValue(errors.New("invalid header value"), fmt.Sprintf("interceptor.webhook.header[%d].value", i))) } } } diff --git a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/validation.go b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/validation.go index 58c7f0e36d..7e43166b0e 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/validation.go +++ b/vendor/github.com/tektoncd/triggers/pkg/apis/triggers/validation.go @@ -17,8 +17,6 @@ limitations under the License. package triggers import ( - "fmt" - "knative.dev/pkg/apis" ) @@ -31,7 +29,7 @@ func ValidateAnnotations(annotations map[string]string) *apis.FieldError { if value, ok := annotations[PayloadValidationAnnotation]; ok { if value != "true" && value != "false" { - errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s annotation must have value 'true' or 'false'", PayloadValidationAnnotation), "metadata.annotations")) + errs = errs.Also(apis.ErrInvalidValue(PayloadValidationAnnotation+" annotation must have value 'true' or 'false'", "metadata.annotations")) } } diff --git a/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/cel.go b/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/cel.go index eaced67406..db50cb24b8 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/cel.go +++ b/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/cel.go @@ -115,7 +115,6 @@ func makeCelEnv(ctx context.Context, ns string, sg interceptors.SecretGetter) (* decls.NewVariable("extensions", mapStrDyn), decls.NewVariable("requestURL", types.StringType), )) - } func makeEvalContext(body []byte, h http.Header, url string, extensions map[string]interface{}) (map[string]interface{}, error) { @@ -188,7 +187,7 @@ func (w *InterceptorImpl) Process(ctx context.Context, r *triggersv1.Interceptor // https://golang.org/pkg/encoding/json/#Marshal // // An alternative might be to return " + val + " for types.Bytes to - // simulate the the JSON encoding. + // simulate the JSON encoding. case types.String, types.Bytes: raw, err = val.ConvertToNative(structType) if err == nil { diff --git a/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/triggers.go b/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/triggers.go index a76e2d98bb..2745e803e5 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/triggers.go +++ b/vendor/github.com/tektoncd/triggers/pkg/interceptors/cel/triggers.go @@ -162,7 +162,7 @@ func Triggers(ctx context.Context, ns string, sg interceptors.SecretGetter) cel. } type triggersLib struct { - ctx context.Context + ctx context.Context //nolint:containedctx defaultNS string secretGetter interceptors.SecretGetter } diff --git a/vendor/github.com/tektoncd/triggers/pkg/interceptors/interceptors.go b/vendor/github.com/tektoncd/triggers/pkg/interceptors/interceptors.go index f8fe7962ef..adf6d49db3 100644 --- a/vendor/github.com/tektoncd/triggers/pkg/interceptors/interceptors.go +++ b/vendor/github.com/tektoncd/triggers/pkg/interceptors/interceptors.go @@ -121,7 +121,7 @@ func Execute(ctx context.Context, client *http.Client, req *triggersv1beta1.Inte return nil, err } // TODO: Seed context with timeouts - r, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(b)) + r, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(b)) if err != nil { return nil, err } diff --git a/vendor/github.com/tektoncd/triggers/test/README.md b/vendor/github.com/tektoncd/triggers/test/README.md index ade812b8f0..c989caa6f4 100644 --- a/vendor/github.com/tektoncd/triggers/test/README.md +++ b/vendor/github.com/tektoncd/triggers/test/README.md @@ -31,6 +31,73 @@ which need `-tags=e2e` to be enabled. Environment variables used by end to end tests: - `KO_DOCKER_REPO` - Set this to an image registry your tests can push images to +**kubeconfig**: + +- Use `--kubeconfig` flag pointing to a kubeconfig file, defaults to `~/.kube/config`. +or +- `KUBECONFIG` - Set this environment variable with the path to a kubeconfig file that will be used when [running](#running) tests + +Setting up the configuration file may differ between environments. Here is an example using a Kubernetes cluster behind a path `/k/cluster`: + +```yaml +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: [REDACTED] + server: https://k8s.example.com/k/cluster + name: proxy +contexts: +- context: + cluster: proxy + namespace: default + user: kubeconfig-user + name: proxy +current-context: proxy +kind: Config +preferences: {} +users: +- name: kubeconfig-user + user: + token: [REDACTED] +``` + +And another example using [minikube](https://minikube.sigs.k8s.io/): + +```yaml +apiVersion: v1 +clusters: +- cluster: + certificate-authority: "[REDACTED]" + extensions: + - extension: + provider: minikube.sigs.k8s.io + version: v1.35.0 + name: cluster_info + server: https://127.0.0.1:32771 + name: minikube +contexts: +- context: + cluster: minikube + extensions: + - extension: + provider: minikube.sigs.k8s.io + version: v1.35.0 + name: context_info + namespace: default + user: minikube + name: minikube +current-context: minikube +kind: Config +preferences: {} +users: +- name: minikube + user: {} # redacted +``` + +**Configuration issues**: + +- Having multiple `config` files in `KUBECONFIG` (i.e., `KUBECONFIG=$HOME/.kube/config:$HOME/.kube/config-2`) will cause test cases to fail. You can either assign `KUBECONFIG` to a single file or use the `--kubeconfig` flag when [running](#running) tests. + ### Running @@ -95,6 +162,8 @@ To run the YAML e2e tests, run the following command: ./test/e2e-tests-yaml.sh ``` +### Configuration + ### Adding integration tests In the [`test`](/test/) dir you will find several libraries in the `test` diff --git a/vendor/github.com/tektoncd/triggers/test/controller.go b/vendor/github.com/tektoncd/triggers/test/controller.go index c95082f35a..48cea68ecd 100644 --- a/vendor/github.com/tektoncd/triggers/test/controller.go +++ b/vendor/github.com/tektoncd/triggers/test/controller.go @@ -120,7 +120,8 @@ func SetupFakeContext(t testing.TB) (context.Context, []controller.Informer) { } // SeedResources returns Clients populated with the given Resources -// nolint: revive +// +//nolint:revive func SeedResources(t *testing.T, ctx context.Context, r Resources) Clients { t.Helper() c := Clients{ @@ -286,7 +287,8 @@ func SeedResources(t *testing.T, ctx context.Context, r Resources) Clients { // GetResourcesFromClients returns the Resources in the Clients provided // Precondition: all Namespaces used in Resources must be listed in Resources.Namespaces -// nolint: golint +// +//nolint:golint func GetResourcesFromClients(c Clients) (*Resources, error) { testResources := &Resources{} // Add ClusterTriggerBindings @@ -390,7 +392,6 @@ func GetResourcesFromClients(c Clients) (*Resources, error) { } testResources.WithPod = append(testResources.WithPod, withPod.DeepCopy()) } - } return testResources, nil } diff --git a/vendor/github.com/tektoncd/triggers/test/e2e-common.sh b/vendor/github.com/tektoncd/triggers/test/e2e-common.sh index d563a63de2..91a330c546 100644 --- a/vendor/github.com/tektoncd/triggers/test/e2e-common.sh +++ b/vendor/github.com/tektoncd/triggers/test/e2e-common.sh @@ -26,7 +26,7 @@ # Check if we have a specific RELEASE_YAML global environment variable to use # instead of detecting the latest released one from tektoncd/pipeline releases RELEASE_YAML=${RELEASE_YAML:-} - +SKIP_SECURITY_CTX=${SKIP_SECURITY_CTX:="false"} source $(dirname $0)/../vendor/github.com/tektoncd/plumbing/scripts/e2e-tests.sh function install_pipeline_crd() { @@ -52,18 +52,37 @@ function install_pipeline_crd() { function install_triggers_crd() { echo ">> Deploying Tekton Triggers" - ko apply -f config/ || fail_test "Tekton Triggers installation failed" + rel=$(mktemp) + release=$(mktemp) + ko resolve -f config/ > "${rel}" || fail_test "Tekton Triggers build failed" + + if [ "${SKIP_SECURITY_CTX}" == "true" ]; then + yq 'del(.spec.template.spec.containers[]?.securityContext.runAsUser, .spec.template.spec.containers[]?.securityContext.runAsGroup)' "${rel}" > "${release}" + else + cat "${rel}" > "${release}" + fi + + kubectl apply -f "${release}" || fail_test "Tekton Triggers installation failed" # Wait for the Interceptors CRD to be available before adding the core-interceptors kubectl wait --for=condition=Established --timeout=30s crds/clusterinterceptors.triggers.tekton.dev - ko apply -f config/interceptors || fail_test "Core interceptors installation failed" + ko resolve -f config/interceptors > "${rel}" || fail_test "Core interceptors build failed" + + if [ "${SKIP_SECURITY_CTX}" == "true" ]; then + kubectl patch configmap config-defaults-triggers -n tekton-pipelines --type='merge' -p='{"data":{"default-run-as-user":"","default-fs-group":"", "default-run-as-group":""}}' + yq 'del(.spec.template.spec.containers[]?.securityContext.runAsUser, .spec.template.spec.containers[]?.securityContext.runAsGroup)' "${rel}" > "${release}" + else + cat "${rel}" > "${release}" + fi + + kubectl apply -f "${release}" || fail_test "Core interceptors installation failed" # Make sure that eveything is cleaned up in the current namespace. for res in eventlistener triggertemplate triggerbinding clustertriggerbinding; do kubectl delete --ignore-not-found=true ${res}.triggers.tekton.dev --all done + rm -f "${rel}" "${release}" # Wait for pods to be running in the namespaces we are deploying to wait_until_pods_running tekton-pipelines || fail_test "Tekton Triggers did not come up" - } diff --git a/vendor/github.com/tektoncd/triggers/test/e2e-tests-examples.sh b/vendor/github.com/tektoncd/triggers/test/e2e-tests-examples.sh index 966e29cbc6..6f8c43c194 100644 --- a/vendor/github.com/tektoncd/triggers/test/e2e-tests-examples.sh +++ b/vendor/github.com/tektoncd/triggers/test/e2e-tests-examples.sh @@ -22,6 +22,8 @@ source $(dirname $0)/e2e-common.sh set -u -e -o pipefail -x +SKIP_KNATIVE_EG=${SKIP_KNATIVE_EG:="false"} + current_example="" current_example_version="" yaml_files="" @@ -202,15 +204,27 @@ main() { cleanup info "Test Successful" done - # To test Knative Serving example - info "Knative Example Test Started" - current_example="custom-resource" - echo "*** Example ${current_example_version}/${current_example} ***"; - apply_files - check_eventlistener - curl_knative_service - cleanup - info "Knative Example Test Successful" + if [ "${SKIP_KNATIVE_EG}" == "false" ]; then + # To test Knative Serving example + info "Knative Example Test Started" + current_example="custom-resource" + echo "*** Example ${current_example_version}/${current_example} ***"; + kubectl delete events -n default --all + apply_files + sleep 60 + kubectl get deployment el-custom-resource-listener-00001-deployment -n default + kubectl get deployment el-custom-resource-listener-00001-deployment -n default -o yaml + kubectl get pod -n default + kubectl get pod -n default -l app=el-custom-resource-listener-00001 + kubectl get el custom-resource-listener + kubectl get el custom-resource-listener -o yaml + kubectl logs -f deployments/el-custom-resource-listener-00001-deployment -c queue-proxy + kubectl get events + check_eventlistener + curl_knative_service + cleanup + info "Knative Example Test Successful" + fi done echo; echo "*** Completed Examples Test Successfully ***"; echo; diff --git a/vendor/github.com/tektoncd/triggers/test/e2e-tests-yaml.sh b/vendor/github.com/tektoncd/triggers/test/e2e-tests-yaml.sh index 92b28e8834..02408c41c9 100644 --- a/vendor/github.com/tektoncd/triggers/test/e2e-tests-yaml.sh +++ b/vendor/github.com/tektoncd/triggers/test/e2e-tests-yaml.sh @@ -4,6 +4,8 @@ set -x set -o errexit set -o pipefail +SKIP_SECURITY_CTX=${SKIP_SECURITY_CTX:="false"} + current_example="" current_example_version="" @@ -47,7 +49,11 @@ main() { kubectl create namespace getting-started for op in apply delete;do for file in $(find ${REPO_ROOT_DIR}/docs/getting-started -name *.yaml | sort); do - kubectl ${op} -f ${file} + if [ "${SKIP_SECURITY_CTX}" == "true" ]; then + yq 'del(.spec.spec.containers[]?.securityContext.runAsUser, .spec.spec.containers[]?.securityContext.runAsGroup)' ${file} | kubectl ${op} -f - + else + kubectl ${op} -f ${file} + fi done done kubectl delete namespace getting-started diff --git a/vendor/github.com/tektoncd/triggers/test/e2e-tests.sh b/vendor/github.com/tektoncd/triggers/test/e2e-tests.sh index 374332bb93..664da84558 100644 --- a/vendor/github.com/tektoncd/triggers/test/e2e-tests.sh +++ b/vendor/github.com/tektoncd/triggers/test/e2e-tests.sh @@ -22,8 +22,10 @@ source $(dirname $0)/e2e-common.sh # Setting defaults failed=0 -SKIP_INITIALIZE=${SKIP_INITIALIZE:="false"} +SKIP_INITIALIZE=${SKIP_INITIALIZE:="false"} +export SKIP_SECURITY_CTX=${SKIP_SECURITY_CTX:="false"} +export SKIP_KNATIVE_EG=${SKIP_KNATIVE_EG:="false"} if [ "${SKIP_INITIALIZE}" != "true" ]; then initialize $@ @@ -34,18 +36,19 @@ install_pipeline_crd install_triggers_crd header "Running yaml tests" -$(dirname $0)/e2e-tests-yaml.sh || failed=1 +$(dirname $0)/e2e-tests-yaml.sh || { failed=1 && echo "failed yaml tests"; } header "Running ingress tests" -$(dirname $0)/e2e-tests-ingress.sh || failed=1 +$(dirname $0)/e2e-tests-ingress.sh || { failed=1 && echo "failed ingress tests"; } # Run the integration tests header "Running Go e2e tests" -go_test_e2e -timeout=20m ./test || failed=1 -go_test_e2e -timeout=20m ./cmd/... || failed=1 +go_test_e2e -timeout=20m ./test || { failed=1 && echo "failed integration tests"; } +go_test_e2e -timeout=20m ./cmd/... || { failed=1 && echo "failed integration tests"; } + header "Running examples tests" -$(dirname $0)/e2e-tests-examples.sh || failed=1 +$(dirname $0)/e2e-tests-examples.sh || { failed=1 && echo "failed example tests"; } (( failed )) && fail_test success diff --git a/vendor/github.com/tektoncd/triggers/test/gate.go b/vendor/github.com/tektoncd/triggers/test/gate.go index 58707480d9..ac5c3e9cdf 100644 --- a/vendor/github.com/tektoncd/triggers/test/gate.go +++ b/vendor/github.com/tektoncd/triggers/test/gate.go @@ -10,7 +10,8 @@ import ( ) // FeatureFlagsToContext takes a map of feature flags and adds it to the context -// nolint:unused,deadcode +// +//nolint:revive func FeatureFlagsToContext(ctx context.Context, flags map[string]string) (context.Context, error) { featureFlags, err := config.NewFeatureFlagsFromMap(flags) if err != nil { @@ -27,7 +28,8 @@ func FeatureFlagsToContext(ctx context.Context, flags map[string]string) (contex // test if the feature-flag with given name does not equal // given value. It will fatally fail the test if it cannot get // the feature-flag configmap. -// nolint:unused,deadcode +// +//nolint:revive,unused func requireGate(name, value string) func(context.Context, *testing.T, *clients, string) { return func(ctx context.Context, t *testing.T, c *clients, _ string) { featureFlagsCM, err := c.KubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, config.GetFeatureFlagsConfigName(), metav1.GetOptions{}) diff --git a/vendor/github.com/tektoncd/triggers/test/resources.go b/vendor/github.com/tektoncd/triggers/test/resources.go index efd8ea1ac3..16ec2937d1 100644 --- a/vendor/github.com/tektoncd/triggers/test/resources.go +++ b/vendor/github.com/tektoncd/triggers/test/resources.go @@ -86,5 +86,4 @@ func AddTektonResources(clientset *fakekubeclientset.Clientset) { Kind: "TaskRun", }}, }) - } diff --git a/vendor/github.com/tektoncd/triggers/test/signature.go b/vendor/github.com/tektoncd/triggers/test/signature.go index f3a3df1500..323a80f569 100644 --- a/vendor/github.com/tektoncd/triggers/test/signature.go +++ b/vendor/github.com/tektoncd/triggers/test/signature.go @@ -2,7 +2,7 @@ package test import ( "crypto/hmac" - "crypto/sha1" //nolint + "crypto/sha1" "crypto/sha256" "encoding/hex" "fmt" diff --git a/vendor/go.yaml.in/yaml/v2/.travis.yml b/vendor/go.yaml.in/yaml/v2/.travis.yml new file mode 100644 index 0000000000..7348c50c0c --- /dev/null +++ b/vendor/go.yaml.in/yaml/v2/.travis.yml @@ -0,0 +1,17 @@ +language: go + +go: + - "1.4.x" + - "1.5.x" + - "1.6.x" + - "1.7.x" + - "1.8.x" + - "1.9.x" + - "1.10.x" + - "1.11.x" + - "1.12.x" + - "1.13.x" + - "1.14.x" + - "tip" + +go_import_path: gopkg.in/yaml.v2 diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE b/vendor/go.yaml.in/yaml/v2/LICENSE similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE rename to vendor/go.yaml.in/yaml/v2/LICENSE diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE.libyaml b/vendor/go.yaml.in/yaml/v2/LICENSE.libyaml similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE.libyaml rename to vendor/go.yaml.in/yaml/v2/LICENSE.libyaml diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/NOTICE b/vendor/go.yaml.in/yaml/v2/NOTICE similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/NOTICE rename to vendor/go.yaml.in/yaml/v2/NOTICE diff --git a/vendor/go.yaml.in/yaml/v2/README.md b/vendor/go.yaml.in/yaml/v2/README.md new file mode 100644 index 0000000000..c9388da425 --- /dev/null +++ b/vendor/go.yaml.in/yaml/v2/README.md @@ -0,0 +1,131 @@ +# YAML support for the Go language + +Introduction +------------ + +The yaml package enables Go programs to comfortably encode and decode YAML +values. It was developed within [Canonical](https://www.canonical.com) as +part of the [juju](https://juju.ubuntu.com) project, and is based on a +pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) +C library to parse and generate YAML data quickly and reliably. + +Compatibility +------------- + +The yaml package supports most of YAML 1.1 and 1.2, including support for +anchors, tags, map merging, etc. Multi-document unmarshalling is not yet +implemented, and base-60 floats from YAML 1.1 are purposefully not +supported since they're a poor design and are gone in YAML 1.2. + +Installation and usage +---------------------- + +The import path for the package is *go.yaml.in/yaml/v2*. + +To install it, run: + + go get go.yaml.in/yaml/v2 + +API documentation +----------------- + +See: + +API stability +------------- + +The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). + + +License +------- + +The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. + + +Example +------- + +```Go +package main + +import ( + "fmt" + "log" + + "go.yaml.in/yaml/v2" +) + +var data = ` +a: Easy! +b: + c: 2 + d: [3, 4] +` + +// Note: struct fields must be public in order for unmarshal to +// correctly populate the data. +type T struct { + A string + B struct { + RenamedC int `yaml:"c"` + D []int `yaml:",flow"` + } +} + +func main() { + t := T{} + + err := yaml.Unmarshal([]byte(data), &t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t:\n%v\n\n", t) + + d, err := yaml.Marshal(&t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t dump:\n%s\n\n", string(d)) + + m := make(map[interface{}]interface{}) + + err = yaml.Unmarshal([]byte(data), &m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m:\n%v\n\n", m) + + d, err = yaml.Marshal(&m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m dump:\n%s\n\n", string(d)) +} +``` + +This example will generate the following output: + +``` +--- t: +{Easy! {2 [3 4]}} + +--- t dump: +a: Easy! +b: + c: 2 + d: [3, 4] + + +--- m: +map[a:Easy! b:map[c:2 d:[3 4]]] + +--- m dump: +a: Easy! +b: + c: 2 + d: + - 3 + - 4 +``` + diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/apic.go b/vendor/go.yaml.in/yaml/v2/apic.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/apic.go rename to vendor/go.yaml.in/yaml/v2/apic.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/decode.go b/vendor/go.yaml.in/yaml/v2/decode.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/decode.go rename to vendor/go.yaml.in/yaml/v2/decode.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/emitterc.go b/vendor/go.yaml.in/yaml/v2/emitterc.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/emitterc.go rename to vendor/go.yaml.in/yaml/v2/emitterc.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/encode.go b/vendor/go.yaml.in/yaml/v2/encode.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/encode.go rename to vendor/go.yaml.in/yaml/v2/encode.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/parserc.go b/vendor/go.yaml.in/yaml/v2/parserc.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/parserc.go rename to vendor/go.yaml.in/yaml/v2/parserc.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/readerc.go b/vendor/go.yaml.in/yaml/v2/readerc.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/readerc.go rename to vendor/go.yaml.in/yaml/v2/readerc.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/resolve.go b/vendor/go.yaml.in/yaml/v2/resolve.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/resolve.go rename to vendor/go.yaml.in/yaml/v2/resolve.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/scannerc.go b/vendor/go.yaml.in/yaml/v2/scannerc.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/scannerc.go rename to vendor/go.yaml.in/yaml/v2/scannerc.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/sorter.go b/vendor/go.yaml.in/yaml/v2/sorter.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/sorter.go rename to vendor/go.yaml.in/yaml/v2/sorter.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/writerc.go b/vendor/go.yaml.in/yaml/v2/writerc.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/writerc.go rename to vendor/go.yaml.in/yaml/v2/writerc.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/yaml.go b/vendor/go.yaml.in/yaml/v2/yaml.go similarity index 99% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/yaml.go rename to vendor/go.yaml.in/yaml/v2/yaml.go index 30813884c0..5248e1263c 100644 --- a/vendor/sigs.k8s.io/yaml/goyaml.v2/yaml.go +++ b/vendor/go.yaml.in/yaml/v2/yaml.go @@ -2,7 +2,7 @@ // // Source code and other details for the project are available at GitHub: // -// https://github.com/go-yaml/yaml +// https://github.com/yaml/go-yaml // package yaml diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/yamlh.go b/vendor/go.yaml.in/yaml/v2/yamlh.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/yamlh.go rename to vendor/go.yaml.in/yaml/v2/yamlh.go diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/yamlprivateh.go b/vendor/go.yaml.in/yaml/v2/yamlprivateh.go similarity index 100% rename from vendor/sigs.k8s.io/yaml/goyaml.v2/yamlprivateh.go rename to vendor/go.yaml.in/yaml/v2/yamlprivateh.go diff --git a/vendor/goa.design/goa/v3/http/client.go b/vendor/goa.design/goa/v3/http/client.go index b25763f8e6..3e7ae875bc 100644 --- a/vendor/goa.design/goa/v3/http/client.go +++ b/vendor/goa.design/goa/v3/http/client.go @@ -101,7 +101,7 @@ func (dd *debugDoer) Fprint(w io.Writer) { return } buf := &bytes.Buffer{} - buf.WriteString(fmt.Sprintf("> %s %s", dd.Request.Method, dd.Request.URL.String())) // nolint: errcheck + fmt.Fprintf(buf, "> %s %s", dd.Request.Method, dd.Request.URL.String()) keys := make([]string, len(dd.Request.Header)) i := 0 @@ -111,7 +111,7 @@ func (dd *debugDoer) Fprint(w io.Writer) { } sort.Strings(keys) for _, k := range keys { - buf.WriteString(fmt.Sprintf("\n> %s: %s", k, strings.Join(dd.Request.Header[k], ", "))) // nolint: errcheck + fmt.Fprintf(buf, "\n> %s: %s", k, strings.Join(dd.Request.Header[k], ", ")) // nolint: errcheck } b, _ := io.ReadAll(dd.Request.Body) @@ -125,7 +125,7 @@ func (dd *debugDoer) Fprint(w io.Writer) { w.Write(buf.Bytes()) // nolint: errcheck return } - buf.WriteString(fmt.Sprintf("\n< %s", dd.Response.Status)) + fmt.Fprintf(buf, "\n< %s", dd.Response.Status) keys = make([]string, len(dd.Response.Header)) i = 0 @@ -135,7 +135,7 @@ func (dd *debugDoer) Fprint(w io.Writer) { } sort.Strings(keys) for _, k := range keys { - buf.WriteString(fmt.Sprintf("\n< %s: %s", k, strings.Join(dd.Response.Header[k], ", "))) // nolint: errcheck + fmt.Fprintf(buf, "\n< %s: %s", k, strings.Join(dd.Response.Header[k], ", ")) // nolint: errcheck } rb, _ := io.ReadAll(dd.Response.Body) // this is reading from a memory buffer so safe to ignore errors diff --git a/vendor/goa.design/goa/v3/http/mux.go b/vendor/goa.design/goa/v3/http/mux.go index 522400a215..1f52cf8c5a 100644 --- a/vendor/goa.design/goa/v3/http/mux.go +++ b/vendor/goa.design/goa/v3/http/mux.go @@ -190,7 +190,7 @@ func (m *mux) ensureContext(r *http.Request) *chi.Context { if ctx.RoutePattern() != "" { return ctx // already initialized } - if !m.Router.Match(ctx, r.Method, r.URL.Path) { + if !m.Match(ctx, r.Method, r.URL.Path) { return nil // route not handled by chi } return ctx diff --git a/vendor/goa.design/goa/v3/pkg/version.go b/vendor/goa.design/goa/v3/pkg/version.go index 027e0aae31..7f8e31ce1f 100644 --- a/vendor/goa.design/goa/v3/pkg/version.go +++ b/vendor/goa.design/goa/v3/pkg/version.go @@ -10,7 +10,7 @@ const ( // Major version number Major = 3 // Minor version number - Minor = 20 + Minor = 21 // Build number Build = 1 // Suffix - set to empty string in release tag commits. diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index c9b343c715..b1264017db 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -360,6 +360,10 @@ type Balancer interface { // call SubConn.Shutdown for its existing SubConns; however, this will be // required in a future release, so it is recommended. Close() + // ExitIdle instructs the LB policy to reconnect to backends / exit the + // IDLE state, if appropriate and possible. Note that SubConns that enter + // the IDLE state will not reconnect until SubConn.Connect is called. + ExitIdle() } // ExitIdler is an optional interface for balancers to implement. If @@ -367,8 +371,8 @@ type Balancer interface { // the ClientConn is idle. If unimplemented, ClientConn.Connect will cause // all SubConns to connect. // -// Notice: it will be required for all balancers to implement this in a future -// release. +// Deprecated: All balancers must implement this interface. This interface will +// be removed in a future release. type ExitIdler interface { // ExitIdle instructs the LB policy to reconnect to backends / exit the // IDLE state, if appropriate and possible. Note that SubConns that enter diff --git a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go index cc606f4dae..0ad6bb1f22 100644 --- a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go +++ b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go @@ -45,7 +45,15 @@ type ChildState struct { // Balancer exposes only the ExitIdler interface of the child LB policy. // Other methods of the child policy are called only by endpointsharding. - Balancer balancer.ExitIdler + Balancer ExitIdler +} + +// ExitIdler provides access to only the ExitIdle method of the child balancer. +type ExitIdler interface { + // ExitIdle instructs the LB policy to reconnect to backends / exit the + // IDLE state, if appropriate and possible. Note that SubConns that enter + // the IDLE state will not reconnect until SubConn.Connect is called. + ExitIdle() } // Options are the options to configure the behaviour of the @@ -205,6 +213,16 @@ func (es *endpointSharding) Close() { } } +func (es *endpointSharding) ExitIdle() { + es.childMu.Lock() + defer es.childMu.Unlock() + for _, bw := range es.children.Load().Values() { + if !bw.isClosed { + bw.child.ExitIdle() + } + } +} + // updateState updates this component's state. It sends the aggregated state, // and a picker with round robin behavior with all the child states present if // needed. @@ -326,15 +344,13 @@ func (bw *balancerWrapper) UpdateState(state balancer.State) { // ExitIdle pings an IDLE child balancer to exit idle in a new goroutine to // avoid deadlocks due to synchronous balancer state updates. func (bw *balancerWrapper) ExitIdle() { - if ei, ok := bw.child.(balancer.ExitIdler); ok { - go func() { - bw.es.childMu.Lock() - if !bw.isClosed { - ei.ExitIdle() - } - bw.es.childMu.Unlock() - }() - } + go func() { + bw.es.childMu.Lock() + if !bw.isClosed { + bw.child.ExitIdle() + } + bw.es.childMu.Unlock() + }() } // updateClientConnStateLocked delivers the ClientConnState to the child diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go index 84e6a25056..c4ace87b26 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go @@ -86,7 +86,7 @@ type LoadBalancerServer interface { type UnimplementedLoadBalancerServer struct{} func (UnimplementedLoadBalancerServer) BalanceLoad(grpc.BidiStreamingServer[LoadBalanceRequest, LoadBalanceResponse]) error { - return status.Errorf(codes.Unimplemented, "method BalanceLoad not implemented") + return status.Error(codes.Unimplemented, "method BalanceLoad not implemented") } func (UnimplementedLoadBalancerServer) testEmbeddedByValue() {} diff --git a/vendor/google.golang.org/grpc/balancer/lazy/lazy.go b/vendor/google.golang.org/grpc/balancer/lazy/lazy.go index 7368d8f4bf..314ccd1b0a 100644 --- a/vendor/google.golang.org/grpc/balancer/lazy/lazy.go +++ b/vendor/google.golang.org/grpc/balancer/lazy/lazy.go @@ -125,9 +125,7 @@ func (lb *lazyBalancer) ExitIdle() { lb.mu.Lock() defer lb.mu.Unlock() if lb.delegate != nil { - if d, ok := lb.delegate.(balancer.ExitIdler); ok { - d.ExitIdle() - } + lb.delegate.ExitIdle() return } lb.delegate = lb.childBuilder(lb.cc, lb.buildOptions) diff --git a/vendor/google.golang.org/grpc/balancer/leastrequest/leastrequest.go b/vendor/google.golang.org/grpc/balancer/leastrequest/leastrequest.go index f758f954e9..f9cf7ccfc1 100644 --- a/vendor/google.golang.org/grpc/balancer/leastrequest/leastrequest.go +++ b/vendor/google.golang.org/grpc/balancer/leastrequest/leastrequest.go @@ -125,9 +125,7 @@ func (lrb *leastRequestBalancer) ResolverError(err error) { } func (lrb *leastRequestBalancer) ExitIdle() { - if ei, ok := lrb.child.(balancer.ExitIdler); ok { // Should always be ok, as child is endpoint sharding. - ei.ExitIdle() - } + lrb.child.ExitIdle() } func (lrb *leastRequestBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error { diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go index 494314f235..e62047256a 100644 --- a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go +++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go @@ -54,18 +54,9 @@ func init() { balancer.Register(pickfirstBuilder{}) } -type ( - // enableHealthListenerKeyType is a unique key type used in resolver - // attributes to indicate whether the health listener usage is enabled. - enableHealthListenerKeyType struct{} - // managedByPickfirstKeyType is an attribute key type to inform Outlier - // Detection that the generic health listener is being used. - // TODO: https://github.com/grpc/grpc-go/issues/7915 - Remove this when - // implementing the dualstack design. This is a hack. Once Dualstack is - // completed, outlier detection will stop sending ejection updates through - // the connectivity listener. - managedByPickfirstKeyType struct{} -) +// enableHealthListenerKeyType is a unique key type used in resolver +// attributes to indicate whether the health listener usage is enabled. +type enableHealthListenerKeyType struct{} var ( logger = grpclog.Component("pick-first-leaf-lb") @@ -149,17 +140,6 @@ func EnableHealthListener(state resolver.State) resolver.State { return state } -// IsManagedByPickfirst returns whether an address belongs to a SubConn -// managed by the pickfirst LB policy. -// TODO: https://github.com/grpc/grpc-go/issues/7915 - This is a hack to disable -// outlier_detection via the with connectivity listener when using pick_first. -// Once Dualstack changes are complete, all SubConns will be created by -// pick_first and outlier detection will only use the health listener for -// ejection. This hack can then be removed. -func IsManagedByPickfirst(addr resolver.Address) bool { - return addr.BalancerAttributes.Value(managedByPickfirstKeyType{}) != nil -} - type pfConfig struct { serviceconfig.LoadBalancingConfig `json:"-"` @@ -186,7 +166,6 @@ type scData struct { } func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData, error) { - addr.BalancerAttributes = addr.BalancerAttributes.WithValue(managedByPickfirstKeyType{}, true) sd := &scData{ rawConnectivityState: connectivity.Idle, effectiveState: connectivity.Idle, diff --git a/vendor/google.golang.org/grpc/balancer/ringhash/ringhash.go b/vendor/google.golang.org/grpc/balancer/ringhash/ringhash.go index acd9ae3afe..d4c41facb9 100644 --- a/vendor/google.golang.org/grpc/balancer/ringhash/ringhash.go +++ b/vendor/google.golang.org/grpc/balancer/ringhash/ringhash.go @@ -268,7 +268,7 @@ func (b *ringhashBalancer) updatePickerLocked() { sort.Slice(endpointStates, func(i, j int) bool { return endpointStates[i].hashKey < endpointStates[j].hashKey }) - var idleBalancer balancer.ExitIdler + var idleBalancer endpointsharding.ExitIdler for _, es := range endpointStates { connState := es.state.ConnectivityState if connState == connectivity.Connecting { @@ -399,7 +399,7 @@ type endpointState struct { // overridden, for example based on EDS endpoint metadata. hashKey string weight uint32 - balancer balancer.ExitIdler + balancer endpointsharding.ExitIdler // state is updated by the balancer while receiving resolver updates from // the channel and picker updates from its children. Access to it is guarded diff --git a/vendor/google.golang.org/grpc/balancer/rls/control_channel.go b/vendor/google.golang.org/grpc/balancer/rls/control_channel.go index 28f063e73e..60e6a021d1 100644 --- a/vendor/google.golang.org/grpc/balancer/rls/control_channel.go +++ b/vendor/google.golang.org/grpc/balancer/rls/control_channel.go @@ -92,12 +92,7 @@ func newControlChannel(rlsServerName, serviceConfig string, rpcTimeout time.Dura ctrlCh.cc.Connect() ctrlCh.client = rlsgrpc.NewRouteLookupServiceClient(ctrlCh.cc) ctrlCh.logger.Infof("Control channel created to RLS server at: %v", rlsServerName) - start := make(chan struct{}) - go func() { - close(start) - ctrlCh.monitorConnectivityState() - }() - <-start + go ctrlCh.monitorConnectivityState() return ctrlCh, nil } diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index 35da5d1ec9..22045bf394 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -70,10 +70,3 @@ func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error { ResolverState: pickfirstleaf.EnableHealthListener(ccs.ResolverState), }) } - -func (b *rrBalancer) ExitIdle() { - // Should always be ok, as child is endpoint sharding. - if ei, ok := b.Balancer.(balancer.ExitIdler); ok { - ei.ExitIdle() - } -} diff --git a/vendor/google.golang.org/grpc/balancer/weightedroundrobin/balancer.go b/vendor/google.golang.org/grpc/balancer/weightedroundrobin/balancer.go index e6fe5a37ac..fe8ebff1f5 100644 --- a/vendor/google.golang.org/grpc/balancer/weightedroundrobin/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/weightedroundrobin/balancer.go @@ -404,9 +404,7 @@ func (b *wrrBalancer) Close() { } func (b *wrrBalancer) ExitIdle() { - if ei, ok := b.child.(balancer.ExitIdler); ok { // Should always be ok, as child is endpoint sharding. - ei.ExitIdle() - } + b.child.ExitIdle() } // picker is the WRR policy's picker. It uses live-updating backend weights to diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go index 34443b1d2d..21cb01be66 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go @@ -95,7 +95,7 @@ type HandshakerServiceServer interface { type UnimplementedHandshakerServiceServer struct{} func (UnimplementedHandshakerServiceServer) DoHandshake(grpc.BidiStreamingServer[HandshakerReq, HandshakerResp]) error { - return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented") + return status.Error(codes.Unimplemented, "method DoHandshake not implemented") } func (UnimplementedHandshakerServiceServer) mustEmbedUnimplementedHandshakerServiceServer() {} func (UnimplementedHandshakerServiceServer) testEmbeddedByValue() {} diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 050ba0f161..ec0ca89ccd 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -213,6 +213,7 @@ func WithReadBufferSize(s int) DialOption { func WithInitialWindowSize(s int32) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.InitialWindowSize = s + o.copts.StaticWindowSize = true }) } @@ -222,6 +223,26 @@ func WithInitialWindowSize(s int32) DialOption { func WithInitialConnWindowSize(s int32) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.InitialConnWindowSize = s + o.copts.StaticWindowSize = true + }) +} + +// WithStaticStreamWindowSize returns a DialOption which sets the initial +// stream window size to the value provided and disables dynamic flow control. +func WithStaticStreamWindowSize(s int32) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.InitialWindowSize = s + o.copts.StaticWindowSize = true + }) +} + +// WithStaticConnWindowSize returns a DialOption which sets the initial +// connection window size to the value provided and disables dynamic flow +// control. +func WithStaticConnWindowSize(s int32) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.InitialConnWindowSize = s + o.copts.StaticWindowSize = true }) } diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index 93136610ec..f2c01f296a 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -188,13 +188,13 @@ type HealthServer interface { type UnimplementedHealthServer struct{} func (UnimplementedHealthServer) Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") + return nil, status.Error(codes.Unimplemented, "method Check not implemented") } func (UnimplementedHealthServer) List(context.Context, *HealthListRequest) (*HealthListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method List not implemented") + return nil, status.Error(codes.Unimplemented, "method List not implemented") } func (UnimplementedHealthServer) Watch(*HealthCheckRequest, grpc.ServerStreamingServer[HealthCheckResponse]) error { - return status.Errorf(codes.Unimplemented, "method Watch not implemented") + return status.Error(codes.Unimplemented, "method Watch not implemented") } func (UnimplementedHealthServer) testEmbeddedByValue() {} diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index fbc1ca356a..ba25b89887 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -223,15 +223,7 @@ func (gsb *Balancer) ExitIdle() { // There is no need to protect this read with a mutex, as the write to the // Balancer field happens in SwitchTo, which completes before this can be // called. - if ei, ok := balToUpdate.Balancer.(balancer.ExitIdler); ok { - ei.ExitIdle() - return - } - gsb.mu.Lock() - defer gsb.mu.Unlock() - for sc := range balToUpdate.subconns { - sc.Connect() - } + balToUpdate.ExitIdle() } // updateSubConnState forwards the update to the appropriate child. diff --git a/vendor/google.golang.org/grpc/internal/balancer/nop/nop.go b/vendor/google.golang.org/grpc/internal/balancer/nop/nop.go index 0c96f1b811..8c5bf96f2d 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/nop/nop.go +++ b/vendor/google.golang.org/grpc/internal/balancer/nop/nop.go @@ -60,3 +60,6 @@ func (b *bal) UpdateSubConnState(_ balancer.SubConn, _ balancer.SubConnState) {} // Close is a no-op. func (b *bal) Close() {} + +// ExitIdle is a no-op. +func (b *bal) ExitIdle() {} diff --git a/vendor/google.golang.org/grpc/internal/balancergroup/balancergroup.go b/vendor/google.golang.org/grpc/internal/balancergroup/balancergroup.go index 9addcf1853..cd1a9ed171 100644 --- a/vendor/google.golang.org/grpc/internal/balancergroup/balancergroup.go +++ b/vendor/google.golang.org/grpc/internal/balancergroup/balancergroup.go @@ -106,15 +106,14 @@ func (sbc *subBalancerWrapper) startBalancer() { } } -// exitIdle invokes the sub-balancer's ExitIdle method. Returns a boolean -// indicating whether or not the operation was completed. -func (sbc *subBalancerWrapper) exitIdle() (complete bool) { +// exitIdle invokes the ExitIdle method on the sub-balancer, a gracefulswitch +// balancer. +func (sbc *subBalancerWrapper) exitIdle() { b := sbc.balancer if b == nil { - return true + return } b.ExitIdle() - return true } func (sbc *subBalancerWrapper) updateClientConnState(s balancer.ClientConnState) error { @@ -411,20 +410,6 @@ func (bg *BalancerGroup) cleanupSubConns(config *subBalancerWrapper) { } } -// connect attempts to connect to all subConns belonging to sb. -func (bg *BalancerGroup) connect(sb *subBalancerWrapper) { - bg.incomingMu.Lock() - defer bg.incomingMu.Unlock() - if bg.incomingClosed { - return - } - for sc, b := range bg.scToSubBalancer { - if b == sb { - sc.Connect() - } - } -} - // Following are actions from the parent grpc.ClientConn, forward to sub-balancers. // updateSubConnState forwards the update to cb and updates scToSubBalancer if @@ -575,9 +560,7 @@ func (bg *BalancerGroup) ExitIdle() { return } for _, config := range bg.idToBalancerConfig { - if !config.exitIdle() { - bg.connect(config) - } + config.exitIdle() } } @@ -590,9 +573,7 @@ func (bg *BalancerGroup) ExitIdleOne(id string) { return } if config := bg.idToBalancerConfig[id]; config != nil { - if !config.exitIdle() { - bg.connect(config) - } + config.exitIdle() } } diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index f5f2bdeb86..2fdaed88db 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -33,10 +33,6 @@ var ( // "GRPC_RING_HASH_CAP". This does not override the default bounds // checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M). RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024) - // LeastRequestLB is set if we should support the least_request_experimental - // LB policy, which can be enabled by setting the environment variable - // "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true". - LeastRequestLB = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST", true) // ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS // handshakes that can be performed. ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100) diff --git a/vendor/google.golang.org/grpc/internal/proto/grpc_lookup_v1/rls_grpc.pb.go b/vendor/google.golang.org/grpc/internal/proto/grpc_lookup_v1/rls_grpc.pb.go index 23dcb2100c..16611074ca 100644 --- a/vendor/google.golang.org/grpc/internal/proto/grpc_lookup_v1/rls_grpc.pb.go +++ b/vendor/google.golang.org/grpc/internal/proto/grpc_lookup_v1/rls_grpc.pb.go @@ -79,7 +79,7 @@ type RouteLookupServiceServer interface { type UnimplementedRouteLookupServiceServer struct{} func (UnimplementedRouteLookupServiceServer) RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RouteLookup not implemented") + return nil, status.Error(codes.Unimplemented, "method RouteLookup not implemented") } func (UnimplementedRouteLookupServiceServer) mustEmbedUnimplementedRouteLookupServiceServer() {} func (UnimplementedRouteLookupServiceServer) testEmbeddedByValue() {} diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index ef72fbb3a0..a2831e5d01 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -40,6 +40,13 @@ var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { e.SetMaxDynamicTableSizeLimit(v) } +// itemNodePool is used to reduce heap allocations. +var itemNodePool = sync.Pool{ + New: func() any { + return &itemNode{} + }, +} + type itemNode struct { it any next *itemNode @@ -51,7 +58,9 @@ type itemList struct { } func (il *itemList) enqueue(i any) { - n := &itemNode{it: i} + n := itemNodePool.Get().(*itemNode) + n.next = nil + n.it = i if il.tail == nil { il.head, il.tail = n, n return @@ -71,7 +80,9 @@ func (il *itemList) dequeue() any { return nil } i := il.head.it + temp := il.head il.head = il.head.next + itemNodePool.Put(temp) if il.head == nil { il.tail = nil } @@ -146,10 +157,11 @@ type earlyAbortStream struct { func (*earlyAbortStream) isTransportResponseFrame() bool { return false } type dataFrame struct { - streamID uint32 - endStream bool - h []byte - reader mem.Reader + streamID uint32 + endStream bool + h []byte + data mem.BufferSlice + processing bool // onEachWrite is called every time // a part of data is written out. onEachWrite func() @@ -234,6 +246,7 @@ type outStream struct { itl *itemList bytesOutStanding int wq *writeQuota + reader mem.Reader next *outStream prev *outStream @@ -461,7 +474,9 @@ func (c *controlBuffer) finish() { v.onOrphaned(ErrConnClosing) } case *dataFrame: - _ = v.reader.Close() + if !v.processing { + v.data.Free() + } } } @@ -650,10 +665,11 @@ func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error { func (l *loopyWriter) registerStreamHandler(h *registerStream) { str := &outStream{ - id: h.streamID, - state: empty, - itl: &itemList{}, - wq: h.wq, + id: h.streamID, + state: empty, + itl: &itemList{}, + wq: h.wq, + reader: mem.BufferSlice{}.Reader(), } l.estdStreams[h.streamID] = str } @@ -685,10 +701,11 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error { } // Case 2: Client wants to originate stream. str := &outStream{ - id: h.streamID, - state: empty, - itl: &itemList{}, - wq: h.wq, + id: h.streamID, + state: empty, + itl: &itemList{}, + wq: h.wq, + reader: mem.BufferSlice{}.Reader(), } return l.originateStream(str, h) } @@ -790,10 +807,13 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error { // a RST_STREAM before stream initialization thus the stream might // not be established yet. delete(l.estdStreams, c.streamID) + str.reader.Close() str.deleteSelf() for head := str.itl.dequeueAll(); head != nil; head = head.next { if df, ok := head.it.(*dataFrame); ok { - _ = df.reader.Close() + if !df.processing { + df.data.Free() + } } } } @@ -928,7 +948,13 @@ func (l *loopyWriter) processData() (bool, error) { if str == nil { return true, nil } + reader := str.reader dataItem := str.itl.peek().(*dataFrame) // Peek at the first data item this stream. + if !dataItem.processing { + dataItem.processing = true + str.reader.Reset(dataItem.data) + dataItem.data.Free() + } // A data item is represented by a dataFrame, since it later translates into // multiple HTTP2 data frames. // Every dataFrame has two buffers; h that keeps grpc-message header and data @@ -936,13 +962,13 @@ func (l *loopyWriter) processData() (bool, error) { // from data is copied to h to make as big as the maximum possible HTTP2 frame // size. - if len(dataItem.h) == 0 && dataItem.reader.Remaining() == 0 { // Empty data frame + if len(dataItem.h) == 0 && reader.Remaining() == 0 { // Empty data frame // Client sends out empty data frame with endStream = true if err := l.framer.fr.WriteData(dataItem.streamID, dataItem.endStream, nil); err != nil { return false, err } str.itl.dequeue() // remove the empty data item from stream - _ = dataItem.reader.Close() + _ = reader.Close() if str.itl.isEmpty() { str.state = empty } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers. @@ -971,8 +997,8 @@ func (l *loopyWriter) processData() (bool, error) { } // Compute how much of the header and data we can send within quota and max frame length hSize := min(maxSize, len(dataItem.h)) - dSize := min(maxSize-hSize, dataItem.reader.Remaining()) - remainingBytes := len(dataItem.h) + dataItem.reader.Remaining() - hSize - dSize + dSize := min(maxSize-hSize, reader.Remaining()) + remainingBytes := len(dataItem.h) + reader.Remaining() - hSize - dSize size := hSize + dSize var buf *[]byte @@ -993,7 +1019,7 @@ func (l *loopyWriter) processData() (bool, error) { defer pool.Put(buf) copy((*buf)[:hSize], dataItem.h) - _, _ = dataItem.reader.Read((*buf)[hSize:]) + _, _ = reader.Read((*buf)[hSize:]) } // Now that outgoing flow controls are checked we can replenish str's write quota @@ -1014,7 +1040,7 @@ func (l *loopyWriter) processData() (bool, error) { dataItem.h = dataItem.h[hSize:] if remainingBytes == 0 { // All the data from that message was written out. - _ = dataItem.reader.Close() + _ = reader.Close() str.itl.dequeue() } if str.itl.isEmpty() { diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index ef56592b94..5467fe9715 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -309,11 +309,9 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts scheme = "https" } } - dynamicWindow := true icwz := int32(initialWindowSize) if opts.InitialConnWindowSize >= defaultWindowSize { icwz = opts.InitialConnWindowSize - dynamicWindow = false } writeBufSize := opts.WriteBufferSize readBufSize := opts.ReadBufferSize @@ -381,9 +379,8 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts t.controlBuf = newControlBuffer(t.ctxDone) if opts.InitialWindowSize >= defaultWindowSize { t.initialWindowSize = opts.InitialWindowSize - dynamicWindow = false } - if dynamicWindow { + if !opts.StaticWindowSize { t.bdpEst = &bdpEstimator{ bdp: initialWindowSize, updateFlowControl: t.updateFlowControl, @@ -1091,32 +1088,29 @@ func (t *http2Client) GracefulClose() { // Write formats the data into HTTP2 data frame(s) and sends it out. The caller // should proceed only if Write returns nil. func (t *http2Client) write(s *ClientStream, hdr []byte, data mem.BufferSlice, opts *WriteOptions) error { - reader := data.Reader() - if opts.Last { // If it's the last message, update stream state. if !s.compareAndSwapState(streamActive, streamWriteDone) { - _ = reader.Close() return errStreamDone } } else if s.getState() != streamActive { - _ = reader.Close() return errStreamDone } df := &dataFrame{ streamID: s.id, endStream: opts.Last, h: hdr, - reader: reader, + data: data, } - if hdr != nil || df.reader.Remaining() != 0 { // If it's not an empty data frame, check quota. - if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil { - _ = reader.Close() + dataLen := data.Len() + if hdr != nil || dataLen != 0 { // If it's not an empty data frame, check quota. + if err := s.wq.get(int32(len(hdr) + dataLen)); err != nil { return err } } + data.Ref() if err := t.controlBuf.put(df); err != nil { - _ = reader.Close() + data.Free() return err } t.incrMsgSent() diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index e4c3731bdb..9f725e15a8 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -132,6 +132,10 @@ type http2Server struct { maxStreamID uint32 // max stream ID ever seen logger *grpclog.PrefixLogger + // setResetPingStrikes is stored as a closure instead of making this a + // method on http2Server to avoid a heap allocation when converting a method + // to a closure for passing to frames objects. + setResetPingStrikes func() } // NewServerTransport creates a http2 transport with conn and configuration @@ -176,16 +180,13 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, Val: config.MaxStreams, }) } - dynamicWindow := true iwz := int32(initialWindowSize) if config.InitialWindowSize >= defaultWindowSize { iwz = config.InitialWindowSize - dynamicWindow = false } icwz := int32(initialWindowSize) if config.InitialConnWindowSize >= defaultWindowSize { icwz = config.InitialConnWindowSize - dynamicWindow = false } if iwz != defaultWindowSize { isettings = append(isettings, http2.Setting{ @@ -266,6 +267,9 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, initialWindowSize: iwz, bufferPool: config.BufferPool, } + t.setResetPingStrikes = func() { + atomic.StoreUint32(&t.resetPingStrikes, 1) + } var czSecurity credentials.ChannelzSecurityValue if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { czSecurity = au.GetSecurityValue() @@ -285,7 +289,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, t.logger = prefixLoggerForServerTransport(t) t.controlBuf = newControlBuffer(t.done) - if dynamicWindow { + if !config.StaticWindowSize { t.bdpEst = &bdpEstimator{ bdp: initialWindowSize, updateFlowControl: t.updateFlowControl, @@ -596,10 +600,25 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade return nil } } + + if s.ctx.Err() != nil { + t.mu.Unlock() + // Early abort in case the timeout was zero or so low it already fired. + t.controlBuf.put(&earlyAbortStream{ + httpStatus: http.StatusOK, + streamID: s.id, + contentSubtype: s.contentSubtype, + status: status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()), + rst: !frame.StreamEnded(), + }) + return nil + } + t.activeStreams[streamID] = s if len(t.activeStreams) == 1 { t.idle = time.Time{} } + // Start a timer to close the stream on reaching the deadline. if timeoutSet { // We need to wait for s.cancel to be updated before calling @@ -1016,10 +1035,6 @@ func (t *http2Server) writeHeader(s *ServerStream, md metadata.MD) error { return nil } -func (t *http2Server) setResetPingStrikes() { - atomic.StoreUint32(&t.resetPingStrikes, 1) -} - func (t *http2Server) writeHeaderLocked(s *ServerStream) error { // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields // first and create a slice of that exact size. @@ -1132,17 +1147,13 @@ func (t *http2Server) writeStatus(s *ServerStream, st *status.Status) error { // Write converts the data into HTTP2 data frame and sends it out. Non-nil error // is returns if it fails (e.g., framing error, transport error). func (t *http2Server) write(s *ServerStream, hdr []byte, data mem.BufferSlice, _ *WriteOptions) error { - reader := data.Reader() - if !s.isHeaderSent() { // Headers haven't been written yet. if err := t.writeHeader(s, nil); err != nil { - _ = reader.Close() return err } } else { // Writing headers checks for this condition. if s.getState() == streamDone { - _ = reader.Close() return t.streamContextErr(s) } } @@ -1150,15 +1161,16 @@ func (t *http2Server) write(s *ServerStream, hdr []byte, data mem.BufferSlice, _ df := &dataFrame{ streamID: s.id, h: hdr, - reader: reader, + data: data, onEachWrite: t.setResetPingStrikes, } - if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil { - _ = reader.Close() + dataLen := data.Len() + if err := s.wq.get(int32(len(hdr) + dataLen)); err != nil { return t.streamContextErr(s) } + data.Ref() if err := t.controlBuf.put(df); err != nil { - _ = reader.Close() + data.Free() return err } t.incrMsgSent() diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index 607d2c4cee..e3663f87f3 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -200,9 +200,6 @@ func decodeTimeout(s string) (time.Duration, error) { if err != nil { return 0, err } - if t == 0 { - return 0, fmt.Errorf("transport: timeout must be positive: %q", s) - } const maxHours = math.MaxInt64 / uint64(time.Hour) if d == time.Hour && t > maxHours { // This timeout would overflow math.MaxInt64; clamp it. diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 1730a639f9..7dd53e80a7 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -466,6 +466,7 @@ type ServerConfig struct { MaxHeaderListSize *uint32 HeaderTableSize *uint32 BufferPool mem.BufferPool + StaticWindowSize bool } // ConnectOptions covers all relevant options for communicating with the server. @@ -504,6 +505,8 @@ type ConnectOptions struct { MaxHeaderListSize *uint32 // The mem.BufferPool to use when reading/writing to the wire. BufferPool mem.BufferPool + // StaticWindowSize controls whether dynamic window sizing is enabled. + StaticWindowSize bool } // WriteOptions provides additional hints and information for message diff --git a/vendor/google.golang.org/grpc/internal/xds/bootstrap/bootstrap.go b/vendor/google.golang.org/grpc/internal/xds/bootstrap/bootstrap.go index 142e803930..6c7b2332fa 100644 --- a/vendor/google.golang.org/grpc/internal/xds/bootstrap/bootstrap.go +++ b/vendor/google.golang.org/grpc/internal/xds/bootstrap/bootstrap.go @@ -217,10 +217,16 @@ func (sc *ServerConfig) ServerFeaturesIgnoreResourceDeletion() bool { return false } +// SelectedCreds returns the selected credentials configuration for +// communicating with this server. +func (sc *ServerConfig) SelectedCreds() ChannelCreds { + return sc.selectedCreds +} + // DialOptions returns a slice of all the configured dial options for this -// server. +// server except grpc.WithCredentialsBundle(). func (sc *ServerConfig) DialOptions() []grpc.DialOption { - dopts := []grpc.DialOption{sc.credsDialOption} + var dopts []grpc.DialOption if sc.extraDialOptions != nil { dopts = append(dopts, sc.extraDialOptions...) } @@ -570,6 +576,9 @@ func (c *Config) UnmarshalJSON(data []byte) error { // the presence of the errors) and may return a Config object with certain // fields left unspecified, in which case the caller should use some sane // defaults. +// +// This function returns an error if it's unable to parse the contents of the +// bootstrap config. It returns (nil, nil) if none of the env vars are set. func GetConfiguration() (*Config, error) { fName := envconfig.XDSBootstrapFileName fContent := envconfig.XDSBootstrapFileContent @@ -592,7 +601,7 @@ func GetConfiguration() (*Config, error) { return NewConfigFromContents([]byte(fContent)) } - return nil, fmt.Errorf("bootstrap environment variables (%q or %q) not defined", envconfig.XDSBootstrapFileNameEnv, envconfig.XDSBootstrapFileContentEnv) + return nil, nil } // NewConfigFromContents creates a new bootstrap configuration from the provided diff --git a/vendor/google.golang.org/grpc/mem/buffer_slice.go b/vendor/google.golang.org/grpc/mem/buffer_slice.go index 65002e2cc8..af510d20c5 100644 --- a/vendor/google.golang.org/grpc/mem/buffer_slice.go +++ b/vendor/google.golang.org/grpc/mem/buffer_slice.go @@ -137,6 +137,9 @@ type Reader interface { Close() error // Remaining returns the number of unread bytes remaining in the slice. Remaining() int + // Reset frees the currently held buffer slice and starts reading from the + // provided slice. This allows reusing the reader object. + Reset(s BufferSlice) } type sliceReader struct { @@ -150,6 +153,14 @@ func (r *sliceReader) Remaining() int { return r.len } +func (r *sliceReader) Reset(s BufferSlice) { + r.data.Free() + s.Ref() + r.data = s + r.len = s.Len() + r.bufferIdx = 0 +} + func (r *sliceReader) Close() error { r.data.Free() r.data = nil diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 976e70ae06..70fe23f550 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -179,6 +179,7 @@ type serverOptions struct { numServerWorkers uint32 bufferPool mem.BufferPool waitForHandlers bool + staticWindowSize bool } var defaultServerOptions = serverOptions{ @@ -279,6 +280,7 @@ func ReadBufferSize(s int) ServerOption { func InitialWindowSize(s int32) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.initialWindowSize = s + o.staticWindowSize = true }) } @@ -287,6 +289,29 @@ func InitialWindowSize(s int32) ServerOption { func InitialConnWindowSize(s int32) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.initialConnWindowSize = s + o.staticWindowSize = true + }) +} + +// StaticStreamWindowSize returns a ServerOption to set the initial stream +// window size to the value provided and disables dynamic flow control. +// The lower bound for window size is 64K and any value smaller than that +// will be ignored. +func StaticStreamWindowSize(s int32) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.initialWindowSize = s + o.staticWindowSize = true + }) +} + +// StaticConnWindowSize returns a ServerOption to set the initial connection +// window size to the value provided and disables dynamic flow control. +// The lower bound for window size is 64K and any value smaller than that +// will be ignored. +func StaticConnWindowSize(s int32) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.initialConnWindowSize = s + o.staticWindowSize = true }) } @@ -986,6 +1011,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { MaxHeaderListSize: s.opts.maxHeaderListSize, HeaderTableSize: s.opts.headerTableSize, BufferPool: s.opts.bufferPool, + StaticWindowSize: s.opts.staticWindowSize, } st, err := transport.NewServerTransport(c, config) if err != nil { diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index d58bb6471a..ca6948926f 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -1171,7 +1171,7 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { } else if err != nil { return toRPCErr(err) } - return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) + return status.Errorf(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") } func (a *csAttempt) finish(err error) { @@ -1495,7 +1495,7 @@ func (as *addrConnStream) RecvMsg(m any) (err error) { } else if err != nil { return toRPCErr(err) } - return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) + return status.Errorf(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") } func (as *addrConnStream) finish(err error) { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index bd82673dc9..8b0e5f973d 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.73.0" +const Version = "1.74.2" diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/cdsbalancer/cdsbalancer.go b/vendor/google.golang.org/grpc/xds/internal/balancer/cdsbalancer/cdsbalancer.go index fa34748c88..3a0e3f9e6b 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/cdsbalancer/cdsbalancer.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/cdsbalancer/cdsbalancer.go @@ -424,9 +424,7 @@ func (b *cdsBalancer) ExitIdle() { // ExitIdle (but still checks for the interface's existence to // avoid a panic if not). If the child does not, no subconns // will be connected. - if ei, ok := b.childLB.(balancer.ExitIdler); ok { - ei.ExitIdle() - } + b.childLB.ExitIdle() }) } diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/clusterimpl.go b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/clusterimpl.go index 71a4c9c9da..096b738b0d 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/clusterimpl.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/clusterimpl.go @@ -24,10 +24,12 @@ package clusterimpl import ( + "context" "encoding/json" "fmt" "sync" "sync/atomic" + "time" "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" @@ -41,14 +43,16 @@ import ( "google.golang.org/grpc/serviceconfig" xdsinternal "google.golang.org/grpc/xds/internal" "google.golang.org/grpc/xds/internal/balancer/loadstore" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/lrsclient" "google.golang.org/grpc/xds/internal/xdsclient" - "google.golang.org/grpc/xds/internal/xdsclient/load" ) const ( // Name is the name of the cluster_impl balancer. Name = "xds_cluster_impl_experimental" defaultRequestCountMax = 1024 + loadStoreStopTimeout = 1 * time.Second ) var ( @@ -90,13 +94,15 @@ type clusterImplBalancer struct { // The following fields are set at creation time, and are read-only after // that, and therefore need not be protected by a mutex. - logger *grpclog.PrefixLogger + logger *grpclog.PrefixLogger + // TODO: #8366 - Refactor usage of loadWrapper to easily plugin a test + // load reporter from tests. loadWrapper *loadstore.Wrapper // The following fields are only accessed from balancer API methods, which // are guaranteed to be called serially by gRPC. xdsClient xdsclient.XDSClient // Sent down in ResolverState attributes. - cancelLoadReport func() // To stop reporting load through the above xDS client. + cancelLoadReport func(context.Context) // To stop reporting load through the above xDS client. edsServiceName string // EDS service name to report load for. lrsServer *bootstrap.ServerConfig // Load reporting server configuration. dropCategories []DropConfig // The categories for drops. @@ -218,7 +224,9 @@ func (b *clusterImplBalancer) updateLoadStore(newConfig *LBConfig) error { if stopOldLoadReport { if b.cancelLoadReport != nil { - b.cancelLoadReport() + stopCtx, stopCancel := context.WithTimeout(context.Background(), loadStoreStopTimeout) + defer stopCancel() + b.cancelLoadReport(stopCtx) b.cancelLoadReport = nil if !startNewLoadReport { // If a new LRS stream will be started later, no need to update @@ -228,7 +236,7 @@ func (b *clusterImplBalancer) updateLoadStore(newConfig *LBConfig) error { } } if startNewLoadReport { - var loadStore *load.Store + var loadStore *lrsclient.LoadStore if b.xdsClient != nil { loadStore, b.cancelLoadReport = b.xdsClient.ReportLoad(b.lrsServer) } @@ -344,7 +352,9 @@ func (b *clusterImplBalancer) Close() { b.childState = balancer.State{} if b.cancelLoadReport != nil { - b.cancelLoadReport() + stopCtx, stopCancel := context.WithTimeout(context.Background(), loadStoreStopTimeout) + defer stopCancel() + b.cancelLoadReport(stopCtx) b.cancelLoadReport = nil } b.logger.Infof("Shutdown") @@ -406,16 +416,19 @@ type scWrapper struct { balancer.SubConn // locality needs to be atomic because it can be updated while being read by // the picker. - locality atomic.Value // type xdsinternal.LocalityID + locality atomic.Pointer[clients.Locality] } -func (scw *scWrapper) updateLocalityID(lID xdsinternal.LocalityID) { - scw.locality.Store(lID) +func (scw *scWrapper) updateLocalityID(lID clients.Locality) { + scw.locality.Store(&lID) } -func (scw *scWrapper) localityID() xdsinternal.LocalityID { - lID, _ := scw.locality.Load().(xdsinternal.LocalityID) - return lID +func (scw *scWrapper) localityID() clients.Locality { + lID := scw.locality.Load() + if lID == nil { + return clients.Locality{} + } + return *lID } func (b *clusterImplBalancer) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { @@ -436,7 +449,7 @@ func (b *clusterImplBalancer) NewSubConn(addrs []resolver.Address, opts balancer // address's locality. https://github.com/grpc/grpc-go/issues/7339 addr := connectedAddress(state) lID := xdsinternal.GetLocalityID(addr) - if lID.Empty() { + if (lID == clients.Locality{}) { if b.logger.V(2) { b.logger.Infof("Locality ID for %s unexpectedly empty", addr) } @@ -459,7 +472,7 @@ func (b *clusterImplBalancer) RemoveSubConn(sc balancer.SubConn) { func (b *clusterImplBalancer) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { clusterName := b.getClusterName() newAddrs := make([]resolver.Address, len(addrs)) - var lID xdsinternal.LocalityID + var lID clients.Locality for i, addr := range addrs { newAddrs[i] = xds.SetXDSHandshakeClusterName(addr, clusterName) lID = xdsinternal.GetLocalityID(newAddrs[i]) diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/picker.go b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/picker.go index 018122f2c6..9ed16ffbe4 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/picker.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterimpl/picker.go @@ -28,6 +28,8 @@ import ( "google.golang.org/grpc/internal/stats" "google.golang.org/grpc/internal/wrr" "google.golang.org/grpc/status" + "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/xds/internal/clients" "google.golang.org/grpc/xds/internal/xdsclient" ) @@ -71,10 +73,10 @@ func (d *dropper) drop() (ret bool) { // loadReporter wraps the methods from the loadStore that are used here. type loadReporter interface { - CallStarted(locality string) - CallFinished(locality string, err error) - CallServerLoad(locality, name string, val float64) - CallDropped(locality string) + CallStarted(locality clients.Locality) + CallFinished(locality clients.Locality, err error) + CallServerLoad(locality clients.Locality, name string, val float64) + CallDropped(category string) } // Picker implements RPC drop, circuit breaking drop and load reporting. @@ -133,7 +135,7 @@ func (d *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { } } - var lIDStr string + var lID clients.Locality pr, err := d.s.Picker.Pick(info) if scw, ok := pr.SubConn.(*scWrapper); ok { // This OK check also covers the case err!=nil, because SubConn will be @@ -141,7 +143,7 @@ func (d *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { pr.SubConn = scw.SubConn // If locality ID isn't found in the wrapper, an empty locality ID will // be used. - lIDStr = scw.localityID().ToString() + lID = scw.localityID() } if err != nil { @@ -153,24 +155,25 @@ func (d *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { } if labels := telemetryLabels(info.Ctx); labels != nil { - labels["grpc.lb.locality"] = lIDStr + labels["grpc.lb.locality"] = internal.LocalityString(lID) } if d.loadStore != nil { - d.loadStore.CallStarted(lIDStr) + locality := clients.Locality{Region: lID.Region, Zone: lID.Zone, SubZone: lID.SubZone} + d.loadStore.CallStarted(locality) oldDone := pr.Done pr.Done = func(info balancer.DoneInfo) { if oldDone != nil { oldDone(info) } - d.loadStore.CallFinished(lIDStr, info.Err) + d.loadStore.CallFinished(locality, info.Err) load, ok := info.ServerLoad.(*v3orcapb.OrcaLoadReport) if !ok || load == nil { return } for n, c := range load.NamedMetrics { - d.loadStore.CallServerLoad(lIDStr, n, c) + d.loadStore.CallServerLoad(locality, n, c) } } } diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/clusterresolver.go b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/clusterresolver.go index fe5d93dbfb..f9ce572933 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/clusterresolver.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/clusterresolver.go @@ -335,13 +335,7 @@ func (b *clusterResolverBalancer) run() { } break } - // This implementation assumes the child balancer supports - // ExitIdle (but still checks for the interface's existence to - // avoid a panic if not). If the child does not, no subconns - // will be connected. - if ei, ok := b.child.(balancer.ExitIdler); ok { - ei.ExitIdle() - } + b.child.ExitIdle() } case u := <-b.resourceWatcher.updateChannel: b.handleResourceUpdate(u) diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder.go b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder.go index 72a023646a..9c7fed8629 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder.go @@ -257,7 +257,7 @@ func priorityLocalitiesToClusterImpl(localities []xdsresource.Locality, priority if locality.Weight != 0 { lw = locality.Weight } - localityStr := locality.ID.ToString() + localityStr := internal.LocalityString(locality.ID) for _, endpoint := range locality.Endpoints { // Filter out all "unhealthy" endpoints (unknown and healthy are // both considered to be healthy: diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder_childname.go b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder_childname.go index 119f4c4747..bf4e33496e 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder_childname.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/clusterresolver/configbuilder_childname.go @@ -20,7 +20,7 @@ package clusterresolver import ( "fmt" - "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/xds/internal/clients" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" ) @@ -31,7 +31,7 @@ import ( // struct keeps state between generate() calls, and a later generate() might // return names returned by the previous call. type nameGenerator struct { - existingNames map[internal.LocalityID]string + existingNames map[clients.Locality]string prefix uint64 nextID uint64 } @@ -55,7 +55,7 @@ func newNameGenerator(prefix uint64) *nameGenerator { func (ng *nameGenerator) generate(priorities [][]xdsresource.Locality) []string { var ret []string usedNames := make(map[string]bool) - newNames := make(map[internal.LocalityID]string) + newNames := make(map[clients.Locality]string) for _, priority := range priorities { var nameFound string for _, locality := range priority { diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/loadstore/load_store_wrapper.go b/vendor/google.golang.org/grpc/xds/internal/balancer/loadstore/load_store_wrapper.go index f5605df832..48a2b7d1ed 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/loadstore/load_store_wrapper.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/loadstore/load_store_wrapper.go @@ -22,7 +22,8 @@ package loadstore import ( "sync" - "google.golang.org/grpc/xds/internal/xdsclient/load" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/lrsclient" ) // NewWrapper creates a Wrapper. @@ -53,8 +54,8 @@ type Wrapper struct { // store and perCluster are initialized as nil. They are only set by the // balancer when LRS is enabled. Before that, all functions to record loads // are no-op. - store *load.Store - perCluster load.PerClusterReporter + store *lrsclient.LoadStore + perCluster *lrsclient.PerClusterReporter } // UpdateClusterAndService updates the cluster name and eds service for this @@ -68,23 +69,30 @@ func (lsw *Wrapper) UpdateClusterAndService(cluster, edsService string) { } lsw.cluster = cluster lsw.edsService = edsService - lsw.perCluster = lsw.store.PerCluster(lsw.cluster, lsw.edsService) + if lsw.store == nil { + return + } + lsw.perCluster = lsw.store.ReporterForCluster(lsw.cluster, lsw.edsService) } // UpdateLoadStore updates the load store for this wrapper. If it is changed // from before, the perCluster store in this wrapper will also be updated. -func (lsw *Wrapper) UpdateLoadStore(store *load.Store) { +func (lsw *Wrapper) UpdateLoadStore(store *lrsclient.LoadStore) { lsw.mu.Lock() defer lsw.mu.Unlock() if store == lsw.store { return } lsw.store = store - lsw.perCluster = lsw.store.PerCluster(lsw.cluster, lsw.edsService) + if lsw.store == nil { + lsw.perCluster = nil + return + } + lsw.perCluster = lsw.store.ReporterForCluster(lsw.cluster, lsw.edsService) } // CallStarted records a call started in the store. -func (lsw *Wrapper) CallStarted(locality string) { +func (lsw *Wrapper) CallStarted(locality clients.Locality) { lsw.mu.RLock() defer lsw.mu.RUnlock() if lsw.perCluster != nil { @@ -93,7 +101,7 @@ func (lsw *Wrapper) CallStarted(locality string) { } // CallFinished records a call finished in the store. -func (lsw *Wrapper) CallFinished(locality string, err error) { +func (lsw *Wrapper) CallFinished(locality clients.Locality, err error) { lsw.mu.RLock() defer lsw.mu.RUnlock() if lsw.perCluster != nil { @@ -102,7 +110,7 @@ func (lsw *Wrapper) CallFinished(locality string, err error) { } // CallServerLoad records the server load in the store. -func (lsw *Wrapper) CallServerLoad(locality, name string, val float64) { +func (lsw *Wrapper) CallServerLoad(locality clients.Locality, name string, val float64) { lsw.mu.RLock() defer lsw.mu.RUnlock() if lsw.perCluster != nil { diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/balancer.go b/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/balancer.go index bc5cea40cc..1b0149e309 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/balancer.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/balancer.go @@ -32,7 +32,6 @@ import ( "time" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/balancer/pickfirst/pickfirstleaf" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/internal/balancer/gracefulswitch" "google.golang.org/grpc/internal/buffer" @@ -467,12 +466,10 @@ func (b *outlierDetectionBalancer) UpdateState(s balancer.State) { func (b *outlierDetectionBalancer) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { oldListener := opts.StateListener scw := &subConnWrapper{ - addresses: addrs, - scUpdateCh: b.scUpdateCh, - listener: oldListener, - latestRawConnectivityState: balancer.SubConnState{ConnectivityState: connectivity.Idle}, - latestHealthState: balancer.SubConnState{ConnectivityState: connectivity.Connecting}, - healthListenerEnabled: len(addrs) == 1 && pickfirstleaf.IsManagedByPickfirst(addrs[0]), + addresses: addrs, + scUpdateCh: b.scUpdateCh, + listener: oldListener, + latestHealthState: balancer.SubConnState{ConnectivityState: connectivity.Connecting}, } opts.StateListener = func(state balancer.SubConnState) { b.updateSubConnState(scw, state) } b.mu.Lock() diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/subconn_wrapper.go b/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/subconn_wrapper.go index 2c390d2302..b893ea68e2 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/subconn_wrapper.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/outlierdetection/subconn_wrapper.go @@ -40,16 +40,6 @@ type subConnWrapper struct { // that. listener func(balancer.SubConnState) - // healthListenerEnabled indicates whether the leaf LB policy is using a - // generic health listener. When enabled, ejection updates are sent via the - // health listener instead of the connectivity listener. Once Dualstack - // changes are complete, all SubConns will be created by pickfirst which - // uses the health listener. - // TODO: https://github.com/grpc/grpc-go/issues/7915 - Once Dualstack - // changes are complete, all SubConns will be created by pick_first and - // outlier detection will only use the health listener for ejection and - // this field can be removed. - healthListenerEnabled bool scUpdateCh *buffer.Unbounded @@ -67,9 +57,6 @@ type subConnWrapper struct { // latestHealthState is tracked to update the child policy during // unejection. latestHealthState balancer.SubConnState - // latestRawConnectivityState is tracked to update the child policy during - // unejection. - latestRawConnectivityState balancer.SubConnState // Access to the following fields are protected by a mutex. These fields // should not be accessed from outside this file, instead use methods @@ -114,12 +101,7 @@ func (scw *subConnWrapper) RegisterHealthListener(listener func(balancer.SubConn // pick_first the universal leaf policy (see A61), both these mechanisms // started using the new health listener to make health signal visible to // the petiole policies without affecting the underlying connectivity - // management of the pick_first policy - if !scw.healthListenerEnabled { - logger.Errorf("Health listener unexpectedly registered on SubConn %v.", scw) - return - } - + // management of the pick_first policy. scw.mu.Lock() defer scw.mu.Unlock() @@ -157,12 +139,6 @@ func (scw *subConnWrapper) updateSubConnHealthState(scs balancer.SubConnState) { // updateSubConnConnectivityState stores the latest connectivity state for // unejection and updates the raw connectivity listener. func (scw *subConnWrapper) updateSubConnConnectivityState(scs balancer.SubConnState) { - scw.latestRawConnectivityState = scs - // If the raw connectivity listener is used for ejection, and the SubConn is - // ejected, don't send the update. - if scw.ejected && !scw.healthListenerEnabled { - return - } if scw.listener != nil { scw.listener(scs) } @@ -176,12 +152,6 @@ func (scw *subConnWrapper) clearHealthListener() { func (scw *subConnWrapper) handleUnejection() { scw.ejected = false - if !scw.healthListenerEnabled { - // If scw.latestRawConnectivityState has never been written to will - // default to connectivity IDLE, which is fine. - scw.updateSubConnConnectivityState(scw.latestRawConnectivityState) - return - } // If scw.latestHealthState has never been written to will use the health // state CONNECTING set during object creation. scw.updateSubConnHealthState(scw.latestHealthState) @@ -192,12 +162,6 @@ func (scw *subConnWrapper) handleEjection() { stateToUpdate := balancer.SubConnState{ ConnectivityState: connectivity.TransientFailure, } - if !scw.healthListenerEnabled { - if scw.listener != nil { - scw.listener(stateToUpdate) - } - return - } scw.mu.Lock() defer scw.mu.Unlock() if scw.healthListener != nil { diff --git a/vendor/google.golang.org/grpc/xds/internal/balancer/wrrlocality/balancer.go b/vendor/google.golang.org/grpc/xds/internal/balancer/wrrlocality/balancer.go index 065de200f4..0c99c108f7 100644 --- a/vendor/google.golang.org/grpc/xds/internal/balancer/wrrlocality/balancer.go +++ b/vendor/google.golang.org/grpc/xds/internal/balancer/wrrlocality/balancer.go @@ -154,6 +154,10 @@ type wrrLocalityBalancer struct { logger *grpclog.PrefixLogger } +func (b *wrrLocalityBalancer) ExitIdle() { + b.child.ExitIdle() +} + func (b *wrrLocalityBalancer) UpdateClientConnState(s balancer.ClientConnState) error { lbCfg, ok := s.BalancerConfig.(*LBConfig) if !ok { @@ -167,7 +171,7 @@ func (b *wrrLocalityBalancer) UpdateClientConnState(s balancer.ClientConnState) // shouldn't happen though (this attribute that is set actually gets // used to build localities in the first place), and thus don't error // out, and just build a weighted target with undefined behavior. - locality := internal.GetLocalityID(addr).ToString() + locality := internal.LocalityString(internal.GetLocalityID(addr)) ai, ok := getAddrInfo(addr) if !ok { return fmt.Errorf("xds_wrr_locality: missing locality weight information in address %q", addr) diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/config.go b/vendor/google.golang.org/grpc/xds/internal/clients/config.go new file mode 100644 index 0000000000..f106465f64 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/config.go @@ -0,0 +1,112 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package clients provides implementations of the clients to interact with +// xDS and LRS servers. +// +// # xDS Client +// +// The xDS client allows applications to: +// - Create client instances with in-memory configurations. +// - Register watches for named resources. +// - Receive resources via the ADS (Aggregated Discovery Service) stream. +// +// This enables applications to dynamically discover and configure resources +// such as listeners, routes, clusters, and endpoints from an xDS management +// server. +// +// # LRS Client +// +// The LRS (Load Reporting Service) client allows applications to report load +// data to an LRS server via the LRS stream. This data can be used for +// monitoring, traffic management, and other purposes. +// +// # Experimental +// +// NOTICE: This package is EXPERIMENTAL and may be changed or removed +// in a later release. +package clients + +// ServerIdentifier holds identifying information for connecting to an xDS +// management or LRS server. +type ServerIdentifier struct { + // ServerURI is the target URI of the server. + ServerURI string + + // Extensions can be populated with arbitrary data to be passed to the + // TransportBuilder and/or xDS Client's ResourceType implementations. + // This field can be used to provide additional configuration or context + // specific to the user's needs. + // + // The xDS and LRS clients do not interpret the contents of this field. + // It is the responsibility of the user's custom TransportBuilder and/or + // ResourceType implementations to handle and interpret these extensions. + // + // For example, a custom TransportBuilder might use this field to + // configure a specific security credentials. + // + // Extensions may be any type that is comparable, as they are used as map + // keys internally. If Extensions are not able to be used as a map key, + // the client may panic. + // + // See: https://go.dev/ref/spec#Comparison_operators + // + // Any equivalent extensions in all ServerIdentifiers present in a single + // client's configuration should have the same value. Not following this + // restriction may result in excess resource usage. + Extensions any +} + +// Node represents the identity of the xDS client, allowing xDS and LRS servers +// to identify the source of xDS requests. +type Node struct { + // ID is a string identifier of the application. + ID string + // Cluster is the name of the cluster the application belongs to. + Cluster string + // Locality is the location of the application including region, zone, + // sub-zone. + Locality Locality + // Metadata provides additional context about the application by associating + // arbitrary key-value pairs with it. + Metadata any + // UserAgentName is the user agent name of application. + UserAgentName string + // UserAgentVersion is the user agent version of application. + UserAgentVersion string +} + +// Locality represents the location of the xDS client application. +type Locality struct { + // Region is the region of the xDS client application. + Region string + // Zone is the area within a region. + Zone string + // SubZone is the further subdivision within a zone. + SubZone string +} + +// MetricsReporter is used by the XDSClient to report metrics. +type MetricsReporter interface { + // ReportMetric reports a metric. The metric will be one of the predefined + // set of types depending on the client (XDSClient or LRSClient). + // + // Each client will produce different metrics. Please see the client's + // documentation for a list of possible metrics events. + ReportMetric(metric any) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/grpctransport/grpc_transport.go b/vendor/google.golang.org/grpc/xds/internal/clients/grpctransport/grpc_transport.go new file mode 100644 index 0000000000..2659c301e5 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/grpctransport/grpc_transport.go @@ -0,0 +1,237 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package grpctransport provides an implementation of the +// clients.TransportBuilder interface using gRPC. +package grpctransport + +import ( + "context" + "fmt" + "sync" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/xds/internal/clients" +) + +var ( + logger = grpclog.Component("grpctransport") +) + +// ServerIdentifierExtension holds settings for connecting to a gRPC server, +// such as an xDS management or an LRS server. +// +// It must be set by value (not pointer) in the +// clients.ServerIdentifier.Extensions field (See Example). +type ServerIdentifierExtension struct { + // ConfigName is the name of the configuration to use for this transport. + // It must be present as a key in the map of configs passed to NewBuilder. + ConfigName string +} + +// Builder creates gRPC-based Transports. It must be paired with ServerIdentifiers +// that contain an Extension field of type ServerIdentifierExtension. +type Builder struct { + // configs is a map of configuration names to their respective Config. + configs map[string]Config + + mu sync.Mutex + // connections is a map of clients.ServerIdentifiers in use by the Builder + // to connect to different servers. + connections map[clients.ServerIdentifier]*grpc.ClientConn + // refs tracks the number of active references to each connection. + refs map[clients.ServerIdentifier]int +} + +// Config defines the configuration for connecting to a gRPC server, including +// credentials and an optional custom new client function. +type Config struct { + // Credentials is the credentials bundle to be used for the connection. + Credentials credentials.Bundle + // GRPCNewClient is an optional custom function to establish a gRPC connection. + // If nil, grpc.NewClient will be used as the default. + GRPCNewClient func(target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) +} + +// NewBuilder provides a builder for creating gRPC-based Transports using +// the credentials from provided map of credentials names to +// credentials.Bundle. +func NewBuilder(configs map[string]Config) *Builder { + return &Builder{ + configs: configs, + connections: make(map[clients.ServerIdentifier]*grpc.ClientConn), + refs: make(map[clients.ServerIdentifier]int), + } +} + +// Build returns a gRPC-based clients.Transport. +// +// The Extension field of the ServerIdentifier must be a ServerIdentifierExtension. +func (b *Builder) Build(si clients.ServerIdentifier) (clients.Transport, error) { + if si.ServerURI == "" { + return nil, fmt.Errorf("grpctransport: ServerURI is not set in ServerIdentifier") + } + if si.Extensions == nil { + return nil, fmt.Errorf("grpctransport: Extensions is not set in ServerIdentifier") + } + sce, ok := si.Extensions.(ServerIdentifierExtension) + if !ok { + return nil, fmt.Errorf("grpctransport: Extensions field is %T, but must be %T in ServerIdentifier", si.Extensions, ServerIdentifierExtension{}) + } + + config, ok := b.configs[sce.ConfigName] + if !ok { + return nil, fmt.Errorf("grpctransport: unknown config name %q specified in ServerIdentifierExtension", sce.ConfigName) + } + if config.Credentials == nil { + return nil, fmt.Errorf("grpctransport: config %q has nil credentials bundle", sce.ConfigName) + } + + b.mu.Lock() + defer b.mu.Unlock() + + if cc, ok := b.connections[si]; ok { + if logger.V(2) { + logger.Info("Reusing existing connection to the server for ServerIdentifier: %v", si) + } + b.refs[si]++ + tr := &grpcTransport{cc: cc} + tr.cleanup = b.cleanupFunc(si, tr) + return tr, nil + } + + // Create a new gRPC client/channel for the server with the provided + // credentials, server URI, and a byte codec to send and receive messages. + // Also set a static keepalive configuration that is common across gRPC + // language implementations. + kpCfg := grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: 5 * time.Minute, + Timeout: 20 * time.Second, + }) + dopts := []grpc.DialOption{kpCfg, grpc.WithCredentialsBundle(config.Credentials), grpc.WithDefaultCallOptions(grpc.ForceCodec(&byteCodec{}))} + newClientFunc := grpc.NewClient + if config.GRPCNewClient != nil { + newClientFunc = config.GRPCNewClient + } + cc, err := newClientFunc(si.ServerURI, dopts...) + if err != nil { + return nil, fmt.Errorf("grpctransport: failed to create connection to server %q: %v", si.ServerURI, err) + } + tr := &grpcTransport{cc: cc} + // Register a cleanup function that decrements the refs to the gRPC + // transport each time Close() is called to close it and remove from + // transports and connections map if last reference is being released. + tr.cleanup = b.cleanupFunc(si, tr) + + // Add the newly created connection to the maps to re-use the transport + // channel and track references. + b.connections[si] = cc + b.refs[si] = 1 + + if logger.V(2) { + logger.Info("Created a new transport to the server for ServerIdentifier: %v", si) + } + return tr, nil +} + +func (b *Builder) cleanupFunc(si clients.ServerIdentifier, tr *grpcTransport) func() { + return sync.OnceFunc(func() { + b.mu.Lock() + defer b.mu.Unlock() + + b.refs[si]-- + if b.refs[si] != 0 { + return + } + + tr.cc.Close() + tr.cc = nil + delete(b.connections, si) + delete(b.refs, si) + }) +} + +type grpcTransport struct { + cc *grpc.ClientConn + + // cleanup is the function to be invoked for releasing the references to + // the gRPC transport each time Close() is called. + cleanup func() +} + +// NewStream creates a new gRPC stream to the server for the specified method. +func (g *grpcTransport) NewStream(ctx context.Context, method string) (clients.Stream, error) { + s, err := g.cc.NewStream(ctx, &grpc.StreamDesc{ClientStreams: true, ServerStreams: true}, method) + if err != nil { + return nil, err + } + return &stream{stream: s}, nil +} + +// Close closes the gRPC channel to the server. +func (g *grpcTransport) Close() { + g.cleanup() +} + +type stream struct { + stream grpc.ClientStream +} + +// Send sends a message to the server. +func (s *stream) Send(msg []byte) error { + return s.stream.SendMsg(msg) +} + +// Recv receives a message from the server. +func (s *stream) Recv() ([]byte, error) { + var typedRes []byte + + if err := s.stream.RecvMsg(&typedRes); err != nil { + return nil, err + } + return typedRes, nil +} + +// byteCodec here is still sending proto messages. It's just they are +// in []byte form. +type byteCodec struct{} + +func (c *byteCodec) Marshal(v any) ([]byte, error) { + if b, ok := v.([]byte); ok { + return b, nil + } + return nil, fmt.Errorf("grpctransport: message is %T, but must be a []byte", v) +} + +func (c *byteCodec) Unmarshal(data []byte, v any) error { + if b, ok := v.(*[]byte); ok { + *b = data + return nil + } + return fmt.Errorf("grpctransport: target is %T, but must be *[]byte", v) +} + +func (c *byteCodec) Name() string { + // Return "" to ensure the Content-Type header is "application/grpc", + // which is expected by standard gRPC servers for protobuf messages. + return "" +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/backoff/backoff.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/backoff/backoff.go new file mode 100644 index 0000000000..c07e155b70 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/backoff/backoff.go @@ -0,0 +1,124 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package backoff implements the backoff strategy for clients. +// +// This is kept in internal until the clients project decides whether or not to +// allow alternative backoff strategies. +package backoff + +import ( + "context" + "errors" + rand "math/rand/v2" + "time" +) + +// config defines the configuration options for backoff. +type config struct { + // baseDelay is the amount of time to backoff after the first failure. + baseDelay time.Duration + // multiplier is the factor with which to multiply backoffs after a + // failed retry. Should ideally be greater than 1. + multiplier float64 + // jitter is the factor with which backoffs are randomized. + jitter float64 + // maxDelay is the upper bound of backoff delay. + maxDelay time.Duration +} + +// defaultConfig is a backoff configuration with the default values specified +// at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. +// +// This should be useful for callers who want to configure backoff with +// non-default values only for a subset of the options. +var defaultConfig = config{ + baseDelay: 1.0 * time.Second, + multiplier: 1.6, + jitter: 0.2, + maxDelay: 120 * time.Second, +} + +// DefaultExponential is an exponential backoff implementation using the +// default values for all the configurable knobs defined in +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. +var DefaultExponential = exponential{config: defaultConfig} + +// exponential implements exponential backoff algorithm as defined in +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. +type exponential struct { + // Config contains all options to configure the backoff algorithm. + config config +} + +// Backoff returns the amount of time to wait before the next retry given the +// number of retries. +func (bc exponential) Backoff(retries int) time.Duration { + if retries == 0 { + return bc.config.baseDelay + } + backoff, max := float64(bc.config.baseDelay), float64(bc.config.maxDelay) + for backoff < max && retries > 0 { + backoff *= bc.config.multiplier + retries-- + } + if backoff > max { + backoff = max + } + // Randomize backoff delays so that if a cluster of requests start at + // the same time, they won't operate in lockstep. + backoff *= 1 + bc.config.jitter*(rand.Float64()*2-1) + if backoff < 0 { + return 0 + } + return time.Duration(backoff) +} + +// ErrResetBackoff is the error to be returned by the function executed by RunF, +// to instruct the latter to reset its backoff state. +var ErrResetBackoff = errors.New("reset backoff state") + +// RunF provides a convenient way to run a function f repeatedly until the +// context expires or f returns a non-nil error that is not ErrResetBackoff. +// When f returns ErrResetBackoff, RunF continues to run f, but resets its +// backoff state before doing so. backoff accepts an integer representing the +// number of retries, and returns the amount of time to backoff. +func RunF(ctx context.Context, f func() error, backoff func(int) time.Duration) { + attempt := 0 + timer := time.NewTimer(0) + for ctx.Err() == nil { + select { + case <-timer.C: + case <-ctx.Done(): + timer.Stop() + return + } + + err := f() + if errors.Is(err, ErrResetBackoff) { + timer.Reset(0) + attempt = 0 + continue + } + if err != nil { + return + } + timer.Reset(backoff(attempt)) + attempt++ + } +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/buffer/unbounded.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/buffer/unbounded.go new file mode 100644 index 0000000000..3e6e99d0e8 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/buffer/unbounded.go @@ -0,0 +1,116 @@ +/* + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package buffer provides an implementation of an unbounded buffer. +package buffer + +import ( + "errors" + "sync" +) + +// Unbounded is an implementation of an unbounded buffer which does not use +// extra goroutines. This is typically used for passing updates from one entity +// to another within gRPC. +// +// All methods on this type are thread-safe and don't block on anything except +// the underlying mutex used for synchronization. +// +// Unbounded supports values of any type to be stored in it by using a channel +// of `any`. This means that a call to Put() incurs an extra memory allocation, +// and also that users need a type assertion while reading. For performance +// critical code paths, using Unbounded is strongly discouraged and defining a +// new type specific implementation of this buffer is preferred. See +// internal/transport/transport.go for an example of this. +type Unbounded struct { + c chan any + closed bool + closing bool + mu sync.Mutex + backlog []any +} + +// NewUnbounded returns a new instance of Unbounded. +func NewUnbounded() *Unbounded { + return &Unbounded{c: make(chan any, 1)} +} + +var errBufferClosed = errors.New("Put() called on closed buffer.Unbounded") + +// Put adds t to the unbounded buffer. +func (b *Unbounded) Put(t any) error { + b.mu.Lock() + defer b.mu.Unlock() + if b.closing { + return errBufferClosed + } + if len(b.backlog) == 0 { + select { + case b.c <- t: + return nil + default: + } + } + b.backlog = append(b.backlog, t) + return nil +} + +// Load sends the earliest buffered data, if any, onto the read channel returned +// by Get(). Users are expected to call this every time they successfully read a +// value from the read channel. +func (b *Unbounded) Load() { + b.mu.Lock() + defer b.mu.Unlock() + if len(b.backlog) > 0 { + select { + case b.c <- b.backlog[0]: + b.backlog[0] = nil + b.backlog = b.backlog[1:] + default: + } + } else if b.closing && !b.closed { + close(b.c) + } +} + +// Get returns a read channel on which values added to the buffer, via Put(), +// are sent on. +// +// Upon reading a value from this channel, users are expected to call Load() to +// send the next buffered value onto the channel if there is any. +// +// If the unbounded buffer is closed, the read channel returned by this method +// is closed after all data is drained. +func (b *Unbounded) Get() <-chan any { + return b.c +} + +// Close closes the unbounded buffer. No subsequent data may be Put(), and the +// channel returned from Get() will be closed after all the data is read and +// Load() is called for the final time. +func (b *Unbounded) Close() { + b.mu.Lock() + defer b.mu.Unlock() + if b.closing { + return + } + b.closing = true + if len(b.backlog) == 0 { + b.closed = true + close(b.c) + } +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/internal.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/internal.go new file mode 100644 index 0000000000..371b4d19d6 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/internal.go @@ -0,0 +1,71 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package internal contains helpers for xDS and LRS clients. +package internal + +import ( + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" + + v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" +) + +// NodeProto returns a protobuf representation of clients.Node n. +// +// This function is intended to be used by the client implementation to convert +// the user-provided Node configuration to its protobuf representation. +func NodeProto(n clients.Node) *v3corepb.Node { + return &v3corepb.Node{ + Id: n.ID, + Cluster: n.Cluster, + Locality: func() *v3corepb.Locality { + if isLocalityEmpty(n.Locality) { + return nil + } + return &v3corepb.Locality{ + Region: n.Locality.Region, + Zone: n.Locality.Zone, + SubZone: n.Locality.SubZone, + } + }(), + Metadata: func() *structpb.Struct { + if n.Metadata == nil { + return nil + } + if md, ok := n.Metadata.(*structpb.Struct); ok { + return proto.Clone(md).(*structpb.Struct) + } + return nil + }(), + UserAgentName: n.UserAgentName, + UserAgentVersionType: &v3corepb.Node_UserAgentVersion{UserAgentVersion: n.UserAgentVersion}, + } +} + +// isLocalityEqual reports whether clients.Locality l is considered empty. +func isLocalityEmpty(l clients.Locality) bool { + return isLocalityEqual(l, clients.Locality{}) +} + +// isLocalityEqual returns true if clients.Locality l1 and l2 are considered +// equal. +func isLocalityEqual(l1, l2 clients.Locality) bool { + return l1.Region == l2.Region && l1.Zone == l2.Zone && l1.SubZone == l2.SubZone +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/pretty/pretty.go new file mode 100644 index 0000000000..dbee7a60d7 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/pretty/pretty.go @@ -0,0 +1,73 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package pretty defines helper functions to pretty-print structs for logging. +package pretty + +import ( + "bytes" + "encoding/json" + "fmt" + + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/protoadapt" +) + +const jsonIndent = " " + +// ToJSON marshals the input into a json string. +// +// If marshal fails, it falls back to fmt.Sprintf("%+v"). +func ToJSON(e any) string { + if ee, ok := e.(protoadapt.MessageV1); ok { + e = protoadapt.MessageV2Of(ee) + } + + if ee, ok := e.(protoadapt.MessageV2); ok { + mm := protojson.MarshalOptions{ + Indent: jsonIndent, + Multiline: true, + } + ret, err := mm.Marshal(ee) + if err != nil { + // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 + // messages are not imported, and this will fail because the message + // is not found. + return fmt.Sprintf("%+v", ee) + } + return string(ret) + } + + ret, err := json.MarshalIndent(e, "", jsonIndent) + if err != nil { + return fmt.Sprintf("%+v", e) + } + return string(ret) +} + +// FormatJSON formats the input json bytes with indentation. +// +// If Indent fails, it returns the unchanged input as string. +func FormatJSON(b []byte) string { + var out bytes.Buffer + err := json.Indent(&out, b, "", jsonIndent) + if err != nil { + return string(b) + } + return out.String() +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/callback_serializer.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/callback_serializer.go new file mode 100644 index 0000000000..9ad1be517c --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/callback_serializer.go @@ -0,0 +1,112 @@ +/* + * + * Copyright 2022 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package syncutil + +import ( + "context" + + "google.golang.org/grpc/xds/internal/clients/internal/buffer" +) + +// CallbackSerializer provides a mechanism to schedule callbacks in a +// synchronized manner. It provides a FIFO guarantee on the order of execution +// of scheduled callbacks. New callbacks can be scheduled by invoking the +// Schedule() method. +// +// This type is safe for concurrent access. +type CallbackSerializer struct { + // done is closed once the serializer is shut down completely, i.e all + // scheduled callbacks are executed and the serializer has deallocated all + // its resources. + done chan struct{} + + callbacks *buffer.Unbounded +} + +// NewCallbackSerializer returns a new CallbackSerializer instance. The provided +// context will be passed to the scheduled callbacks. Users should cancel the +// provided context to shutdown the CallbackSerializer. It is guaranteed that no +// callbacks will be added once this context is canceled, and any pending un-run +// callbacks will be executed before the serializer is shut down. +func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { + cs := &CallbackSerializer{ + done: make(chan struct{}), + callbacks: buffer.NewUnbounded(), + } + go cs.run(ctx) + return cs +} + +// TrySchedule tries to schedule the provided callback function f to be +// executed in the order it was added. This is a best-effort operation. If the +// context passed to NewCallbackSerializer was canceled before this method is +// called, the callback will not be scheduled. +// +// Callbacks are expected to honor the context when performing any blocking +// operations, and should return early when the context is canceled. +func (cs *CallbackSerializer) TrySchedule(f func(ctx context.Context)) { + cs.callbacks.Put(f) +} + +// ScheduleOr schedules the provided callback function f to be executed in the +// order it was added. If the context passed to NewCallbackSerializer has been +// canceled before this method is called, the onFailure callback will be +// executed inline instead. +// +// Callbacks are expected to honor the context when performing any blocking +// operations, and should return early when the context is canceled. +func (cs *CallbackSerializer) ScheduleOr(f func(ctx context.Context), onFailure func()) { + if cs.callbacks.Put(f) != nil { + onFailure() + } +} + +func (cs *CallbackSerializer) run(ctx context.Context) { + defer close(cs.done) + + // TODO: when Go 1.21 is the oldest supported version, this loop and Close + // can be replaced with: + // + // context.AfterFunc(ctx, cs.callbacks.Close) + for ctx.Err() == nil { + select { + case <-ctx.Done(): + // Do nothing here. Next iteration of the for loop will not happen, + // since ctx.Err() would be non-nil. + case cb := <-cs.callbacks.Get(): + cs.callbacks.Load() + cb.(func(context.Context))(ctx) + } + } + + // Close the buffer to prevent new callbacks from being added. + cs.callbacks.Close() + + // Run all pending callbacks. + for cb := range cs.callbacks.Get() { + cs.callbacks.Load() + cb.(func(context.Context))(ctx) + } +} + +// Done returns a channel that is closed after the context passed to +// NewCallbackSerializer is canceled and all callbacks have been executed. +func (cs *CallbackSerializer) Done() <-chan struct{} { + return cs.done +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/event.go b/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/event.go new file mode 100644 index 0000000000..1850ca3798 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/internal/syncutil/event.go @@ -0,0 +1,61 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package syncutil implements additional synchronization primitives built upon +// the sync package. +package syncutil + +import ( + "sync" + "sync/atomic" +) + +// Event represents a one-time event that may occur in the future. +type Event struct { + fired int32 + c chan struct{} + o sync.Once +} + +// Fire causes e to complete. It is safe to call multiple times, and +// concurrently. It returns true iff this call to Fire caused the signaling +// channel returned by Done to close. +func (e *Event) Fire() bool { + ret := false + e.o.Do(func() { + atomic.StoreInt32(&e.fired, 1) + close(e.c) + ret = true + }) + return ret +} + +// Done returns a channel that will be closed when Fire is called. +func (e *Event) Done() <-chan struct{} { + return e.c +} + +// HasFired returns true if Fire has been called. +func (e *Event) HasFired() bool { + return atomic.LoadInt32(&e.fired) == 1 +} + +// NewEvent returns a new, ready-to-use Event. +func NewEvent() *Event { + return &Event{c: make(chan struct{})} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/load/reporter.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/internal/internal.go similarity index 64% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/load/reporter.go rename to vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/internal/internal.go index 67e29e5bae..86eb14ea4c 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/load/reporter.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/internal/internal.go @@ -1,6 +1,6 @@ /* * - * Copyright 2020 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,15 +13,14 @@ * 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 load +// Package internal contains functionality internal to the lrsclient package. +package internal + +import "time" -// PerClusterReporter wraps the methods from the loadStore that are used here. -type PerClusterReporter interface { - CallStarted(locality string) - CallFinished(locality string, err error) - CallServerLoad(locality, name string, val float64) - CallDropped(category string) -} +var ( + // TimeNow is used to get the current time. It can be overridden in tests. + TimeNow func() time.Time +) diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/load_store.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/load_store.go new file mode 100644 index 0000000000..6b35fd979a --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/load_store.go @@ -0,0 +1,438 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package lrsclient + +import ( + "context" + "sync" + "sync/atomic" + "time" + + "google.golang.org/grpc/xds/internal/clients" + lrsclientinternal "google.golang.org/grpc/xds/internal/clients/lrsclient/internal" +) + +// A LoadStore aggregates loads for multiple clusters and services that are +// intended to be reported via LRS. +// +// LoadStore stores loads reported to a single LRS server. Use multiple stores +// for multiple servers. +// +// It is safe for concurrent use. +type LoadStore struct { + // stop is the function to call to Stop the LoadStore reporting. + stop func(ctx context.Context) + + // mu only protects the map (2 layers). The read/write to + // *PerClusterReporter doesn't need to hold the mu. + mu sync.Mutex + // clusters is a map with cluster name as the key. The second layer is a + // map with service name as the key. Each value (PerClusterReporter) + // contains data for a (cluster, service) pair. + // + // Note that new entries are added to this map, but never removed. This is + // potentially a memory leak. But the memory is allocated for each new + // (cluster,service) pair, and the memory allocated is just pointers and + // maps. So this shouldn't get too bad. + clusters map[string]map[string]*PerClusterReporter +} + +func init() { + lrsclientinternal.TimeNow = time.Now +} + +// newLoadStore creates a LoadStore. +func newLoadStore() *LoadStore { + return &LoadStore{ + clusters: make(map[string]map[string]*PerClusterReporter), + } +} + +// Stop signals the LoadStore to stop reporting. +// +// Before closing the underlying LRS stream, this method may block until a +// final load report send attempt completes or the provided context `ctx` +// expires. +// +// The provided context must have a deadline or timeout set to prevent Stop +// from blocking indefinitely if the final send attempt fails to complete. +// +// Calling Stop on an already stopped LoadStore is a no-op. +func (ls *LoadStore) Stop(ctx context.Context) { + ls.stop(ctx) +} + +// ReporterForCluster returns the PerClusterReporter for the given cluster and +// service. +func (ls *LoadStore) ReporterForCluster(clusterName, serviceName string) *PerClusterReporter { + ls.mu.Lock() + defer ls.mu.Unlock() + c, ok := ls.clusters[clusterName] + if !ok { + c = make(map[string]*PerClusterReporter) + ls.clusters[clusterName] = c + } + + if p, ok := c[serviceName]; ok { + return p + } + p := &PerClusterReporter{ + cluster: clusterName, + service: serviceName, + lastLoadReportAt: lrsclientinternal.TimeNow(), + } + c[serviceName] = p + return p +} + +// stats returns the load data for the given cluster names. Data is returned in +// a slice with no specific order. +// +// If no clusterName is given (an empty slice), all data for all known clusters +// is returned. +// +// If a cluster's loadData is empty (no load to report), it's not appended to +// the returned slice. +func (ls *LoadStore) stats(clusterNames []string) []*loadData { + ls.mu.Lock() + defer ls.mu.Unlock() + + var ret []*loadData + if len(clusterNames) == 0 { + for _, c := range ls.clusters { + ret = appendClusterStats(ret, c) + } + return ret + } + for _, n := range clusterNames { + if c, ok := ls.clusters[n]; ok { + ret = appendClusterStats(ret, c) + } + } + + return ret +} + +// PerClusterReporter records load data pertaining to a single cluster. It +// provides methods to record call starts, finishes, server-reported loads, +// and dropped calls. +// +// It is safe for concurrent use. +// +// TODO(purnesh42h): Use regular maps with mutexes instead of sync.Map here. +// The latter is optimized for two common use cases: (1) when the entry for a +// given key is only ever written once but read many times, as in caches that +// only grow, or (2) when multiple goroutines read, write, and overwrite +// entries for disjoint sets of keys. In these two cases, use of a Map may +// significantly reduce lock contention compared to a Go map paired with a +// separate Mutex or RWMutex. +// Neither of these conditions are met here, and we should transition to a +// regular map with a mutex for better type safety. +type PerClusterReporter struct { + cluster, service string + drops sync.Map // map[string]*uint64 + localityRPCCount sync.Map // map[clients.Locality]*rpcCountData + + mu sync.Mutex + lastLoadReportAt time.Time +} + +// CallStarted records a call started in the LoadStore. +func (p *PerClusterReporter) CallStarted(locality clients.Locality) { + s, ok := p.localityRPCCount.Load(locality) + if !ok { + tp := newRPCCountData() + s, _ = p.localityRPCCount.LoadOrStore(locality, tp) + } + s.(*rpcCountData).incrInProgress() + s.(*rpcCountData).incrIssued() +} + +// CallFinished records a call finished in the LoadStore. +func (p *PerClusterReporter) CallFinished(locality clients.Locality, err error) { + f, ok := p.localityRPCCount.Load(locality) + if !ok { + // The map is never cleared, only values in the map are reset. So the + // case where entry for call-finish is not found should never happen. + return + } + f.(*rpcCountData).decrInProgress() + if err == nil { + f.(*rpcCountData).incrSucceeded() + } else { + f.(*rpcCountData).incrErrored() + } +} + +// CallServerLoad records the server load in the LoadStore. +func (p *PerClusterReporter) CallServerLoad(locality clients.Locality, name string, val float64) { + s, ok := p.localityRPCCount.Load(locality) + if !ok { + // The map is never cleared, only values in the map are reset. So the + // case where entry for callServerLoad is not found should never happen. + return + } + s.(*rpcCountData).addServerLoad(name, val) +} + +// CallDropped records a call dropped in the LoadStore. +func (p *PerClusterReporter) CallDropped(category string) { + d, ok := p.drops.Load(category) + if !ok { + tp := new(uint64) + d, _ = p.drops.LoadOrStore(category, tp) + } + atomic.AddUint64(d.(*uint64), 1) +} + +// stats returns and resets all loads reported to the store, except inProgress +// rpc counts. +// +// It returns nil if the store doesn't contain any (new) data. +func (p *PerClusterReporter) stats() *loadData { + sd := newLoadData(p.cluster, p.service) + p.drops.Range(func(key, val any) bool { + d := atomic.SwapUint64(val.(*uint64), 0) + if d == 0 { + return true + } + sd.totalDrops += d + keyStr := key.(string) + if keyStr != "" { + // Skip drops without category. They are counted in total_drops, but + // not in per category. One example is drops by circuit breaking. + sd.drops[keyStr] = d + } + return true + }) + p.localityRPCCount.Range(func(key, val any) bool { + countData := val.(*rpcCountData) + succeeded := countData.loadAndClearSucceeded() + inProgress := countData.loadInProgress() + errored := countData.loadAndClearErrored() + issued := countData.loadAndClearIssued() + if succeeded == 0 && inProgress == 0 && errored == 0 && issued == 0 { + return true + } + + ld := localityData{ + requestStats: requestData{ + succeeded: succeeded, + errored: errored, + inProgress: inProgress, + issued: issued, + }, + loadStats: make(map[string]serverLoadData), + } + countData.serverLoads.Range(func(key, val any) bool { + sum, count := val.(*rpcLoadData).loadAndClear() + if count == 0 { + return true + } + ld.loadStats[key.(string)] = serverLoadData{ + count: count, + sum: sum, + } + return true + }) + sd.localityStats[key.(clients.Locality)] = ld + return true + }) + + p.mu.Lock() + sd.reportInterval = lrsclientinternal.TimeNow().Sub(p.lastLoadReportAt) + p.lastLoadReportAt = lrsclientinternal.TimeNow() + p.mu.Unlock() + + if sd.totalDrops == 0 && len(sd.drops) == 0 && len(sd.localityStats) == 0 { + return nil + } + return sd +} + +// loadData contains all load data reported to the LoadStore since the most recent +// call to stats(). +type loadData struct { + // cluster is the name of the cluster this data is for. + cluster string + // service is the name of the EDS service this data is for. + service string + // totalDrops is the total number of dropped requests. + totalDrops uint64 + // drops is the number of dropped requests per category. + drops map[string]uint64 + // localityStats contains load reports per locality. + localityStats map[clients.Locality]localityData + // reportInternal is the duration since last time load was reported (stats() + // was called). + reportInterval time.Duration +} + +// localityData contains load data for a single locality. +type localityData struct { + // requestStats contains counts of requests made to the locality. + requestStats requestData + // loadStats contains server load data for requests made to the locality, + // indexed by the load type. + loadStats map[string]serverLoadData +} + +// requestData contains request counts. +type requestData struct { + // succeeded is the number of succeeded requests. + succeeded uint64 + // errored is the number of requests which ran into errors. + errored uint64 + // inProgress is the number of requests in flight. + inProgress uint64 + // issued is the total number requests that were sent. + issued uint64 +} + +// serverLoadData contains server load data. +type serverLoadData struct { + // count is the number of load reports. + count uint64 + // sum is the total value of all load reports. + sum float64 +} + +// appendClusterStats gets the Data for all the given clusters, append to ret, +// and return the new slice. +// +// Data is only appended to ret if it's not empty. +func appendClusterStats(ret []*loadData, clusters map[string]*PerClusterReporter) []*loadData { + for _, d := range clusters { + data := d.stats() + if data == nil { + // Skip this data if it doesn't contain any information. + continue + } + ret = append(ret, data) + } + return ret +} + +func newLoadData(cluster, service string) *loadData { + return &loadData{ + cluster: cluster, + service: service, + drops: make(map[string]uint64), + localityStats: make(map[clients.Locality]localityData), + } +} + +type rpcCountData struct { + // Only atomic accesses are allowed for the fields. + succeeded *uint64 + errored *uint64 + inProgress *uint64 + issued *uint64 + + // Map from load desc to load data (sum+count). Loading data from map is + // atomic, but updating data takes a lock, which could cause contention when + // multiple RPCs try to report loads for the same desc. + // + // To fix the contention, shard this map. + serverLoads sync.Map // map[string]*rpcLoadData +} + +func newRPCCountData() *rpcCountData { + return &rpcCountData{ + succeeded: new(uint64), + errored: new(uint64), + inProgress: new(uint64), + issued: new(uint64), + } +} + +func (rcd *rpcCountData) incrSucceeded() { + atomic.AddUint64(rcd.succeeded, 1) +} + +func (rcd *rpcCountData) loadAndClearSucceeded() uint64 { + return atomic.SwapUint64(rcd.succeeded, 0) +} + +func (rcd *rpcCountData) incrErrored() { + atomic.AddUint64(rcd.errored, 1) +} + +func (rcd *rpcCountData) loadAndClearErrored() uint64 { + return atomic.SwapUint64(rcd.errored, 0) +} + +func (rcd *rpcCountData) incrInProgress() { + atomic.AddUint64(rcd.inProgress, 1) +} + +func (rcd *rpcCountData) decrInProgress() { + atomic.AddUint64(rcd.inProgress, ^uint64(0)) // atomic.Add(x, -1) +} + +func (rcd *rpcCountData) loadInProgress() uint64 { + return atomic.LoadUint64(rcd.inProgress) // InProgress count is not clear when reading. +} + +func (rcd *rpcCountData) incrIssued() { + atomic.AddUint64(rcd.issued, 1) +} + +func (rcd *rpcCountData) loadAndClearIssued() uint64 { + return atomic.SwapUint64(rcd.issued, 0) +} + +func (rcd *rpcCountData) addServerLoad(name string, d float64) { + loads, ok := rcd.serverLoads.Load(name) + if !ok { + tl := newRPCLoadData() + loads, _ = rcd.serverLoads.LoadOrStore(name, tl) + } + loads.(*rpcLoadData).add(d) +} + +// rpcLoadData is data for server loads (from trailers or oob). Fields in this +// struct must be updated consistently. +// +// The current solution is to hold a lock, which could cause contention. To fix, +// shard serverLoads map in rpcCountData. +type rpcLoadData struct { + mu sync.Mutex + sum float64 + count uint64 +} + +func newRPCLoadData() *rpcLoadData { + return &rpcLoadData{} +} + +func (rld *rpcLoadData) add(v float64) { + rld.mu.Lock() + rld.sum += v + rld.count++ + rld.mu.Unlock() +} + +func (rld *rpcLoadData) loadAndClear() (s float64, c uint64) { + rld.mu.Lock() + s, rld.sum = rld.sum, 0 + c, rld.count = rld.count, 0 + rld.mu.Unlock() + return s, c +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/logging.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/logging.go new file mode 100644 index 0000000000..032b56bd81 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/logging.go @@ -0,0 +1,36 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package lrsclient + +import ( + "fmt" + + "google.golang.org/grpc/grpclog" + internalgrpclog "google.golang.org/grpc/internal/grpclog" +) + +var logger = grpclog.Component("xds") + +func prefixLogger(c *LRSClient) *internalgrpclog.PrefixLogger { + return internalgrpclog.NewPrefixLogger(logger, clientPrefix(c)) +} + +func clientPrefix(c *LRSClient) string { + return fmt.Sprintf("[lrs-client %p] ", c) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/lrs/lrs_stream.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrs_stream.go similarity index 56% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/lrs/lrs_stream.go rename to vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrs_stream.go index 7260816b67..bb275bdb46 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/lrs/lrs_stream.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrs_stream.go @@ -1,6 +1,6 @@ /* * - * Copyright 2024 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,24 +15,19 @@ * limitations under the License. */ -// Package lrs provides the implementation of an LRS (Load Reporting Service) -// stream for the xDS client. -package lrs +package lrsclient import ( "context" "fmt" "io" - "sync" "time" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/backoff" igrpclog "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/pretty" - "google.golang.org/grpc/xds/internal" - "google.golang.org/grpc/xds/internal/xdsclient/load" - "google.golang.org/grpc/xds/internal/xdsclient/transport" + "google.golang.org/grpc/xds/internal/clients" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" @@ -46,101 +41,58 @@ import ( // terse output should be at `INFO` and verbosity 2. const perRPCVerbosityLevel = 9 -// StreamImpl provides all the functionality associated with an LRS (Load Reporting -// Service) stream on the client-side. It manages the lifecycle of the LRS stream, -// including starting, stopping, and retrying the stream. It also provides a -// load.Store that can be used to report load, and a cleanup function that should -// be called when the load reporting is no longer needed. -type StreamImpl struct { - // The following fields are initialized when a Stream instance is created +// streamImpl provides all the functionality associated with an LRS (Load +// Reporting Service) stream on the client-side. It manages the lifecycle of +// the LRS stream, including starting, stopping, and retrying the stream. It +// also provides a LoadStore that can be used to report load, with a Stop +// function that should be called when the load reporting is no longer +// needed. +type streamImpl struct { + // The following fields are initialized when a stream instance is created // and are read-only afterwards, and hence can be accessed without a mutex. - transport transport.Transport // Transport to use for LRS stream. + transport clients.Transport // Transport to use for LRS stream. backoff func(int) time.Duration // Backoff for retries, after stream failures. nodeProto *v3corepb.Node // Identifies the gRPC application. doneCh chan struct{} // To notify exit of LRS goroutine. logger *igrpclog.PrefixLogger - // Guards access to the below fields. - mu sync.Mutex cancelStream context.CancelFunc // Cancel the stream. If nil, the stream is not active. - refCount int // Number of interested parties. - lrsStore *load.Store // Store returned to user for pushing loads. + loadStore *LoadStore // LoadStore returned to user for pushing loads. + + finalSendRequest chan struct{} // To request for the final attempt to send loads. + finalSendDone chan error // To signal completion of the final attempt of sending loads. } -// StreamOpts holds the options for creating an lrsStream. -type StreamOpts struct { - Transport transport.Transport // xDS transport to create the stream on. - Backoff func(int) time.Duration // Backoff for retries, after stream failures. - NodeProto *v3corepb.Node // Node proto to identify the gRPC application. - LogPrefix string // Prefix to be used for log messages. +// streamOpts holds the options for creating an lrsStream. +type streamOpts struct { + transport clients.Transport // xDS transport to create the stream on. + backoff func(int) time.Duration // Backoff for retries, after stream failures. + nodeProto *v3corepb.Node // Node proto to identify the gRPC application. + logPrefix string // Prefix to be used for log messages. } -// NewStreamImpl creates a new StreamImpl with the provided options. +// newStreamImpl creates a new StreamImpl with the provided options. // // The actual streaming RPC call is initiated when the first call to ReportLoad // is made, and is terminated when the last call to ReportLoad is canceled. -func NewStreamImpl(opts StreamOpts) *StreamImpl { - lrs := &StreamImpl{ - transport: opts.Transport, - backoff: opts.Backoff, - nodeProto: opts.NodeProto, - lrsStore: load.NewStore(), - } - - l := grpclog.Component("xds") - lrs.logger = igrpclog.NewPrefixLogger(l, opts.LogPrefix+fmt.Sprintf("[lrs-stream %p] ", lrs)) - return lrs -} - -// ReportLoad returns a load.Store that can be used to report load, and a -// cleanup function that should be called when the load reporting is no longer -// needed. -// -// The first call to ReportLoad sets the reference count to one, and starts the -// LRS streaming call. Subsequent calls increment the reference count and return -// the same load.Store. -// -// The cleanup function decrements the reference count and stops the LRS stream -// when the last reference is removed. -func (lrs *StreamImpl) ReportLoad() (*load.Store, func()) { - lrs.mu.Lock() - defer lrs.mu.Unlock() - - cleanup := sync.OnceFunc(func() { - lrs.mu.Lock() - defer lrs.mu.Unlock() - - if lrs.refCount == 0 { - lrs.logger.Errorf("Attempting to stop already stopped StreamImpl") - return - } - lrs.refCount-- - if lrs.refCount != 0 { - return - } - - if lrs.cancelStream == nil { - // It is possible that Stop() is called before the cleanup function - // is called, thereby setting cancelStream to nil. Hence we need a - // nil check here bofore invoking the cancel function. - return - } - lrs.cancelStream() - lrs.cancelStream = nil - lrs.logger.Infof("Stopping StreamImpl") - }) +func newStreamImpl(opts streamOpts) *streamImpl { + ctx, cancel := context.WithCancel(context.Background()) - if lrs.refCount != 0 { - lrs.refCount++ - return lrs.lrsStore, cleanup + lrs := &streamImpl{ + transport: opts.transport, + backoff: opts.backoff, + nodeProto: opts.nodeProto, + cancelStream: cancel, + doneCh: make(chan struct{}), + finalSendRequest: make(chan struct{}, 1), + finalSendDone: make(chan error, 1), } - lrs.refCount++ - ctx, cancel := context.WithCancel(context.Background()) - lrs.cancelStream = cancel - lrs.doneCh = make(chan struct{}) + l := grpclog.Component("xds") + lrs.logger = igrpclog.NewPrefixLogger(l, opts.logPrefix+fmt.Sprintf("[lrs-stream %p] ", lrs)) + lrs.loadStore = newLoadStore() go lrs.runner(ctx) - return lrs.lrsStore, cleanup + return lrs } // runner is responsible for managing the lifetime of an LRS streaming call. It @@ -148,7 +100,7 @@ func (lrs *StreamImpl) ReportLoad() (*load.Store, func()) { // LoadStatsResponse, and then starts a goroutine to periodically send // LoadStatsRequests. The runner will restart the stream if it encounters any // errors. -func (lrs *StreamImpl) runner(ctx context.Context) { +func (lrs *streamImpl) runner(ctx context.Context) { defer close(lrs.doneCh) // This feature indicates that the client supports the @@ -163,7 +115,7 @@ func (lrs *StreamImpl) runner(ctx context.Context) { streamCtx, cancel := context.WithCancel(ctx) defer cancel() - stream, err := lrs.transport.CreateStreamingCall(streamCtx, "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats") + stream, err := lrs.transport.NewStream(streamCtx, "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats") if err != nil { lrs.logger.Warningf("Failed to create new LRS streaming RPC: %v", err) return nil @@ -194,7 +146,7 @@ func (lrs *StreamImpl) runner(ctx context.Context) { // sendLoads is responsible for periodically sending load reports to the LRS // server at the specified interval for the specified clusters, until the passed // in context is canceled. -func (lrs *StreamImpl) sendLoads(ctx context.Context, stream transport.StreamingCall, clusterNames []string, interval time.Duration) { +func (lrs *streamImpl) sendLoads(ctx context.Context, stream clients.Stream, clusterNames []string, interval time.Duration) { tick := time.NewTicker(interval) defer tick.Stop() for { @@ -202,20 +154,40 @@ func (lrs *StreamImpl) sendLoads(ctx context.Context, stream transport.Streaming case <-tick.C: case <-ctx.Done(): return + case <-lrs.finalSendRequest: + var finalSendErr error + if lrs.logger.V(2) { + lrs.logger.Infof("Final send request received. Attempting final LRS report.") + } + if err := lrs.sendLoadStatsRequest(stream, lrs.loadStore.stats(clusterNames)); err != nil { + lrs.logger.Warningf("Failed to send final load report. Writing to LRS stream failed: %v", err) + finalSendErr = err + } + if lrs.logger.V(2) { + lrs.logger.Infof("Successfully sent final load report.") + } + lrs.finalSendDone <- finalSendErr + return } - if err := lrs.sendLoadStatsRequest(stream, lrs.lrsStore.Stats(clusterNames)); err != nil { - lrs.logger.Warningf("Writing to LRS stream failed: %v", err) + + if err := lrs.sendLoadStatsRequest(stream, lrs.loadStore.stats(clusterNames)); err != nil { + lrs.logger.Warningf("Failed to send periodic load report. Writing to LRS stream failed: %v", err) return } } } -func (lrs *StreamImpl) sendFirstLoadStatsRequest(stream transport.StreamingCall, node *v3corepb.Node) error { +func (lrs *streamImpl) sendFirstLoadStatsRequest(stream clients.Stream, node *v3corepb.Node) error { req := &v3lrspb.LoadStatsRequest{Node: node} if lrs.logger.V(perRPCVerbosityLevel) { lrs.logger.Infof("Sending initial LoadStatsRequest: %s", pretty.ToJSON(req)) } - err := stream.Send(req) + msg, err := proto.Marshal(req) + if err != nil { + lrs.logger.Warningf("Failed to marshal LoadStatsRequest: %v", err) + return err + } + err = stream.Send(msg) if err == io.EOF { return getStreamError(stream) } @@ -228,24 +200,27 @@ func (lrs *StreamImpl) sendFirstLoadStatsRequest(stream transport.StreamingCall, // server requested for load from all clusters // - the load reporting interval, and // - any error encountered -func (lrs *StreamImpl) recvFirstLoadStatsResponse(stream transport.StreamingCall) ([]string, time.Duration, error) { +func (lrs *streamImpl) recvFirstLoadStatsResponse(stream clients.Stream) ([]string, time.Duration, error) { r, err := stream.Recv() if err != nil { return nil, 0, fmt.Errorf("lrs: failed to receive first LoadStatsResponse: %v", err) } - resp, ok := r.(*v3lrspb.LoadStatsResponse) - if !ok { + var resp v3lrspb.LoadStatsResponse + if err := proto.Unmarshal(r, &resp); err != nil { + if lrs.logger.V(2) { + lrs.logger.Infof("Failed to unmarshal response to LoadStatsResponse: %v", err) + } return nil, time.Duration(0), fmt.Errorf("lrs: unexpected message type %T", r) } if lrs.logger.V(perRPCVerbosityLevel) { - lrs.logger.Infof("Received first LoadStatsResponse: %s", pretty.ToJSON(resp)) + lrs.logger.Infof("Received first LoadStatsResponse: %s", pretty.ToJSON(&resp)) } - interval := resp.GetLoadReportingInterval() - if err := interval.CheckValid(); err != nil { + internal := resp.GetLoadReportingInterval() + if internal.CheckValid() != nil { return nil, 0, fmt.Errorf("lrs: invalid load_reporting_interval: %v", err) } - loadReportingInterval := interval.AsDuration() + loadReportingInterval := internal.AsDuration() clusters := resp.Clusters if resp.SendAllClusters { @@ -256,28 +231,24 @@ func (lrs *StreamImpl) recvFirstLoadStatsResponse(stream transport.StreamingCall return clusters, loadReportingInterval, nil } -func (lrs *StreamImpl) sendLoadStatsRequest(stream transport.StreamingCall, loads []*load.Data) error { +func (lrs *streamImpl) sendLoadStatsRequest(stream clients.Stream, loads []*loadData) error { clusterStats := make([]*v3endpointpb.ClusterStats, 0, len(loads)) for _, sd := range loads { - droppedReqs := make([]*v3endpointpb.ClusterStats_DroppedRequests, 0, len(sd.Drops)) - for category, count := range sd.Drops { + droppedReqs := make([]*v3endpointpb.ClusterStats_DroppedRequests, 0, len(sd.drops)) + for category, count := range sd.drops { droppedReqs = append(droppedReqs, &v3endpointpb.ClusterStats_DroppedRequests{ Category: category, DroppedCount: count, }) } - localityStats := make([]*v3endpointpb.UpstreamLocalityStats, 0, len(sd.LocalityStats)) - for l, localityData := range sd.LocalityStats { - lid, err := internal.LocalityIDFromString(l) - if err != nil { - return err - } - loadMetricStats := make([]*v3endpointpb.EndpointLoadMetricStats, 0, len(localityData.LoadStats)) - for name, loadData := range localityData.LoadStats { + localityStats := make([]*v3endpointpb.UpstreamLocalityStats, 0, len(sd.localityStats)) + for lid, localityData := range sd.localityStats { + loadMetricStats := make([]*v3endpointpb.EndpointLoadMetricStats, 0, len(localityData.loadStats)) + for name, loadData := range localityData.loadStats { loadMetricStats = append(loadMetricStats, &v3endpointpb.EndpointLoadMetricStats{ MetricName: name, - NumRequestsFinishedWithMetric: loadData.Count, - TotalMetricValue: loadData.Sum, + NumRequestsFinishedWithMetric: loadData.count, + TotalMetricValue: loadData.sum, }) } localityStats = append(localityStats, &v3endpointpb.UpstreamLocalityStats{ @@ -286,22 +257,22 @@ func (lrs *StreamImpl) sendLoadStatsRequest(stream transport.StreamingCall, load Zone: lid.Zone, SubZone: lid.SubZone, }, - TotalSuccessfulRequests: localityData.RequestStats.Succeeded, - TotalRequestsInProgress: localityData.RequestStats.InProgress, - TotalErrorRequests: localityData.RequestStats.Errored, - TotalIssuedRequests: localityData.RequestStats.Issued, + TotalSuccessfulRequests: localityData.requestStats.succeeded, + TotalRequestsInProgress: localityData.requestStats.inProgress, + TotalErrorRequests: localityData.requestStats.errored, + TotalIssuedRequests: localityData.requestStats.issued, LoadMetricStats: loadMetricStats, UpstreamEndpointStats: nil, // TODO: populate for per endpoint loads. }) } clusterStats = append(clusterStats, &v3endpointpb.ClusterStats{ - ClusterName: sd.Cluster, - ClusterServiceName: sd.Service, + ClusterName: sd.cluster, + ClusterServiceName: sd.service, UpstreamLocalityStats: localityStats, - TotalDroppedRequests: sd.TotalDrops, + TotalDroppedRequests: sd.totalDrops, DroppedRequests: droppedReqs, - LoadReportInterval: durationpb.New(sd.ReportInterval), + LoadReportInterval: durationpb.New(sd.reportInterval), }) } @@ -309,31 +280,24 @@ func (lrs *StreamImpl) sendLoadStatsRequest(stream transport.StreamingCall, load if lrs.logger.V(perRPCVerbosityLevel) { lrs.logger.Infof("Sending LRS loads: %s", pretty.ToJSON(req)) } - err := stream.Send(req) + msg, err := proto.Marshal(req) + if err != nil { + if lrs.logger.V(2) { + lrs.logger.Infof("Failed to marshal LoadStatsRequest: %v", err) + } + return err + } + err = stream.Send(msg) if err == io.EOF { return getStreamError(stream) } return err } -func getStreamError(stream transport.StreamingCall) error { +func getStreamError(stream clients.Stream) error { for { if _, err := stream.Recv(); err != nil { return err } } } - -// Stop blocks until the stream is closed and all spawned goroutines exit. -func (lrs *StreamImpl) Stop() { - lrs.mu.Lock() - defer lrs.mu.Unlock() - - if lrs.cancelStream == nil { - return - } - lrs.cancelStream() - lrs.cancelStream = nil - lrs.logger.Infof("Stopping LRS stream") - <-lrs.doneCh -} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsclient.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsclient.go new file mode 100644 index 0000000000..af163e2201 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsclient.go @@ -0,0 +1,183 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package lrsclient provides an LRS (Load Reporting Service) client. +// +// See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/load_stats/v3/lrs.proto +package lrsclient + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "google.golang.org/grpc/grpclog" + igrpclog "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/xds/internal/clients" + clientsinternal "google.golang.org/grpc/xds/internal/clients/internal" + "google.golang.org/grpc/xds/internal/clients/internal/backoff" +) + +const ( + clientFeatureNoOverprovisioning = "envoy.lb.does_not_support_overprovisioning" + clientFeatureResourceWrapper = "xds.config.resource-in-sotw" +) + +var ( + defaultExponentialBackoff = backoff.DefaultExponential.Backoff +) + +// LRSClient is an LRS (Load Reporting Service) client. +type LRSClient struct { + transportBuilder clients.TransportBuilder + node clients.Node + backoff func(int) time.Duration // Backoff for LRS stream failures. + logger *igrpclog.PrefixLogger + + // The LRSClient owns a bunch of streams to individual LRS servers. + // + // Once all references to a stream are dropped, the stream is closed. + mu sync.Mutex + lrsStreams map[clients.ServerIdentifier]*streamImpl // Map from server config to in-use streamImpls. + lrsRefs map[clients.ServerIdentifier]int // Map from server config to number of references. +} + +// New returns a new LRS Client configured with the provided config. +func New(config Config) (*LRSClient, error) { + switch { + case config.Node.ID == "": + return nil, errors.New("lrsclient: node ID in node is empty") + case config.TransportBuilder == nil: + return nil, errors.New("lrsclient: transport builder is nil") + } + + c := &LRSClient{ + transportBuilder: config.TransportBuilder, + node: config.Node, + backoff: defaultExponentialBackoff, + lrsStreams: make(map[clients.ServerIdentifier]*streamImpl), + lrsRefs: make(map[clients.ServerIdentifier]int), + } + c.logger = prefixLogger(c) + return c, nil +} + +// ReportLoad creates and returns a LoadStore for the caller to report loads +// using a LoadReportingStream. +// +// Caller must call Stop on the returned LoadStore when they are done reporting +// load to this server. +func (c *LRSClient) ReportLoad(si clients.ServerIdentifier) (*LoadStore, error) { + lrs, err := c.getOrCreateLRSStream(si) + if err != nil { + return nil, err + } + return lrs.loadStore, nil +} + +// getOrCreateLRSStream returns an lrs stream for the given server identifier. +// +// If an active lrs stream exists for the given server identifier, it is +// returned. Otherwise, a new lrs stream is created and returned. +func (c *LRSClient) getOrCreateLRSStream(serverIdentifier clients.ServerIdentifier) (*streamImpl, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.logger.V(2) { + c.logger.Infof("Received request for a reference to an lrs stream for server identifier %q", serverIdentifier) + } + + // Use an existing stream, if one exists for this server identifier. + if s, ok := c.lrsStreams[serverIdentifier]; ok { + if c.logger.V(2) { + c.logger.Infof("Reusing an existing lrs stream for server identifier %q", serverIdentifier) + } + c.lrsRefs[serverIdentifier]++ + return s, nil + } + + if c.logger.V(2) { + c.logger.Infof("Creating a new lrs stream for server identifier %q", serverIdentifier) + } + + l := grpclog.Component("xds") + logPrefix := clientPrefix(c) + c.logger = igrpclog.NewPrefixLogger(l, logPrefix) + + // Create a new transport and create a new lrs stream, and add it to the + // map of lrs streams. + tr, err := c.transportBuilder.Build(serverIdentifier) + if err != nil { + return nil, fmt.Errorf("lrsclient: failed to create transport for server identifier %s: %v", serverIdentifier, err) + } + + nodeProto := clientsinternal.NodeProto(c.node) + nodeProto.ClientFeatures = []string{clientFeatureNoOverprovisioning, clientFeatureResourceWrapper} + lrs := newStreamImpl(streamOpts{ + transport: tr, + backoff: c.backoff, + nodeProto: nodeProto, + logPrefix: logPrefix, + }) + + // Register a stop function that decrements the reference count, stops + // the LRS stream when the last reference is removed and closes the + // transport and removes the lrs stream and its references from the + // respective maps. Before closing the stream, it waits for the provided + // context to be done (timeout or cancellation). + stop := func(ctx context.Context) { + c.mu.Lock() + defer c.mu.Unlock() + + if r, ok := c.lrsRefs[serverIdentifier]; !ok || r == 0 { + c.logger.Errorf("Attempting to stop already stopped StreamImpl") + return + } + c.lrsRefs[serverIdentifier]-- + if c.lrsRefs[serverIdentifier] != 0 { + return + } + + lrs.finalSendRequest <- struct{}{} + + select { + case err := <-lrs.finalSendDone: + if err != nil { + c.logger.Warningf("Final send attempt failed: %v", err) + } + case <-ctx.Done(): + c.logger.Warningf("Context canceled before finishing the final send attempt: %v", err) + } + + lrs.cancelStream() + lrs.cancelStream = nil + lrs.logger.Infof("Stopping LRS stream") + <-lrs.doneCh + + delete(c.lrsStreams, serverIdentifier) + tr.Close() + } + lrs.loadStore.stop = stop + + c.lrsStreams[serverIdentifier] = lrs + c.lrsRefs[serverIdentifier] = 1 + + return lrs, nil +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsconfig.go b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsconfig.go new file mode 100644 index 0000000000..c4862ff767 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/lrsclient/lrsconfig.go @@ -0,0 +1,35 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package lrsclient + +import ( + "google.golang.org/grpc/xds/internal/clients" +) + +// Config is used to configure an LRS client. After one has been passed to the +// LRS client's New function, no part of it may modified. A Config may be +// reused; the lrsclient package will also not modify it. +type Config struct { + // Node is the identity of the client application reporting load to the + // LRS server. + Node clients.Node + + // TransportBuilder is used to connect to the LRS server. + TransportBuilder clients.TransportBuilder +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/transport_builder.go b/vendor/google.golang.org/grpc/xds/internal/clients/transport_builder.go new file mode 100644 index 0000000000..f940675d91 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/transport_builder.go @@ -0,0 +1,53 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package clients + +import ( + "context" +) + +// TransportBuilder provides the functionality to create a communication +// channel to an xDS or LRS server. +type TransportBuilder interface { + // Build creates a new Transport instance to the server based on the + // provided ServerIdentifier. + Build(serverIdentifier ServerIdentifier) (Transport, error) +} + +// Transport provides the functionality to communicate with an xDS or LRS +// server using streaming calls. +type Transport interface { + // NewStream creates a new streaming call to the server for the specific + // RPC method name. The returned Stream interface can be used to send and + // receive messages on the stream. + NewStream(context.Context, string) (Stream, error) + + // Close closes the Transport. + Close() +} + +// Stream provides methods to send and receive messages on a stream. Messages +// are represented as a byte slice. +type Stream interface { + // Send sends the provided message on the stream. + Send([]byte) error + + // Recv blocks until the next message is received on the stream. + Recv() ([]byte, error) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/ads/ads_stream.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/ads_stream.go similarity index 68% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/ads/ads_stream.go rename to vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/ads_stream.go index fc41b38eda..774f8ab24e 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/ads/ads_stream.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/ads_stream.go @@ -1,6 +1,6 @@ /* * - * Copyright 2024 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,10 @@ * 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 ads provides the implementation of an ADS (Aggregated Discovery -// Service) stream for the xDS client. -package ads +package xdsclient import ( "context" @@ -26,95 +25,73 @@ import ( "sync/atomic" "time" - "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal/backoff" - "google.golang.org/grpc/internal/buffer" igrpclog "google.golang.org/grpc/internal/grpclog" - "google.golang.org/grpc/internal/pretty" - "google.golang.org/grpc/xds/internal/xdsclient/transport" - "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/internal/backoff" + "google.golang.org/grpc/xds/internal/clients/internal/buffer" + "google.golang.org/grpc/xds/internal/clients/internal/pretty" + "google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource" + + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" v3discoverypb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + cpb "google.golang.org/genproto/googleapis/rpc/code" statuspb "google.golang.org/genproto/googleapis/rpc/status" ) -// Any per-RPC level logs which print complete request or response messages -// should be gated at this verbosity level. Other per-RPC level logs which print -// terse output should be at `INFO` and verbosity 2. -const perRPCVerbosityLevel = 9 +const ( + // Any per-RPC level logs which print complete request or response messages + // should be gated at this verbosity level. Other per-RPC level logs which print + // terse output should be at `INFO` and verbosity 2. + perRPCVerbosityLevel = 9 +) -// Response represents a response received on the ADS stream. It contains the +// response represents a response received on the ADS stream. It contains the // type URL, version, and resources for the response. -type Response struct { - TypeURL string - Version string - Resources []*anypb.Any +type response struct { + typeURL string + version string + resources []*anypb.Any } -// DataAndErrTuple is a struct that holds a resource and an error. It is used to +// dataAndErrTuple is a struct that holds a resource and an error. It is used to // return a resource and any associated error from a function. -type DataAndErrTuple struct { - Resource xdsresource.ResourceData +type dataAndErrTuple struct { + Resource ResourceData Err error } -// StreamEventHandler is an interface that defines the callbacks for events that +// adsStreamEventHandler is an interface that defines the callbacks for events that // occur on the ADS stream. Methods on this interface may be invoked // concurrently and implementations need to handle them in a thread-safe manner. -type StreamEventHandler interface { - OnADSStreamError(error) // Called when the ADS stream breaks. - OnADSWatchExpiry(xdsresource.Type, string) // Called when the watch timer expires for a resource. - OnADSResponse(Response, func()) ([]string, error) // Called when a response is received on the ADS stream. +type adsStreamEventHandler interface { + onStreamError(error) // Called when the ADS stream breaks. + onWatchExpiry(ResourceType, string) // Called when the watch timer expires for a resource. + onResponse(response, func()) ([]string, error) // Called when a response is received on the ADS stream. } -// WatchState is a enum that describes the watch state of a particular -// resource. -type WatchState int - -const ( - // ResourceWatchStateStarted is the state where a watch for a resource was - // started, but a request asking for that resource is yet to be sent to the - // management server. - ResourceWatchStateStarted WatchState = iota - // ResourceWatchStateRequested is the state when a request has been sent for - // the resource being watched. - ResourceWatchStateRequested - // ResourceWatchStateReceived is the state when a response has been received - // for the resource being watched. - ResourceWatchStateReceived - // ResourceWatchStateTimeout is the state when the watch timer associated - // with the resource expired because no response was received. - ResourceWatchStateTimeout -) - -// ResourceWatchState is the state corresponding to a resource being watched. -type ResourceWatchState struct { - State WatchState // Watch state of the resource. - ExpiryTimer *time.Timer // Timer for the expiry of the watch. -} - -// State corresponding to a resource type. +// state corresponding to a resource type. type resourceTypeState struct { - version string // Last acked version. Should not be reset when the stream breaks. - nonce string // Last received nonce. Should be reset when the stream breaks. - bufferedRequests chan struct{} // Channel to buffer requests when writing is blocked. - subscribedResources map[string]*ResourceWatchState // Map of subscribed resource names to their state. - pendingWrite bool // True if there is a pending write for this resource type. + version string // Last acked version. Should not be reset when the stream breaks. + nonce string // Last received nonce. Should be reset when the stream breaks. + bufferedRequests chan struct{} // Channel to buffer requests when writing is blocked. + subscribedResources map[string]*xdsresource.ResourceWatchState // Map of subscribed resource names to their state. + pendingWrite bool // True if there is a pending write for this resource type. } -// StreamImpl provides the functionality associated with an ADS (Aggregated +// adsStreamImpl provides the functionality associated with an ADS (Aggregated // Discovery Service) stream on the client side. It manages the lifecycle of the // ADS stream, including creating the stream, sending requests, and handling // responses. It also handles flow control and retries for the stream. -type StreamImpl struct { +type adsStreamImpl struct { // The following fields are initialized from arguments passed to the // constructor and are read-only afterwards, and hence can be accessed // without a mutex. - transport transport.Transport // Transport to use for ADS stream. - eventHandler StreamEventHandler // Callbacks into the xdsChannel. + transport clients.Transport // Transport to use for ADS stream. + eventHandler adsStreamEventHandler // Callbacks into the xdsChannel. backoff func(int) time.Duration // Backoff for retries, after stream failures. nodeProto *v3corepb.Node // Identifies the gRPC application. watchExpiryTimeout time.Duration // Resource watch expiry timeout @@ -122,47 +99,47 @@ type StreamImpl struct { // The following fields are initialized in the constructor and are not // written to afterwards, and hence can be accessed without a mutex. - streamCh chan transport.StreamingCall // New ADS streams are pushed here. - requestCh *buffer.Unbounded // Subscriptions and unsubscriptions are pushed here. - runnerDoneCh chan struct{} // Notify completion of runner goroutine. - cancel context.CancelFunc // To cancel the context passed to the runner goroutine. + streamCh chan clients.Stream // New ADS streams are pushed here. + requestCh *buffer.Unbounded // Subscriptions and unsubscriptions are pushed here. + runnerDoneCh chan struct{} // Notify completion of runner goroutine. + cancel context.CancelFunc // To cancel the context passed to the runner goroutine. // Guards access to the below fields (and to the contents of the map). mu sync.Mutex - resourceTypeState map[xdsresource.Type]*resourceTypeState // Map of resource types to their state. - fc *adsFlowControl // Flow control for ADS stream. - firstRequest bool // False after the first request is sent out. + resourceTypeState map[ResourceType]*resourceTypeState // Map of resource types to their state. + fc *adsFlowControl // Flow control for ADS stream. + firstRequest bool // False after the first request is sent out. } -// StreamOpts contains the options for creating a new ADS Stream. -type StreamOpts struct { - Transport transport.Transport // xDS transport to create the stream on. - EventHandler StreamEventHandler // Callbacks for stream events. - Backoff func(int) time.Duration // Backoff for retries, after stream failures. - NodeProto *v3corepb.Node // Node proto to identify the gRPC application. - WatchExpiryTimeout time.Duration // Resource watch expiry timeout. - LogPrefix string // Prefix to be used for log messages. +// adsStreamOpts contains the options for creating a new ADS Stream. +type adsStreamOpts struct { + transport clients.Transport // xDS transport to create the stream on. + eventHandler adsStreamEventHandler // Callbacks for stream events. + backoff func(int) time.Duration // Backoff for retries, after stream failures. + nodeProto *v3corepb.Node // Node proto to identify the gRPC application. + watchExpiryTimeout time.Duration // Resource watch expiry timeout. + logPrefix string // Prefix to be used for log messages. } -// NewStreamImpl initializes a new StreamImpl instance using the given +// newADSStreamImpl initializes a new adsStreamImpl instance using the given // parameters. It also launches goroutines responsible for managing reads and // writes for messages of the underlying stream. -func NewStreamImpl(opts StreamOpts) *StreamImpl { - s := &StreamImpl{ - transport: opts.Transport, - eventHandler: opts.EventHandler, - backoff: opts.Backoff, - nodeProto: opts.NodeProto, - watchExpiryTimeout: opts.WatchExpiryTimeout, - - streamCh: make(chan transport.StreamingCall, 1), +func newADSStreamImpl(opts adsStreamOpts) *adsStreamImpl { + s := &adsStreamImpl{ + transport: opts.transport, + eventHandler: opts.eventHandler, + backoff: opts.backoff, + nodeProto: opts.nodeProto, + watchExpiryTimeout: opts.watchExpiryTimeout, + + streamCh: make(chan clients.Stream, 1), requestCh: buffer.NewUnbounded(), runnerDoneCh: make(chan struct{}), - resourceTypeState: make(map[xdsresource.Type]*resourceTypeState), + resourceTypeState: make(map[ResourceType]*resourceTypeState), } l := grpclog.Component("xds") - s.logger = igrpclog.NewPrefixLogger(l, opts.LogPrefix+fmt.Sprintf("[ads-stream %p] ", s)) + s.logger = igrpclog.NewPrefixLogger(l, opts.logPrefix+fmt.Sprintf("[ads-stream %p] ", s)) ctx, cancel := context.WithCancel(context.Background()) s.cancel = cancel @@ -171,20 +148,20 @@ func NewStreamImpl(opts StreamOpts) *StreamImpl { } // Stop blocks until the stream is closed and all spawned goroutines exit. -func (s *StreamImpl) Stop() { +func (s *adsStreamImpl) Stop() { s.cancel() s.requestCh.Close() <-s.runnerDoneCh - s.logger.Infof("Stopping ADS stream") + s.logger.Infof("Shutdown ADS stream") } -// Subscribe subscribes to the given resource. It is assumed that multiple +// subscribe subscribes to the given resource. It is assumed that multiple // subscriptions for the same resource is deduped at the caller. A discovery // request is sent out on the underlying stream for the resource type when there // is sufficient flow control quota. -func (s *StreamImpl) Subscribe(typ xdsresource.Type, name string) { +func (s *adsStreamImpl) subscribe(typ ResourceType, name string) { if s.logger.V(2) { - s.logger.Infof("Subscribing to resource %q of type %q", name, typ.TypeName()) + s.logger.Infof("Subscribing to resource %q of type %q", name, typ.TypeName) } s.mu.Lock() @@ -195,7 +172,7 @@ func (s *StreamImpl) Subscribe(typ xdsresource.Type, name string) { // An entry in the type state map is created as part of the first // subscription request for this type. state = &resourceTypeState{ - subscribedResources: make(map[string]*ResourceWatchState), + subscribedResources: make(map[string]*xdsresource.ResourceWatchState), bufferedRequests: make(chan struct{}, 1), } s.resourceTypeState[typ] = state @@ -203,7 +180,7 @@ func (s *StreamImpl) Subscribe(typ xdsresource.Type, name string) { // Create state for the newly subscribed resource. The watch timer will // be started when a request for this resource is actually sent out. - state.subscribedResources[name] = &ResourceWatchState{State: ResourceWatchStateStarted} + state.subscribedResources[name] = &xdsresource.ResourceWatchState{State: xdsresource.ResourceWatchStateStarted} state.pendingWrite = true // Send a request for the resource type with updated subscriptions. @@ -214,9 +191,9 @@ func (s *StreamImpl) Subscribe(typ xdsresource.Type, name string) { // the given resource does not exist. The watch expiry timer associated with the // resource is stopped if one is active. A discovery request is sent out on the // stream for the resource type when there is sufficient flow control quota. -func (s *StreamImpl) Unsubscribe(typ xdsresource.Type, name string) { +func (s *adsStreamImpl) Unsubscribe(typ ResourceType, name string) { if s.logger.V(2) { - s.logger.Infof("Unsubscribing to resource %q of type %q", name, typ.TypeName()) + s.logger.Infof("Unsubscribing to resource %q of type %q", name, typ.TypeName) } s.mu.Lock() @@ -246,13 +223,13 @@ func (s *StreamImpl) Unsubscribe(typ xdsresource.Type, name string) { // messages on the stream. Whenever an existing stream fails, it performs // exponential backoff (if no messages were received on that stream) before // creating a new stream. -func (s *StreamImpl) runner(ctx context.Context) { +func (s *adsStreamImpl) runner(ctx context.Context) { defer close(s.runnerDoneCh) go s.send(ctx) runStreamWithBackoff := func() error { - stream, err := s.transport.CreateStreamingCall(ctx, "/envoy.service.discovery.v3.AggregatedDiscoveryService/StreamAggregatedResources") + stream, err := s.transport.NewStream(ctx, "/envoy.service.discovery.v3.AggregatedDiscoveryService/StreamAggregatedResources") if err != nil { s.logger.Warningf("Failed to create a new ADS streaming RPC: %v", err) s.onError(err, false) @@ -291,9 +268,9 @@ func (s *StreamImpl) runner(ctx context.Context) { // two scenarios: // - a new subscription or unsubscription request is received // - a new stream is created after the previous one failed -func (s *StreamImpl) send(ctx context.Context) { +func (s *adsStreamImpl) send(ctx context.Context) { // Stores the most recent stream instance received on streamCh. - var stream transport.StreamingCall + var stream clients.Stream for { select { case <-ctx.Done(): @@ -311,7 +288,7 @@ func (s *StreamImpl) send(ctx context.Context) { } s.requestCh.Load() - typ := req.(xdsresource.Type) + typ := req.(ResourceType) if err := s.sendNew(stream, typ); err != nil { stream = nil continue @@ -325,7 +302,7 @@ func (s *StreamImpl) send(ctx context.Context) { // and will be sent later. This method also starts the watch expiry timer for // resources that were sent in the request for the first time, i.e. their watch // state is `watchStateStarted`. -func (s *StreamImpl) sendNew(stream transport.StreamingCall, typ xdsresource.Type) error { +func (s *adsStreamImpl) sendNew(stream clients.Stream, typ ResourceType) error { s.mu.Lock() defer s.mu.Unlock() @@ -356,7 +333,7 @@ func (s *StreamImpl) sendNew(stream transport.StreamingCall, typ xdsresource.Typ // recovering from a broken stream. // // The stream argument is guaranteed to be non-nil. -func (s *StreamImpl) sendExisting(stream transport.StreamingCall) error { +func (s *adsStreamImpl) sendExisting(stream clients.Stream) error { s.mu.Lock() defer s.mu.Unlock() @@ -391,7 +368,7 @@ func (s *StreamImpl) sendExisting(stream transport.StreamingCall) error { // received response was not yet complete. // // The stream argument is guaranteed to be non-nil. -func (s *StreamImpl) sendBuffered(stream transport.StreamingCall) error { +func (s *adsStreamImpl) sendBuffered(stream clients.Stream) error { s.mu.Lock() defer s.mu.Unlock() @@ -416,16 +393,16 @@ func (s *StreamImpl) sendBuffered(stream transport.StreamingCall) error { // watch timers are started for the resources in the request. // // Caller needs to hold c.mu. -func (s *StreamImpl) sendMessageIfWritePendingLocked(stream transport.StreamingCall, typ xdsresource.Type, state *resourceTypeState) error { +func (s *adsStreamImpl) sendMessageIfWritePendingLocked(stream clients.Stream, typ ResourceType, state *resourceTypeState) error { if !state.pendingWrite { if s.logger.V(2) { - s.logger.Infof("Skipping sending request for type %q, because all subscribed resources were already sent", typ.TypeURL()) + s.logger.Infof("Skipping sending request for type %q, because all subscribed resources were already sent", typ.TypeURL) } return nil } names := resourceNames(state.subscribedResources) - if err := s.sendMessageLocked(stream, names, typ.TypeURL(), state.version, state.nonce, nil); err != nil { + if err := s.sendMessageLocked(stream, names, typ.TypeURL, state.version, state.nonce, nil); err != nil { return err } state.pendingWrite = false @@ -446,7 +423,7 @@ func (s *StreamImpl) sendMessageIfWritePendingLocked(stream transport.StreamingC // error if the request could not be sent. // // Caller needs to hold c.mu. -func (s *StreamImpl) sendMessageLocked(stream transport.StreamingCall, names []string, url, version, nonce string, nackErr error) error { +func (s *adsStreamImpl) sendMessageLocked(stream clients.Stream, names []string, url, version, nonce string, nackErr error) error { req := &v3discoverypb.DiscoveryRequest{ ResourceNames: names, TypeUrl: url, @@ -463,11 +440,16 @@ func (s *StreamImpl) sendMessageLocked(stream transport.StreamingCall, names []s if nackErr != nil { req.ErrorDetail = &statuspb.Status{ - Code: int32(codes.InvalidArgument), Message: nackErr.Error(), + Code: int32(cpb.Code_INVALID_ARGUMENT), Message: nackErr.Error(), } } - if err := stream.Send(req); err != nil { + msg, err := proto.Marshal(req) + if err != nil { + s.logger.Warningf("Failed to marshal DiscoveryRequest: %v", err) + return err + } + if err := stream.Send(msg); err != nil { s.logger.Warningf("Sending ADS request for type %q, resources: %v, version: %q, nonce: %q failed: %v", url, names, version, nonce, err) return err } @@ -494,7 +476,7 @@ func (s *StreamImpl) sendMessageLocked(stream transport.StreamingCall, names []s // // It returns a boolean indicating whether at least one message was received // from the server. -func (s *StreamImpl) recv(ctx context.Context, stream transport.StreamingCall) bool { +func (s *adsStreamImpl) recv(ctx context.Context, stream clients.Stream) bool { msgReceived := false for { // Wait for ADS stream level flow control to be available, and send out @@ -518,20 +500,20 @@ func (s *StreamImpl) recv(ctx context.Context, stream transport.StreamingCall) b // Invoke the onResponse event handler to parse the incoming message and // decide whether to send an ACK or NACK. - resp := Response{ - Resources: resources, - TypeURL: url, - Version: version, + resp := response{ + resources: resources, + typeURL: url, + version: version, } var resourceNames []string var nackErr error s.fc.setPending() - resourceNames, nackErr = s.eventHandler.OnADSResponse(resp, s.fc.onDone) + resourceNames, nackErr = s.eventHandler.onResponse(resp, s.fc.onDone) if xdsresource.ErrType(nackErr) == xdsresource.ErrorTypeResourceTypeUnsupported { - // Based on gRFC A27, a general guiding principle is that if the - // server sends something the client didn't actually subscribe to, - // then the client ignores it. Here, we have received a response - // with resources of a type that we don't know about. + // A general guiding principle is that if the server sends + // something the client didn't actually subscribe to, then the + // client ignores it. Here, we have received a response with + // resources of a type that we don't know about. // // Sending a NACK doesn't really seem appropriate here, since we're // not actually validating what the server sent and therefore don't @@ -545,19 +527,18 @@ func (s *StreamImpl) recv(ctx context.Context, stream transport.StreamingCall) b } } -func (s *StreamImpl) recvMessage(stream transport.StreamingCall) (resources []*anypb.Any, url, version, nonce string, err error) { +func (s *adsStreamImpl) recvMessage(stream clients.Stream) (resources []*anypb.Any, url, version, nonce string, err error) { r, err := stream.Recv() if err != nil { return nil, "", "", "", err } - resp, ok := r.(*v3discoverypb.DiscoveryResponse) - if !ok { - s.logger.Infof("Message received on ADS stream of unexpected type: %T", r) + var resp v3discoverypb.DiscoveryResponse + if err := proto.Unmarshal(r, &resp); err != nil { + s.logger.Infof("Failed to unmarshal response to DiscoveryResponse: %v", err) return nil, "", "", "", fmt.Errorf("unexpected message type %T", r) } - if s.logger.V(perRPCVerbosityLevel) { - s.logger.Infof("ADS response received: %v", pretty.ToJSON(resp)) + s.logger.Infof("ADS response received: %v", pretty.ToJSON(&resp)) } else if s.logger.V(2) { s.logger.Infof("ADS response received for type %q, version %q, nonce %q", resp.GetTypeUrl(), resp.GetVersionInfo(), resp.GetNonce()) } @@ -571,14 +552,14 @@ func (s *StreamImpl) recvMessage(stream transport.StreamingCall) (resources []*a // - updates resource type specific state // - updates resource specific state for resources in the response // - sends an ACK or NACK to the server based on the response -func (s *StreamImpl) onRecv(stream transport.StreamingCall, names []string, url, version, nonce string, nackErr error) { +func (s *adsStreamImpl) onRecv(stream clients.Stream, names []string, url, version, nonce string, nackErr error) { s.mu.Lock() defer s.mu.Unlock() // Lookup the resource type specific state based on the type URL. - var typ xdsresource.Type + var typ ResourceType for t := range s.resourceTypeState { - if t.TypeURL() == url { + if t.TypeURL == url { typ = t break } @@ -609,8 +590,8 @@ func (s *StreamImpl) onRecv(stream transport.StreamingCall, names []string, url, s.logger.Warningf("ADS stream received a response for resource %q, but no state exists for it", name) continue } - if ws := rs.State; ws == ResourceWatchStateStarted || ws == ResourceWatchStateRequested { - rs.State = ResourceWatchStateReceived + if ws := rs.State; ws == xdsresource.ResourceWatchStateStarted || ws == xdsresource.ResourceWatchStateRequested { + rs.State = xdsresource.ResourceWatchStateReceived if rs.ExpiryTimer != nil { rs.ExpiryTimer.Stop() rs.ExpiryTimer = nil @@ -637,7 +618,7 @@ func (s *StreamImpl) onRecv(stream transport.StreamingCall, names []string, url, // resources that were in the requested state. It also handles the case where // the ADS stream was closed after receiving a response, which is not // considered an error. -func (s *StreamImpl) onError(err error, msgReceived bool) { +func (s *adsStreamImpl) onError(err error, msgReceived bool) { // For resources that been requested but not yet responded to by the // management server, stop the resource timers and reset the watch state to // watchStateStarted. This is because we don't want the expiry timer to be @@ -645,14 +626,14 @@ func (s *StreamImpl) onError(err error, msgReceived bool) { s.mu.Lock() for _, state := range s.resourceTypeState { for _, rs := range state.subscribedResources { - if rs.State != ResourceWatchStateRequested { + if rs.State != xdsresource.ResourceWatchStateRequested { continue } if rs.ExpiryTimer != nil { rs.ExpiryTimer.Stop() rs.ExpiryTimer = nil } - rs.State = ResourceWatchStateStarted + rs.State = xdsresource.ResourceWatchStateStarted } } s.mu.Unlock() @@ -667,7 +648,7 @@ func (s *StreamImpl) onError(err error, msgReceived bool) { err = xdsresource.NewError(xdsresource.ErrTypeStreamFailedAfterRecv, err.Error()) } - s.eventHandler.OnADSStreamError(err) + s.eventHandler.onStreamError(err) } // startWatchTimersLocked starts the expiry timers for the given resource names @@ -677,84 +658,52 @@ func (s *StreamImpl) onError(err error, msgReceived bool) { // watch state is set to "timeout" and the event handler callback is called. // // The caller must hold the s.mu lock. -func (s *StreamImpl) startWatchTimersLocked(typ xdsresource.Type, names []string) { +func (s *adsStreamImpl) startWatchTimersLocked(typ ResourceType, names []string) { typeState := s.resourceTypeState[typ] for _, name := range names { resourceState, ok := typeState.subscribedResources[name] if !ok { continue } - if resourceState.State != ResourceWatchStateStarted { + if resourceState.State != xdsresource.ResourceWatchStateStarted { continue } - resourceState.State = ResourceWatchStateRequested + resourceState.State = xdsresource.ResourceWatchStateRequested rs := resourceState resourceState.ExpiryTimer = time.AfterFunc(s.watchExpiryTimeout, func() { s.mu.Lock() - rs.State = ResourceWatchStateTimeout + rs.State = xdsresource.ResourceWatchStateTimeout rs.ExpiryTimer = nil s.mu.Unlock() - s.eventHandler.OnADSWatchExpiry(typ, name) + s.eventHandler.onWatchExpiry(typ, name) }) } } -func resourceNames(m map[string]*ResourceWatchState) []string { - ret := make([]string, len(m)) - idx := 0 - for name := range m { - ret[idx] = name - idx++ - } - return ret -} - -// TriggerResourceNotFoundForTesting triggers a resource not found event for the -// given resource type and name. This is intended for testing purposes only, to -// simulate a resource not found scenario. -func (s *StreamImpl) TriggerResourceNotFoundForTesting(typ xdsresource.Type, resourceName string) { +func (s *adsStreamImpl) adsResourceWatchStateForTesting(rType ResourceType, resourceName string) (xdsresource.ResourceWatchState, error) { s.mu.Lock() + defer s.mu.Unlock() - state, ok := s.resourceTypeState[typ] + state, ok := s.resourceTypeState[rType] if !ok { - s.mu.Unlock() - return + return xdsresource.ResourceWatchState{}, fmt.Errorf("unknown resource type: %v", rType) } resourceState, ok := state.subscribedResources[resourceName] if !ok { - s.mu.Unlock() - return + return xdsresource.ResourceWatchState{}, fmt.Errorf("unknown resource name: %v", resourceName) } - - if s.logger.V(2) { - s.logger.Infof("Triggering resource not found for type: %s, resource name: %s", typ.TypeName(), resourceName) - } - resourceState.State = ResourceWatchStateTimeout - if resourceState.ExpiryTimer != nil { - resourceState.ExpiryTimer.Stop() - resourceState.ExpiryTimer = nil - } - s.mu.Unlock() - go s.eventHandler.OnADSWatchExpiry(typ, resourceName) + return *resourceState, nil } -// ResourceWatchStateForTesting returns the ResourceWatchState for the given -// resource type and name. This is intended for testing purposes only, to -// inspect the internal state of the ADS stream. -func (s *StreamImpl) ResourceWatchStateForTesting(typ xdsresource.Type, resourceName string) (ResourceWatchState, error) { - s.mu.Lock() - defer s.mu.Unlock() - - state, ok := s.resourceTypeState[typ] - if !ok { - return ResourceWatchState{}, fmt.Errorf("unknown resource type: %v", typ) - } - resourceState, ok := state.subscribedResources[resourceName] - if !ok { - return ResourceWatchState{}, fmt.Errorf("unknown resource name: %v", resourceName) +func resourceNames(m map[string]*xdsresource.ResourceWatchState) []string { + ret := make([]string, len(m)) + idx := 0 + for name := range m { + ret[idx] = name + idx++ } - return *resourceState, nil + return ret } // adsFlowControl implements ADS stream level flow control that enables the diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/authority.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/authority.go similarity index 87% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/authority.go rename to vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/authority.go index ec3a7352f9..7a3a296913 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/authority.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/authority.go @@ -1,6 +1,6 @@ /* * - * Copyright 2021 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * 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 xdsclient @@ -23,13 +24,12 @@ import ( "sync" "sync/atomic" - "google.golang.org/grpc/experimental/stats" "google.golang.org/grpc/grpclog" igrpclog "google.golang.org/grpc/internal/grpclog" - "google.golang.org/grpc/internal/grpcsync" - "google.golang.org/grpc/internal/xds/bootstrap" - "google.golang.org/grpc/xds/internal/xdsclient/transport/ads" - "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/internal/syncutil" + "google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource" + "google.golang.org/grpc/xds/internal/clients/xdsclient/metrics" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" @@ -38,11 +38,11 @@ import ( ) type resourceState struct { - watchers map[xdsresource.ResourceWatcher]bool // Set of watchers for this resource. - cache xdsresource.ResourceData // Most recent ACKed update for this resource. - md xdsresource.UpdateMetadata // Metadata for the most recent update. - deletionIgnored bool // True, if resource deletion was ignored for a prior update. - xdsChannelConfigs map[*xdsChannelWithConfig]bool // Set of xdsChannels where this resource is subscribed. + watchers map[ResourceWatcher]bool // Set of watchers for this resource. + cache ResourceData // Most recent ACKed update for this resource. + md xdsresource.UpdateMetadata // Metadata for the most recent update. + deletionIgnored bool // True, if resource deletion was ignored for a prior update. + xdsChannelConfigs map[*xdsChannelWithConfig]bool // Set of xdsChannels where this resource is subscribed. } // xdsChannelForADS is used to acquire a reference to an xdsChannel. This @@ -56,22 +56,22 @@ type resourceState struct { // Returns a reference to the xdsChannel and a function to release the same. A // non-nil error is returned if the channel creation fails and the first two // return values are meaningless in this case. -type xdsChannelForADS func(*bootstrap.ServerConfig, *authority) (*xdsChannel, func(), error) +type xdsChannelForADS func(*ServerConfig, *authority) (*xdsChannel, func(), error) // xdsChannelWithConfig is a struct that holds an xdsChannel and its associated // ServerConfig, along with a cleanup function to release the xdsChannel. type xdsChannelWithConfig struct { channel *xdsChannel - serverConfig *bootstrap.ServerConfig + serverConfig *ServerConfig cleanup func() } // authority provides the functionality required to communicate with a // management server corresponding to an authority name specified in the -// bootstrap configuration. +// xDS client configuration. // // It holds references to one or more xdsChannels, one for each server -// configuration in the bootstrap, to allow fallback from a primary management +// configuration in the config, to allow fallback from a primary management // server to a secondary management server. Authorities that contain similar // server configuration entries will end up sharing the xdsChannel for that // server configuration. The xdsChannels are owned and managed by the xdsClient. @@ -82,14 +82,14 @@ type xdsChannelWithConfig struct { type authority struct { // The following fields are initialized at creation time and are read-only // afterwards, and therefore don't need to be protected with a mutex. - name string // Name of the authority from bootstrap configuration. - watcherCallbackSerializer *grpcsync.CallbackSerializer // Serializer to run watcher callbacks, owned by the xDS client implementation. + name string // Name of the authority from xDS client configuration. + watcherCallbackSerializer *syncutil.CallbackSerializer // Serializer to run watcher callbacks, owned by the xDS client implementation. getChannelForADS xdsChannelForADS // Function to get an xdsChannel for ADS, provided by the xDS client implementation. - xdsClientSerializer *grpcsync.CallbackSerializer // Serializer to run call ins from the xDS client, owned by this authority. + xdsClientSerializer *syncutil.CallbackSerializer // Serializer to run call ins from the xDS client, owned by this authority. xdsClientSerializerClose func() // Function to close the above serializer. logger *igrpclog.PrefixLogger // Logger for this authority. target string // The gRPC Channel target. - metricsRecorder stats.MetricsRecorder // The metrics recorder used for emitting metrics. + metricsReporter clients.MetricsReporter // The below defined fields must only be accessed in the context of the // serializer callback, owned by this authority. @@ -102,10 +102,10 @@ type authority struct { // // The second level map key is the resource name, with the value being the // actual state of the resource. - resources map[xdsresource.Type]map[string]*resourceState + resources map[ResourceType]map[string]*resourceState // An ordered list of xdsChannels corresponding to the list of server - // configurations specified for this authority in the bootstrap. The + // configurations specified for this authority in the config. The // ordering specifies the order in which these channels are preferred for // fallback. xdsChannelConfigs []*xdsChannelWithConfig @@ -118,13 +118,13 @@ type authority struct { // authorityBuildOptions wraps arguments required to create a new authority. type authorityBuildOptions struct { - serverConfigs bootstrap.ServerConfigs // Server configs for the authority + serverConfigs []ServerConfig // Server configs for the authority name string // Name of the authority - serializer *grpcsync.CallbackSerializer // Callback serializer for invoking watch callbacks + serializer *syncutil.CallbackSerializer // Callback serializer for invoking watch callbacks getChannelForADS xdsChannelForADS // Function to acquire a reference to an xdsChannel logPrefix string // Prefix for logging target string // Target for the gRPC Channel that owns xDS Client/Authority - metricsRecorder stats.MetricsRecorder // metricsRecorder to emit metrics + metricsReporter clients.MetricsReporter // Metrics reporter for the authority } // newAuthority creates a new authority instance with the provided @@ -144,12 +144,12 @@ func newAuthority(args authorityBuildOptions) *authority { name: args.name, watcherCallbackSerializer: args.serializer, getChannelForADS: args.getChannelForADS, - xdsClientSerializer: grpcsync.NewCallbackSerializer(ctx), + xdsClientSerializer: syncutil.NewCallbackSerializer(ctx), xdsClientSerializerClose: cancel, logger: igrpclog.NewPrefixLogger(l, logPrefix), - resources: make(map[xdsresource.Type]map[string]*resourceState), + resources: make(map[ResourceType]map[string]*resourceState), target: args.target, - metricsRecorder: args.metricsRecorder, + metricsReporter: args.metricsReporter, } // Create an ordered list of xdsChannels with their server configs. The @@ -157,7 +157,7 @@ func newAuthority(args authorityBuildOptions) *authority { // first watch is registered, and channels to other server configurations // are created as needed to support fallback. for _, sc := range args.serverConfigs { - ret.xdsChannelConfigs = append(ret.xdsChannelConfigs, &xdsChannelWithConfig{serverConfig: sc}) + ret.xdsChannelConfigs = append(ret.xdsChannelConfigs, &xdsChannelWithConfig{serverConfig: &sc}) } return ret } @@ -170,7 +170,7 @@ func newAuthority(args authorityBuildOptions) *authority { // authorities) when a stream error is reported by an xdsChannel. // // Errors of type xdsresource.ErrTypeStreamFailedAfterRecv are ignored. -func (a *authority) adsStreamFailure(serverConfig *bootstrap.ServerConfig, err error) { +func (a *authority) adsStreamFailure(serverConfig *ServerConfig, err error) { a.xdsClientSerializer.TrySchedule(func(context.Context) { a.handleADSStreamFailure(serverConfig, err) }) @@ -180,7 +180,7 @@ func (a *authority) adsStreamFailure(serverConfig *bootstrap.ServerConfig, err e // fallback if the associated conditions are met. // // Only executed in the context of a serializer callback. -func (a *authority) handleADSStreamFailure(serverConfig *bootstrap.ServerConfig, err error) { +func (a *authority) handleADSStreamFailure(serverConfig *ServerConfig, err error) { if a.logger.V(2) { a.logger.Infof("Connection to server %s failed with error: %v", serverConfig, err) } @@ -255,9 +255,9 @@ func (a *authority) propagateConnectivityErrorToAllWatchers(err error) { // serverIndexForConfig returns the index of the xdsChannelConfig matching the // provided server config, panicking if no match is found (which indicates a // programming error). -func (a *authority) serverIndexForConfig(sc *bootstrap.ServerConfig) int { +func (a *authority) serverIndexForConfig(sc *ServerConfig) int { for i, cfg := range a.xdsChannelConfigs { - if cfg.serverConfig.Equal(sc) { + if isServerConfigEqual(sc, cfg.serverConfig) { return i } } @@ -294,7 +294,7 @@ func (a *authority) fallbackToServer(xc *xdsChannelWithConfig) bool { for typ, resources := range a.resources { for name, state := range resources { if a.logger.V(2) { - a.logger.Infof("Resubscribing to resource of type %q and name %q", typ.TypeName(), name) + a.logger.Infof("Resubscribing to resource of type %q and name %q", typ.TypeName, name) } xc.channel.subscribe(typ, name) @@ -313,7 +313,7 @@ func (a *authority) fallbackToServer(xc *xdsChannelWithConfig) bool { // // This method is called by the xDS client implementation (on all interested // authorities) when a stream error is reported by an xdsChannel. -func (a *authority) adsResourceUpdate(serverConfig *bootstrap.ServerConfig, rType xdsresource.Type, updates map[string]ads.DataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { +func (a *authority) adsResourceUpdate(serverConfig *ServerConfig, rType ResourceType, updates map[string]dataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { a.xdsClientSerializer.TrySchedule(func(context.Context) { a.handleADSResourceUpdate(serverConfig, rType, updates, md, onDone) }) @@ -329,7 +329,7 @@ func (a *authority) adsResourceUpdate(serverConfig *bootstrap.ServerConfig, rTyp // to invoke the onDone callback. // // Only executed in the context of a serializer callback. -func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig, rType xdsresource.Type, updates map[string]ads.DataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { +func (a *authority) handleADSResourceUpdate(serverConfig *ServerConfig, rType ResourceType, updates map[string]dataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { a.handleRevertingToPrimaryOnUpdate(serverConfig) // We build a list of callback funcs to invoke, and invoke them at the end @@ -368,7 +368,11 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig // On error, keep previous version of the resource. But update status // and error. if uErr.Err != nil { - xdsClientResourceUpdatesInvalidMetric.Record(a.metricsRecorder, 1, a.target, serverConfig.ServerURI(), rType.TypeName()) + if a.metricsReporter != nil { + a.metricsReporter.ReportMetric(&metrics.ResourceUpdateInvalid{ + ServerURI: serverConfig.ServerIdentifier.ServerURI, ResourceType: rType.TypeName, + }) + } state.md.ErrState = md.ErrState state.md.Status = md.Status for watcher := range state.watchers { @@ -384,21 +388,25 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig continue } - xdsClientResourceUpdatesValidMetric.Record(a.metricsRecorder, 1, a.target, serverConfig.ServerURI(), rType.TypeName()) + if a.metricsReporter != nil { + a.metricsReporter.ReportMetric(&metrics.ResourceUpdateValid{ + ServerURI: serverConfig.ServerIdentifier.ServerURI, ResourceType: rType.TypeName, + }) + } if state.deletionIgnored { state.deletionIgnored = false - a.logger.Infof("A valid update was received for resource %q of type %q after previously ignoring a deletion", name, rType.TypeName()) + a.logger.Infof("A valid update was received for resource %q of type %q after previously ignoring a deletion", name, rType.TypeName) } // Notify watchers if any of these conditions are met: // - this is the first update for this resource // - this update is different from the one currently cached // - the previous update for this resource was NACKed, but the update // before that was the same as this update. - if state.cache == nil || !state.cache.RawEqual(uErr.Resource) || state.md.ErrState != nil { + if state.cache == nil || !state.cache.Equal(uErr.Resource) || state.md.ErrState != nil { // Update the resource cache. if a.logger.V(2) { - a.logger.Infof("Resource type %q with name %q added to cache", rType.TypeName(), name) + a.logger.Infof("Resource type %q with name %q added to cache", rType.TypeName, name) } state.cache = uErr.Resource @@ -426,7 +434,7 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig // previously seen resource will be interpreted as a deletion of that // resource unless ignore_resource_deletion option was set in the server // config. - if !rType.AllResourcesRequiredInSotW() { + if !rType.AllResourcesRequiredInSotW { return } for name, state := range resourceStates { @@ -459,16 +467,16 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig // "resource-not-found" error. continue } - if serverConfig.ServerFeaturesIgnoreResourceDeletion() { + if serverConfig.IgnoreResourceDeletion { // Per A53, resource deletions are ignored if the // `ignore_resource_deletion` server feature is enabled through the - // bootstrap configuration. If the resource deletion is to be + // xDS client configuration. If the resource deletion is to be // ignored, the resource is not removed from the cache and the - // corresponding ResourceError() callback is not invoked on + // corresponding OnResourceDoesNotExist() callback is not invoked on // the watchers. if !state.deletionIgnored { state.deletionIgnored = true - a.logger.Warningf("Ignoring resource deletion for resource %q of type %q", name, rType.TypeName()) + a.logger.Warningf("Ignoring resource deletion for resource %q of type %q", name, rType.TypeName) } continue } @@ -484,7 +492,7 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig watcher := watcher watcherCnt.Add(1) funcsToSchedule = append(funcsToSchedule, func(context.Context) { - watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q has been removed", name, rType.TypeName()), done) + watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q has been removed", name, rType.TypeName), done) }) } } @@ -493,7 +501,7 @@ func (a *authority) handleADSResourceUpdate(serverConfig *bootstrap.ServerConfig // adsResourceDoesNotExist is called by the xDS client implementation (on all // interested authorities) to notify the authority that a subscribed resource // does not exist. -func (a *authority) adsResourceDoesNotExist(rType xdsresource.Type, resourceName string) { +func (a *authority) adsResourceDoesNotExist(rType ResourceType, resourceName string) { a.xdsClientSerializer.TrySchedule(func(context.Context) { a.handleADSResourceDoesNotExist(rType, resourceName) }) @@ -503,22 +511,22 @@ func (a *authority) adsResourceDoesNotExist(rType xdsresource.Type, resourceName // exist. It removes the resource from the cache, updates the metadata status // to ServiceStatusNotExist, and notifies all watchers that the resource does // not exist. -func (a *authority) handleADSResourceDoesNotExist(rType xdsresource.Type, resourceName string) { +func (a *authority) handleADSResourceDoesNotExist(rType ResourceType, resourceName string) { if a.logger.V(2) { - a.logger.Infof("Watch for resource %q of type %s timed out", resourceName, rType.TypeName()) + a.logger.Infof("Watch for resource %q of type %s timed out", resourceName, rType.TypeName) } resourceStates := a.resources[rType] if resourceStates == nil { if a.logger.V(2) { - a.logger.Infof("Resource %q of type %s currently not being watched", resourceName, rType.TypeName()) + a.logger.Infof("Resource %q of type %s currently not being watched", resourceName, rType.TypeName) } return } state, ok := resourceStates[resourceName] if !ok { if a.logger.V(2) { - a.logger.Infof("Resource %q of type %s currently not being watched", resourceName, rType.TypeName()) + a.logger.Infof("Resource %q of type %s currently not being watched", resourceName, rType.TypeName) } return } @@ -528,7 +536,7 @@ func (a *authority) handleADSResourceDoesNotExist(rType xdsresource.Type, resour for watcher := range state.watchers { watcher := watcher a.watcherCallbackSerializer.TrySchedule(func(context.Context) { - watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q does not exist", resourceName, rType.TypeName()), func() {}) + watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q has been removed", resourceName, rType.TypeName), func() {}) }) } } @@ -541,8 +549,8 @@ func (a *authority) handleADSResourceDoesNotExist(rType xdsresource.Type, resour // highest priority server that sent the update. // // This method is only executed in the context of a serializer callback. -func (a *authority) handleRevertingToPrimaryOnUpdate(serverConfig *bootstrap.ServerConfig) { - if a.activeXDSChannel != nil && a.activeXDSChannel.serverConfig.Equal(serverConfig) { +func (a *authority) handleRevertingToPrimaryOnUpdate(serverConfig *ServerConfig) { + if a.activeXDSChannel != nil && isServerConfigEqual(serverConfig, a.activeXDSChannel.serverConfig) { // If the resource update is from the current active server, nothing // needs to be done from fallback point of view. return @@ -607,7 +615,7 @@ func (a *authority) handleRevertingToPrimaryOnUpdate(serverConfig *bootstrap.Ser // the resource with the xdsChannel. If a cached copy of the resource exists, it // will immediately notify the new watcher. When the last watcher for a resource // is removed, it will unsubscribe the resource from the xdsChannel. -func (a *authority) watchResource(rType xdsresource.Type, resourceName string, watcher xdsresource.ResourceWatcher) func() { +func (a *authority) watchResource(rType ResourceType, resourceName string, watcher ResourceWatcher) func() { cleanup := func() {} done := make(chan struct{}) @@ -615,7 +623,7 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w defer close(done) if a.logger.V(2) { - a.logger.Infof("New watch for type %q, resource name %q", rType.TypeName(), resourceName) + a.logger.Infof("New watch for type %q, resource name %q", rType.TypeName, resourceName) } xdsChannel, err := a.xdsChannelToUse() @@ -638,10 +646,10 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w state := resources[resourceName] if state == nil { if a.logger.V(2) { - a.logger.Infof("First watch for type %q, resource name %q", rType.TypeName(), resourceName) + a.logger.Infof("First watch for type %q, resource name %q", rType.TypeName, resourceName) } state = &resourceState{ - watchers: make(map[xdsresource.ResourceWatcher]bool), + watchers: make(map[ResourceWatcher]bool), md: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}, xdsChannelConfigs: map[*xdsChannelWithConfig]bool{xdsChannel: true}, } @@ -655,7 +663,7 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w // immediately. if state.cache != nil { if a.logger.V(2) { - a.logger.Infof("Resource type %q with resource name %q found in cache: %s", rType.TypeName(), resourceName, state.cache.ToJSON()) + a.logger.Infof("Resource type %q with resource name %q found in cache: %v", rType.TypeName, resourceName, state.cache) } // state can only be accessed in the context of an // xdsClientSerializer callback. Hence making a copy of the cached @@ -667,7 +675,7 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w // immediately as well. if state.md.Status == xdsresource.ServiceStatusNACKed { if a.logger.V(2) { - a.logger.Infof("Resource type %q with resource name %q was NACKed", rType.TypeName(), resourceName) + a.logger.Infof("Resource type %q with resource name %q was NACKed", rType.TypeName, resourceName) } // state can only be accessed in the context of an // xdsClientSerializer callback. Hence making a copy of the error @@ -683,13 +691,13 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w // server does not have this resource, notify the new watcher. if state.md.Status == xdsresource.ServiceStatusNotExist { a.watcherCallbackSerializer.TrySchedule(func(context.Context) { - watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q does not exist", resourceName, rType.TypeName()), func() {}) + watcher.ResourceError(xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "xds: resource %q of type %q has been removed", resourceName, rType.TypeName), func() {}) }) } cleanup = a.unwatchResource(rType, resourceName, watcher) }, func() { if a.logger.V(2) { - a.logger.Infof("Failed to schedule a watch for type %q, resource name %q, because the xDS client is closed", rType.TypeName(), resourceName) + a.logger.Infof("Failed to schedule a watch for type %q, resource name %q, because the xDS client is closed", rType.TypeName, resourceName) } close(done) }) @@ -697,14 +705,14 @@ func (a *authority) watchResource(rType xdsresource.Type, resourceName string, w return cleanup } -func (a *authority) unwatchResource(rType xdsresource.Type, resourceName string, watcher xdsresource.ResourceWatcher) func() { +func (a *authority) unwatchResource(rType ResourceType, resourceName string, watcher ResourceWatcher) func() { return sync.OnceFunc(func() { done := make(chan struct{}) a.xdsClientSerializer.ScheduleOr(func(context.Context) { defer close(done) if a.logger.V(2) { - a.logger.Infof("Canceling a watch for type %q, resource name %q", rType.TypeName(), resourceName) + a.logger.Infof("Canceling a watch for type %q, resource name %q", rType.TypeName, resourceName) } // Lookup the resource type from the resource cache. The entry is @@ -718,7 +726,7 @@ func (a *authority) unwatchResource(rType xdsresource.Type, resourceName string, delete(state.watchers, watcher) if len(state.watchers) > 0 { if a.logger.V(2) { - a.logger.Infof("Other watchers exist for type %q, resource name %q", rType.TypeName(), resourceName) + a.logger.Infof("Other watchers exist for type %q, resource name %q", rType.TypeName, resourceName) } return } @@ -738,7 +746,7 @@ func (a *authority) unwatchResource(rType xdsresource.Type, resourceName string, // resource type from the top-level map. if len(resources) == 0 { if a.logger.V(2) { - a.logger.Infof("Removing last watch for resource type %q", rType.TypeName()) + a.logger.Infof("Removing last watch for resource type %q", rType.TypeName) } delete(a.resources, rType) } @@ -831,11 +839,11 @@ func (a *authority) dumpResources() []*v3statuspb.ClientConfig_GenericXdsConfig func (a *authority) resourceConfig() []*v3statuspb.ClientConfig_GenericXdsConfig { var ret []*v3statuspb.ClientConfig_GenericXdsConfig for rType, resourceStates := range a.resources { - typeURL := rType.TypeURL() + typeURL := rType.TypeURL for name, state := range resourceStates { var raw *anypb.Any if state.cache != nil { - raw = state.cache.Raw() + raw = &anypb.Any{TypeUrl: typeURL, Value: state.cache.Bytes()} } config := &v3statuspb.ClientConfig_GenericXdsConfig{ TypeUrl: typeURL, diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/channel.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/channel.go similarity index 56% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/channel.go rename to vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/channel.go index 60ab9290b5..2d424b811d 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/channel.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/channel.go @@ -1,6 +1,6 @@ /* * - * Copyright 2024 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * 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 xdsclient @@ -24,15 +25,17 @@ import ( "time" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal/backoff" igrpclog "google.golang.org/grpc/internal/grpclog" - "google.golang.org/grpc/internal/grpcsync" - "google.golang.org/grpc/internal/xds/bootstrap" - "google.golang.org/grpc/xds/internal/xdsclient/load" - "google.golang.org/grpc/xds/internal/xdsclient/transport" - "google.golang.org/grpc/xds/internal/xdsclient/transport/ads" - "google.golang.org/grpc/xds/internal/xdsclient/transport/lrs" - "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/internal" + "google.golang.org/grpc/xds/internal/clients/internal/backoff" + "google.golang.org/grpc/xds/internal/clients/internal/syncutil" + "google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource" +) + +const ( + clientFeatureNoOverprovisioning = "envoy.lb.does_not_support_overprovisioning" + clientFeatureResourceWrapper = "xds.config.resource-in-sotw" ) // xdsChannelEventHandler wraps callbacks used to notify the xDS client about @@ -51,23 +54,22 @@ type xdsChannelEventHandler interface { // - a map of resources in the response, keyed by resource name // - the metadata associated with the response // - a callback to be invoked when the updated is processed - adsResourceUpdate(xdsresource.Type, map[string]ads.DataAndErrTuple, xdsresource.UpdateMetadata, func()) + adsResourceUpdate(ResourceType, map[string]dataAndErrTuple, xdsresource.UpdateMetadata, func()) // adsResourceDoesNotExist is called when the xdsChannel determines that a // requested ADS resource does not exist. - adsResourceDoesNotExist(xdsresource.Type, string) + adsResourceDoesNotExist(ResourceType, string) } // xdsChannelOpts holds the options for creating a new xdsChannel. type xdsChannelOpts struct { - transport transport.Transport // Takes ownership of this transport. - serverConfig *bootstrap.ServerConfig // Configuration of the server to connect to. - bootstrapConfig *bootstrap.Config // Complete bootstrap configuration, used to decode resources. - resourceTypeGetter func(string) xdsresource.Type // Function to retrieve resource parsing functionality, based on resource type. - eventHandler xdsChannelEventHandler // Callbacks for ADS stream events. - backoff func(int) time.Duration // Backoff function to use for stream retries. Defaults to exponential backoff, if unset. - watchExpiryTimeout time.Duration // Timeout for ADS resource watch expiry. - logPrefix string // Prefix to use for logging. + transport clients.Transport // Takes ownership of this transport. + serverConfig *ServerConfig // Configuration of the server to connect to. + clientConfig *Config // Complete xDS client configuration, used to decode resources. + eventHandler xdsChannelEventHandler // Callbacks for ADS stream events. + backoff func(int) time.Duration // Backoff function to use for stream retries. Defaults to exponential backoff, if unset. + watchExpiryTimeout time.Duration // Timeout for ADS resource watch expiry. + logPrefix string // Prefix to use for logging. } // newXDSChannel creates a new xdsChannel instance with the provided options. @@ -76,24 +78,21 @@ type xdsChannelOpts struct { func newXDSChannel(opts xdsChannelOpts) (*xdsChannel, error) { switch { case opts.transport == nil: - return nil, errors.New("xdsChannel: transport is nil") + return nil, errors.New("xdsclient: transport is nil") case opts.serverConfig == nil: - return nil, errors.New("xdsChannel: serverConfig is nil") - case opts.bootstrapConfig == nil: - return nil, errors.New("xdsChannel: bootstrapConfig is nil") - case opts.resourceTypeGetter == nil: - return nil, errors.New("xdsChannel: resourceTypeGetter is nil") + return nil, errors.New("xdsclient: serverConfig is nil") + case opts.clientConfig == nil: + return nil, errors.New("xdsclient: clientConfig is nil") case opts.eventHandler == nil: - return nil, errors.New("xdsChannel: eventHandler is nil") + return nil, errors.New("xdsclient: eventHandler is nil") } xc := &xdsChannel{ - transport: opts.transport, - serverConfig: opts.serverConfig, - bootstrapConfig: opts.bootstrapConfig, - resourceTypeGetter: opts.resourceTypeGetter, - eventHandler: opts.eventHandler, - closed: grpcsync.NewEvent(), + transport: opts.transport, + serverConfig: opts.serverConfig, + clientConfig: opts.clientConfig, + eventHandler: opts.eventHandler, + closed: syncutil.NewEvent(), } l := grpclog.Component("xds") @@ -103,90 +102,76 @@ func newXDSChannel(opts xdsChannelOpts) (*xdsChannel, error) { if opts.backoff == nil { opts.backoff = backoff.DefaultExponential.Backoff } - xc.ads = ads.NewStreamImpl(ads.StreamOpts{ - Transport: xc.transport, - EventHandler: xc, - Backoff: opts.backoff, - NodeProto: xc.bootstrapConfig.Node(), - WatchExpiryTimeout: opts.watchExpiryTimeout, - LogPrefix: logPrefix, - }) - xc.lrs = lrs.NewStreamImpl(lrs.StreamOpts{ - Transport: xc.transport, - Backoff: opts.backoff, - NodeProto: xc.bootstrapConfig.Node(), - LogPrefix: logPrefix, + np := internal.NodeProto(opts.clientConfig.Node) + np.ClientFeatures = []string{clientFeatureNoOverprovisioning, clientFeatureResourceWrapper} + xc.ads = newADSStreamImpl(adsStreamOpts{ + transport: opts.transport, + eventHandler: xc, + backoff: opts.backoff, + nodeProto: np, + watchExpiryTimeout: opts.watchExpiryTimeout, + logPrefix: logPrefix, }) + if xc.logger.V(2) { + xc.logger.Infof("xdsChannel is created for ServerConfig %v", opts.serverConfig) + } return xc, nil } // xdsChannel represents a client channel to a management server, and is // responsible for managing the lifecycle of the ADS and LRS streams. It invokes // callbacks on the registered event handler for various ADS stream events. +// +// It is safe for concurrent use. type xdsChannel struct { // The following fields are initialized at creation time and are read-only // after that, and hence need not be guarded by a mutex. - transport transport.Transport // Takes ownership of this transport (used to make streaming calls). - ads *ads.StreamImpl // An ADS stream to the management server. - lrs *lrs.StreamImpl // An LRS stream to the management server. - serverConfig *bootstrap.ServerConfig // Configuration of the server to connect to. - bootstrapConfig *bootstrap.Config // Complete bootstrap configuration, used to decode resources. - resourceTypeGetter func(string) xdsresource.Type // Function to retrieve resource parsing functionality, based on resource type. - eventHandler xdsChannelEventHandler // Callbacks for ADS stream events. - logger *igrpclog.PrefixLogger // Logger to use for logging. - closed *grpcsync.Event // Fired when the channel is closed. + transport clients.Transport // Takes ownership of this transport (used to make streaming calls). + ads *adsStreamImpl // An ADS stream to the management server. + serverConfig *ServerConfig // Configuration of the server to connect to. + clientConfig *Config // Complete xDS client configuration, used to decode resources. + eventHandler xdsChannelEventHandler // Callbacks for ADS stream events. + logger *igrpclog.PrefixLogger // Logger to use for logging. + closed *syncutil.Event // Fired when the channel is closed. } func (xc *xdsChannel) close() { xc.closed.Fire() xc.ads.Stop() - xc.lrs.Stop() xc.transport.Close() xc.logger.Infof("Shutdown") } -// reportLoad returns a load.Store that can be used to report load to the LRS, and a -// function that can be called to stop reporting load. -func (xc *xdsChannel) reportLoad() (*load.Store, func()) { - if xc.closed.HasFired() { - if xc.logger.V(2) { - xc.logger.Infof("Attempt to start load reporting on closed channel") - } - return nil, func() {} - } - return xc.lrs.ReportLoad() -} - // subscribe adds a subscription for the given resource name of the given // resource type on the ADS stream. -func (xc *xdsChannel) subscribe(typ xdsresource.Type, name string) { +func (xc *xdsChannel) subscribe(typ ResourceType, name string) { if xc.closed.HasFired() { if xc.logger.V(2) { - xc.logger.Infof("Attempt to subscribe to an xDS resource of type %s and name %q on a closed channel", typ.TypeName(), name) + xc.logger.Infof("Attempt to subscribe to an xDS resource of type %s and name %q on a closed channel", typ.TypeName, name) } return } - xc.ads.Subscribe(typ, name) + xc.ads.subscribe(typ, name) } // unsubscribe removes the subscription for the given resource name of the given // resource type from the ADS stream. -func (xc *xdsChannel) unsubscribe(typ xdsresource.Type, name string) { +func (xc *xdsChannel) unsubscribe(typ ResourceType, name string) { if xc.closed.HasFired() { if xc.logger.V(2) { - xc.logger.Infof("Attempt to unsubscribe to an xDS resource of type %s and name %q on a closed channel", typ.TypeName(), name) + xc.logger.Infof("Attempt to unsubscribe to an xDS resource of type %s and name %q on a closed channel", typ.TypeName, name) } return } xc.ads.Unsubscribe(typ, name) } -// The following OnADSXxx() methods implement the ads.StreamEventHandler interface +// The following onADSXxx() methods implement the StreamEventHandler interface // and are invoked by the ADS stream implementation. -// OnADSStreamError is invoked when an error occurs on the ADS stream. It +// onStreamError is invoked when an error occurs on the ADS stream. It // propagates the update to the xDS client. -func (xc *xdsChannel) OnADSStreamError(err error) { +func (xc *xdsChannel) onStreamError(err error) { if xc.closed.HasFired() { if xc.logger.V(2) { xc.logger.Infof("Received ADS stream error on a closed xdsChannel: %v", err) @@ -196,9 +181,9 @@ func (xc *xdsChannel) OnADSStreamError(err error) { xc.eventHandler.adsStreamFailure(err) } -// OnADSWatchExpiry is invoked when a watch for a resource expires. It +// onWatchExpiry is invoked when a watch for a resource expires. It // propagates the update to the xDS client. -func (xc *xdsChannel) OnADSWatchExpiry(typ xdsresource.Type, name string) { +func (xc *xdsChannel) onWatchExpiry(typ ResourceType, name string) { if xc.closed.HasFired() { if xc.logger.V(2) { xc.logger.Infof("Received ADS resource watch expiry for resource %q on a closed xdsChannel", name) @@ -208,13 +193,13 @@ func (xc *xdsChannel) OnADSWatchExpiry(typ xdsresource.Type, name string) { xc.eventHandler.adsResourceDoesNotExist(typ, name) } -// OnADSResponse is invoked when a response is received on the ADS stream. It +// onResponse is invoked when a response is received on the ADS stream. It // decodes the resources in the response, and propagates the updates to the xDS // client. // // It returns the list of resource names in the response and any errors // encountered during decoding. -func (xc *xdsChannel) OnADSResponse(resp ads.Response, onDone func()) ([]string, error) { +func (xc *xdsChannel) onResponse(resp response, onDone func()) ([]string, error) { if xc.closed.HasFired() { if xc.logger.V(2) { xc.logger.Infof("Received an update from the ADS stream on closed ADS stream") @@ -223,17 +208,17 @@ func (xc *xdsChannel) OnADSResponse(resp ads.Response, onDone func()) ([]string, } // Lookup the resource parser based on the resource type. - rType := xc.resourceTypeGetter(resp.TypeURL) - if rType == nil { - return nil, xdsresource.NewErrorf(xdsresource.ErrorTypeResourceTypeUnsupported, "Resource type URL %q unknown in response from server", resp.TypeURL) + rType, ok := xc.clientConfig.ResourceTypes[resp.typeURL] + if !ok { + return nil, xdsresource.NewErrorf(xdsresource.ErrorTypeResourceTypeUnsupported, "Resource type URL %q unknown in response from server", resp.typeURL) } // Decode the resources and build the list of resource names to return. - opts := &xdsresource.DecodeOptions{ - BootstrapConfig: xc.bootstrapConfig, - ServerConfig: xc.serverConfig, + opts := &DecodeOptions{ + Config: xc.clientConfig, + ServerConfig: xc.serverConfig, } - updates, md, err := decodeResponse(opts, rType, resp) + updates, md, err := decodeResponse(opts, &rType, resp) var names []string for name := range updates { names = append(names, name) @@ -257,18 +242,21 @@ func (xc *xdsChannel) OnADSResponse(resp ads.Response, onDone func()) ([]string, // If there are any errors decoding the resources, the metadata will indicate // that the update was NACKed, and the returned error will contain information // about all errors encountered by this function. -func decodeResponse(opts *xdsresource.DecodeOptions, rType xdsresource.Type, resp ads.Response) (map[string]ads.DataAndErrTuple, xdsresource.UpdateMetadata, error) { +func decodeResponse(opts *DecodeOptions, rType *ResourceType, resp response) (map[string]dataAndErrTuple, xdsresource.UpdateMetadata, error) { timestamp := time.Now() md := xdsresource.UpdateMetadata{ - Version: resp.Version, + Version: resp.version, Timestamp: timestamp, } topLevelErrors := make([]error, 0) // Tracks deserialization errors, where we don't have a resource name. perResourceErrors := make(map[string]error) // Tracks resource validation errors, where we have a resource name. - ret := make(map[string]ads.DataAndErrTuple) // Return result, a map from resource name to either resource data or error. - for _, r := range resp.Resources { - result, err := rType.Decode(opts, r) + ret := make(map[string]dataAndErrTuple) // Return result, a map from resource name to either resource data or error. + for _, r := range resp.resources { + result, err := rType.Decoder.Decode(AnyProto{ + TypeURL: r.GetTypeUrl(), + Value: r.GetValue(), + }, *opts) // Name field of the result is left unpopulated only when resource // deserialization fails. @@ -277,7 +265,7 @@ func decodeResponse(opts *xdsresource.DecodeOptions, rType xdsresource.Type, res name = xdsresource.ParseName(result.Name).String() } if err == nil { - ret[name] = ads.DataAndErrTuple{Resource: result.Resource} + ret[name] = dataAndErrTuple{Resource: result.Resource} continue } if name == "" { @@ -287,7 +275,7 @@ func decodeResponse(opts *xdsresource.DecodeOptions, rType xdsresource.Type, res perResourceErrors[name] = err // Add place holder in the map so we know this resource name was in // the response. - ret[name] = ads.DataAndErrTuple{Err: xdsresource.NewError(xdsresource.ErrorTypeNACKed, err.Error())} + ret[name] = dataAndErrTuple{Err: xdsresource.NewError(xdsresource.ErrorTypeNACKed, err.Error())} } if len(topLevelErrors) == 0 && len(perResourceErrors) == 0 { @@ -296,9 +284,9 @@ func decodeResponse(opts *xdsresource.DecodeOptions, rType xdsresource.Type, res } md.Status = xdsresource.ServiceStatusNACKed - errRet := combineErrors(rType.TypeName(), topLevelErrors, perResourceErrors) + errRet := combineErrors(rType.TypeName, topLevelErrors, perResourceErrors) md.ErrState = &xdsresource.UpdateErrorMetadata{ - Version: resp.Version, + Version: resp.version, Err: xdsresource.NewError(xdsresource.ErrorTypeNACKed, errRet.Error()), Timestamp: timestamp, } @@ -329,14 +317,3 @@ func combineErrors(rType string, topLevelErrors []error, perResourceErrors map[s } return errors.New(errStrB.String()) } - -func (xc *xdsChannel) triggerResourceNotFoundForTesting(rType xdsresource.Type, resourceName string) error { - if xc.closed.HasFired() { - return fmt.Errorf("triggerResourceNotFoundForTesting() called on a closed channel") - } - if xc.logger.V(2) { - xc.logger.Infof("Triggering resource not found for type: %s, resource name: %s", rType.TypeName(), resourceName) - } - xc.ads.TriggerResourceNotFoundForTesting(rType, resourceName) - return nil -} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/clientimpl_watchers.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/clientimpl_watchers.go new file mode 100644 index 0000000000..913e313e1e --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/clientimpl_watchers.go @@ -0,0 +1,102 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package xdsclient + +import ( + "fmt" + + "google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource" +) + +// wrappingWatcher is a wrapper around an xdsresource.ResourceWatcher that adds +// the node ID to the error messages reported to the watcher. +type wrappingWatcher struct { + ResourceWatcher + nodeID string +} + +func (w *wrappingWatcher) AmbientError(err error, done func()) { + w.ResourceWatcher.AmbientError(fmt.Errorf("[xDS node id: %v]: %w", w.nodeID, err), done) +} + +func (w *wrappingWatcher) ResourceError(err error, done func()) { + w.ResourceWatcher.ResourceError(fmt.Errorf("[xDS node id: %v]: %w", w.nodeID, err), done) +} + +// WatchResource starts watching the specified resource. +// +// typeURL specifies the resource type implementation to use. The watch fails +// if there is no resource type implementation for the given typeURL. See the +// ResourceTypes field in the Config struct used to create the XDSClient. +// +// The returned function cancels the watch and prevents future calls to the +// watcher. +func (c *XDSClient) WatchResource(typeURL, resourceName string, watcher ResourceWatcher) (cancel func()) { + // Return early if the client is already closed. + if c.done.HasFired() { + logger.Warningf("Watch registered for type %q, but client is closed", typeURL) + return func() {} + } + + watcher = &wrappingWatcher{ + ResourceWatcher: watcher, + nodeID: c.config.Node.ID, + } + + rType, ok := c.config.ResourceTypes[typeURL] + if !ok { + logger.Warningf("ResourceType implementation for resource type url %v is not found", rType.TypeURL) + watcher.ResourceError(fmt.Errorf("ResourceType implementation for resource type url %v is not found", rType.TypeURL), func() {}) + return func() {} + } + + n := xdsresource.ParseName(resourceName) + a := c.getAuthorityForResource(n) + if a == nil { + logger.Warningf("Watch registered for name %q of type %q, authority %q is not found", rType.TypeName, resourceName, n.Authority) + watcher.ResourceError(fmt.Errorf("authority %q not found in bootstrap config for resource %q", n.Authority, resourceName), func() {}) + return func() {} + } + // The watchResource method on the authority is invoked with n.String() + // instead of resourceName because n.String() canonicalizes the given name. + // So, two resource names which don't differ in the query string, but only + // differ in the order of context params will result in the same resource + // being watched by the authority. + return a.watchResource(rType, n.String(), watcher) +} + +// Gets the authority for the given resource name. +// +// See examples in this section of the gRFC: +// https://github.com/grpc/proposal/blob/master/A47-xds-federation.md#bootstrap-config-changes +func (c *XDSClient) getAuthorityForResource(name *xdsresource.Name) *authority { + // For new-style resource names, always lookup the authorities map. If the + // name does not specify an authority, we will end up looking for an entry + // in the map with the empty string as the key. + if name.Scheme == xdsresource.FederationScheme { + return c.authorities[name.Authority] + } + + // For old-style resource names, we use the top-level authority if the name + // does not specify an authority. + if name.Authority == "" { + return c.topLevelAuthority + } + return c.authorities[name.Authority] +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/internal/internal.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/internal.go similarity index 63% rename from vendor/google.golang.org/grpc/xds/internal/xdsclient/internal/internal.go rename to vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/internal.go index cdbb86db82..7adb671909 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/internal/internal.go +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/internal.go @@ -1,6 +1,6 @@ /* * - * Copyright 2024 gRPC authors. + * Copyright 2025 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,19 @@ // Package internal contains functionality internal to the xdsclient package. package internal -// The following vars can be overridden by tests. +import "time" + var ( - // GRPCNewClient returns a new gRPC Client. - GRPCNewClient any // func(string, ...grpc.DialOption) (*grpc.ClientConn, error) + // WatchExpiryTimeout is the watch expiry timeout for xDS client. It can be + // overridden by tests to change the default watch expiry timeout. + WatchExpiryTimeout time.Duration - // NewADSStream returns a new ADS stream. - NewADSStream any // func(context.Context, *grpc.ClientConn) (v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesClient, error) + // StreamBackoff is the stream backoff for xDS client. It can be overridden + // by tests to change the default backoff strategy. + StreamBackoff func(int) time.Duration // ResourceWatchStateForTesting gets the watch state for the resource // identified by the given resource type and resource name. Returns a // non-nil error if there is no such resource being watched. - ResourceWatchStateForTesting any // func(xdsclient.XDSClient, xdsresource.Type, string) error + ResourceWatchStateForTesting any // func(*xdsclient.XDSClient, xdsclient.ResourceType, string) error ) diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/ads_stream.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/ads_stream.go new file mode 100644 index 0000000000..87fe9ac868 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/ads_stream.go @@ -0,0 +1,46 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsresource + +import "time" + +// WatchState is a enum that describes the watch state of a particular +// resource. +type WatchState int + +const ( + // ResourceWatchStateStarted is the state where a watch for a resource was + // started, but a request asking for that resource is yet to be sent to the + // management server. + ResourceWatchStateStarted WatchState = iota + // ResourceWatchStateRequested is the state when a request has been sent for + // the resource being watched. + ResourceWatchStateRequested + // ResourceWatchStateReceived is the state when a response has been received + // for the resource being watched. + ResourceWatchStateReceived + // ResourceWatchStateTimeout is the state when the watch timer associated + // with the resource expired because no response was received. + ResourceWatchStateTimeout +) + +// ResourceWatchState is the state corresponding to a resource being watched. +type ResourceWatchState struct { + State WatchState // Watch state of the resource. + ExpiryTimer *time.Timer // Timer for the expiry of the watch. +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/errors.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/errors.go new file mode 100644 index 0000000000..2bcc2e5409 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/errors.go @@ -0,0 +1,78 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsresource + +import ( + "errors" + "fmt" +) + +// ErrorType is the type of the error that the watcher will receive from the xds +// client. +type ErrorType int + +const ( + // ErrorTypeUnknown indicates the error doesn't have a specific type. It is + // the default value, and is returned if the error is not an xds error. + ErrorTypeUnknown ErrorType = iota + // ErrorTypeConnection indicates a connection error from the gRPC client. + ErrorTypeConnection + // ErrorTypeResourceNotFound indicates a resource is not found from the xds + // response. It's typically returned if the resource is removed in the xds + // server. + ErrorTypeResourceNotFound + // ErrorTypeResourceTypeUnsupported indicates the receipt of a message from + // the management server with resources of an unsupported resource type. + ErrorTypeResourceTypeUnsupported + // ErrTypeStreamFailedAfterRecv indicates an ADS stream error, after + // successful receipt of at least one message from the server. + ErrTypeStreamFailedAfterRecv + // ErrorTypeNACKed indicates that configuration provided by the xDS management + // server was NACKed. + ErrorTypeNACKed +) + +type xdsClientError struct { + t ErrorType + desc string +} + +func (e *xdsClientError) Error() string { + return e.desc +} + +// NewErrorf creates an xDS client error. The callbacks are called with this +// error, to pass additional information about the error. +func NewErrorf(t ErrorType, format string, args ...any) error { + return &xdsClientError{t: t, desc: fmt.Sprintf(format, args...)} +} + +// NewError creates an xDS client error. The callbacks are called with this +// error, to pass additional information about the error. +func NewError(t ErrorType, message string) error { + return NewErrorf(t, "%s", message) +} + +// ErrType returns the error's type. +func ErrType(e error) ErrorType { + var xe *xdsClientError + if ok := errors.As(e, &xe); ok { + return xe.t + } + return ErrorTypeUnknown +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/name.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/name.go new file mode 100644 index 0000000000..24200ea8db --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/name.go @@ -0,0 +1,127 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsresource + +import ( + "net/url" + "sort" + "strings" +) + +// FederationScheme is the scheme of a federation resource name. +const FederationScheme = "xdstp" + +// Name contains the parsed component of an xDS resource name. +// +// An xDS resource name is in the format of +// xdstp://[{authority}]/{resource type}/{id/*}?{context parameters}{#processing directive,*} +// +// See +// https://github.com/cncf/xds/blob/main/proposals/TP1-xds-transport-next.md#uri-based-xds-resource-names +// for details, and examples. +type Name struct { + Scheme string + Authority string + Type string + ID string + + ContextParams map[string]string + + processingDirective string +} + +// ParseName splits the name and returns a struct representation of the Name. +// +// If the name isn't a valid new-style xDS name, field ID is set to the input. +// Note that this is not an error, because we still support the old-style +// resource names (those not starting with "xdstp:"). +// +// The caller can tell if the parsing is successful by checking the returned +// Scheme. +func ParseName(name string) *Name { + if !strings.Contains(name, "://") { + // Only the long form URL, with ://, is valid. + return &Name{ID: name} + } + parsed, err := url.Parse(name) + if err != nil { + return &Name{ID: name} + } + + ret := &Name{ + Scheme: parsed.Scheme, + Authority: parsed.Host, + } + split := strings.SplitN(parsed.Path, "/", 3) + if len(split) < 3 { + // Path is in the format of "/type/id". There must be at least 3 + // segments after splitting. + return &Name{ID: name} + } + ret.Type = split[1] + ret.ID = split[2] + if len(parsed.Query()) != 0 { + ret.ContextParams = make(map[string]string) + for k, vs := range parsed.Query() { + if len(vs) > 0 { + // We only keep one value of each key. Behavior for multiple values + // is undefined. + ret.ContextParams[k] = vs[0] + } + } + } + // TODO: processing directive (the part comes after "#" in the URL, stored + // in parsed.RawFragment) is kept but not processed. Add support for that + // when it's needed. + ret.processingDirective = parsed.RawFragment + return ret +} + +// String returns a canonicalized string of name. The context parameters are +// sorted by the keys. +func (n *Name) String() string { + if n.Scheme == "" { + return n.ID + } + + // Sort and build query. + keys := make([]string, 0, len(n.ContextParams)) + for k := range n.ContextParams { + keys = append(keys, k) + } + sort.Strings(keys) + var pairs []string + for _, k := range keys { + pairs = append(pairs, strings.Join([]string{k, n.ContextParams[k]}, "=")) + } + rawQuery := strings.Join(pairs, "&") + + path := n.Type + if n.ID != "" { + path = "/" + path + "/" + n.ID + } + + tempURL := &url.URL{ + Scheme: n.Scheme, + Host: n.Authority, + Path: path, + RawQuery: rawQuery, + RawFragment: n.processingDirective, + } + return tempURL.String() +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/type.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/type.go new file mode 100644 index 0000000000..ea4d85447d --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/type.go @@ -0,0 +1,101 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsresource + +import ( + "time" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + + v3discoverypb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" +) + +// UpdateMetadata contains the metadata for each update, including timestamp, +// raw message, and so on. +type UpdateMetadata struct { + // Status is the status of this resource, e.g. ACKed, NACKed, or + // Not_exist(removed). + Status ServiceStatus + // Version is the version of the xds response. Note that this is the version + // of the resource in use (previous ACKed). If a response is NACKed, the + // NACKed version is in ErrState. + Version string + // Timestamp is when the response is received. + Timestamp time.Time + // ErrState is set when the update is NACKed. + ErrState *UpdateErrorMetadata +} + +// IsListenerResource returns true if the provider URL corresponds to an xDS +// Listener resource. +func IsListenerResource(url string) bool { + return url == V3ListenerURL +} + +// IsHTTPConnManagerResource returns true if the provider URL corresponds to an xDS +// HTTPConnManager resource. +func IsHTTPConnManagerResource(url string) bool { + return url == V3HTTPConnManagerURL +} + +// UnwrapResource unwraps and returns the inner resource if it's in a resource +// wrapper. The original resource is returned if it's not wrapped. +func UnwrapResource(r *anypb.Any) (*anypb.Any, error) { + url := r.GetTypeUrl() + if url != V3ResourceWrapperURL { + // Not wrapped. + return r, nil + } + inner := &v3discoverypb.Resource{} + if err := proto.Unmarshal(r.GetValue(), inner); err != nil { + return nil, err + } + return inner.Resource, nil +} + +// ServiceStatus is the status of the update. +type ServiceStatus int + +const ( + // ServiceStatusUnknown is the default state, before a watch is started for + // the resource. + ServiceStatusUnknown ServiceStatus = iota + // ServiceStatusRequested is when the watch is started, but before and + // response is received. + ServiceStatusRequested + // ServiceStatusNotExist is when the resource doesn't exist in + // state-of-the-world responses (e.g. LDS and CDS), which means the resource + // is removed by the management server. + ServiceStatusNotExist // Resource is removed in the server, in LDS/CDS. + // ServiceStatusACKed is when the resource is ACKed. + ServiceStatusACKed + // ServiceStatusNACKed is when the resource is NACKed. + ServiceStatusNACKed +) + +// UpdateErrorMetadata is part of UpdateMetadata. It contains the error state +// when a response is NACKed. +type UpdateErrorMetadata struct { + // Version is the version of the NACKed response. + Version string + // Err contains why the response was NACKed. + Err error + // Timestamp is when the NACKed response was received. + Timestamp time.Time +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/version.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/version.go new file mode 100644 index 0000000000..60f47e6942 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource/version.go @@ -0,0 +1,31 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package xdsresource defines constants to distinguish between supported xDS +// API versions. +package xdsresource + +// Resource URLs. We need to be able to accept either version of the resource +// regardless of the version of the transport protocol in use. +const ( + googleapiPrefix = "type.googleapis.com/" + + V3ListenerURL = googleapiPrefix + "envoy.config.listener.v3.Listener" + V3HTTPConnManagerURL = googleapiPrefix + "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" + V3ResourceWrapperURL = googleapiPrefix + "envoy.service.discovery.v3.Resource" +) diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/logging.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/logging.go new file mode 100644 index 0000000000..c7ba21c493 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/logging.go @@ -0,0 +1,36 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package xdsclient + +import ( + "fmt" + + "google.golang.org/grpc/grpclog" + internalgrpclog "google.golang.org/grpc/internal/grpclog" +) + +var logger = grpclog.Component("xds") + +func prefixLogger(p *XDSClient) *internalgrpclog.PrefixLogger { + return internalgrpclog.NewPrefixLogger(logger, clientPrefix(p)) +} + +func clientPrefix(p *XDSClient) string { + return fmt.Sprintf("[xds-client %p] ", p) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/metrics/metrics.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/metrics/metrics.go new file mode 100644 index 0000000000..2e14efb1ae --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/metrics/metrics.go @@ -0,0 +1,42 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package metrics defines all metrics that can be produced by an xDS client. +// All calls to the MetricsRecorder by the xDS client will contain a struct +// from this package passed by pointer. +package metrics + +// ResourceUpdateValid is a metric to report a valid resource update from +// the xDS management server for a given resource type. +type ResourceUpdateValid struct { + ServerURI string + ResourceType string +} + +// ResourceUpdateInvalid is a metric to report an invalid resource update +// from the xDS management server for a given resource type. +type ResourceUpdateInvalid struct { + ServerURI string + ResourceType string +} + +// ServerFailure is a metric to report a server failure of the xDS +// management server. +type ServerFailure struct { + ServerURI string +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_type.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_type.go new file mode 100644 index 0000000000..ae8e21dfef --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_type.go @@ -0,0 +1,104 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package xdsclient + +// ResourceType wraps all resource-type specific functionality. Each supported +// resource type needs to provide an implementation of the Decoder. +type ResourceType struct { + // TypeURL is the xDS type URL of this resource type for the v3 xDS + // protocol. This URL is used as the key to look up the corresponding + // ResourceType implementation in the ResourceTypes map provided in the + // Config. + TypeURL string + + // TODO: Revisit if we need TypeURL to be part of the struct because it is + // already a key in config's ResouceTypes map. + + // TypeName is a shorter representation of the TypeURL to identify the + // resource type. It is used for logging/debugging purposes. + TypeName string + + // AllResourcesRequiredInSotW indicates whether this resource type requires + // that all resources be present in every SotW response from the server. If + // true, a response that does not include a previously seen resource will + // be interpreted as a deletion of that resource. + AllResourcesRequiredInSotW bool + + // Decoder is used to deserialize and validate an xDS resource received + // from the xDS management server. + Decoder Decoder +} + +// Decoder wraps the resource-type specific functionality for validation +// and deserialization. +type Decoder interface { + // Decode deserializes and validates an xDS resource as received from the + // xDS management server. + // + // The `resource` parameter may contain a value of the serialized wrapped + // resource (i.e. with the type URL + // `type.googleapis.com/envoy.service.discovery.v3.Resource`). + // Implementations are responsible for unwrapping the underlying resource if + // it is wrapped. + // + // If unmarshalling or validation fails, it returns a non-nil error. + // Otherwise, returns a fully populated DecodeResult. + Decode(resource AnyProto, options DecodeOptions) (*DecodeResult, error) +} + +// AnyProto contains the type URL and serialized proto data of an xDS resource. +type AnyProto struct { + TypeURL string + Value []byte +} + +// DecodeOptions wraps the options required by ResourceType implementations for +// decoding configuration received from the xDS management server. +type DecodeOptions struct { + // Config contains the complete configuration passed to the xDS client. + // This contains useful data for resource validation. + Config *Config + + // ServerConfig contains the configuration of the xDS server that provided + // the current resource being decoded. + ServerConfig *ServerConfig +} + +// DecodeResult is the result of a decode operation. +type DecodeResult struct { + // Name is the name of the decoded resource. + Name string + + // Resource contains the configuration associated with the decoded + // resource. + Resource ResourceData +} + +// ResourceData contains the configuration data sent by the xDS management +// server, associated with the resource being watched. Every resource type must +// provide an implementation of this interface to represent the configuration +// received from the xDS management server. +type ResourceData interface { + // Equal returns true if the passed in resource data is equal to that of + // the receiver. + Equal(other ResourceData) bool + + // Bytes returns the underlying raw bytes of the resource proto. + Bytes() []byte +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_watcher.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_watcher.go new file mode 100644 index 0000000000..37d01bc71e --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/resource_watcher.go @@ -0,0 +1,45 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package xdsclient + +// ResourceWatcher is notified of the resource updates and errors that are +// received by the xDS client from the management server. +// +// All methods contain a done parameter which should be called when processing +// of the update has completed. For example, if processing a resource requires +// watching new resources, those watches should be completed before done is +// called, which can happen after the ResourceWatcher method has returned. +// Failure to call done will prevent the xDS client from providing future +// ResourceWatcher notifications. +type ResourceWatcher interface { + // ResourceChanged indicates a new version of the resource is available. + ResourceChanged(resourceData ResourceData, done func()) + + // ResourceError indicates an error occurred while trying to fetch or + // decode the associated resource. The previous version of the resource + // should be considered invalid. + ResourceError(err error, done func()) + + // AmbientError indicates an error occurred after a resource has been + // received that should not modify the use of that resource but may provide + // useful information about the state of the XDSClient for debugging + // purposes. The previous version of the resource should still be + // considered valid. + AmbientError(err error, done func()) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsclient.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsclient.go new file mode 100644 index 0000000000..c9cd52a1e6 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsclient.go @@ -0,0 +1,452 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package xdsclient provides an xDS (* Discovery Service) client. +// +// It allows applications to: +// - Create xDS client instances with in-memory configurations. +// - Register watches for named resources. +// - Receive resources via an ADS (Aggregated Discovery Service) stream. +// - Register watches for named resources (e.g. listeners, routes, or +// clusters). +// +// This enables applications to dynamically discover and configure resources +// such as listeners, routes, clusters, and endpoints from an xDS management +// server. +package xdsclient + +import ( + "context" + "errors" + "fmt" + "sync" + "sync/atomic" + "time" + + "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/xds/internal/clients" + clientsinternal "google.golang.org/grpc/xds/internal/clients/internal" + "google.golang.org/grpc/xds/internal/clients/internal/backoff" + "google.golang.org/grpc/xds/internal/clients/internal/syncutil" + xdsclientinternal "google.golang.org/grpc/xds/internal/clients/xdsclient/internal" + "google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource" + "google.golang.org/grpc/xds/internal/clients/xdsclient/metrics" + "google.golang.org/protobuf/proto" + + v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" +) + +const ( + defaultWatchExpiryTimeout = 15 * time.Second + name = "xds-client" +) + +var ( + defaultExponentialBackoff = backoff.DefaultExponential.Backoff +) + +func init() { + xdsclientinternal.WatchExpiryTimeout = defaultWatchExpiryTimeout + xdsclientinternal.StreamBackoff = defaultExponentialBackoff + xdsclientinternal.ResourceWatchStateForTesting = resourceWatchStateForTesting +} + +// XDSClient is a client which queries a set of discovery APIs (collectively +// termed as xDS) on a remote management server, to discover +// various dynamic resources. +type XDSClient struct { + // The following fields are initialized at creation time and are read-only + // after that, and therefore can be accessed without a mutex. + done *syncutil.Event // Fired when the client is closed. + topLevelAuthority *authority // The top-level authority, used only for old-style names without an authority. + authorities map[string]*authority // Map from authority names in config to authority struct. + config *Config // Complete xDS client configuration. + watchExpiryTimeout time.Duration // Expiry timeout for ADS watch. + backoff func(int) time.Duration // Backoff for ADS and LRS stream failures. + transportBuilder clients.TransportBuilder // Builder to create transports to xDS server. + resourceTypes map[string]ResourceType // Registry of resource types, for parsing incoming ADS responses. + serializer *syncutil.CallbackSerializer // Serializer for invoking resource watcher callbacks. + serializerClose func() // Function to close the serializer. + logger *grpclog.PrefixLogger + target string + metricsReporter clients.MetricsReporter + + // The XDSClient owns a bunch of channels to individual xDS servers + // specified in the xDS client configuration. Authorities acquire references + // to these channels based on server configs within the authority config. + // The XDSClient maintains a list of interested authorities for each of + // these channels, and forwards updates from the channels to each of these + // authorities. + // + // Once all references to a channel are dropped, the channel is closed. + channelsMu sync.Mutex + xdsActiveChannels map[ServerConfig]*channelState // Map from server config to in-use xdsChannels. +} + +// New returns a new xDS Client configured with the provided config. +func New(config Config) (*XDSClient, error) { + switch { + case config.Node.ID == "": + return nil, errors.New("xdsclient: node ID is empty") + case config.ResourceTypes == nil: + return nil, errors.New("xdsclient: resource types map is nil") + case config.TransportBuilder == nil: + return nil, errors.New("xdsclient: transport builder is nil") + case config.Authorities == nil && config.Servers == nil: + return nil, errors.New("xdsclient: no servers or authorities specified") + } + + client, err := newClient(&config, name) + if err != nil { + return nil, err + } + return client, nil +} + +// SetWatchExpiryTimeoutForTesting override the default watch expiry timeout +// with provided timeout value. +func (c *XDSClient) SetWatchExpiryTimeoutForTesting(watchExpiryTimeout time.Duration) { + c.watchExpiryTimeout = watchExpiryTimeout +} + +// newClient returns a new XDSClient with the given config. +func newClient(config *Config, target string) (*XDSClient, error) { + ctx, cancel := context.WithCancel(context.Background()) + c := &XDSClient{ + target: target, + done: syncutil.NewEvent(), + authorities: make(map[string]*authority), + config: config, + watchExpiryTimeout: xdsclientinternal.WatchExpiryTimeout, + backoff: xdsclientinternal.StreamBackoff, + serializer: syncutil.NewCallbackSerializer(ctx), + serializerClose: cancel, + transportBuilder: config.TransportBuilder, + resourceTypes: config.ResourceTypes, + xdsActiveChannels: make(map[ServerConfig]*channelState), + metricsReporter: config.MetricsReporter, + } + + for name, cfg := range config.Authorities { + // If server configs are specified in the authorities map, use that. + // Else, use the top-level server configs. + serverCfg := config.Servers + if len(cfg.XDSServers) >= 1 { + serverCfg = cfg.XDSServers + } + c.authorities[name] = newAuthority(authorityBuildOptions{ + serverConfigs: serverCfg, + name: name, + serializer: c.serializer, + getChannelForADS: c.getChannelForADS, + logPrefix: clientPrefix(c), + target: target, + metricsReporter: c.metricsReporter, + }) + } + c.topLevelAuthority = newAuthority(authorityBuildOptions{ + serverConfigs: config.Servers, + name: "", + serializer: c.serializer, + getChannelForADS: c.getChannelForADS, + logPrefix: clientPrefix(c), + target: target, + metricsReporter: c.metricsReporter, + }) + c.logger = prefixLogger(c) + + return c, nil +} + +// Close closes the xDS client and releases all resources. +func (c *XDSClient) Close() { + if c.done.HasFired() { + return + } + c.done.Fire() + + c.topLevelAuthority.close() + for _, a := range c.authorities { + a.close() + } + + // Channel close cannot be invoked with the lock held, because it can race + // with stream failure happening at the same time. The latter will callback + // into the XDSClient and will attempt to grab the lock. This will result + // in a deadlock. So instead, we release the lock and wait for all active + // channels to be closed. + var channelsToClose []*xdsChannel + c.channelsMu.Lock() + for _, cs := range c.xdsActiveChannels { + channelsToClose = append(channelsToClose, cs.channel) + } + c.xdsActiveChannels = nil + c.channelsMu.Unlock() + for _, c := range channelsToClose { + c.close() + } + + c.serializerClose() + <-c.serializer.Done() + + c.logger.Infof("Shutdown") +} + +// getChannelForADS returns an xdsChannel for the given server configuration. +// +// If an xdsChannel exists for the given server configuration, it is returned. +// Else a new one is created. It also ensures that the calling authority is +// added to the set of interested authorities for the returned channel. +// +// It returns the xdsChannel and a function to release the calling authority's +// reference on the channel. The caller must call the cancel function when it is +// no longer interested in this channel. +// +// A non-nil error is returned if an xdsChannel was not created. +func (c *XDSClient) getChannelForADS(serverConfig *ServerConfig, callingAuthority *authority) (*xdsChannel, func(), error) { + if c.done.HasFired() { + return nil, nil, errors.New("xds: the xDS client is closed") + } + + initLocked := func(s *channelState) { + if c.logger.V(2) { + c.logger.Infof("Adding authority %q to the set of interested authorities for channel [%p]", callingAuthority.name, s.channel) + } + s.interestedAuthorities[callingAuthority] = true + } + deInitLocked := func(s *channelState) { + if c.logger.V(2) { + c.logger.Infof("Removing authority %q from the set of interested authorities for channel [%p]", callingAuthority.name, s.channel) + } + delete(s.interestedAuthorities, callingAuthority) + } + + return c.getOrCreateChannel(serverConfig, initLocked, deInitLocked) +} + +// getOrCreateChannel returns an xdsChannel for the given server configuration. +// +// If an active xdsChannel exists for the given server configuration, it is +// returned. If an idle xdsChannel exists for the given server configuration, it +// is revived from the idle cache and returned. Else a new one is created. +// +// The initLocked function runs some initialization logic before the channel is +// returned. This includes adding the calling authority to the set of interested +// authorities for the channel or incrementing the count of the number of LRS +// calls on the channel. +// +// The deInitLocked function runs some cleanup logic when the returned cleanup +// function is called. This involves removing the calling authority from the set +// of interested authorities for the channel or decrementing the count of the +// number of LRS calls on the channel. +// +// Both initLocked and deInitLocked are called with the c.channelsMu held. +// +// Returns the xdsChannel and a cleanup function to be invoked when the channel +// is no longer required. A non-nil error is returned if an xdsChannel was not +// created. +func (c *XDSClient) getOrCreateChannel(serverConfig *ServerConfig, initLocked, deInitLocked func(*channelState)) (*xdsChannel, func(), error) { + c.channelsMu.Lock() + defer c.channelsMu.Unlock() + + if c.logger.V(2) { + c.logger.Infof("Received request for a reference to an xdsChannel for server config %q", serverConfig) + } + + // Use an existing channel, if one exists for this server config. + if st, ok := c.xdsActiveChannels[*serverConfig]; ok { + if c.logger.V(2) { + c.logger.Infof("Reusing an existing xdsChannel for server config %q", serverConfig) + } + initLocked(st) + return st.channel, c.releaseChannel(serverConfig, st, deInitLocked), nil + } + + if c.logger.V(2) { + c.logger.Infof("Creating a new xdsChannel for server config %q", serverConfig) + } + + // Create a new transport and create a new xdsChannel, and add it to the + // map of xdsChannels. + tr, err := c.transportBuilder.Build(serverConfig.ServerIdentifier) + if err != nil { + return nil, func() {}, fmt.Errorf("xds: failed to create transport for server config %v: %v", serverConfig, err) + } + state := &channelState{ + parent: c, + serverConfig: serverConfig, + interestedAuthorities: make(map[*authority]bool), + } + channel, err := newXDSChannel(xdsChannelOpts{ + transport: tr, + serverConfig: serverConfig, + clientConfig: c.config, + eventHandler: state, + backoff: c.backoff, + watchExpiryTimeout: c.watchExpiryTimeout, + logPrefix: clientPrefix(c), + }) + if err != nil { + return nil, func() {}, fmt.Errorf("xds: failed to create a new channel for server config %v: %v", serverConfig, err) + } + state.channel = channel + c.xdsActiveChannels[*serverConfig] = state + initLocked(state) + return state.channel, c.releaseChannel(serverConfig, state, deInitLocked), nil +} + +// releaseChannel is a function that is called when a reference to an xdsChannel +// needs to be released. It handles closing channels with no active references. +// +// The function takes the following parameters: +// - serverConfig: the server configuration for the xdsChannel +// - state: the state of the xdsChannel +// - deInitLocked: a function that performs any necessary cleanup for the xdsChannel +// +// The function returns another function that can be called to release the +// reference to the xdsChannel. This returned function is idempotent, meaning +// it can be called multiple times without any additional effect. +func (c *XDSClient) releaseChannel(serverConfig *ServerConfig, state *channelState, deInitLocked func(*channelState)) func() { + return sync.OnceFunc(func() { + c.channelsMu.Lock() + + if c.logger.V(2) { + c.logger.Infof("Received request to release a reference to an xdsChannel for server config %q", serverConfig) + } + deInitLocked(state) + + // The channel has active users. Do nothing and return. + if len(state.interestedAuthorities) != 0 { + if c.logger.V(2) { + c.logger.Infof("xdsChannel %p has other active references", state.channel) + } + c.channelsMu.Unlock() + return + } + + delete(c.xdsActiveChannels, *serverConfig) + if c.logger.V(2) { + c.logger.Infof("Closing xdsChannel [%p] for server config %s", state.channel, serverConfig) + } + channelToClose := state.channel + c.channelsMu.Unlock() + + channelToClose.close() + }) +} + +// DumpResources returns the status and contents of all xDS resources being +// watched by the xDS client. +func (c *XDSClient) DumpResources() ([]byte, error) { + retCfg := c.topLevelAuthority.dumpResources() + for _, a := range c.authorities { + retCfg = append(retCfg, a.dumpResources()...) + } + + nodeProto := clientsinternal.NodeProto(c.config.Node) + nodeProto.ClientFeatures = []string{clientFeatureNoOverprovisioning, clientFeatureResourceWrapper} + resp := &v3statuspb.ClientStatusResponse{} + resp.Config = append(resp.Config, &v3statuspb.ClientConfig{ + Node: nodeProto, + GenericXdsConfigs: retCfg, + }) + return proto.Marshal(resp) +} + +// channelState represents the state of an xDS channel. It tracks the number of +// LRS references, the authorities interested in the channel, and the server +// configuration used for the channel. +// +// It receives callbacks for events on the underlying ADS stream and invokes +// corresponding callbacks on interested authorities. +type channelState struct { + parent *XDSClient + serverConfig *ServerConfig + + // Access to the following fields should be protected by the parent's + // channelsMu. + channel *xdsChannel + interestedAuthorities map[*authority]bool +} + +func (cs *channelState) adsStreamFailure(err error) { + if cs.parent.done.HasFired() { + return + } + + if xdsresource.ErrType(err) != xdsresource.ErrTypeStreamFailedAfterRecv && cs.parent.metricsReporter != nil { + cs.parent.metricsReporter.ReportMetric(&metrics.ServerFailure{ + ServerURI: cs.serverConfig.ServerIdentifier.ServerURI, + }) + } + + cs.parent.channelsMu.Lock() + defer cs.parent.channelsMu.Unlock() + for authority := range cs.interestedAuthorities { + authority.adsStreamFailure(cs.serverConfig, err) + } +} + +func (cs *channelState) adsResourceUpdate(typ ResourceType, updates map[string]dataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { + if cs.parent.done.HasFired() { + return + } + + cs.parent.channelsMu.Lock() + defer cs.parent.channelsMu.Unlock() + + if len(cs.interestedAuthorities) == 0 { + onDone() + return + } + + authorityCnt := new(atomic.Int64) + authorityCnt.Add(int64(len(cs.interestedAuthorities))) + done := func() { + if authorityCnt.Add(-1) == 0 { + onDone() + } + } + for authority := range cs.interestedAuthorities { + authority.adsResourceUpdate(cs.serverConfig, typ, updates, md, done) + } +} + +func (cs *channelState) adsResourceDoesNotExist(typ ResourceType, resourceName string) { + if cs.parent.done.HasFired() { + return + } + + cs.parent.channelsMu.Lock() + defer cs.parent.channelsMu.Unlock() + for authority := range cs.interestedAuthorities { + authority.adsResourceDoesNotExist(typ, resourceName) + } +} + +func resourceWatchStateForTesting(c *XDSClient, rType ResourceType, resourceName string) (xdsresource.ResourceWatchState, error) { + c.channelsMu.Lock() + defer c.channelsMu.Unlock() + + for _, state := range c.xdsActiveChannels { + if st, err := state.channel.ads.adsResourceWatchStateForTesting(rType, resourceName); err == nil { + return st, nil + } + } + return xdsresource.ResourceWatchState{}, fmt.Errorf("unable to find watch state for resource type %q and name %q", rType.TypeName, resourceName) +} diff --git a/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsconfig.go b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsconfig.go new file mode 100644 index 0000000000..a276309dff --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/clients/xdsclient/xdsconfig.go @@ -0,0 +1,93 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package xdsclient + +import ( + "google.golang.org/grpc/xds/internal/clients" +) + +// Config is used to configure an xDS client. After one has been passed to the +// xDS client's New function, no part of it may be modified. A Config may be +// reused; the xdsclient package will also not modify it. +type Config struct { + // Servers specifies a list of xDS management servers to connect to. The + // order of the servers in this list reflects the order of preference of + // the data returned by those servers. The xDS client uses the first + // available server from the list. + // + // See gRFC A71 for more details on fallback behavior when the primary + // xDS server is unavailable. + // + // gRFC A71: https://github.com/grpc/proposal/blob/master/A71-xds-fallback.md + Servers []ServerConfig + + // Authorities defines the configuration for each xDS authority. Federated resources + // will be fetched from the servers specified by the corresponding Authority. + Authorities map[string]Authority + + // Node is the identity of the xDS client connecting to the xDS + // management server. + Node clients.Node + + // TransportBuilder is used to create connections to xDS management servers. + TransportBuilder clients.TransportBuilder + + // ResourceTypes is a map from resource type URLs to resource type + // implementations. Each resource type URL uniquely identifies a specific + // kind of xDS resource, and the corresponding resource type implementation + // provides logic for parsing, validating, and processing resources of that + // type. + // + // For example: "type.googleapis.com/envoy.config.listener.v3.Listener" + ResourceTypes map[string]ResourceType + + // MetricsReporter is used to report registered metrics. If unset, no + // metrics will be reported. + MetricsReporter clients.MetricsReporter +} + +// ServerConfig contains configuration for an xDS management server. +type ServerConfig struct { + ServerIdentifier clients.ServerIdentifier + + // IgnoreResourceDeletion is a server feature which if set to true, + // indicates that resource deletion errors from xDS management servers can + // be ignored and cached resource data can be used. + // + // This will be removed in the future once we implement gRFC A88 + // and two new fields FailOnDataErrors and + // ResourceTimerIsTransientError will be introduced. + IgnoreResourceDeletion bool + + // TODO: Link to gRFC A88 +} + +// Authority contains configuration for an xDS control plane authority. +// +// See: https://www.envoyproxy.io/docs/envoy/latest/xds/core/v3/resource_locator.proto#xds-core-v3-resourcelocator +type Authority struct { + // XDSServers contains the list of server configurations for this authority. + // + // See Config.Servers for more details. + XDSServers []ServerConfig +} + +func isServerConfigEqual(a, b *ServerConfig) bool { + return a.ServerIdentifier == b.ServerIdentifier && a.IgnoreResourceDeletion == b.IgnoreResourceDeletion +} diff --git a/vendor/google.golang.org/grpc/xds/internal/internal.go b/vendor/google.golang.org/grpc/xds/internal/internal.go index 23db64a4d4..9e0b7931b5 100644 --- a/vendor/google.golang.org/grpc/xds/internal/internal.go +++ b/vendor/google.golang.org/grpc/xds/internal/internal.go @@ -23,44 +23,30 @@ import ( "fmt" "google.golang.org/grpc/resolver" + "google.golang.org/grpc/xds/internal/clients" ) -// LocalityID is xds.Locality without XXX fields, so it can be used as map -// keys. -// -// xds.Locality cannot be map keys because one of the XXX fields is a slice. -type LocalityID struct { - Region string `json:"region,omitempty"` - Zone string `json:"zone,omitempty"` - SubZone string `json:"subZone,omitempty"` -} - -// ToString generates a string representation of LocalityID in the format -// specified in gRFC A76. Not calling it String() so printf won't call it. -func (l LocalityID) ToString() string { +// LocalityString generates a string representation of clients.Locality in the +// format specified in gRFC A76. +func LocalityString(l clients.Locality) string { return fmt.Sprintf("{region=%q, zone=%q, sub_zone=%q}", l.Region, l.Zone, l.SubZone) } -// Equal allows the values to be compared by Attributes.Equal. -func (l LocalityID) Equal(o any) bool { - ol, ok := o.(LocalityID) +// IsLocalityEqual allows the values to be compared by Attributes.Equal. +func IsLocalityEqual(l clients.Locality, o any) bool { + ol, ok := o.(clients.Locality) if !ok { return false } return l.Region == ol.Region && l.Zone == ol.Zone && l.SubZone == ol.SubZone } -// Empty returns whether or not the locality ID is empty. -func (l LocalityID) Empty() bool { - return l.Region == "" && l.Zone == "" && l.SubZone == "" -} - -// LocalityIDFromString converts a string representation of locality as +// LocalityFromString converts a string representation of clients.locality as // specified in gRFC A76, into a LocalityID struct. -func LocalityIDFromString(s string) (ret LocalityID, _ error) { +func LocalityFromString(s string) (ret clients.Locality, _ error) { _, err := fmt.Sscanf(s, "{region=%q, zone=%q, sub_zone=%q}", &ret.Region, &ret.Zone, &ret.SubZone) if err != nil { - return LocalityID{}, fmt.Errorf("%s is not a well formatted locality ID, error: %v", s, err) + return clients.Locality{}, fmt.Errorf("%s is not a well formatted locality ID, error: %v", s, err) } return ret, nil } @@ -70,19 +56,19 @@ type localityKeyType string const localityKey = localityKeyType("grpc.xds.internal.address.locality") // GetLocalityID returns the locality ID of addr. -func GetLocalityID(addr resolver.Address) LocalityID { - path, _ := addr.BalancerAttributes.Value(localityKey).(LocalityID) +func GetLocalityID(addr resolver.Address) clients.Locality { + path, _ := addr.BalancerAttributes.Value(localityKey).(clients.Locality) return path } // SetLocalityID sets locality ID in addr to l. -func SetLocalityID(addr resolver.Address, l LocalityID) resolver.Address { +func SetLocalityID(addr resolver.Address, l clients.Locality) resolver.Address { addr.BalancerAttributes = addr.BalancerAttributes.WithValue(localityKey, l) return addr } // SetLocalityIDInEndpoint sets locality ID in endpoint to l. -func SetLocalityIDInEndpoint(endpoint resolver.Endpoint, l LocalityID) resolver.Endpoint { +func SetLocalityIDInEndpoint(endpoint resolver.Endpoint, l clients.Locality) resolver.Endpoint { endpoint.Attributes = endpoint.Attributes.WithValue(localityKey, l) return endpoint } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/client.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/client.go index 8fa6b1a522..42f1a28f0c 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/client.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/client.go @@ -21,9 +21,11 @@ package xdsclient import ( + "context" + v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" "google.golang.org/grpc/internal/xds/bootstrap" - "google.golang.org/grpc/xds/internal/xdsclient/load" + "google.golang.org/grpc/xds/internal/clients/lrsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" ) @@ -47,7 +49,7 @@ type XDSClient interface { // the watcher is canceled. Callers need to handle this case. WatchResource(rType xdsresource.Type, resourceName string, watcher xdsresource.ResourceWatcher) (cancel func()) - ReportLoad(*bootstrap.ServerConfig) (*load.Store, func()) + ReportLoad(*bootstrap.ServerConfig) (*lrsclient.LoadStore, func(context.Context)) BootstrapConfig() *bootstrap.Config } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl.go index d8e727e318..9671827407 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl.go @@ -19,25 +19,22 @@ package xdsclient import ( - "context" - "errors" "fmt" - "sync" "sync/atomic" "time" - v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" + "google.golang.org/grpc" estats "google.golang.org/grpc/experimental/stats" - "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/grpclog" - "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/xds/bootstrap" - xdsclientinternal "google.golang.org/grpc/xds/internal/xdsclient/internal" - "google.golang.org/grpc/xds/internal/xdsclient/transport" - "google.golang.org/grpc/xds/internal/xdsclient/transport/ads" - "google.golang.org/grpc/xds/internal/xdsclient/transport/grpctransport" - "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" + + xdsbootstrap "google.golang.org/grpc/xds/bootstrap" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/grpctransport" + "google.golang.org/grpc/xds/internal/clients/lrsclient" + "google.golang.org/grpc/xds/internal/clients/xdsclient" + "google.golang.org/grpc/xds/internal/clients/xdsclient/metrics" ) const ( @@ -50,11 +47,6 @@ const ( ) var ( - _ XDSClient = &clientImpl{} - - // ErrClientClosed is returned when the xDS client is closed. - ErrClientClosed = errors.New("xds: the xDS client is closed") - // The following functions are no-ops in the actual code, but can be // overridden in tests to give them visibility into certain events. xdsClientImplCreateHook = func(string) {} @@ -85,88 +77,59 @@ var ( }) ) -// clientImpl is the real implementation of the xDS client. The exported Client -// is a wrapper of this struct with a ref count. +// clientImpl embed xdsclient.XDSClient and implement internal XDSClient +// interface with ref counting so that it can be shared by the xds resolver and +// balancer implementations, across multiple ClientConns and Servers. type clientImpl struct { + *xdsclient.XDSClient // TODO: #8313 - get rid of embedding, if possible. + // The following fields are initialized at creation time and are read-only - // after that, and therefore can be accessed without a mutex. - done *grpcsync.Event // Fired when the client is closed. - topLevelAuthority *authority // The top-level authority, used only for old-style names without an authority. - authorities map[string]*authority // Map from authority names in bootstrap to authority struct. - config *bootstrap.Config // Complete bootstrap configuration. - watchExpiryTimeout time.Duration // Expiry timeout for ADS watch. - backoff func(int) time.Duration // Backoff for ADS and LRS stream failures. - transportBuilder transport.Builder // Builder to create transports to xDS server. - resourceTypes *resourceTypeRegistry // Registry of resource types, for parsing incoming ADS responses. - serializer *grpcsync.CallbackSerializer // Serializer for invoking resource watcher callbacks. - serializerClose func() // Function to close the serializer. - logger *grpclog.PrefixLogger // Logger for this client. - metricsRecorder estats.MetricsRecorder // Metrics recorder for metrics. - target string // The gRPC target for this client. + // after that. + xdsClientConfig xdsclient.Config + bootstrapConfig *bootstrap.Config + logger *grpclog.PrefixLogger + target string + lrsClient *lrsclient.LRSClient - // The clientImpl owns a bunch of channels to individual xDS servers - // specified in the bootstrap configuration. Authorities acquire references - // to these channels based on server configs within the authority config. - // The clientImpl maintains a list of interested authorities for each of - // these channels, and forwards updates from the channels to each of these - // authorities. - // - // Once all references to a channel are dropped, the channel is closed. - channelsMu sync.Mutex - xdsActiveChannels map[string]*channelState // Map from server config to in-use xdsChannels. + // Accessed atomically + refCount int32 } -func init() { - internal.TriggerXDSResourceNotFoundForTesting = triggerXDSResourceNotFoundForTesting - xdsclientinternal.ResourceWatchStateForTesting = resourceWatchStateForTesting - - DefaultPool = &Pool{clients: make(map[string]*clientRefCounted)} +// metricsReporter implements the clients.MetricsReporter interface and uses an +// underlying stats.MetricsRecorderList to record metrics. +type metricsReporter struct { + recorder estats.MetricsRecorder + target string } -// newClientImpl returns a new xdsClient with the given config. -func newClientImpl(config *bootstrap.Config, watchExpiryTimeout time.Duration, streamBackoff func(int) time.Duration, mr estats.MetricsRecorder, target string) (*clientImpl, error) { - ctx, cancel := context.WithCancel(context.Background()) - c := &clientImpl{ - metricsRecorder: mr, - target: target, - done: grpcsync.NewEvent(), - authorities: make(map[string]*authority), - config: config, - watchExpiryTimeout: watchExpiryTimeout, - backoff: streamBackoff, - serializer: grpcsync.NewCallbackSerializer(ctx), - serializerClose: cancel, - transportBuilder: &grpctransport.Builder{}, - resourceTypes: newResourceTypeRegistry(), - xdsActiveChannels: make(map[string]*channelState), +// ReportMetric implements the clients.MetricsReporter interface. +// It receives metric data, determines the appropriate metric based on the type +// of the data, and records it using the embedded MetricsRecorderList. +func (mr *metricsReporter) ReportMetric(metric any) { + if mr.recorder == nil { + return } - for name, cfg := range config.Authorities() { - // If server configs are specified in the authorities map, use that. - // Else, use the top-level server configs. - serverCfg := config.XDSServers() - if len(cfg.XDSServers) >= 1 { - serverCfg = cfg.XDSServers - } - c.authorities[name] = newAuthority(authorityBuildOptions{ - serverConfigs: serverCfg, - name: name, - serializer: c.serializer, - getChannelForADS: c.getChannelForADS, - logPrefix: clientPrefix(c), - target: target, - metricsRecorder: c.metricsRecorder, - }) + switch m := metric.(type) { + case *metrics.ResourceUpdateValid: + xdsClientResourceUpdatesValidMetric.Record(mr.recorder, 1, mr.target, m.ServerURI, m.ResourceType) + case *metrics.ResourceUpdateInvalid: + xdsClientResourceUpdatesInvalidMetric.Record(mr.recorder, 1, mr.target, m.ServerURI, m.ResourceType) + case *metrics.ServerFailure: + xdsClientServerFailureMetric.Record(mr.recorder, 1, mr.target, m.ServerURI) } - c.topLevelAuthority = newAuthority(authorityBuildOptions{ - serverConfigs: config.XDSServers(), - name: "", - serializer: c.serializer, - getChannelForADS: c.getChannelForADS, - logPrefix: clientPrefix(c), - target: target, - metricsRecorder: c.metricsRecorder, - }) +} + +func newClientImpl(config *bootstrap.Config, metricsRecorder estats.MetricsRecorder, target string) (*clientImpl, error) { + gConfig, err := buildXDSClientConfig(config, metricsRecorder, target) + if err != nil { + return nil, err + } + client, err := xdsclient.New(gConfig) + if err != nil { + return nil, err + } + c := &clientImpl{XDSClient: client, xdsClientConfig: gConfig, bootstrapConfig: config, target: target, refCount: 1} c.logger = prefixLogger(c) return c, nil } @@ -174,332 +137,102 @@ func newClientImpl(config *bootstrap.Config, watchExpiryTimeout time.Duration, s // BootstrapConfig returns the configuration read from the bootstrap file. // Callers must treat the return value as read-only. func (c *clientImpl) BootstrapConfig() *bootstrap.Config { - return c.config + return c.bootstrapConfig } -// close closes the xDS client and releases all resources. -func (c *clientImpl) close() { - if c.done.HasFired() { - return - } - c.done.Fire() - - c.topLevelAuthority.close() - for _, a := range c.authorities { - a.close() - } +func (c *clientImpl) incrRef() int32 { + return atomic.AddInt32(&c.refCount, 1) +} - // Channel close cannot be invoked with the lock held, because it can race - // with stream failure happening at the same time. The latter will callback - // into the clientImpl and will attempt to grab the lock. This will result - // in a deadlock. So instead, we release the lock and wait for all active - // channels to be closed. - var channelsToClose []*xdsChannel - c.channelsMu.Lock() - for _, cs := range c.xdsActiveChannels { - channelsToClose = append(channelsToClose, cs.channel) - } - c.xdsActiveChannels = nil - c.channelsMu.Unlock() - for _, c := range channelsToClose { - c.close() - } +func (c *clientImpl) decrRef() int32 { + return atomic.AddInt32(&c.refCount, -1) +} - c.serializerClose() - <-c.serializer.Done() +// buildXDSClientConfig builds the xdsclient.Config from the bootstrap.Config. +func buildXDSClientConfig(config *bootstrap.Config, metricsRecorder estats.MetricsRecorder, target string) (xdsclient.Config, error) { + grpcTransportConfigs := make(map[string]grpctransport.Config) + gServerCfgMap := make(map[xdsclient.ServerConfig]*bootstrap.ServerConfig) - for _, s := range c.config.XDSServers() { - for _, f := range s.Cleanups() { - f() + gAuthorities := make(map[string]xdsclient.Authority) + for name, cfg := range config.Authorities() { + // If server configs are specified in the authorities map, use that. + // Else, use the top-level server configs. + serverCfg := config.XDSServers() + if len(cfg.XDSServers) >= 1 { + serverCfg = cfg.XDSServers } - } - for _, a := range c.config.Authorities() { - for _, s := range a.XDSServers { - for _, f := range s.Cleanups() { - f() + var gServerCfg []xdsclient.ServerConfig + for _, sc := range serverCfg { + if err := populateGRPCTransportConfigsFromServerConfig(sc, grpcTransportConfigs); err != nil { + return xdsclient.Config{}, err } + gsc := xdsclient.ServerConfig{ + ServerIdentifier: clients.ServerIdentifier{ServerURI: sc.ServerURI(), Extensions: grpctransport.ServerIdentifierExtension{ConfigName: sc.SelectedCreds().Type}}, + IgnoreResourceDeletion: sc.ServerFeaturesIgnoreResourceDeletion()} + gServerCfg = append(gServerCfg, gsc) + gServerCfgMap[gsc] = sc } - } - c.logger.Infof("Shutdown") -} - -// getChannelForADS returns an xdsChannel for the given server configuration. -// -// If an xdsChannel exists for the given server configuration, it is returned. -// Else a new one is created. It also ensures that the calling authority is -// added to the set of interested authorities for the returned channel. -// -// It returns the xdsChannel and a function to release the calling authority's -// reference on the channel. The caller must call the cancel function when it is -// no longer interested in this channel. -// -// A non-nil error is returned if an xdsChannel was not created. -func (c *clientImpl) getChannelForADS(serverConfig *bootstrap.ServerConfig, callingAuthority *authority) (*xdsChannel, func(), error) { - if c.done.HasFired() { - return nil, nil, ErrClientClosed + gAuthorities[name] = xdsclient.Authority{XDSServers: gServerCfg} } - initLocked := func(s *channelState) { - if c.logger.V(2) { - c.logger.Infof("Adding authority %q to the set of interested authorities for channel [%p]", callingAuthority.name, s.channel) + gServerCfgs := make([]xdsclient.ServerConfig, 0, len(config.XDSServers())) + for _, sc := range config.XDSServers() { + if err := populateGRPCTransportConfigsFromServerConfig(sc, grpcTransportConfigs); err != nil { + return xdsclient.Config{}, err } - s.interestedAuthorities[callingAuthority] = true - } - deInitLocked := func(s *channelState) { - if c.logger.V(2) { - c.logger.Infof("Removing authority %q from the set of interested authorities for channel [%p]", callingAuthority.name, s.channel) - } - delete(s.interestedAuthorities, callingAuthority) - } - - return c.getOrCreateChannel(serverConfig, initLocked, deInitLocked) -} - -// getChannelForLRS returns an xdsChannel for the given server configuration. -// -// If an xdsChannel exists for the given server configuration, it is returned. -// Else a new one is created. A reference count that tracks the number of LRS -// calls on the returned channel is incremented before returning the channel. -// -// It returns the xdsChannel and a function to decrement the reference count -// that tracks the number of LRS calls on the returned channel. The caller must -// call the cancel function when it is no longer interested in this channel. -// -// A non-nil error is returned if an xdsChannel was not created. -func (c *clientImpl) getChannelForLRS(serverConfig *bootstrap.ServerConfig) (*xdsChannel, func(), error) { - if c.done.HasFired() { - return nil, nil, ErrClientClosed - } - - initLocked := func(s *channelState) { s.lrsRefs++ } - deInitLocked := func(s *channelState) { s.lrsRefs-- } - - return c.getOrCreateChannel(serverConfig, initLocked, deInitLocked) -} - -// getOrCreateChannel returns an xdsChannel for the given server configuration. -// -// If an active xdsChannel exists for the given server configuration, it is -// returned. If an idle xdsChannel exists for the given server configuration, it -// is revived from the idle cache and returned. Else a new one is created. -// -// The initLocked function runs some initialization logic before the channel is -// returned. This includes adding the calling authority to the set of interested -// authorities for the channel or incrementing the count of the number of LRS -// calls on the channel. -// -// The deInitLocked function runs some cleanup logic when the returned cleanup -// function is called. This involves removing the calling authority from the set -// of interested authorities for the channel or decrementing the count of the -// number of LRS calls on the channel. -// -// Both initLocked and deInitLocked are called with the c.channelsMu held. -// -// Returns the xdsChannel and a cleanup function to be invoked when the channel -// is no longer required. A non-nil error is returned if an xdsChannel was not -// created. -func (c *clientImpl) getOrCreateChannel(serverConfig *bootstrap.ServerConfig, initLocked, deInitLocked func(*channelState)) (*xdsChannel, func(), error) { - c.channelsMu.Lock() - defer c.channelsMu.Unlock() - - if c.logger.V(2) { - c.logger.Infof("Received request for a reference to an xdsChannel for server config %q", serverConfig) - } - - // Use an existing channel, if one exists for this server config. - if state, ok := c.xdsActiveChannels[serverConfig.String()]; ok { - if c.logger.V(2) { - c.logger.Infof("Reusing an existing xdsChannel for server config %q", serverConfig) + gsc := xdsclient.ServerConfig{ + ServerIdentifier: clients.ServerIdentifier{ServerURI: sc.ServerURI(), Extensions: grpctransport.ServerIdentifierExtension{ConfigName: sc.SelectedCreds().Type}}, + IgnoreResourceDeletion: sc.ServerFeaturesIgnoreResourceDeletion()} + gServerCfgs = append(gServerCfgs, gsc) + gServerCfgMap[gsc] = sc + } + + node := config.Node() + gNode := clients.Node{ + ID: node.GetId(), + Cluster: node.GetCluster(), + Metadata: node.Metadata, + UserAgentName: node.UserAgentName, + UserAgentVersion: node.GetUserAgentVersion(), + } + if node.Locality != nil { + gNode.Locality = clients.Locality{ + Region: node.Locality.Region, + Zone: node.Locality.Zone, + SubZone: node.Locality.SubZone, } - initLocked(state) - return state.channel, c.releaseChannel(serverConfig, state, deInitLocked), nil - } - - if c.logger.V(2) { - c.logger.Infof("Creating a new xdsChannel for server config %q", serverConfig) - } - - // Create a new transport and create a new xdsChannel, and add it to the - // map of xdsChannels. - tr, err := c.transportBuilder.Build(transport.BuildOptions{ServerConfig: serverConfig}) - if err != nil { - return nil, func() {}, fmt.Errorf("xds: failed to create transport for server config %s: %v", serverConfig, err) } - state := &channelState{ - parent: c, - serverConfig: serverConfig, - interestedAuthorities: make(map[*authority]bool), - } - channel, err := newXDSChannel(xdsChannelOpts{ - transport: tr, - serverConfig: serverConfig, - bootstrapConfig: c.config, - resourceTypeGetter: c.resourceTypes.get, - eventHandler: state, - backoff: c.backoff, - watchExpiryTimeout: c.watchExpiryTimeout, - logPrefix: clientPrefix(c), - }) - if err != nil { - return nil, func() {}, fmt.Errorf("xds: failed to create xdsChannel for server config %s: %v", serverConfig, err) - } - state.channel = channel - c.xdsActiveChannels[serverConfig.String()] = state - initLocked(state) - return state.channel, c.releaseChannel(serverConfig, state, deInitLocked), nil -} - -// releaseChannel is a function that is called when a reference to an xdsChannel -// needs to be released. It handles closing channels with no active references. -// -// The function takes the following parameters: -// - serverConfig: the server configuration for the xdsChannel -// - state: the state of the xdsChannel -// - deInitLocked: a function that performs any necessary cleanup for the xdsChannel -// -// The function returns another function that can be called to release the -// reference to the xdsChannel. This returned function is idempotent, meaning -// it can be called multiple times without any additional effect. -func (c *clientImpl) releaseChannel(serverConfig *bootstrap.ServerConfig, state *channelState, deInitLocked func(*channelState)) func() { - return sync.OnceFunc(func() { - c.channelsMu.Lock() - if c.logger.V(2) { - c.logger.Infof("Received request to release a reference to an xdsChannel for server config %q", serverConfig) + return xdsclient.Config{ + Authorities: gAuthorities, + Servers: gServerCfgs, + Node: gNode, + TransportBuilder: grpctransport.NewBuilder(grpcTransportConfigs), + ResourceTypes: supportedResourceTypes(config, gServerCfgMap), + MetricsReporter: &metricsReporter{recorder: metricsRecorder, target: target}, + }, nil +} + +// populateGRPCTransportConfigsFromServerConfig iterates through the channel +// credentials of the provided server configuration, builds credential bundles, +// and populates the grpctransport.Config map. +func populateGRPCTransportConfigsFromServerConfig(sc *bootstrap.ServerConfig, grpcTransportConfigs map[string]grpctransport.Config) error { + for _, cc := range sc.ChannelCreds() { + c := xdsbootstrap.GetCredentials(cc.Type) + if c == nil { + continue } - deInitLocked(state) - - // The channel has active users. Do nothing and return. - if state.lrsRefs != 0 || len(state.interestedAuthorities) != 0 { - if c.logger.V(2) { - c.logger.Infof("xdsChannel %p has other active references", state.channel) - } - c.channelsMu.Unlock() - return + bundle, _, err := c.Build(cc.Config) + if err != nil { + return fmt.Errorf("xds: failed to build credentials bundle from bootstrap for %q: %v", cc.Type, err) } - - delete(c.xdsActiveChannels, serverConfig.String()) - if c.logger.V(2) { - c.logger.Infof("Closing xdsChannel [%p] for server config %s", state.channel, serverConfig) - } - channelToClose := state.channel - c.channelsMu.Unlock() - - channelToClose.close() - }) -} - -// dumpResources returns the status and contents of all xDS resources. -func (c *clientImpl) dumpResources() *v3statuspb.ClientConfig { - retCfg := c.topLevelAuthority.dumpResources() - for _, a := range c.authorities { - retCfg = append(retCfg, a.dumpResources()...) - } - - return &v3statuspb.ClientConfig{ - Node: c.config.Node(), - GenericXdsConfigs: retCfg, - } -} - -// channelState represents the state of an xDS channel. It tracks the number of -// LRS references, the authorities interested in the channel, and the server -// configuration used for the channel. -// -// It receives callbacks for events on the underlying ADS stream and invokes -// corresponding callbacks on interested authorities. -type channelState struct { - parent *clientImpl - serverConfig *bootstrap.ServerConfig - - // Access to the following fields should be protected by the parent's - // channelsMu. - channel *xdsChannel - lrsRefs int - interestedAuthorities map[*authority]bool -} - -func (cs *channelState) adsStreamFailure(err error) { - if cs.parent.done.HasFired() { - return - } - - if xdsresource.ErrType(err) != xdsresource.ErrTypeStreamFailedAfterRecv { - xdsClientServerFailureMetric.Record(cs.parent.metricsRecorder, 1, cs.parent.target, cs.serverConfig.ServerURI()) - } - - cs.parent.channelsMu.Lock() - defer cs.parent.channelsMu.Unlock() - for authority := range cs.interestedAuthorities { - authority.adsStreamFailure(cs.serverConfig, err) - } -} - -func (cs *channelState) adsResourceUpdate(typ xdsresource.Type, updates map[string]ads.DataAndErrTuple, md xdsresource.UpdateMetadata, onDone func()) { - if cs.parent.done.HasFired() { - return - } - - cs.parent.channelsMu.Lock() - defer cs.parent.channelsMu.Unlock() - - if len(cs.interestedAuthorities) == 0 { - onDone() - return - } - - authorityCnt := new(atomic.Int64) - authorityCnt.Add(int64(len(cs.interestedAuthorities))) - done := func() { - if authorityCnt.Add(-1) == 0 { - onDone() + grpcTransportConfigs[cc.Type] = grpctransport.Config{ + Credentials: bundle, + GRPCNewClient: func(target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) { + opts = append(opts, sc.DialOptions()...) + return grpc.NewClient(target, opts...) + }, } } - for authority := range cs.interestedAuthorities { - authority.adsResourceUpdate(cs.serverConfig, typ, updates, md, done) - } -} - -func (cs *channelState) adsResourceDoesNotExist(typ xdsresource.Type, resourceName string) { - if cs.parent.done.HasFired() { - return - } - - cs.parent.channelsMu.Lock() - defer cs.parent.channelsMu.Unlock() - for authority := range cs.interestedAuthorities { - authority.adsResourceDoesNotExist(typ, resourceName) - } -} - -// clientRefCounted is ref-counted, and to be shared by the xds resolver and -// balancer implementations, across multiple ClientConns and Servers. -type clientRefCounted struct { - *clientImpl - - refCount int32 // accessed atomically -} - -func (c *clientRefCounted) incrRef() int32 { - return atomic.AddInt32(&c.refCount, 1) -} - -func (c *clientRefCounted) decrRef() int32 { - return atomic.AddInt32(&c.refCount, -1) -} - -func triggerXDSResourceNotFoundForTesting(client XDSClient, typ xdsresource.Type, name string) error { - crc, ok := client.(*clientRefCounted) - if !ok { - return fmt.Errorf("xds: xDS client is of type %T, want %T", client, &clientRefCounted{}) - } - return crc.clientImpl.triggerResourceNotFoundForTesting(typ, name) -} - -func resourceWatchStateForTesting(client XDSClient, typ xdsresource.Type, name string) (ads.ResourceWatchState, error) { - crc, ok := client.(*clientRefCounted) - if !ok { - return ads.ResourceWatchState{}, fmt.Errorf("xds: xDS client is of type %T, want %T", client, &clientRefCounted{}) - } - return crc.clientImpl.resourceWatchStateForTesting(typ, name) + return nil } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_loadreport.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_loadreport.go index efb41b87db..39004ae7ef 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_loadreport.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_loadreport.go @@ -18,24 +18,44 @@ package xdsclient import ( + "context" + "sync" + "google.golang.org/grpc/internal/xds/bootstrap" - "google.golang.org/grpc/xds/internal/xdsclient/load" + "google.golang.org/grpc/xds/internal/clients" + "google.golang.org/grpc/xds/internal/clients/grpctransport" + "google.golang.org/grpc/xds/internal/clients/lrsclient" ) // ReportLoad starts a load reporting stream to the given server. All load // reports to the same server share the LRS stream. // -// It returns a Store for the user to report loads, a function to cancel the -// load reporting stream. -func (c *clientImpl) ReportLoad(server *bootstrap.ServerConfig) (*load.Store, func()) { - xc, releaseChannelRef, err := c.getChannelForLRS(server) +// It returns a lrsclient.LoadStore for the user to report loads. +func (c *clientImpl) ReportLoad(server *bootstrap.ServerConfig) (*lrsclient.LoadStore, func(context.Context)) { + if c.lrsClient == nil { + lrsC, err := lrsclient.New(lrsclient.Config{ + Node: c.xdsClientConfig.Node, + TransportBuilder: c.xdsClientConfig.TransportBuilder, + }) + if err != nil { + c.logger.Warningf("Failed to create an lrs client to the management server to report load: %v", server, err) + return nil, func(context.Context) {} + } + c.lrsClient = lrsC + } + + load, err := c.lrsClient.ReportLoad(clients.ServerIdentifier{ + ServerURI: server.ServerURI(), + Extensions: grpctransport.ServerIdentifierExtension{ + ConfigName: server.SelectedCreds().Type, + }, + }) if err != nil { - c.logger.Warningf("Failed to create a channel to the management server to report load: %v", server, err) - return nil, func() {} + c.logger.Warningf("Failed to create a load store to the management server to report load: %v", server, err) + return nil, func(context.Context) {} } - load, stopLoadReporting := xc.reportLoad() - return load, func() { - stopLoadReporting() - releaseChannelRef() + var loadStop sync.Once + return load, func(ctx context.Context) { + loadStop.Do(func() { load.Stop(ctx) }) } } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_watchers.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_watchers.go index 2cce17b05a..29435993f1 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_watchers.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/clientimpl_watchers.go @@ -18,147 +18,14 @@ package xdsclient import ( - "context" - "fmt" - "sync" - - "google.golang.org/grpc/xds/internal/xdsclient/transport/ads" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" ) -// wrappingWatcher is a wrapper around an xdsresource.ResourceWatcher that adds -// the node ID to the error messages reported to the watcher. -type wrappingWatcher struct { - xdsresource.ResourceWatcher - nodeID string -} - -func (w *wrappingWatcher) ResourceError(err error, done func()) { - w.ResourceWatcher.ResourceError(fmt.Errorf("[xDS node id: %v]: %w", w.nodeID, err), done) -} - -func (w *wrappingWatcher) AmbientError(err error, done func()) { - w.ResourceWatcher.AmbientError(fmt.Errorf("[xDS node id: %v]: %w", w.nodeID, err), done) -} - // WatchResource uses xDS to discover the resource associated with the provided // resource name. The resource type implementation determines how xDS responses // are are deserialized and validated, as received from the xDS management // server. Upon receipt of a response from the management server, an // appropriate callback on the watcher is invoked. func (c *clientImpl) WatchResource(rType xdsresource.Type, resourceName string, watcher xdsresource.ResourceWatcher) (cancel func()) { - // Return early if the client is already closed. - // - // The client returned from the top-level API is a ref-counted client which - // contains a pointer to `clientImpl`. When all references are released, the - // ref-counted client sets its pointer to `nil`. And if any watch APIs are - // made on such a closed client, we will get here with a `nil` receiver. - if c == nil || c.done.HasFired() { - logger.Warningf("Watch registered for name %q of type %q, but client is closed", rType.TypeName(), resourceName) - return func() {} - } - - watcher = &wrappingWatcher{ - ResourceWatcher: watcher, - nodeID: c.config.Node().GetId(), - } - - if err := c.resourceTypes.maybeRegister(rType); err != nil { - logger.Warningf("Watch registered for type %q, which is already registered", rType.TypeName()) - c.serializer.TrySchedule(func(context.Context) { watcher.ResourceError(err, func() {}) }) - return func() {} - } - - n := xdsresource.ParseName(resourceName) - a := c.getAuthorityForResource(n) - if a == nil { - logger.Warningf("Watch registered for name %q of type %q, authority %q is not found", rType.TypeName(), resourceName, n.Authority) - watcher.ResourceError(fmt.Errorf("authority %q not found in bootstrap config for resource %q", n.Authority, resourceName), func() {}) - return func() {} - } - // The watchResource method on the authority is invoked with n.String() - // instead of resourceName because n.String() canonicalizes the given name. - // So, two resource names which don't differ in the query string, but only - // differ in the order of context params will result in the same resource - // being watched by the authority. - return a.watchResource(rType, n.String(), watcher) -} - -// Gets the authority for the given resource name. -// -// See examples in this section of the gRFC: -// https://github.com/grpc/proposal/blob/master/A47-xds-federation.md#bootstrap-config-changes -func (c *clientImpl) getAuthorityForResource(name *xdsresource.Name) *authority { - // For new-style resource names, always lookup the authorities map. If the - // name does not specify an authority, we will end up looking for an entry - // in the map with the empty string as the key. - if name.Scheme == xdsresource.FederationScheme { - return c.authorities[name.Authority] - } - - // For old-style resource names, we use the top-level authority if the name - // does not specify an authority. - if name.Authority == "" { - return c.topLevelAuthority - } - return c.authorities[name.Authority] -} - -// A registry of xdsresource.Type implementations indexed by their corresponding -// type URLs. Registration of an xdsresource.Type happens the first time a watch -// for a resource of that type is invoked. -type resourceTypeRegistry struct { - mu sync.Mutex - types map[string]xdsresource.Type -} - -func newResourceTypeRegistry() *resourceTypeRegistry { - return &resourceTypeRegistry{types: make(map[string]xdsresource.Type)} -} - -func (r *resourceTypeRegistry) get(url string) xdsresource.Type { - r.mu.Lock() - defer r.mu.Unlock() - return r.types[url] -} - -func (r *resourceTypeRegistry) maybeRegister(rType xdsresource.Type) error { - r.mu.Lock() - defer r.mu.Unlock() - - url := rType.TypeURL() - typ, ok := r.types[url] - if ok && typ != rType { - return fmt.Errorf("attempt to re-register a resource type implementation for %v", rType.TypeName()) - } - r.types[url] = rType - return nil -} - -func (c *clientImpl) triggerResourceNotFoundForTesting(rType xdsresource.Type, resourceName string) error { - c.channelsMu.Lock() - defer c.channelsMu.Unlock() - - if c.logger.V(2) { - c.logger.Infof("Triggering resource not found for type: %s, resource name: %s", rType.TypeName(), resourceName) - } - - for _, state := range c.xdsActiveChannels { - if err := state.channel.triggerResourceNotFoundForTesting(rType, resourceName); err != nil { - return err - } - } - return nil -} - -func (c *clientImpl) resourceWatchStateForTesting(rType xdsresource.Type, resourceName string) (ads.ResourceWatchState, error) { - c.channelsMu.Lock() - defer c.channelsMu.Unlock() - - for _, state := range c.xdsActiveChannels { - if st, err := state.channel.ads.ResourceWatchStateForTesting(rType, resourceName); err == nil { - return st, nil - } - } - return ads.ResourceWatchState{}, fmt.Errorf("unable to find watch state for resource type %q and name %q", rType.TypeName(), resourceName) + return c.XDSClient.WatchResource(rType.TypeURL(), resourceName, xdsresource.GenericResourceWatcher(watcher)) } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/load/store.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/load/store.go deleted file mode 100644 index f1e265ee7d..0000000000 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/load/store.go +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright 2020 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Package load provides functionality to record and maintain load data. -package load - -import ( - "sync" - "sync/atomic" - "time" -) - -const negativeOneUInt64 = ^uint64(0) - -// Store keeps the loads for multiple clusters and services to be reported via -// LRS. It contains loads to reported to one LRS server. Create multiple stores -// for multiple servers. -// -// It is safe for concurrent use. -type Store struct { - // mu only protects the map (2 layers). The read/write to *perClusterStore - // doesn't need to hold the mu. - mu sync.Mutex - // clusters is a map with cluster name as the key. The second layer is a map - // with service name as the key. Each value (perClusterStore) contains data - // for a (cluster, service) pair. - // - // Note that new entries are added to this map, but never removed. This is - // potentially a memory leak. But the memory is allocated for each new - // (cluster,service) pair, and the memory allocated is just pointers and - // maps. So this shouldn't get too bad. - clusters map[string]map[string]*perClusterStore -} - -// NewStore creates a Store. -func NewStore() *Store { - return &Store{ - clusters: make(map[string]map[string]*perClusterStore), - } -} - -// Stats returns the load data for the given cluster names. Data is returned in -// a slice with no specific order. -// -// If no clusterName is given (an empty slice), all data for all known clusters -// is returned. -// -// If a cluster's Data is empty (no load to report), it's not appended to the -// returned slice. -func (s *Store) Stats(clusterNames []string) []*Data { - var ret []*Data - s.mu.Lock() - defer s.mu.Unlock() - - if len(clusterNames) == 0 { - for _, c := range s.clusters { - ret = appendClusterStats(ret, c) - } - return ret - } - - for _, n := range clusterNames { - if c, ok := s.clusters[n]; ok { - ret = appendClusterStats(ret, c) - } - } - return ret -} - -// appendClusterStats gets Data for the given cluster, append to ret, and return -// the new slice. -// -// Data is only appended to ret if it's not empty. -func appendClusterStats(ret []*Data, cluster map[string]*perClusterStore) []*Data { - for _, d := range cluster { - data := d.stats() - if data == nil { - // Skip this data if it doesn't contain any information. - continue - } - ret = append(ret, data) - } - return ret -} - -// PerCluster returns the perClusterStore for the given clusterName + -// serviceName. -func (s *Store) PerCluster(clusterName, serviceName string) PerClusterReporter { - if s == nil { - return nil - } - - s.mu.Lock() - defer s.mu.Unlock() - c, ok := s.clusters[clusterName] - if !ok { - c = make(map[string]*perClusterStore) - s.clusters[clusterName] = c - } - - if p, ok := c[serviceName]; ok { - return p - } - p := &perClusterStore{ - cluster: clusterName, - service: serviceName, - } - c[serviceName] = p - return p -} - -// perClusterStore is a repository for LB policy implementations to report store -// load data. It contains load for a (cluster, edsService) pair. -// -// It is safe for concurrent use. -// -// TODO(easwars): Use regular maps with mutexes instead of sync.Map here. The -// latter is optimized for two common use cases: (1) when the entry for a given -// key is only ever written once but read many times, as in caches that only -// grow, or (2) when multiple goroutines read, write, and overwrite entries for -// disjoint sets of keys. In these two cases, use of a Map may significantly -// reduce lock contention compared to a Go map paired with a separate Mutex or -// RWMutex. -// Neither of these conditions are met here, and we should transition to a -// regular map with a mutex for better type safety. -type perClusterStore struct { - cluster, service string - drops sync.Map // map[string]*uint64 - localityRPCCount sync.Map // map[string]*rpcCountData - - mu sync.Mutex - lastLoadReportAt time.Time -} - -// Update functions are called by picker for each RPC. To avoid contention, all -// updates are done atomically. - -// CallDropped adds one drop record with the given category to store. -func (ls *perClusterStore) CallDropped(category string) { - if ls == nil { - return - } - - p, ok := ls.drops.Load(category) - if !ok { - tp := new(uint64) - p, _ = ls.drops.LoadOrStore(category, tp) - } - atomic.AddUint64(p.(*uint64), 1) -} - -// CallStarted adds one call started record for the given locality. -func (ls *perClusterStore) CallStarted(locality string) { - if ls == nil { - return - } - - p, ok := ls.localityRPCCount.Load(locality) - if !ok { - tp := newRPCCountData() - p, _ = ls.localityRPCCount.LoadOrStore(locality, tp) - } - p.(*rpcCountData).incrInProgress() - p.(*rpcCountData).incrIssued() -} - -// CallFinished adds one call finished record for the given locality. -// For successful calls, err needs to be nil. -func (ls *perClusterStore) CallFinished(locality string, err error) { - if ls == nil { - return - } - - p, ok := ls.localityRPCCount.Load(locality) - if !ok { - // The map is never cleared, only values in the map are reset. So the - // case where entry for call-finish is not found should never happen. - return - } - p.(*rpcCountData).decrInProgress() - if err == nil { - p.(*rpcCountData).incrSucceeded() - } else { - p.(*rpcCountData).incrErrored() - } -} - -// CallServerLoad adds one server load record for the given locality. The -// load type is specified by desc, and its value by val. -func (ls *perClusterStore) CallServerLoad(locality, name string, d float64) { - if ls == nil { - return - } - - p, ok := ls.localityRPCCount.Load(locality) - if !ok { - // The map is never cleared, only values in the map are reset. So the - // case where entry for callServerLoad is not found should never happen. - return - } - p.(*rpcCountData).addServerLoad(name, d) -} - -// Data contains all load data reported to the Store since the most recent call -// to stats(). -type Data struct { - // Cluster is the name of the cluster this data is for. - Cluster string - // Service is the name of the EDS service this data is for. - Service string - // TotalDrops is the total number of dropped requests. - TotalDrops uint64 - // Drops is the number of dropped requests per category. - Drops map[string]uint64 - // LocalityStats contains load reports per locality. - LocalityStats map[string]LocalityData - // ReportInternal is the duration since last time load was reported (stats() - // was called). - ReportInterval time.Duration -} - -// LocalityData contains load data for a single locality. -type LocalityData struct { - // RequestStats contains counts of requests made to the locality. - RequestStats RequestData - // LoadStats contains server load data for requests made to the locality, - // indexed by the load type. - LoadStats map[string]ServerLoadData -} - -// RequestData contains request counts. -type RequestData struct { - // Succeeded is the number of succeeded requests. - Succeeded uint64 - // Errored is the number of requests which ran into errors. - Errored uint64 - // InProgress is the number of requests in flight. - InProgress uint64 - // Issued is the total number requests that were sent. - Issued uint64 -} - -// ServerLoadData contains server load data. -type ServerLoadData struct { - // Count is the number of load reports. - Count uint64 - // Sum is the total value of all load reports. - Sum float64 -} - -func newData(cluster, service string) *Data { - return &Data{ - Cluster: cluster, - Service: service, - Drops: make(map[string]uint64), - LocalityStats: make(map[string]LocalityData), - } -} - -// stats returns and resets all loads reported to the store, except inProgress -// rpc counts. -// -// It returns nil if the store doesn't contain any (new) data. -func (ls *perClusterStore) stats() *Data { - if ls == nil { - return nil - } - - sd := newData(ls.cluster, ls.service) - ls.drops.Range(func(key, val any) bool { - d := atomic.SwapUint64(val.(*uint64), 0) - if d == 0 { - return true - } - sd.TotalDrops += d - keyStr := key.(string) - if keyStr != "" { - // Skip drops without category. They are counted in total_drops, but - // not in per category. One example is drops by circuit breaking. - sd.Drops[keyStr] = d - } - return true - }) - ls.localityRPCCount.Range(func(key, val any) bool { - countData := val.(*rpcCountData) - succeeded := countData.loadAndClearSucceeded() - inProgress := countData.loadInProgress() - errored := countData.loadAndClearErrored() - issued := countData.loadAndClearIssued() - if succeeded == 0 && inProgress == 0 && errored == 0 && issued == 0 { - return true - } - - ld := LocalityData{ - RequestStats: RequestData{ - Succeeded: succeeded, - Errored: errored, - InProgress: inProgress, - Issued: issued, - }, - LoadStats: make(map[string]ServerLoadData), - } - countData.serverLoads.Range(func(key, val any) bool { - sum, count := val.(*rpcLoadData).loadAndClear() - if count == 0 { - return true - } - ld.LoadStats[key.(string)] = ServerLoadData{ - Count: count, - Sum: sum, - } - return true - }) - sd.LocalityStats[key.(string)] = ld - return true - }) - - ls.mu.Lock() - sd.ReportInterval = time.Since(ls.lastLoadReportAt) - ls.lastLoadReportAt = time.Now() - ls.mu.Unlock() - - if sd.TotalDrops == 0 && len(sd.Drops) == 0 && len(sd.LocalityStats) == 0 { - return nil - } - return sd -} - -type rpcCountData struct { - // Only atomic accesses are allowed for the fields. - succeeded *uint64 - errored *uint64 - inProgress *uint64 - issued *uint64 - - // Map from load desc to load data (sum+count). Loading data from map is - // atomic, but updating data takes a lock, which could cause contention when - // multiple RPCs try to report loads for the same desc. - // - // To fix the contention, shard this map. - serverLoads sync.Map // map[string]*rpcLoadData -} - -func newRPCCountData() *rpcCountData { - return &rpcCountData{ - succeeded: new(uint64), - errored: new(uint64), - inProgress: new(uint64), - issued: new(uint64), - } -} - -func (rcd *rpcCountData) incrSucceeded() { - atomic.AddUint64(rcd.succeeded, 1) -} - -func (rcd *rpcCountData) loadAndClearSucceeded() uint64 { - return atomic.SwapUint64(rcd.succeeded, 0) -} - -func (rcd *rpcCountData) incrErrored() { - atomic.AddUint64(rcd.errored, 1) -} - -func (rcd *rpcCountData) loadAndClearErrored() uint64 { - return atomic.SwapUint64(rcd.errored, 0) -} - -func (rcd *rpcCountData) incrInProgress() { - atomic.AddUint64(rcd.inProgress, 1) -} - -func (rcd *rpcCountData) decrInProgress() { - atomic.AddUint64(rcd.inProgress, negativeOneUInt64) // atomic.Add(x, -1) -} - -func (rcd *rpcCountData) loadInProgress() uint64 { - return atomic.LoadUint64(rcd.inProgress) // InProgress count is not clear when reading. -} - -func (rcd *rpcCountData) incrIssued() { - atomic.AddUint64(rcd.issued, 1) -} - -func (rcd *rpcCountData) loadAndClearIssued() uint64 { - return atomic.SwapUint64(rcd.issued, 0) -} - -func (rcd *rpcCountData) addServerLoad(name string, d float64) { - loads, ok := rcd.serverLoads.Load(name) - if !ok { - tl := newRPCLoadData() - loads, _ = rcd.serverLoads.LoadOrStore(name, tl) - } - loads.(*rpcLoadData).add(d) -} - -// Data for server loads (from trailers or oob). Fields in this struct must be -// updated consistently. -// -// The current solution is to hold a lock, which could cause contention. To fix, -// shard serverLoads map in rpcCountData. -type rpcLoadData struct { - mu sync.Mutex - sum float64 - count uint64 -} - -func newRPCLoadData() *rpcLoadData { - return &rpcLoadData{} -} - -func (rld *rpcLoadData) add(v float64) { - rld.mu.Lock() - rld.sum += v - rld.count++ - rld.mu.Unlock() -} - -func (rld *rpcLoadData) loadAndClear() (s float64, c uint64) { - rld.mu.Lock() - s = rld.sum - rld.sum = 0 - c = rld.count - rld.count = 0 - rld.mu.Unlock() - return -} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/pool.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/pool.go index 4a9c0e0922..d1cc847623 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/pool.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/pool.go @@ -25,15 +25,20 @@ import ( v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" estats "google.golang.org/grpc/experimental/stats" - "google.golang.org/grpc/internal/backoff" + "google.golang.org/grpc/internal/envconfig" istats "google.golang.org/grpc/internal/stats" "google.golang.org/grpc/internal/xds/bootstrap" + "google.golang.org/protobuf/proto" ) var ( // DefaultPool is the default pool for xDS clients. It is created at init - // time by reading bootstrap configuration from env vars. - DefaultPool *Pool + // time and reads bootstrap configuration from env vars to create the xDS + // client. + DefaultPool = &Pool{ + clients: make(map[string]*clientImpl), + getConfiguration: sync.OnceValues(bootstrap.GetConfiguration), + } ) // Pool represents a pool of xDS clients that share the same bootstrap @@ -42,9 +47,12 @@ type Pool struct { // Note that mu should ideally only have to guard clients. But here, we need // it to guard config as well since SetFallbackBootstrapConfig writes to // config. - mu sync.Mutex - clients map[string]*clientRefCounted - config *bootstrap.Config + mu sync.Mutex + clients map[string]*clientImpl + fallbackConfig *bootstrap.Config + // getConfiguration is a sync.OnceValues that attempts to read the bootstrap + // configuration from environment variables once. + getConfiguration func() (*bootstrap.Config, error) } // OptionsForTesting contains options to configure xDS client creation for @@ -76,8 +84,10 @@ type OptionsForTesting struct { // bootstrap configuration), xDS client creation will fail. func NewPool(config *bootstrap.Config) *Pool { return &Pool{ - clients: make(map[string]*clientRefCounted), - config: config, + clients: make(map[string]*clientImpl), + getConfiguration: func() (*bootstrap.Config, error) { + return config, nil + }, } } @@ -89,7 +99,7 @@ func NewPool(config *bootstrap.Config) *Pool { // expected to invoke once they are done using the client. It is safe for the // caller to invoke this close function multiple times. func (p *Pool) NewClient(name string, metricsRecorder estats.MetricsRecorder) (XDSClient, func(), error) { - return p.newRefCounted(name, defaultWatchExpiryTimeout, backoff.DefaultExponential.Backoff, metricsRecorder) + return p.newRefCounted(name, metricsRecorder) } // NewClientForTesting returns an xDS client configured with the provided @@ -116,7 +126,12 @@ func (p *Pool) NewClientForTesting(opts OptionsForTesting) (XDSClient, func(), e if opts.MetricsRecorder == nil { opts.MetricsRecorder = istats.NewMetricsRecorderList(nil) } - return p.newRefCounted(opts.Name, opts.WatchExpiryTimeout, opts.StreamBackoffAfterFailure, opts.MetricsRecorder) + c, cancel, err := p.newRefCounted(opts.Name, opts.MetricsRecorder) + if err != nil { + return nil, nil, err + } + c.SetWatchExpiryTimeoutForTesting(opts.WatchExpiryTimeout) + return c, cancel, nil } // GetClientForTesting returns an xDS client created earlier using the given @@ -148,12 +163,7 @@ func (p *Pool) GetClientForTesting(name string) (XDSClient, func(), error) { func (p *Pool) SetFallbackBootstrapConfig(config *bootstrap.Config) { p.mu.Lock() defer p.mu.Unlock() - - if p.config != nil { - logger.Error("Attempt to set a bootstrap configuration even though one is already set via environment variables.") - return - } - p.config = config + p.fallbackConfig = config } // DumpResources returns the status and contents of all xDS resources. @@ -163,7 +173,15 @@ func (p *Pool) DumpResources() *v3statuspb.ClientStatusResponse { resp := &v3statuspb.ClientStatusResponse{} for key, client := range p.clients { - cfg := client.dumpResources() + b, err := client.DumpResources() + if err != nil { + return nil + } + r := &v3statuspb.ClientStatusResponse{} + if err := proto.Unmarshal(b, r); err != nil { + return nil + } + cfg := r.Config[0] cfg.ClientScope = key resp.Config = append(resp.Config, cfg) } @@ -177,7 +195,11 @@ func (p *Pool) DumpResources() *v3statuspb.ClientStatusResponse { func (p *Pool) BootstrapConfigForTesting() *bootstrap.Config { p.mu.Lock() defer p.mu.Unlock() - return p.config + cfg, _ := p.getConfiguration() + if cfg != nil { + return cfg + } + return p.fallbackConfig } // UnsetBootstrapConfigForTesting unsets the bootstrap configuration used by @@ -187,7 +209,8 @@ func (p *Pool) BootstrapConfigForTesting() *bootstrap.Config { func (p *Pool) UnsetBootstrapConfigForTesting() { p.mu.Lock() defer p.mu.Unlock() - p.config = nil + p.fallbackConfig = nil + p.getConfiguration = sync.OnceValues(bootstrap.GetConfiguration) } func (p *Pool) clientRefCountedClose(name string) { @@ -203,42 +226,49 @@ func (p *Pool) clientRefCountedClose(name string) { return } delete(p.clients, name) + + for _, s := range client.bootstrapConfig.XDSServers() { + for _, f := range s.Cleanups() { + f() + } + } + for _, a := range client.bootstrapConfig.Authorities() { + for _, s := range a.XDSServers { + for _, f := range s.Cleanups() { + f() + } + } + } p.mu.Unlock() // This attempts to close the transport to the management server and could // theoretically call back into the xdsclient package again and deadlock. // Hence, this needs to be called without holding the lock. - client.clientImpl.close() + client.Close() + xdsClientImplCloseHook(name) } // newRefCounted creates a new reference counted xDS client implementation for // name, if one does not exist already. If an xDS client for the given name // exists, it gets a reference to it and returns it. -func (p *Pool) newRefCounted(name string, watchExpiryTimeout time.Duration, streamBackoff func(int) time.Duration, metricsRecorder estats.MetricsRecorder) (XDSClient, func(), error) { +func (p *Pool) newRefCounted(name string, metricsRecorder estats.MetricsRecorder) (*clientImpl, func(), error) { p.mu.Lock() defer p.mu.Unlock() - if p.config == nil { - if len(p.clients) != 0 || p != DefaultPool { - // If the current pool `p` already contains xDS clients or it is not - // the `DefaultPool`, the bootstrap config should have been already - // present in the pool. - return nil, nil, fmt.Errorf("xds: bootstrap configuration not set in the pool") - } - // If the current pool `p` is the `DefaultPool` and has no clients, it - // might be the first time an xDS client is being created on it. So, - // the bootstrap configuration is read from environment variables. - // - // DefaultPool is initialized with bootstrap configuration from one of the - // supported environment variables. If the environment variables are not - // set, then fallback bootstrap configuration should be set before - // attempting to create an xDS client, else xDS client creation will fail. - config, err := bootstrap.GetConfiguration() - if err != nil { - return nil, nil, fmt.Errorf("xds: failed to read xDS bootstrap config from env vars: %v", err) - } - p.config = config + config, err := p.getConfiguration() + if err != nil { + return nil, nil, fmt.Errorf("xds: failed to read xDS bootstrap config from env vars: %v", err) + } + + if config == nil { + // If the environment variables are not set, then fallback bootstrap + // configuration should be set before attempting to create an xDS client, + // else xDS client creation will fail. + config = p.fallbackConfig + } + if config == nil { + return nil, nil, fmt.Errorf("failed to read xDS bootstrap config from env vars: bootstrap environment variables (%q or %q) not defined and fallback config not set", envconfig.XDSBootstrapFileNameEnv, envconfig.XDSBootstrapFileContentEnv) } if c := p.clients[name]; c != nil { @@ -246,17 +276,16 @@ func (p *Pool) newRefCounted(name string, watchExpiryTimeout time.Duration, stre return c, sync.OnceFunc(func() { p.clientRefCountedClose(name) }), nil } - c, err := newClientImpl(p.config, watchExpiryTimeout, streamBackoff, metricsRecorder, name) + c, err := newClientImpl(config, metricsRecorder, name) if err != nil { return nil, nil, err } if logger.V(2) { - c.logger.Infof("Created client with name %q and bootstrap configuration:\n %s", name, p.config) + c.logger.Infof("Created client with name %q and bootstrap configuration:\n %s", name, config) } - client := &clientRefCounted{clientImpl: c, refCount: 1} - p.clients[name] = client + p.clients[name] = c xdsClientImplCreateHook(name) - logger.Infof("xDS node ID: %s", p.config.Node().GetId()) - return client, sync.OnceFunc(func() { p.clientRefCountedClose(name) }), nil + logger.Infof("xDS node ID: %s", config.Node().GetId()) + return c, sync.OnceFunc(func() { p.clientRefCountedClose(name) }), nil } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/resource_types.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/resource_types.go new file mode 100644 index 0000000000..2f76c83c84 --- /dev/null +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/resource_types.go @@ -0,0 +1,54 @@ +/* + * + * Copyright 2025 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsclient + +import ( + "google.golang.org/grpc/internal/xds/bootstrap" + "google.golang.org/grpc/xds/internal/clients/xdsclient" + "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" + "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" +) + +func supportedResourceTypes(config *bootstrap.Config, gServerCfgMap map[xdsclient.ServerConfig]*bootstrap.ServerConfig) map[string]xdsclient.ResourceType { + return map[string]xdsclient.ResourceType{ + version.V3ListenerURL: { + TypeURL: version.V3ListenerURL, + TypeName: xdsresource.ListenerResourceTypeName, + AllResourcesRequiredInSotW: true, + Decoder: xdsresource.NewGenericListenerResourceTypeDecoder(config), + }, + version.V3RouteConfigURL: { + TypeURL: version.V3RouteConfigURL, + TypeName: xdsresource.RouteConfigTypeName, + AllResourcesRequiredInSotW: false, + Decoder: xdsresource.NewGenericRouteConfigResourceTypeDecoder(), + }, + version.V3ClusterURL: { + TypeURL: version.V3ClusterURL, + TypeName: xdsresource.ClusterResourceTypeName, + AllResourcesRequiredInSotW: true, + Decoder: xdsresource.NewGenericClusterResourceTypeDecoder(config, gServerCfgMap), + }, + version.V3EndpointsURL: { + TypeURL: version.V3EndpointsURL, + TypeName: xdsresource.EndpointsResourceTypeName, + AllResourcesRequiredInSotW: false, + Decoder: xdsresource.NewGenericEndpointsResourceTypeDecoder(), + }, + } +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/grpctransport/grpctransport.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/grpctransport/grpctransport.go deleted file mode 100644 index fb740ade13..0000000000 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/grpctransport/grpctransport.go +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Package grpctransport provides an implementation of the transport interface -// using gRPC. -package grpctransport - -import ( - "context" - "fmt" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/keepalive" - "google.golang.org/grpc/xds/internal/xdsclient/internal" - "google.golang.org/grpc/xds/internal/xdsclient/transport" - - v3adsgrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - v3adspb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - v3lrsgrpc "github.com/envoyproxy/go-control-plane/envoy/service/load_stats/v3" - v3lrspb "github.com/envoyproxy/go-control-plane/envoy/service/load_stats/v3" -) - -func init() { - internal.GRPCNewClient = grpc.NewClient - internal.NewADSStream = func(ctx context.Context, cc *grpc.ClientConn) (v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesClient, error) { - return v3adsgrpc.NewAggregatedDiscoveryServiceClient(cc).StreamAggregatedResources(ctx) - } -} - -// Builder provides a way to build a gRPC-based transport to an xDS server. -type Builder struct{} - -// Build creates a new gRPC-based transport to an xDS server using the provided -// options. This involves creating a grpc.ClientConn to the server identified by -// the server URI in the provided options. -func (b *Builder) Build(opts transport.BuildOptions) (transport.Transport, error) { - if opts.ServerConfig == nil { - return nil, fmt.Errorf("ServerConfig field in opts cannot be nil") - } - - // NOTE: The bootstrap package ensures that the server_uri and credentials - // inside the server config are always populated. If we end up using a - // different type in BuildOptions to specify the server configuration, we - // must ensure that those fields are not empty before proceeding. - - // Dial the xDS management server with dial options specified by the server - // configuration and a static keepalive configuration that is common across - // gRPC language implementations. - kpCfg := grpc.WithKeepaliveParams(keepalive.ClientParameters{ - Time: 5 * time.Minute, - Timeout: 20 * time.Second, - }) - dopts := append(opts.ServerConfig.DialOptions(), kpCfg) - dialer := internal.GRPCNewClient.(func(string, ...grpc.DialOption) (*grpc.ClientConn, error)) - cc, err := dialer(opts.ServerConfig.ServerURI(), dopts...) - if err != nil { - // An error from a non-blocking dial indicates something serious. - return nil, fmt.Errorf("failed to create a grpc transport to the management server %q: %v", opts.ServerConfig.ServerURI(), err) - } - cc.Connect() - - return &grpcTransport{cc: cc}, nil -} - -type grpcTransport struct { - cc *grpc.ClientConn -} - -func (g *grpcTransport) CreateStreamingCall(ctx context.Context, method string) (transport.StreamingCall, error) { - switch method { - case v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResources_FullMethodName: - return g.newADSStreamingCall(ctx) - case v3lrsgrpc.LoadReportingService_StreamLoadStats_FullMethodName: - return g.newLRSStreamingCall(ctx) - default: - return nil, fmt.Errorf("unsupported method: %v", method) - } -} - -func (g *grpcTransport) newADSStreamingCall(ctx context.Context) (transport.StreamingCall, error) { - newStream := internal.NewADSStream.(func(context.Context, *grpc.ClientConn) (v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesClient, error)) - stream, err := newStream(ctx, g.cc) - if err != nil { - return nil, fmt.Errorf("failed to create an ADS stream: %v", err) - } - return &adsStream{stream: stream}, nil -} - -func (g *grpcTransport) newLRSStreamingCall(ctx context.Context) (transport.StreamingCall, error) { - stream, err := v3lrsgrpc.NewLoadReportingServiceClient(g.cc).StreamLoadStats(ctx) - if err != nil { - return nil, fmt.Errorf("failed to create an LRS stream: %v", err) - } - return &lrsStream{stream: stream}, nil -} - -func (g *grpcTransport) Close() error { - return g.cc.Close() -} - -type adsStream struct { - stream v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesClient -} - -func (a *adsStream) Send(msg any) error { - return a.stream.Send(msg.(*v3adspb.DiscoveryRequest)) -} - -func (a *adsStream) Recv() (any, error) { - return a.stream.Recv() -} - -type lrsStream struct { - stream v3lrsgrpc.LoadReportingService_StreamLoadStatsClient -} - -func (l *lrsStream) Send(msg any) error { - return l.stream.Send(msg.(*v3lrspb.LoadStatsRequest)) -} - -func (l *lrsStream) Recv() (any, error) { - return l.stream.Recv() -} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/transport_interface.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/transport_interface.go deleted file mode 100644 index 48ce82a06e..0000000000 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/transport/transport_interface.go +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Package transport defines the interface that describe the functionality -// required to communicate with an xDS server using streaming calls. -package transport - -import ( - "context" - - "google.golang.org/grpc/internal/xds/bootstrap" -) - -// Builder is an interface for building a new xDS transport. -type Builder interface { - // Build creates a new xDS transport with the provided options. - Build(opts BuildOptions) (Transport, error) -} - -// BuildOptions contains the options for building a new xDS transport. -type BuildOptions struct { - // ServerConfig contains the configuration that controls how the transport - // interacts with the xDS server. This includes the server URI and the - // credentials to use to connect to the server, among other things. - ServerConfig *bootstrap.ServerConfig -} - -// Transport provides the functionality to communicate with an xDS server using -// streaming calls. -type Transport interface { - // CreateStreamingCall creates a new streaming call to the xDS server for the - // specified method name. The returned StreamingCall interface can be used to - // send and receive messages on the stream. - CreateStreamingCall(context.Context, string) (StreamingCall, error) - - // Close closes the underlying connection and cleans up any resources used by the - // Transport. - Close() error -} - -// StreamingCall is an interface that provides a way to send and receive -// messages on a stream. The methods accept or return any.Any messages instead -// of concrete types to allow this interface to be used for both ADS and LRS. -type StreamingCall interface { - // Send sends the provided message on the stream. - Send(any) error - - // Recv block until the next message is received on the stream. - Recv() (any, error) -} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry/converter/converter.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry/converter/converter.go index f0d064c679..959c6588b0 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry/converter/converter.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry/converter/converter.go @@ -33,7 +33,6 @@ import ( "google.golang.org/grpc/balancer/ringhash" "google.golang.org/grpc/balancer/roundrobin" "google.golang.org/grpc/balancer/weightedroundrobin" - "google.golang.org/grpc/internal/envconfig" iringhash "google.golang.org/grpc/internal/ringhash" internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" "google.golang.org/grpc/xds/internal/balancer/wrrlocality" @@ -177,9 +176,6 @@ func convertWeightedRoundRobinProtoToServiceConfig(rawProto []byte, _ int) (json } func convertLeastRequestProtoToServiceConfig(rawProto []byte, _ int) (json.RawMessage, error) { - if !envconfig.LeastRequestLB { - return nil, nil - } lrProto := &v3leastrequestpb.LeastRequest{} if err := proto.Unmarshal(rawProto, lrProto); err != nil { return nil, fmt.Errorf("failed to unmarshal resource: %v", err) diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/cluster_resource_type.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/cluster_resource_type.go index 3d85c31ff4..de63350814 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/cluster_resource_type.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/cluster_resource_type.go @@ -19,6 +19,8 @@ package xdsresource import ( "google.golang.org/grpc/internal/pretty" + "google.golang.org/grpc/internal/xds/bootstrap" + xdsclient "google.golang.org/grpc/xds/internal/clients/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -150,3 +152,9 @@ func WatchCluster(p Producer, name string, w ClusterWatcher) (cancel func()) { delegator := &delegatingClusterWatcher{watcher: w} return p.WatchResource(clusterType, name, delegator) } + +// NewGenericClusterResourceTypeDecoder returns a xdsclient.Decoder that +// wraps the xdsresource.clusterType. +func NewGenericClusterResourceTypeDecoder(bc *bootstrap.Config, gServerCfgMap map[xdsclient.ServerConfig]*bootstrap.ServerConfig) xdsclient.Decoder { + return &GenericResourceTypeDecoder{ResourceType: clusterType, BootstrapConfig: bc, ServerConfigMap: gServerCfgMap} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/endpoints_resource_type.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/endpoints_resource_type.go index de574dd8d3..dd8a3b38c7 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/endpoints_resource_type.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/endpoints_resource_type.go @@ -19,6 +19,7 @@ package xdsresource import ( "google.golang.org/grpc/internal/pretty" + xdsclient "google.golang.org/grpc/xds/internal/clients/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -146,3 +147,9 @@ func WatchEndpoints(p Producer, name string, w EndpointsWatcher) (cancel func()) delegator := &delegatingEndpointsWatcher{watcher: w} return p.WatchResource(endpointsType, name, delegator) } + +// NewGenericEndpointsResourceTypeDecoder returns a xdsclient.Decoder that +// wraps the xdsresource.endpointsType. +func NewGenericEndpointsResourceTypeDecoder() xdsclient.Decoder { + return &GenericResourceTypeDecoder{ResourceType: endpointsType} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/listener_resource_type.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/listener_resource_type.go index 0f49e6c56a..29ff887045 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/listener_resource_type.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/listener_resource_type.go @@ -22,6 +22,7 @@ import ( "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/xds/bootstrap" + xdsclient "google.golang.org/grpc/xds/internal/clients/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -103,7 +104,6 @@ func (listenerResourceType) Decode(opts *DecodeOptions, resource *anypb.Any) (*D } return &DecodeResult{Name: name, Resource: &ListenerResourceData{Resource: listener}}, nil - } // ListenerResourceData wraps the configuration of a Listener resource as @@ -127,7 +127,6 @@ func (l *ListenerResourceData) RawEqual(other ResourceData) bool { return false } return proto.Equal(l.Resource.Raw, other.Raw()) - } // ToJSON returns a JSON string representation of the resource data. @@ -182,3 +181,9 @@ func WatchListener(p Producer, name string, w ListenerWatcher) (cancel func()) { delegator := &delegatingListenerWatcher{watcher: w} return p.WatchResource(listenerType, name, delegator) } + +// NewGenericListenerResourceTypeDecoder returns a xdsclient.Decoder that wraps +// the xdsresource.listenerType. +func NewGenericListenerResourceTypeDecoder(bc *bootstrap.Config) xdsclient.Decoder { + return &GenericResourceTypeDecoder{ResourceType: listenerType, BootstrapConfig: bc} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/resource_type.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/resource_type.go index c22c5a6a3a..4ecf63a1c3 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/resource_type.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/resource_type.go @@ -25,8 +25,11 @@ package xdsresource import ( + "fmt" + "google.golang.org/grpc/internal/xds/bootstrap" xdsinternal "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/xds/internal/clients/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" "google.golang.org/protobuf/types/known/anypb" ) @@ -167,3 +170,119 @@ func (r resourceTypeState) TypeName() string { func (r resourceTypeState) AllResourcesRequiredInSotW() bool { return r.allResourcesRequiredInSotW } + +// GenericResourceTypeDecoder wraps an xdsresource.Type and implements +// xdsclient.Decoder. +// +// TODO: #8313 - Delete this once the internal xdsclient usages are updated +// to use the generic xdsclient.ResourceType interface directly. +type GenericResourceTypeDecoder struct { + ResourceType Type + BootstrapConfig *bootstrap.Config + ServerConfigMap map[xdsclient.ServerConfig]*bootstrap.ServerConfig +} + +// Decode deserialize and validate resource bytes of an xDS resource received +// from the xDS management server. +func (gd *GenericResourceTypeDecoder) Decode(resource xdsclient.AnyProto, gOpts xdsclient.DecodeOptions) (*xdsclient.DecodeResult, error) { + rProto := &anypb.Any{ + TypeUrl: resource.TypeURL, + Value: resource.Value, + } + opts := &DecodeOptions{BootstrapConfig: gd.BootstrapConfig} + if gOpts.ServerConfig != nil { + opts.ServerConfig = gd.ServerConfigMap[*gOpts.ServerConfig] + } + + result, err := gd.ResourceType.Decode(opts, rProto) + if result == nil { + return nil, err + } + if err != nil { + return &xdsclient.DecodeResult{Name: result.Name}, err + } + + return &xdsclient.DecodeResult{Name: result.Name, Resource: &genericResourceData{resourceData: result.Resource}}, nil +} + +// genericResourceData embed an xdsresource.ResourceData and implements +// xdsclient.ResourceData. +// +// TODO: #8313 - Delete this once the internal xdsclient usages are updated +// to use the generic xdsclient.ResourceData interface directly. +type genericResourceData struct { + resourceData ResourceData +} + +// Equal returns true if the passed in xdsclient.ResourceData +// is equal to that of the receiver. +func (grd *genericResourceData) Equal(other xdsclient.ResourceData) bool { + if other == nil { + return false + } + otherResourceData, ok := other.(*genericResourceData) + if !ok { + return false + } + return grd.resourceData.RawEqual(otherResourceData.resourceData) +} + +// Bytes returns the underlying raw bytes of the wrapped resource. +func (grd *genericResourceData) Bytes() []byte { + rawAny := grd.resourceData.Raw() + if rawAny == nil { + return nil + } + return rawAny.Value +} + +// genericResourceWatcher wraps xdsresource.ResourceWatcher and implements +// xdsclient.ResourceWatcher. +// +// TODO: #8313 - Delete this once the internal xdsclient usages are updated +// to use the generic xdsclient.ResourceWatcher interface directly. +type genericResourceWatcher struct { + xdsResourceWatcher ResourceWatcher +} + +// ResourceChanged indicates a new version of the wrapped resource is +// available. +func (gw *genericResourceWatcher) ResourceChanged(gData xdsclient.ResourceData, done func()) { + if gData == nil { + gw.xdsResourceWatcher.ResourceChanged(nil, done) + return + } + + grd, ok := gData.(*genericResourceData) + if !ok { + err := fmt.Errorf("genericResourceWatcher received unexpected xdsclient.ResourceData type %T, want *genericResourceData", gData) + gw.xdsResourceWatcher.ResourceError(err, done) + return + } + gw.xdsResourceWatcher.ResourceChanged(grd.resourceData, done) +} + +// ResourceError indicates an error occurred while trying to fetch or +// decode the associated wrapped resource. The previous version of the +// wrapped resource should be considered invalid. +func (gw *genericResourceWatcher) ResourceError(err error, done func()) { + gw.xdsResourceWatcher.ResourceError(err, done) +} + +// AmbientError indicates an error occurred after a resource has been +// received that should not modify the use of that wrapped resource but may +// provide useful information about the state of the XDSClient for debugging +// purposes. The previous version of the wrapped resource should still be +// considered valid. +func (gw *genericResourceWatcher) AmbientError(err error, done func()) { + gw.xdsResourceWatcher.AmbientError(err, done) +} + +// GenericResourceWatcher returns a xdsclient.ResourceWatcher that wraps an +// xdsresource.ResourceWatcher to make it compatible with xdsclient.ResourceWatcher. +func GenericResourceWatcher(xdsResourceWatcher ResourceWatcher) xdsclient.ResourceWatcher { + if xdsResourceWatcher == nil { + return nil + } + return &genericResourceWatcher{xdsResourceWatcher: xdsResourceWatcher} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/route_config_resource_type.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/route_config_resource_type.go index c292b1b8ef..344932e93d 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/route_config_resource_type.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/route_config_resource_type.go @@ -19,6 +19,7 @@ package xdsresource import ( "google.golang.org/grpc/internal/pretty" + xdsclient "google.golang.org/grpc/xds/internal/clients/xdsclient" "google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -148,3 +149,9 @@ func WatchRouteConfig(p Producer, name string, w RouteConfigWatcher) (cancel fun delegator := &delegatingRouteConfigWatcher{watcher: w} return p.WatchResource(routeConfigType, name, delegator) } + +// NewGenericRouteConfigResourceTypeDecoder returns a xdsclient.Decoder that +// wraps the xdsresource.routeConfigType. +func NewGenericRouteConfigResourceTypeDecoder() xdsclient.Decoder { + return &GenericResourceTypeDecoder{ResourceType: routeConfigType} +} diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/type_eds.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/type_eds.go index a7eab2361d..12294626f3 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/type_eds.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/type_eds.go @@ -18,7 +18,7 @@ package xdsresource import ( - "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/xds/internal/clients" "google.golang.org/protobuf/types/known/anypb" ) @@ -58,7 +58,7 @@ type Endpoint struct { // Locality contains information of a locality. type Locality struct { Endpoints []Endpoint - ID internal.LocalityID + ID clients.Locality Priority uint32 Weight uint32 } diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_cds.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_cds.go index 00b73383bd..c2ced0d620 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_cds.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_cds.go @@ -133,10 +133,6 @@ func validateClusterAndConstructClusterUpdate(cluster *v3clusterpb.Cluster, serv rhLBCfg := []byte(fmt.Sprintf("{\"minRingSize\": %d, \"maxRingSize\": %d}", minSize, maxSize)) lbPolicy = []byte(fmt.Sprintf(`[{"ring_hash_experimental": %s}]`, rhLBCfg)) case v3clusterpb.Cluster_LEAST_REQUEST: - if !envconfig.LeastRequestLB { - return ClusterUpdate{}, fmt.Errorf("unexpected lbPolicy %v in response: %+v", cluster.GetLbPolicy(), cluster) - } - // "The configuration for the Least Request LB policy is the // least_request_lb_config field. The field is optional; if not present, // defaults will be assumed for all of its values." - A48 diff --git a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_eds.go b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_eds.go index 8a7397d160..d56b42dd36 100644 --- a/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_eds.go +++ b/vendor/google.golang.org/grpc/xds/internal/xdsclient/xdsresource/unmarshal_eds.go @@ -29,6 +29,7 @@ import ( "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/xds/internal/clients" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" ) @@ -164,12 +165,12 @@ func parseEDSRespProto(m *v3endpointpb.ClusterLoadAssignment) (EndpointsUpdate, localitiesWithPriority = make(map[string]bool) priorities[priority] = localitiesWithPriority } - lid := internal.LocalityID{ + lid := clients.Locality{ Region: l.Region, Zone: l.Zone, SubZone: l.SubZone, } - lidStr := lid.ToString() + lidStr := internal.LocalityString(lid) // "Since an xDS configuration can place a given locality under multiple // priorities, it is possible to see locality weight attributes with diff --git a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go index e942bc983e..743bfb81d6 100644 --- a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go +++ b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go @@ -371,7 +371,31 @@ func ConsumeVarint(b []byte) (v uint64, n int) { func SizeVarint(v uint64) int { // This computes 1 + (bits.Len64(v)-1)/7. // 9/64 is a good enough approximation of 1/7 - return int(9*uint32(bits.Len64(v))+64) / 64 + // + // The Go compiler can translate the bits.LeadingZeros64 call into the LZCNT + // instruction, which is very fast on CPUs from the last few years. The + // specific way of expressing the calculation matches C++ Protobuf, see + // https://godbolt.org/z/4P3h53oM4 for the C++ code and how gcc/clang + // optimize that function for GOAMD64=v1 and GOAMD64=v3 (-march=haswell). + + // By OR'ing v with 1, we guarantee that v is never 0, without changing the + // result of SizeVarint. LZCNT is not defined for 0, meaning the compiler + // needs to add extra instructions to handle that case. + // + // The Go compiler currently (go1.24.4) does not make use of this knowledge. + // This opportunity (removing the XOR instruction, which handles the 0 case) + // results in a small (1%) performance win across CPU architectures. + // + // Independently of avoiding the 0 case, we need the v |= 1 line because + // it allows the Go compiler to eliminate an extra XCHGL barrier. + v |= 1 + + // It would be clearer to write log2value := 63 - uint32(...), but + // writing uint32(...) ^ 63 is much more efficient (-14% ARM, -20% Intel). + // Proof of identity for our value range [0..63]: + // https://go.dev/play/p/Pdn9hEWYakX + log2value := uint32(bits.LeadingZeros64(v)) ^ 63 + return int((log2value*9 + (64 + 9)) / 64) } // AppendFixed32 appends v to b as a little-endian uint32. diff --git a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb index 323829da14..04696351ee 100644 Binary files a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb and b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb differ diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/editions.go b/vendor/google.golang.org/protobuf/internal/filedesc/editions.go index b08b71830c..a0aad2777f 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/editions.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/editions.go @@ -72,6 +72,9 @@ func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures { case genid.FeatureSet_EnforceNamingStyle_field_number: // EnforceNamingStyle is enforced in protoc, languages other than C++ // are not supposed to do anything with this feature. + case genid.FeatureSet_DefaultSymbolVisibility_field_number: + // DefaultSymbolVisibility is enforced in protoc, runtimes should not + // inspect this value. default: panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num)) } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/presence.go b/vendor/google.golang.org/protobuf/internal/filedesc/presence.go new file mode 100644 index 0000000000..a12ec9791c --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/filedesc/presence.go @@ -0,0 +1,33 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package filedesc + +import "google.golang.org/protobuf/reflect/protoreflect" + +// UsePresenceForField reports whether the presence bitmap should be used for +// the specified field. +func UsePresenceForField(fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) { + switch { + case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): + // Oneof fields never use the presence bitmap. + // + // Synthetic oneofs are an exception: Those are used to implement proto3 + // optional fields and hence should follow non-oneof field semantics. + return false, false + + case fd.IsMap(): + // Map-typed fields never use the presence bitmap. + return false, false + + case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind: + // Lazy fields always use the presence bitmap (only messages can be lazy). + isLazy := fd.(interface{ IsLazy() bool }).IsLazy() + return isLazy, isLazy + + default: + // If the field has presence, use the presence bitmap. + return fd.HasPresence(), false + } +} diff --git a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go index 39524782ad..950a6a325a 100644 --- a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go +++ b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go @@ -34,6 +34,19 @@ const ( Edition_EDITION_MAX_enum_value = 2147483647 ) +// Full and short names for google.protobuf.SymbolVisibility. +const ( + SymbolVisibility_enum_fullname = "google.protobuf.SymbolVisibility" + SymbolVisibility_enum_name = "SymbolVisibility" +) + +// Enum values for google.protobuf.SymbolVisibility. +const ( + SymbolVisibility_VISIBILITY_UNSET_enum_value = 0 + SymbolVisibility_VISIBILITY_LOCAL_enum_value = 1 + SymbolVisibility_VISIBILITY_EXPORT_enum_value = 2 +) + // Names for google.protobuf.FileDescriptorSet. const ( FileDescriptorSet_message_name protoreflect.Name = "FileDescriptorSet" @@ -65,6 +78,7 @@ const ( FileDescriptorProto_Dependency_field_name protoreflect.Name = "dependency" FileDescriptorProto_PublicDependency_field_name protoreflect.Name = "public_dependency" FileDescriptorProto_WeakDependency_field_name protoreflect.Name = "weak_dependency" + FileDescriptorProto_OptionDependency_field_name protoreflect.Name = "option_dependency" FileDescriptorProto_MessageType_field_name protoreflect.Name = "message_type" FileDescriptorProto_EnumType_field_name protoreflect.Name = "enum_type" FileDescriptorProto_Service_field_name protoreflect.Name = "service" @@ -79,6 +93,7 @@ const ( FileDescriptorProto_Dependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.dependency" FileDescriptorProto_PublicDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.public_dependency" FileDescriptorProto_WeakDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.weak_dependency" + FileDescriptorProto_OptionDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.option_dependency" FileDescriptorProto_MessageType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.message_type" FileDescriptorProto_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.enum_type" FileDescriptorProto_Service_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.service" @@ -96,6 +111,7 @@ const ( FileDescriptorProto_Dependency_field_number protoreflect.FieldNumber = 3 FileDescriptorProto_PublicDependency_field_number protoreflect.FieldNumber = 10 FileDescriptorProto_WeakDependency_field_number protoreflect.FieldNumber = 11 + FileDescriptorProto_OptionDependency_field_number protoreflect.FieldNumber = 15 FileDescriptorProto_MessageType_field_number protoreflect.FieldNumber = 4 FileDescriptorProto_EnumType_field_number protoreflect.FieldNumber = 5 FileDescriptorProto_Service_field_number protoreflect.FieldNumber = 6 @@ -124,6 +140,7 @@ const ( DescriptorProto_Options_field_name protoreflect.Name = "options" DescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range" DescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name" + DescriptorProto_Visibility_field_name protoreflect.Name = "visibility" DescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.name" DescriptorProto_Field_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.field" @@ -135,6 +152,7 @@ const ( DescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.options" DescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_range" DescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_name" + DescriptorProto_Visibility_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.visibility" ) // Field numbers for google.protobuf.DescriptorProto. @@ -149,6 +167,7 @@ const ( DescriptorProto_Options_field_number protoreflect.FieldNumber = 7 DescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 9 DescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 10 + DescriptorProto_Visibility_field_number protoreflect.FieldNumber = 11 ) // Names for google.protobuf.DescriptorProto.ExtensionRange. @@ -388,12 +407,14 @@ const ( EnumDescriptorProto_Options_field_name protoreflect.Name = "options" EnumDescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range" EnumDescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name" + EnumDescriptorProto_Visibility_field_name protoreflect.Name = "visibility" EnumDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.name" EnumDescriptorProto_Value_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.value" EnumDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.options" EnumDescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_range" EnumDescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_name" + EnumDescriptorProto_Visibility_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.visibility" ) // Field numbers for google.protobuf.EnumDescriptorProto. @@ -403,6 +424,7 @@ const ( EnumDescriptorProto_Options_field_number protoreflect.FieldNumber = 3 EnumDescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 4 EnumDescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 5 + EnumDescriptorProto_Visibility_field_number protoreflect.FieldNumber = 6 ) // Names for google.protobuf.EnumDescriptorProto.EnumReservedRange. @@ -1008,32 +1030,35 @@ const ( // Field names for google.protobuf.FeatureSet. const ( - FeatureSet_FieldPresence_field_name protoreflect.Name = "field_presence" - FeatureSet_EnumType_field_name protoreflect.Name = "enum_type" - FeatureSet_RepeatedFieldEncoding_field_name protoreflect.Name = "repeated_field_encoding" - FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation" - FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding" - FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format" - FeatureSet_EnforceNamingStyle_field_name protoreflect.Name = "enforce_naming_style" - - FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence" - FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type" - FeatureSet_RepeatedFieldEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding" - FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation" - FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding" - FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format" - FeatureSet_EnforceNamingStyle_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style" + FeatureSet_FieldPresence_field_name protoreflect.Name = "field_presence" + FeatureSet_EnumType_field_name protoreflect.Name = "enum_type" + FeatureSet_RepeatedFieldEncoding_field_name protoreflect.Name = "repeated_field_encoding" + FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation" + FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding" + FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format" + FeatureSet_EnforceNamingStyle_field_name protoreflect.Name = "enforce_naming_style" + FeatureSet_DefaultSymbolVisibility_field_name protoreflect.Name = "default_symbol_visibility" + + FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence" + FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type" + FeatureSet_RepeatedFieldEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding" + FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation" + FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding" + FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format" + FeatureSet_EnforceNamingStyle_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style" + FeatureSet_DefaultSymbolVisibility_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.default_symbol_visibility" ) // Field numbers for google.protobuf.FeatureSet. const ( - FeatureSet_FieldPresence_field_number protoreflect.FieldNumber = 1 - FeatureSet_EnumType_field_number protoreflect.FieldNumber = 2 - FeatureSet_RepeatedFieldEncoding_field_number protoreflect.FieldNumber = 3 - FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4 - FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5 - FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6 - FeatureSet_EnforceNamingStyle_field_number protoreflect.FieldNumber = 7 + FeatureSet_FieldPresence_field_number protoreflect.FieldNumber = 1 + FeatureSet_EnumType_field_number protoreflect.FieldNumber = 2 + FeatureSet_RepeatedFieldEncoding_field_number protoreflect.FieldNumber = 3 + FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4 + FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5 + FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6 + FeatureSet_EnforceNamingStyle_field_number protoreflect.FieldNumber = 7 + FeatureSet_DefaultSymbolVisibility_field_number protoreflect.FieldNumber = 8 ) // Full and short names for google.protobuf.FeatureSet.FieldPresence. @@ -1128,6 +1153,27 @@ const ( FeatureSet_STYLE_LEGACY_enum_value = 2 ) +// Names for google.protobuf.FeatureSet.VisibilityFeature. +const ( + FeatureSet_VisibilityFeature_message_name protoreflect.Name = "VisibilityFeature" + FeatureSet_VisibilityFeature_message_fullname protoreflect.FullName = "google.protobuf.FeatureSet.VisibilityFeature" +) + +// Full and short names for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility. +const ( + FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_fullname = "google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility" + FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_name = "DefaultSymbolVisibility" +) + +// Enum values for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility. +const ( + FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN_enum_value = 0 + FeatureSet_VisibilityFeature_EXPORT_ALL_enum_value = 1 + FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL_enum_value = 2 + FeatureSet_VisibilityFeature_LOCAL_ALL_enum_value = 3 + FeatureSet_VisibilityFeature_STRICT_enum_value = 4 +) + // Names for google.protobuf.FeatureSetDefaults. const ( FeatureSetDefaults_message_name protoreflect.Name = "FeatureSetDefaults" diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go b/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go index 41c1f74ef8..bdad12a9bb 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" + "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/order" "google.golang.org/protobuf/reflect/protoreflect" piface "google.golang.org/protobuf/runtime/protoiface" @@ -80,7 +81,7 @@ func (mi *MessageInfo) makeOpaqueCoderMethods(t reflect.Type, si opaqueStructInf // permit us to skip over definitely-unset fields at marshal time. var hasPresence bool - hasPresence, cf.isLazy = usePresenceForField(si, fd) + hasPresence, cf.isLazy = filedesc.UsePresenceForField(fd) if hasPresence { cf.presenceIndex, mi.presenceSize = presenceIndex(mi.Desc, fd) diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go index dd55e8e009..5a439daacb 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go @@ -11,6 +11,7 @@ import ( "strings" "sync/atomic" + "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -53,7 +54,7 @@ func opaqueInitHook(mi *MessageInfo) bool { fd := fds.Get(i) fs := si.fieldsByNumber[fd.Number()] var fi fieldInfo - usePresence, _ := usePresenceForField(si, fd) + usePresence, _ := filedesc.UsePresenceForField(fd) switch { case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): @@ -343,17 +344,15 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructIn if p.IsNil() { return false } - sp := p.Apply(fieldOffset).AtomicGetPointer() - if sp.IsNil() { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if rv.IsNil() { return false } - rv := sp.AsValueOf(fs.Type.Elem()) return rv.Elem().Len() > 0 }, clear: func(p pointer) { - sp := p.Apply(fieldOffset).AtomicGetPointer() - if !sp.IsNil() { - rv := sp.AsValueOf(fs.Type.Elem()) + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if !rv.IsNil() { rv.Elem().Set(reflect.Zero(rv.Type().Elem())) } }, @@ -361,11 +360,10 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructIn if p.IsNil() { return conv.Zero() } - sp := p.Apply(fieldOffset).AtomicGetPointer() - if sp.IsNil() { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if rv.IsNil() { return conv.Zero() } - rv := sp.AsValueOf(fs.Type.Elem()) if rv.Elem().Len() == 0 { return conv.Zero() } @@ -598,30 +596,3 @@ func (mi *MessageInfo) clearPresent(p pointer, index uint32) { func (mi *MessageInfo) present(p pointer, index uint32) bool { return p.Apply(mi.presenceOffset).PresenceInfo().Present(index) } - -// usePresenceForField implements the somewhat intricate logic of when -// the presence bitmap is used for a field. The main logic is that a -// field that is optional or that can be lazy will use the presence -// bit, but for proto2, also maps have a presence bit. It also records -// if the field can ever be lazy, which is true if we have a -// lazyOffset and the field is a message or a slice of messages. A -// field that is lazy will always need a presence bit. Oneofs are not -// lazy and do not use presence, unless they are a synthetic oneof, -// which is a proto3 optional field. For proto3 optionals, we use the -// presence and they can also be lazy when applicable (a message). -func usePresenceForField(si opaqueStructInfo, fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) { - hasLazyField := fd.(interface{ IsLazy() bool }).IsLazy() - - // Non-oneof scalar fields with explicit field presence use the presence array. - usesPresenceArray := fd.HasPresence() && fd.Message() == nil && (fd.ContainingOneof() == nil || fd.ContainingOneof().IsSynthetic()) - switch { - case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): - return false, false - case fd.IsMap(): - return false, false - case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind: - return hasLazyField, hasLazyField - default: - return usesPresenceArray || (hasLazyField && fd.HasPresence()), false - } -} diff --git a/vendor/google.golang.org/protobuf/internal/impl/presence.go b/vendor/google.golang.org/protobuf/internal/impl/presence.go index 914cb1deda..443afe81cd 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/presence.go +++ b/vendor/google.golang.org/protobuf/internal/impl/presence.go @@ -32,9 +32,6 @@ func (p presence) toElem(num uint32) (ret *uint32) { // Present checks for the presence of a specific field number in a presence set. func (p presence) Present(num uint32) bool { - if p.P == nil { - return false - } return Export{}.Present(p.toElem(num), num) } diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index aac1cb18a7..a53364c599 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,7 +52,7 @@ import ( const ( Major = 1 Minor = 36 - Patch = 6 + Patch = 7 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go index a4a0a2971d..730331e666 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go @@ -21,6 +21,8 @@ func (p *SourcePath) appendFileDescriptorProto(b []byte) []byte { b = p.appendRepeatedField(b, "public_dependency", nil) case 11: b = p.appendRepeatedField(b, "weak_dependency", nil) + case 15: + b = p.appendRepeatedField(b, "option_dependency", nil) case 4: b = p.appendRepeatedField(b, "message_type", (*SourcePath).appendDescriptorProto) case 5: @@ -66,6 +68,8 @@ func (p *SourcePath) appendDescriptorProto(b []byte) []byte { b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendDescriptorProto_ReservedRange) case 10: b = p.appendRepeatedField(b, "reserved_name", nil) + case 11: + b = p.appendSingularField(b, "visibility", nil) } return b } @@ -85,6 +89,8 @@ func (p *SourcePath) appendEnumDescriptorProto(b []byte) []byte { b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendEnumDescriptorProto_EnumReservedRange) case 5: b = p.appendRepeatedField(b, "reserved_name", nil) + case 6: + b = p.appendSingularField(b, "visibility", nil) } return b } @@ -400,6 +406,8 @@ func (p *SourcePath) appendFeatureSet(b []byte) []byte { b = p.appendSingularField(b, "json_format", nil) case 7: b = p.appendSingularField(b, "enforce_naming_style", nil) + case 8: + b = p.appendSingularField(b, "default_symbol_visibility", nil) } return b } diff --git a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go index 7fe280f194..6843b0beaf 100644 --- a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go +++ b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go @@ -151,6 +151,70 @@ func (Edition) EnumDescriptor() ([]byte, []int) { return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{0} } +// Describes the 'visibility' of a symbol with respect to the proto import +// system. Symbols can only be imported when the visibility rules do not prevent +// it (ex: local symbols cannot be imported). Visibility modifiers can only set +// on `message` and `enum` as they are the only types available to be referenced +// from other files. +type SymbolVisibility int32 + +const ( + SymbolVisibility_VISIBILITY_UNSET SymbolVisibility = 0 + SymbolVisibility_VISIBILITY_LOCAL SymbolVisibility = 1 + SymbolVisibility_VISIBILITY_EXPORT SymbolVisibility = 2 +) + +// Enum value maps for SymbolVisibility. +var ( + SymbolVisibility_name = map[int32]string{ + 0: "VISIBILITY_UNSET", + 1: "VISIBILITY_LOCAL", + 2: "VISIBILITY_EXPORT", + } + SymbolVisibility_value = map[string]int32{ + "VISIBILITY_UNSET": 0, + "VISIBILITY_LOCAL": 1, + "VISIBILITY_EXPORT": 2, + } +) + +func (x SymbolVisibility) Enum() *SymbolVisibility { + p := new(SymbolVisibility) + *p = x + return p +} + +func (x SymbolVisibility) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SymbolVisibility) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor() +} + +func (SymbolVisibility) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[1] +} + +func (x SymbolVisibility) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *SymbolVisibility) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = SymbolVisibility(num) + return nil +} + +// Deprecated: Use SymbolVisibility.Descriptor instead. +func (SymbolVisibility) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{1} +} + // The verification state of the extension range. type ExtensionRangeOptions_VerificationState int32 @@ -183,11 +247,11 @@ func (x ExtensionRangeOptions_VerificationState) String() string { } func (ExtensionRangeOptions_VerificationState) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor() } func (ExtensionRangeOptions_VerificationState) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[1] + return &file_google_protobuf_descriptor_proto_enumTypes[2] } func (x ExtensionRangeOptions_VerificationState) Number() protoreflect.EnumNumber { @@ -299,11 +363,11 @@ func (x FieldDescriptorProto_Type) String() string { } func (FieldDescriptorProto_Type) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor() } func (FieldDescriptorProto_Type) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[2] + return &file_google_protobuf_descriptor_proto_enumTypes[3] } func (x FieldDescriptorProto_Type) Number() protoreflect.EnumNumber { @@ -362,11 +426,11 @@ func (x FieldDescriptorProto_Label) String() string { } func (FieldDescriptorProto_Label) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor() } func (FieldDescriptorProto_Label) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[3] + return &file_google_protobuf_descriptor_proto_enumTypes[4] } func (x FieldDescriptorProto_Label) Number() protoreflect.EnumNumber { @@ -423,11 +487,11 @@ func (x FileOptions_OptimizeMode) String() string { } func (FileOptions_OptimizeMode) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor() } func (FileOptions_OptimizeMode) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[4] + return &file_google_protobuf_descriptor_proto_enumTypes[5] } func (x FileOptions_OptimizeMode) Number() protoreflect.EnumNumber { @@ -489,11 +553,11 @@ func (x FieldOptions_CType) String() string { } func (FieldOptions_CType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[6].Descriptor() } func (FieldOptions_CType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[5] + return &file_google_protobuf_descriptor_proto_enumTypes[6] } func (x FieldOptions_CType) Number() protoreflect.EnumNumber { @@ -551,11 +615,11 @@ func (x FieldOptions_JSType) String() string { } func (FieldOptions_JSType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[6].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[7].Descriptor() } func (FieldOptions_JSType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[6] + return &file_google_protobuf_descriptor_proto_enumTypes[7] } func (x FieldOptions_JSType) Number() protoreflect.EnumNumber { @@ -611,11 +675,11 @@ func (x FieldOptions_OptionRetention) String() string { } func (FieldOptions_OptionRetention) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[7].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[8].Descriptor() } func (FieldOptions_OptionRetention) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[7] + return &file_google_protobuf_descriptor_proto_enumTypes[8] } func (x FieldOptions_OptionRetention) Number() protoreflect.EnumNumber { @@ -694,11 +758,11 @@ func (x FieldOptions_OptionTargetType) String() string { } func (FieldOptions_OptionTargetType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[8].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[9].Descriptor() } func (FieldOptions_OptionTargetType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[8] + return &file_google_protobuf_descriptor_proto_enumTypes[9] } func (x FieldOptions_OptionTargetType) Number() protoreflect.EnumNumber { @@ -756,11 +820,11 @@ func (x MethodOptions_IdempotencyLevel) String() string { } func (MethodOptions_IdempotencyLevel) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[9].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[10].Descriptor() } func (MethodOptions_IdempotencyLevel) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[9] + return &file_google_protobuf_descriptor_proto_enumTypes[10] } func (x MethodOptions_IdempotencyLevel) Number() protoreflect.EnumNumber { @@ -818,11 +882,11 @@ func (x FeatureSet_FieldPresence) String() string { } func (FeatureSet_FieldPresence) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[10].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[11].Descriptor() } func (FeatureSet_FieldPresence) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[10] + return &file_google_protobuf_descriptor_proto_enumTypes[11] } func (x FeatureSet_FieldPresence) Number() protoreflect.EnumNumber { @@ -877,11 +941,11 @@ func (x FeatureSet_EnumType) String() string { } func (FeatureSet_EnumType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[11].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[12].Descriptor() } func (FeatureSet_EnumType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[11] + return &file_google_protobuf_descriptor_proto_enumTypes[12] } func (x FeatureSet_EnumType) Number() protoreflect.EnumNumber { @@ -936,11 +1000,11 @@ func (x FeatureSet_RepeatedFieldEncoding) String() string { } func (FeatureSet_RepeatedFieldEncoding) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[12].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[13].Descriptor() } func (FeatureSet_RepeatedFieldEncoding) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[12] + return &file_google_protobuf_descriptor_proto_enumTypes[13] } func (x FeatureSet_RepeatedFieldEncoding) Number() protoreflect.EnumNumber { @@ -995,11 +1059,11 @@ func (x FeatureSet_Utf8Validation) String() string { } func (FeatureSet_Utf8Validation) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[13].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[14].Descriptor() } func (FeatureSet_Utf8Validation) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[13] + return &file_google_protobuf_descriptor_proto_enumTypes[14] } func (x FeatureSet_Utf8Validation) Number() protoreflect.EnumNumber { @@ -1054,11 +1118,11 @@ func (x FeatureSet_MessageEncoding) String() string { } func (FeatureSet_MessageEncoding) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[14].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[15].Descriptor() } func (FeatureSet_MessageEncoding) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[14] + return &file_google_protobuf_descriptor_proto_enumTypes[15] } func (x FeatureSet_MessageEncoding) Number() protoreflect.EnumNumber { @@ -1113,11 +1177,11 @@ func (x FeatureSet_JsonFormat) String() string { } func (FeatureSet_JsonFormat) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[15].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[16].Descriptor() } func (FeatureSet_JsonFormat) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[15] + return &file_google_protobuf_descriptor_proto_enumTypes[16] } func (x FeatureSet_JsonFormat) Number() protoreflect.EnumNumber { @@ -1172,11 +1236,11 @@ func (x FeatureSet_EnforceNamingStyle) String() string { } func (FeatureSet_EnforceNamingStyle) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[16].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[17].Descriptor() } func (FeatureSet_EnforceNamingStyle) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[16] + return &file_google_protobuf_descriptor_proto_enumTypes[17] } func (x FeatureSet_EnforceNamingStyle) Number() protoreflect.EnumNumber { @@ -1198,6 +1262,77 @@ func (FeatureSet_EnforceNamingStyle) EnumDescriptor() ([]byte, []int) { return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 6} } +type FeatureSet_VisibilityFeature_DefaultSymbolVisibility int32 + +const ( + FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 0 + // Default pre-EDITION_2024, all UNSET visibility are export. + FeatureSet_VisibilityFeature_EXPORT_ALL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 1 + // All top-level symbols default to export, nested default to local. + FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 2 + // All symbols default to local. + FeatureSet_VisibilityFeature_LOCAL_ALL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 3 + // All symbols local by default. Nested types cannot be exported. + // With special case caveat for message { enum {} reserved 1 to max; } + // This is the recommended setting for new protos. + FeatureSet_VisibilityFeature_STRICT FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 4 +) + +// Enum value maps for FeatureSet_VisibilityFeature_DefaultSymbolVisibility. +var ( + FeatureSet_VisibilityFeature_DefaultSymbolVisibility_name = map[int32]string{ + 0: "DEFAULT_SYMBOL_VISIBILITY_UNKNOWN", + 1: "EXPORT_ALL", + 2: "EXPORT_TOP_LEVEL", + 3: "LOCAL_ALL", + 4: "STRICT", + } + FeatureSet_VisibilityFeature_DefaultSymbolVisibility_value = map[string]int32{ + "DEFAULT_SYMBOL_VISIBILITY_UNKNOWN": 0, + "EXPORT_ALL": 1, + "EXPORT_TOP_LEVEL": 2, + "LOCAL_ALL": 3, + "STRICT": 4, + } +) + +func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Enum() *FeatureSet_VisibilityFeature_DefaultSymbolVisibility { + p := new(FeatureSet_VisibilityFeature_DefaultSymbolVisibility) + *p = x + return p +} + +func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[18].Descriptor() +} + +func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[18] +} + +func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *FeatureSet_VisibilityFeature_DefaultSymbolVisibility) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = FeatureSet_VisibilityFeature_DefaultSymbolVisibility(num) + return nil +} + +// Deprecated: Use FeatureSet_VisibilityFeature_DefaultSymbolVisibility.Descriptor instead. +func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 0, 0} +} + // Represents the identified object's effect on the element in the original // .proto file. type GeneratedCodeInfo_Annotation_Semantic int32 @@ -1236,11 +1371,11 @@ func (x GeneratedCodeInfo_Annotation_Semantic) String() string { } func (GeneratedCodeInfo_Annotation_Semantic) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[17].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[19].Descriptor() } func (GeneratedCodeInfo_Annotation_Semantic) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[17] + return &file_google_protobuf_descriptor_proto_enumTypes[19] } func (x GeneratedCodeInfo_Annotation_Semantic) Number() protoreflect.EnumNumber { @@ -1321,6 +1456,9 @@ type FileDescriptorProto struct { // Indexes of the weak imported files in the dependency list. // For Google-internal migration only. Do not use. WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"` + // Names of files imported by this file purely for the purpose of providing + // option extensions. These are excluded from the dependency list above. + OptionDependency []string `protobuf:"bytes,15,rep,name=option_dependency,json=optionDependency" json:"option_dependency,omitempty"` // All top-level definitions in this file. MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"` EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` @@ -1414,6 +1552,13 @@ func (x *FileDescriptorProto) GetWeakDependency() []int32 { return nil } +func (x *FileDescriptorProto) GetOptionDependency() []string { + if x != nil { + return x.OptionDependency + } + return nil +} + func (x *FileDescriptorProto) GetMessageType() []*DescriptorProto { if x != nil { return x.MessageType @@ -1484,7 +1629,9 @@ type DescriptorProto struct { ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` // Reserved field names, which may not be used by fields in the same message. // A given name may only be reserved once. - ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + // Support for `export` and `local` keywords on enums. + Visibility *SymbolVisibility `protobuf:"varint,11,opt,name=visibility,enum=google.protobuf.SymbolVisibility" json:"visibility,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1589,6 +1736,13 @@ func (x *DescriptorProto) GetReservedName() []string { return nil } +func (x *DescriptorProto) GetVisibility() SymbolVisibility { + if x != nil && x.Visibility != nil { + return *x.Visibility + } + return SymbolVisibility_VISIBILITY_UNSET +} + type ExtensionRangeOptions struct { state protoimpl.MessageState `protogen:"open.v1"` // The parser stores options it doesn't recognize here. See above. @@ -1901,7 +2055,9 @@ type EnumDescriptorProto struct { ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` // Reserved enum value names, which may not be reused. A given name may only // be reserved once. - ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + // Support for `export` and `local` keywords on enums. + Visibility *SymbolVisibility `protobuf:"varint,6,opt,name=visibility,enum=google.protobuf.SymbolVisibility" json:"visibility,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1971,6 +2127,13 @@ func (x *EnumDescriptorProto) GetReservedName() []string { return nil } +func (x *EnumDescriptorProto) GetVisibility() SymbolVisibility { + if x != nil && x.Visibility != nil { + return *x.Visibility + } + return SymbolVisibility_VISIBILITY_UNSET +} + // Describes a value within an enum. type EnumValueDescriptorProto struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -3392,17 +3555,18 @@ func (x *UninterpretedOption) GetAggregateValue() string { // be designed and implemented to handle this, hopefully before we ever hit a // conflict here. type FeatureSet struct { - state protoimpl.MessageState `protogen:"open.v1"` - FieldPresence *FeatureSet_FieldPresence `protobuf:"varint,1,opt,name=field_presence,json=fieldPresence,enum=google.protobuf.FeatureSet_FieldPresence" json:"field_presence,omitempty"` - EnumType *FeatureSet_EnumType `protobuf:"varint,2,opt,name=enum_type,json=enumType,enum=google.protobuf.FeatureSet_EnumType" json:"enum_type,omitempty"` - RepeatedFieldEncoding *FeatureSet_RepeatedFieldEncoding `protobuf:"varint,3,opt,name=repeated_field_encoding,json=repeatedFieldEncoding,enum=google.protobuf.FeatureSet_RepeatedFieldEncoding" json:"repeated_field_encoding,omitempty"` - Utf8Validation *FeatureSet_Utf8Validation `protobuf:"varint,4,opt,name=utf8_validation,json=utf8Validation,enum=google.protobuf.FeatureSet_Utf8Validation" json:"utf8_validation,omitempty"` - MessageEncoding *FeatureSet_MessageEncoding `protobuf:"varint,5,opt,name=message_encoding,json=messageEncoding,enum=google.protobuf.FeatureSet_MessageEncoding" json:"message_encoding,omitempty"` - JsonFormat *FeatureSet_JsonFormat `protobuf:"varint,6,opt,name=json_format,json=jsonFormat,enum=google.protobuf.FeatureSet_JsonFormat" json:"json_format,omitempty"` - EnforceNamingStyle *FeatureSet_EnforceNamingStyle `protobuf:"varint,7,opt,name=enforce_naming_style,json=enforceNamingStyle,enum=google.protobuf.FeatureSet_EnforceNamingStyle" json:"enforce_naming_style,omitempty"` - extensionFields protoimpl.ExtensionFields - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + FieldPresence *FeatureSet_FieldPresence `protobuf:"varint,1,opt,name=field_presence,json=fieldPresence,enum=google.protobuf.FeatureSet_FieldPresence" json:"field_presence,omitempty"` + EnumType *FeatureSet_EnumType `protobuf:"varint,2,opt,name=enum_type,json=enumType,enum=google.protobuf.FeatureSet_EnumType" json:"enum_type,omitempty"` + RepeatedFieldEncoding *FeatureSet_RepeatedFieldEncoding `protobuf:"varint,3,opt,name=repeated_field_encoding,json=repeatedFieldEncoding,enum=google.protobuf.FeatureSet_RepeatedFieldEncoding" json:"repeated_field_encoding,omitempty"` + Utf8Validation *FeatureSet_Utf8Validation `protobuf:"varint,4,opt,name=utf8_validation,json=utf8Validation,enum=google.protobuf.FeatureSet_Utf8Validation" json:"utf8_validation,omitempty"` + MessageEncoding *FeatureSet_MessageEncoding `protobuf:"varint,5,opt,name=message_encoding,json=messageEncoding,enum=google.protobuf.FeatureSet_MessageEncoding" json:"message_encoding,omitempty"` + JsonFormat *FeatureSet_JsonFormat `protobuf:"varint,6,opt,name=json_format,json=jsonFormat,enum=google.protobuf.FeatureSet_JsonFormat" json:"json_format,omitempty"` + EnforceNamingStyle *FeatureSet_EnforceNamingStyle `protobuf:"varint,7,opt,name=enforce_naming_style,json=enforceNamingStyle,enum=google.protobuf.FeatureSet_EnforceNamingStyle" json:"enforce_naming_style,omitempty"` + DefaultSymbolVisibility *FeatureSet_VisibilityFeature_DefaultSymbolVisibility `protobuf:"varint,8,opt,name=default_symbol_visibility,json=defaultSymbolVisibility,enum=google.protobuf.FeatureSet_VisibilityFeature_DefaultSymbolVisibility" json:"default_symbol_visibility,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FeatureSet) Reset() { @@ -3484,6 +3648,13 @@ func (x *FeatureSet) GetEnforceNamingStyle() FeatureSet_EnforceNamingStyle { return FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN } +func (x *FeatureSet) GetDefaultSymbolVisibility() FeatureSet_VisibilityFeature_DefaultSymbolVisibility { + if x != nil && x.DefaultSymbolVisibility != nil { + return *x.DefaultSymbolVisibility + } + return FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN +} + // A compiled specification for the defaults of a set of features. These // messages are generated from FeatureSet extensions and can be used to seed // feature resolution. The resolution with this object becomes a simple search @@ -4144,6 +4315,42 @@ func (x *UninterpretedOption_NamePart) GetIsExtension() bool { return false } +type FeatureSet_VisibilityFeature struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FeatureSet_VisibilityFeature) Reset() { + *x = FeatureSet_VisibilityFeature{} + mi := &file_google_protobuf_descriptor_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FeatureSet_VisibilityFeature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FeatureSet_VisibilityFeature) ProtoMessage() {} + +func (x *FeatureSet_VisibilityFeature) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_descriptor_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FeatureSet_VisibilityFeature.ProtoReflect.Descriptor instead. +func (*FeatureSet_VisibilityFeature) Descriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 0} +} + // A map from every known edition with a unique set of defaults to its // defaults. Not all editions may be contained here. For a given edition, // the defaults at the closest matching edition ordered at or before it should @@ -4161,7 +4368,7 @@ type FeatureSetDefaults_FeatureSetEditionDefault struct { func (x *FeatureSetDefaults_FeatureSetEditionDefault) Reset() { *x = FeatureSetDefaults_FeatureSetEditionDefault{} - mi := &file_google_protobuf_descriptor_proto_msgTypes[30] + mi := &file_google_protobuf_descriptor_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4173,7 +4380,7 @@ func (x *FeatureSetDefaults_FeatureSetEditionDefault) String() string { func (*FeatureSetDefaults_FeatureSetEditionDefault) ProtoMessage() {} func (x *FeatureSetDefaults_FeatureSetEditionDefault) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[30] + mi := &file_google_protobuf_descriptor_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4309,7 +4516,7 @@ type SourceCodeInfo_Location struct { func (x *SourceCodeInfo_Location) Reset() { *x = SourceCodeInfo_Location{} - mi := &file_google_protobuf_descriptor_proto_msgTypes[31] + mi := &file_google_protobuf_descriptor_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4321,7 +4528,7 @@ func (x *SourceCodeInfo_Location) String() string { func (*SourceCodeInfo_Location) ProtoMessage() {} func (x *SourceCodeInfo_Location) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[31] + mi := &file_google_protobuf_descriptor_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4393,7 +4600,7 @@ type GeneratedCodeInfo_Annotation struct { func (x *GeneratedCodeInfo_Annotation) Reset() { *x = GeneratedCodeInfo_Annotation{} - mi := &file_google_protobuf_descriptor_proto_msgTypes[32] + mi := &file_google_protobuf_descriptor_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4405,7 +4612,7 @@ func (x *GeneratedCodeInfo_Annotation) String() string { func (*GeneratedCodeInfo_Annotation) ProtoMessage() {} func (x *GeneratedCodeInfo_Annotation) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[32] + mi := &file_google_protobuf_descriptor_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4462,7 +4669,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\n" + " google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n" + "\x11FileDescriptorSet\x128\n" + - "\x04file\x18\x01 \x03(\v2$.google.protobuf.FileDescriptorProtoR\x04file*\f\b\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\x98\x05\n" + + "\x04file\x18\x01 \x03(\v2$.google.protobuf.FileDescriptorProtoR\x04file*\f\b\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n" + "\x13FileDescriptorProto\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" + "\apackage\x18\x02 \x01(\tR\apackage\x12\x1e\n" + @@ -4471,7 +4678,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "dependency\x12+\n" + "\x11public_dependency\x18\n" + " \x03(\x05R\x10publicDependency\x12'\n" + - "\x0fweak_dependency\x18\v \x03(\x05R\x0eweakDependency\x12C\n" + + "\x0fweak_dependency\x18\v \x03(\x05R\x0eweakDependency\x12+\n" + + "\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12C\n" + "\fmessage_type\x18\x04 \x03(\v2 .google.protobuf.DescriptorProtoR\vmessageType\x12A\n" + "\tenum_type\x18\x05 \x03(\v2$.google.protobuf.EnumDescriptorProtoR\benumType\x12A\n" + "\aservice\x18\x06 \x03(\v2'.google.protobuf.ServiceDescriptorProtoR\aservice\x12C\n" + @@ -4479,7 +4687,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\aoptions\x18\b \x01(\v2\x1c.google.protobuf.FileOptionsR\aoptions\x12I\n" + "\x10source_code_info\x18\t \x01(\v2\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n" + "\x06syntax\x18\f \x01(\tR\x06syntax\x122\n" + - "\aedition\x18\x0e \x01(\x0e2\x18.google.protobuf.EditionR\aedition\"\xb9\x06\n" + + "\aedition\x18\x0e \x01(\x0e2\x18.google.protobuf.EditionR\aedition\"\xfc\x06\n" + "\x0fDescriptorProto\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12;\n" + "\x05field\x18\x02 \x03(\v2%.google.protobuf.FieldDescriptorProtoR\x05field\x12C\n" + @@ -4493,7 +4701,10 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\aoptions\x18\a \x01(\v2\x1f.google.protobuf.MessageOptionsR\aoptions\x12U\n" + "\x0ereserved_range\x18\t \x03(\v2..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n" + "\rreserved_name\x18\n" + - " \x03(\tR\freservedName\x1az\n" + + " \x03(\tR\freservedName\x12A\n" + + "\n" + + "visibility\x18\v \x01(\x0e2!.google.protobuf.SymbolVisibilityR\n" + + "visibility\x1az\n" + "\x0eExtensionRange\x12\x14\n" + "\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" + "\x03end\x18\x02 \x01(\x05R\x03end\x12@\n" + @@ -4562,13 +4773,16 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x0eLABEL_REQUIRED\x10\x02\"c\n" + "\x14OneofDescriptorProto\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x127\n" + - "\aoptions\x18\x02 \x01(\v2\x1d.google.protobuf.OneofOptionsR\aoptions\"\xe3\x02\n" + + "\aoptions\x18\x02 \x01(\v2\x1d.google.protobuf.OneofOptionsR\aoptions\"\xa6\x03\n" + "\x13EnumDescriptorProto\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12?\n" + "\x05value\x18\x02 \x03(\v2).google.protobuf.EnumValueDescriptorProtoR\x05value\x126\n" + "\aoptions\x18\x03 \x01(\v2\x1c.google.protobuf.EnumOptionsR\aoptions\x12]\n" + "\x0ereserved_range\x18\x04 \x03(\v26.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n" + - "\rreserved_name\x18\x05 \x03(\tR\freservedName\x1a;\n" + + "\rreserved_name\x18\x05 \x03(\tR\freservedName\x12A\n" + + "\n" + + "visibility\x18\x06 \x01(\x0e2!.google.protobuf.SymbolVisibilityR\n" + + "visibility\x1a;\n" + "\x11EnumReservedRange\x12\x14\n" + "\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" + "\x03end\x18\x02 \x01(\x05R\x03end\"\x83\x01\n" + @@ -4728,7 +4942,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x0faggregate_value\x18\b \x01(\tR\x0eaggregateValue\x1aJ\n" + "\bNamePart\x12\x1b\n" + "\tname_part\x18\x01 \x02(\tR\bnamePart\x12!\n" + - "\fis_extension\x18\x02 \x02(\bR\visExtension\"\xae\f\n" + + "\fis_extension\x18\x02 \x02(\bR\visExtension\"\x8e\x0f\n" + "\n" + "FeatureSet\x12\x91\x01\n" + "\x0efield_presence\x18\x01 \x01(\x0e2).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\bEXPLICIT\x18\x84\a\xa2\x01\r\x12\bIMPLICIT\x18\xe7\a\xa2\x01\r\x12\bEXPLICIT\x18\xe8\a\xb2\x01\x03\b\xe8\aR\rfieldPresence\x12l\n" + @@ -4739,7 +4953,18 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\vjson_format\x18\x06 \x01(\x0e2&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\a\xa2\x01\n" + "\x12\x05ALLOW\x18\xe7\a\xb2\x01\x03\b\xe8\aR\n" + "jsonFormat\x12\xab\x01\n" + - "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\"\\\n" + + "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" + + "\x19default_symbol_visibility\x18\b \x01(\x0e2E.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityB6\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\n" + + "EXPORT_ALL\x18\x84\a\xa2\x01\x15\x12\x10EXPORT_TOP_LEVEL\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x17defaultSymbolVisibility\x1a\xa1\x01\n" + + "\x11VisibilityFeature\"\x81\x01\n" + + "\x17DefaultSymbolVisibility\x12%\n" + + "!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n" + + "\n" + + "EXPORT_ALL\x10\x01\x12\x14\n" + + "\x10EXPORT_TOP_LEVEL\x10\x02\x12\r\n" + + "\tLOCAL_ALL\x10\x03\x12\n" + + "\n" + + "\x06STRICT\x10\x04J\b\b\x01\x10\x80\x80\x80\x80\x02\"\\\n" + "\rFieldPresence\x12\x1a\n" + "\x16FIELD_PRESENCE_UNKNOWN\x10\x00\x12\f\n" + "\bEXPLICIT\x10\x01\x12\f\n" + @@ -4817,7 +5042,11 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x17EDITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n" + "\x17EDITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n" + "\x17EDITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n" + - "\vEDITION_MAX\x10\xff\xff\xff\xff\aB~\n" + + "\vEDITION_MAX\x10\xff\xff\xff\xff\a*U\n" + + "\x10SymbolVisibility\x12\x14\n" + + "\x10VISIBILITY_UNSET\x10\x00\x12\x14\n" + + "\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n" + + "\x11VISIBILITY_EXPORT\x10\x02B~\n" + "\x13com.google.protobufB\x10DescriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection" var ( @@ -4832,145 +5061,151 @@ func file_google_protobuf_descriptor_proto_rawDescGZIP() []byte { return file_google_protobuf_descriptor_proto_rawDescData } -var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 18) -var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 20) +var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_google_protobuf_descriptor_proto_goTypes = []any{ - (Edition)(0), // 0: google.protobuf.Edition - (ExtensionRangeOptions_VerificationState)(0), // 1: google.protobuf.ExtensionRangeOptions.VerificationState - (FieldDescriptorProto_Type)(0), // 2: google.protobuf.FieldDescriptorProto.Type - (FieldDescriptorProto_Label)(0), // 3: google.protobuf.FieldDescriptorProto.Label - (FileOptions_OptimizeMode)(0), // 4: google.protobuf.FileOptions.OptimizeMode - (FieldOptions_CType)(0), // 5: google.protobuf.FieldOptions.CType - (FieldOptions_JSType)(0), // 6: google.protobuf.FieldOptions.JSType - (FieldOptions_OptionRetention)(0), // 7: google.protobuf.FieldOptions.OptionRetention - (FieldOptions_OptionTargetType)(0), // 8: google.protobuf.FieldOptions.OptionTargetType - (MethodOptions_IdempotencyLevel)(0), // 9: google.protobuf.MethodOptions.IdempotencyLevel - (FeatureSet_FieldPresence)(0), // 10: google.protobuf.FeatureSet.FieldPresence - (FeatureSet_EnumType)(0), // 11: google.protobuf.FeatureSet.EnumType - (FeatureSet_RepeatedFieldEncoding)(0), // 12: google.protobuf.FeatureSet.RepeatedFieldEncoding - (FeatureSet_Utf8Validation)(0), // 13: google.protobuf.FeatureSet.Utf8Validation - (FeatureSet_MessageEncoding)(0), // 14: google.protobuf.FeatureSet.MessageEncoding - (FeatureSet_JsonFormat)(0), // 15: google.protobuf.FeatureSet.JsonFormat - (FeatureSet_EnforceNamingStyle)(0), // 16: google.protobuf.FeatureSet.EnforceNamingStyle - (GeneratedCodeInfo_Annotation_Semantic)(0), // 17: google.protobuf.GeneratedCodeInfo.Annotation.Semantic - (*FileDescriptorSet)(nil), // 18: google.protobuf.FileDescriptorSet - (*FileDescriptorProto)(nil), // 19: google.protobuf.FileDescriptorProto - (*DescriptorProto)(nil), // 20: google.protobuf.DescriptorProto - (*ExtensionRangeOptions)(nil), // 21: google.protobuf.ExtensionRangeOptions - (*FieldDescriptorProto)(nil), // 22: google.protobuf.FieldDescriptorProto - (*OneofDescriptorProto)(nil), // 23: google.protobuf.OneofDescriptorProto - (*EnumDescriptorProto)(nil), // 24: google.protobuf.EnumDescriptorProto - (*EnumValueDescriptorProto)(nil), // 25: google.protobuf.EnumValueDescriptorProto - (*ServiceDescriptorProto)(nil), // 26: google.protobuf.ServiceDescriptorProto - (*MethodDescriptorProto)(nil), // 27: google.protobuf.MethodDescriptorProto - (*FileOptions)(nil), // 28: google.protobuf.FileOptions - (*MessageOptions)(nil), // 29: google.protobuf.MessageOptions - (*FieldOptions)(nil), // 30: google.protobuf.FieldOptions - (*OneofOptions)(nil), // 31: google.protobuf.OneofOptions - (*EnumOptions)(nil), // 32: google.protobuf.EnumOptions - (*EnumValueOptions)(nil), // 33: google.protobuf.EnumValueOptions - (*ServiceOptions)(nil), // 34: google.protobuf.ServiceOptions - (*MethodOptions)(nil), // 35: google.protobuf.MethodOptions - (*UninterpretedOption)(nil), // 36: google.protobuf.UninterpretedOption - (*FeatureSet)(nil), // 37: google.protobuf.FeatureSet - (*FeatureSetDefaults)(nil), // 38: google.protobuf.FeatureSetDefaults - (*SourceCodeInfo)(nil), // 39: google.protobuf.SourceCodeInfo - (*GeneratedCodeInfo)(nil), // 40: google.protobuf.GeneratedCodeInfo - (*DescriptorProto_ExtensionRange)(nil), // 41: google.protobuf.DescriptorProto.ExtensionRange - (*DescriptorProto_ReservedRange)(nil), // 42: google.protobuf.DescriptorProto.ReservedRange - (*ExtensionRangeOptions_Declaration)(nil), // 43: google.protobuf.ExtensionRangeOptions.Declaration - (*EnumDescriptorProto_EnumReservedRange)(nil), // 44: google.protobuf.EnumDescriptorProto.EnumReservedRange - (*FieldOptions_EditionDefault)(nil), // 45: google.protobuf.FieldOptions.EditionDefault - (*FieldOptions_FeatureSupport)(nil), // 46: google.protobuf.FieldOptions.FeatureSupport - (*UninterpretedOption_NamePart)(nil), // 47: google.protobuf.UninterpretedOption.NamePart - (*FeatureSetDefaults_FeatureSetEditionDefault)(nil), // 48: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault - (*SourceCodeInfo_Location)(nil), // 49: google.protobuf.SourceCodeInfo.Location - (*GeneratedCodeInfo_Annotation)(nil), // 50: google.protobuf.GeneratedCodeInfo.Annotation + (Edition)(0), // 0: google.protobuf.Edition + (SymbolVisibility)(0), // 1: google.protobuf.SymbolVisibility + (ExtensionRangeOptions_VerificationState)(0), // 2: google.protobuf.ExtensionRangeOptions.VerificationState + (FieldDescriptorProto_Type)(0), // 3: google.protobuf.FieldDescriptorProto.Type + (FieldDescriptorProto_Label)(0), // 4: google.protobuf.FieldDescriptorProto.Label + (FileOptions_OptimizeMode)(0), // 5: google.protobuf.FileOptions.OptimizeMode + (FieldOptions_CType)(0), // 6: google.protobuf.FieldOptions.CType + (FieldOptions_JSType)(0), // 7: google.protobuf.FieldOptions.JSType + (FieldOptions_OptionRetention)(0), // 8: google.protobuf.FieldOptions.OptionRetention + (FieldOptions_OptionTargetType)(0), // 9: google.protobuf.FieldOptions.OptionTargetType + (MethodOptions_IdempotencyLevel)(0), // 10: google.protobuf.MethodOptions.IdempotencyLevel + (FeatureSet_FieldPresence)(0), // 11: google.protobuf.FeatureSet.FieldPresence + (FeatureSet_EnumType)(0), // 12: google.protobuf.FeatureSet.EnumType + (FeatureSet_RepeatedFieldEncoding)(0), // 13: google.protobuf.FeatureSet.RepeatedFieldEncoding + (FeatureSet_Utf8Validation)(0), // 14: google.protobuf.FeatureSet.Utf8Validation + (FeatureSet_MessageEncoding)(0), // 15: google.protobuf.FeatureSet.MessageEncoding + (FeatureSet_JsonFormat)(0), // 16: google.protobuf.FeatureSet.JsonFormat + (FeatureSet_EnforceNamingStyle)(0), // 17: google.protobuf.FeatureSet.EnforceNamingStyle + (FeatureSet_VisibilityFeature_DefaultSymbolVisibility)(0), // 18: google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility + (GeneratedCodeInfo_Annotation_Semantic)(0), // 19: google.protobuf.GeneratedCodeInfo.Annotation.Semantic + (*FileDescriptorSet)(nil), // 20: google.protobuf.FileDescriptorSet + (*FileDescriptorProto)(nil), // 21: google.protobuf.FileDescriptorProto + (*DescriptorProto)(nil), // 22: google.protobuf.DescriptorProto + (*ExtensionRangeOptions)(nil), // 23: google.protobuf.ExtensionRangeOptions + (*FieldDescriptorProto)(nil), // 24: google.protobuf.FieldDescriptorProto + (*OneofDescriptorProto)(nil), // 25: google.protobuf.OneofDescriptorProto + (*EnumDescriptorProto)(nil), // 26: google.protobuf.EnumDescriptorProto + (*EnumValueDescriptorProto)(nil), // 27: google.protobuf.EnumValueDescriptorProto + (*ServiceDescriptorProto)(nil), // 28: google.protobuf.ServiceDescriptorProto + (*MethodDescriptorProto)(nil), // 29: google.protobuf.MethodDescriptorProto + (*FileOptions)(nil), // 30: google.protobuf.FileOptions + (*MessageOptions)(nil), // 31: google.protobuf.MessageOptions + (*FieldOptions)(nil), // 32: google.protobuf.FieldOptions + (*OneofOptions)(nil), // 33: google.protobuf.OneofOptions + (*EnumOptions)(nil), // 34: google.protobuf.EnumOptions + (*EnumValueOptions)(nil), // 35: google.protobuf.EnumValueOptions + (*ServiceOptions)(nil), // 36: google.protobuf.ServiceOptions + (*MethodOptions)(nil), // 37: google.protobuf.MethodOptions + (*UninterpretedOption)(nil), // 38: google.protobuf.UninterpretedOption + (*FeatureSet)(nil), // 39: google.protobuf.FeatureSet + (*FeatureSetDefaults)(nil), // 40: google.protobuf.FeatureSetDefaults + (*SourceCodeInfo)(nil), // 41: google.protobuf.SourceCodeInfo + (*GeneratedCodeInfo)(nil), // 42: google.protobuf.GeneratedCodeInfo + (*DescriptorProto_ExtensionRange)(nil), // 43: google.protobuf.DescriptorProto.ExtensionRange + (*DescriptorProto_ReservedRange)(nil), // 44: google.protobuf.DescriptorProto.ReservedRange + (*ExtensionRangeOptions_Declaration)(nil), // 45: google.protobuf.ExtensionRangeOptions.Declaration + (*EnumDescriptorProto_EnumReservedRange)(nil), // 46: google.protobuf.EnumDescriptorProto.EnumReservedRange + (*FieldOptions_EditionDefault)(nil), // 47: google.protobuf.FieldOptions.EditionDefault + (*FieldOptions_FeatureSupport)(nil), // 48: google.protobuf.FieldOptions.FeatureSupport + (*UninterpretedOption_NamePart)(nil), // 49: google.protobuf.UninterpretedOption.NamePart + (*FeatureSet_VisibilityFeature)(nil), // 50: google.protobuf.FeatureSet.VisibilityFeature + (*FeatureSetDefaults_FeatureSetEditionDefault)(nil), // 51: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault + (*SourceCodeInfo_Location)(nil), // 52: google.protobuf.SourceCodeInfo.Location + (*GeneratedCodeInfo_Annotation)(nil), // 53: google.protobuf.GeneratedCodeInfo.Annotation } var file_google_protobuf_descriptor_proto_depIdxs = []int32{ - 19, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto - 20, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto - 24, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto - 26, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto - 22, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto - 28, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions - 39, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo + 21, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto + 22, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto + 26, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto + 28, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto + 24, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto + 30, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions + 41, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo 0, // 7: google.protobuf.FileDescriptorProto.edition:type_name -> google.protobuf.Edition - 22, // 8: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto - 22, // 9: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto - 20, // 10: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto - 24, // 11: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto - 41, // 12: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange - 23, // 13: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto - 29, // 14: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions - 42, // 15: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange - 36, // 16: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 43, // 17: google.protobuf.ExtensionRangeOptions.declaration:type_name -> google.protobuf.ExtensionRangeOptions.Declaration - 37, // 18: google.protobuf.ExtensionRangeOptions.features:type_name -> google.protobuf.FeatureSet - 1, // 19: google.protobuf.ExtensionRangeOptions.verification:type_name -> google.protobuf.ExtensionRangeOptions.VerificationState - 3, // 20: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label - 2, // 21: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type - 30, // 22: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions - 31, // 23: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions - 25, // 24: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto - 32, // 25: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions - 44, // 26: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange - 33, // 27: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions - 27, // 28: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto - 34, // 29: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions - 35, // 30: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions - 4, // 31: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode - 37, // 32: google.protobuf.FileOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 33: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 37, // 34: google.protobuf.MessageOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 35: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 5, // 36: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType - 6, // 37: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType - 7, // 38: google.protobuf.FieldOptions.retention:type_name -> google.protobuf.FieldOptions.OptionRetention - 8, // 39: google.protobuf.FieldOptions.targets:type_name -> google.protobuf.FieldOptions.OptionTargetType - 45, // 40: google.protobuf.FieldOptions.edition_defaults:type_name -> google.protobuf.FieldOptions.EditionDefault - 37, // 41: google.protobuf.FieldOptions.features:type_name -> google.protobuf.FeatureSet - 46, // 42: google.protobuf.FieldOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport - 36, // 43: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 37, // 44: google.protobuf.OneofOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 45: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 37, // 46: google.protobuf.EnumOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 47: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 37, // 48: google.protobuf.EnumValueOptions.features:type_name -> google.protobuf.FeatureSet - 46, // 49: google.protobuf.EnumValueOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport - 36, // 50: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 37, // 51: google.protobuf.ServiceOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 52: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 9, // 53: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel - 37, // 54: google.protobuf.MethodOptions.features:type_name -> google.protobuf.FeatureSet - 36, // 55: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 47, // 56: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart - 10, // 57: google.protobuf.FeatureSet.field_presence:type_name -> google.protobuf.FeatureSet.FieldPresence - 11, // 58: google.protobuf.FeatureSet.enum_type:type_name -> google.protobuf.FeatureSet.EnumType - 12, // 59: google.protobuf.FeatureSet.repeated_field_encoding:type_name -> google.protobuf.FeatureSet.RepeatedFieldEncoding - 13, // 60: google.protobuf.FeatureSet.utf8_validation:type_name -> google.protobuf.FeatureSet.Utf8Validation - 14, // 61: google.protobuf.FeatureSet.message_encoding:type_name -> google.protobuf.FeatureSet.MessageEncoding - 15, // 62: google.protobuf.FeatureSet.json_format:type_name -> google.protobuf.FeatureSet.JsonFormat - 16, // 63: google.protobuf.FeatureSet.enforce_naming_style:type_name -> google.protobuf.FeatureSet.EnforceNamingStyle - 48, // 64: google.protobuf.FeatureSetDefaults.defaults:type_name -> google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault - 0, // 65: google.protobuf.FeatureSetDefaults.minimum_edition:type_name -> google.protobuf.Edition - 0, // 66: google.protobuf.FeatureSetDefaults.maximum_edition:type_name -> google.protobuf.Edition - 49, // 67: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location - 50, // 68: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation - 21, // 69: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions - 0, // 70: google.protobuf.FieldOptions.EditionDefault.edition:type_name -> google.protobuf.Edition - 0, // 71: google.protobuf.FieldOptions.FeatureSupport.edition_introduced:type_name -> google.protobuf.Edition - 0, // 72: google.protobuf.FieldOptions.FeatureSupport.edition_deprecated:type_name -> google.protobuf.Edition - 0, // 73: google.protobuf.FieldOptions.FeatureSupport.edition_removed:type_name -> google.protobuf.Edition - 0, // 74: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition:type_name -> google.protobuf.Edition - 37, // 75: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features:type_name -> google.protobuf.FeatureSet - 37, // 76: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features:type_name -> google.protobuf.FeatureSet - 17, // 77: google.protobuf.GeneratedCodeInfo.Annotation.semantic:type_name -> google.protobuf.GeneratedCodeInfo.Annotation.Semantic - 78, // [78:78] is the sub-list for method output_type - 78, // [78:78] is the sub-list for method input_type - 78, // [78:78] is the sub-list for extension type_name - 78, // [78:78] is the sub-list for extension extendee - 0, // [0:78] is the sub-list for field type_name + 24, // 8: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto + 24, // 9: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto + 22, // 10: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto + 26, // 11: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto + 43, // 12: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange + 25, // 13: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto + 31, // 14: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions + 44, // 15: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange + 1, // 16: google.protobuf.DescriptorProto.visibility:type_name -> google.protobuf.SymbolVisibility + 38, // 17: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 45, // 18: google.protobuf.ExtensionRangeOptions.declaration:type_name -> google.protobuf.ExtensionRangeOptions.Declaration + 39, // 19: google.protobuf.ExtensionRangeOptions.features:type_name -> google.protobuf.FeatureSet + 2, // 20: google.protobuf.ExtensionRangeOptions.verification:type_name -> google.protobuf.ExtensionRangeOptions.VerificationState + 4, // 21: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label + 3, // 22: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type + 32, // 23: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions + 33, // 24: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions + 27, // 25: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto + 34, // 26: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions + 46, // 27: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange + 1, // 28: google.protobuf.EnumDescriptorProto.visibility:type_name -> google.protobuf.SymbolVisibility + 35, // 29: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions + 29, // 30: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto + 36, // 31: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions + 37, // 32: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions + 5, // 33: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode + 39, // 34: google.protobuf.FileOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 35: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 39, // 36: google.protobuf.MessageOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 37: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 6, // 38: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType + 7, // 39: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType + 8, // 40: google.protobuf.FieldOptions.retention:type_name -> google.protobuf.FieldOptions.OptionRetention + 9, // 41: google.protobuf.FieldOptions.targets:type_name -> google.protobuf.FieldOptions.OptionTargetType + 47, // 42: google.protobuf.FieldOptions.edition_defaults:type_name -> google.protobuf.FieldOptions.EditionDefault + 39, // 43: google.protobuf.FieldOptions.features:type_name -> google.protobuf.FeatureSet + 48, // 44: google.protobuf.FieldOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport + 38, // 45: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 39, // 46: google.protobuf.OneofOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 47: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 39, // 48: google.protobuf.EnumOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 49: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 39, // 50: google.protobuf.EnumValueOptions.features:type_name -> google.protobuf.FeatureSet + 48, // 51: google.protobuf.EnumValueOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport + 38, // 52: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 39, // 53: google.protobuf.ServiceOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 54: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 10, // 55: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel + 39, // 56: google.protobuf.MethodOptions.features:type_name -> google.protobuf.FeatureSet + 38, // 57: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 49, // 58: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart + 11, // 59: google.protobuf.FeatureSet.field_presence:type_name -> google.protobuf.FeatureSet.FieldPresence + 12, // 60: google.protobuf.FeatureSet.enum_type:type_name -> google.protobuf.FeatureSet.EnumType + 13, // 61: google.protobuf.FeatureSet.repeated_field_encoding:type_name -> google.protobuf.FeatureSet.RepeatedFieldEncoding + 14, // 62: google.protobuf.FeatureSet.utf8_validation:type_name -> google.protobuf.FeatureSet.Utf8Validation + 15, // 63: google.protobuf.FeatureSet.message_encoding:type_name -> google.protobuf.FeatureSet.MessageEncoding + 16, // 64: google.protobuf.FeatureSet.json_format:type_name -> google.protobuf.FeatureSet.JsonFormat + 17, // 65: google.protobuf.FeatureSet.enforce_naming_style:type_name -> google.protobuf.FeatureSet.EnforceNamingStyle + 18, // 66: google.protobuf.FeatureSet.default_symbol_visibility:type_name -> google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility + 51, // 67: google.protobuf.FeatureSetDefaults.defaults:type_name -> google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault + 0, // 68: google.protobuf.FeatureSetDefaults.minimum_edition:type_name -> google.protobuf.Edition + 0, // 69: google.protobuf.FeatureSetDefaults.maximum_edition:type_name -> google.protobuf.Edition + 52, // 70: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location + 53, // 71: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation + 23, // 72: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions + 0, // 73: google.protobuf.FieldOptions.EditionDefault.edition:type_name -> google.protobuf.Edition + 0, // 74: google.protobuf.FieldOptions.FeatureSupport.edition_introduced:type_name -> google.protobuf.Edition + 0, // 75: google.protobuf.FieldOptions.FeatureSupport.edition_deprecated:type_name -> google.protobuf.Edition + 0, // 76: google.protobuf.FieldOptions.FeatureSupport.edition_removed:type_name -> google.protobuf.Edition + 0, // 77: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition:type_name -> google.protobuf.Edition + 39, // 78: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features:type_name -> google.protobuf.FeatureSet + 39, // 79: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features:type_name -> google.protobuf.FeatureSet + 19, // 80: google.protobuf.GeneratedCodeInfo.Annotation.semantic:type_name -> google.protobuf.GeneratedCodeInfo.Annotation.Semantic + 81, // [81:81] is the sub-list for method output_type + 81, // [81:81] is the sub-list for method input_type + 81, // [81:81] is the sub-list for extension type_name + 81, // [81:81] is the sub-list for extension extendee + 0, // [0:81] is the sub-list for field type_name } func init() { file_google_protobuf_descriptor_proto_init() } @@ -4983,8 +5218,8 @@ func file_google_protobuf_descriptor_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_descriptor_proto_rawDesc), len(file_google_protobuf_descriptor_proto_rawDesc)), - NumEnums: 18, - NumMessages: 33, + NumEnums: 20, + NumMessages: 34, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/modules.txt b/vendor/modules.txt index 82d58e046c..3dadc296fb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# cel.dev/expr v0.23.1 +# cel.dev/expr v0.24.0 ## explicit; go 1.22.0 cel.dev/expr # cloud.google.com/go v0.121.1 @@ -185,7 +185,7 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity github.com/AzureAD/microsoft-authentication-library-for-go/apps/public -# github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 +# github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 ## explicit; go 1.12 github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/grpc_gcp @@ -478,7 +478,7 @@ github.com/cloudevents/sdk-go/v2/event/datacodec/xml github.com/cloudevents/sdk-go/v2/protocol github.com/cloudevents/sdk-go/v2/protocol/http github.com/cloudevents/sdk-go/v2/types -# github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f +# github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 ## explicit; go 1.19 github.com/cncf/xds/go/udpa/annotations github.com/cncf/xds/go/udpa/type/v1 @@ -774,7 +774,7 @@ github.com/golang/snappy # github.com/google/btree v1.1.3 ## explicit; go 1.18 github.com/google/btree -# github.com/google/cel-go v0.25.0 +# github.com/google/cel-go v0.26.0 ## explicit; go 1.22.0 github.com/google/cel-go/cel github.com/google/cel-go/checker @@ -1507,7 +1507,7 @@ github.com/tektoncd/chains/pkg/chains/storage/pubsub github.com/tektoncd/chains/pkg/chains/storage/tekton github.com/tektoncd/chains/pkg/config github.com/tektoncd/chains/pkg/patch -# github.com/tektoncd/hub v1.21.0 +# github.com/tektoncd/hub v1.22.2 ## explicit; go 1.23.0 github.com/tektoncd/hub/api/pkg/cli/app github.com/tektoncd/hub/api/pkg/cli/cmd @@ -1536,7 +1536,7 @@ github.com/tektoncd/hub/api/v1/gen/http/catalog/client github.com/tektoncd/hub/api/v1/gen/http/resource/client github.com/tektoncd/hub/api/v1/gen/resource github.com/tektoncd/hub/api/v1/gen/resource/views -# github.com/tektoncd/pipeline v1.2.0 +# github.com/tektoncd/pipeline v1.3.1 ## explicit; go 1.24.0 github.com/tektoncd/pipeline/internal/artifactref github.com/tektoncd/pipeline/pkg/apis/config @@ -1638,8 +1638,8 @@ github.com/tektoncd/pipeline/test/diff # github.com/tektoncd/plumbing v0.0.0-20250430145243-3b7cd59879c1 ## explicit; go 1.23 github.com/tektoncd/plumbing/scripts -# github.com/tektoncd/triggers v0.32.0 -## explicit; go 1.23.0 +# github.com/tektoncd/triggers v0.33.0 +## explicit; go 1.24.0 github.com/tektoncd/triggers/pkg/apis/config github.com/tektoncd/triggers/pkg/apis/triggers github.com/tektoncd/triggers/pkg/apis/triggers/contexts @@ -1930,7 +1930,10 @@ go.uber.org/zap/internal/stacktrace go.uber.org/zap/internal/ztest go.uber.org/zap/zapcore go.uber.org/zap/zaptest -# goa.design/goa/v3 v3.20.1 +# go.yaml.in/yaml/v2 v2.4.2 +## explicit; go 1.15 +go.yaml.in/yaml/v2 +# goa.design/goa/v3 v3.21.1 ## explicit; go 1.23.0 goa.design/goa/v3/http goa.design/goa/v3/pkg @@ -2118,7 +2121,7 @@ google.golang.org/genproto/googleapis/api/monitoredres google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.73.0 +# google.golang.org/grpc v1.74.2 ## explicit; go 1.23.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -2246,6 +2249,19 @@ google.golang.org/grpc/xds/internal/balancer/loadstore google.golang.org/grpc/xds/internal/balancer/outlierdetection google.golang.org/grpc/xds/internal/balancer/priority google.golang.org/grpc/xds/internal/balancer/wrrlocality +google.golang.org/grpc/xds/internal/clients +google.golang.org/grpc/xds/internal/clients/grpctransport +google.golang.org/grpc/xds/internal/clients/internal +google.golang.org/grpc/xds/internal/clients/internal/backoff +google.golang.org/grpc/xds/internal/clients/internal/buffer +google.golang.org/grpc/xds/internal/clients/internal/pretty +google.golang.org/grpc/xds/internal/clients/internal/syncutil +google.golang.org/grpc/xds/internal/clients/lrsclient +google.golang.org/grpc/xds/internal/clients/lrsclient/internal +google.golang.org/grpc/xds/internal/clients/xdsclient +google.golang.org/grpc/xds/internal/clients/xdsclient/internal +google.golang.org/grpc/xds/internal/clients/xdsclient/internal/xdsresource +google.golang.org/grpc/xds/internal/clients/xdsclient/metrics google.golang.org/grpc/xds/internal/clusterspecifier google.golang.org/grpc/xds/internal/clusterspecifier/rls google.golang.org/grpc/xds/internal/httpfilter @@ -2256,17 +2272,11 @@ google.golang.org/grpc/xds/internal/resolver google.golang.org/grpc/xds/internal/resolver/internal google.golang.org/grpc/xds/internal/server google.golang.org/grpc/xds/internal/xdsclient -google.golang.org/grpc/xds/internal/xdsclient/internal -google.golang.org/grpc/xds/internal/xdsclient/load -google.golang.org/grpc/xds/internal/xdsclient/transport -google.golang.org/grpc/xds/internal/xdsclient/transport/ads -google.golang.org/grpc/xds/internal/xdsclient/transport/grpctransport -google.golang.org/grpc/xds/internal/xdsclient/transport/lrs google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry google.golang.org/grpc/xds/internal/xdsclient/xdslbregistry/converter google.golang.org/grpc/xds/internal/xdsclient/xdsresource google.golang.org/grpc/xds/internal/xdsclient/xdsresource/version -# google.golang.org/protobuf v1.36.6 +# google.golang.org/protobuf v1.36.7 ## explicit; go 1.22 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson @@ -2405,7 +2415,7 @@ k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 k8s.io/api/storagemigration/v1alpha1 -# k8s.io/apiextensions-apiserver v0.32.6 +# k8s.io/apiextensions-apiserver v0.32.7 ## explicit; go 1.23.0 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 @@ -3051,8 +3061,8 @@ sigs.k8s.io/structured-merge-diff/v4/merge sigs.k8s.io/structured-merge-diff/v4/schema sigs.k8s.io/structured-merge-diff/v4/typed sigs.k8s.io/structured-merge-diff/v4/value -# sigs.k8s.io/yaml v1.4.0 -## explicit; go 1.12 +# sigs.k8s.io/yaml v1.6.0 +## explicit; go 1.22 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 # github.com/alibabacloud-go/cr-20160607 => github.com/vdemeester/cr-20160607 v1.0.1 diff --git a/vendor/sigs.k8s.io/yaml/.travis.yml b/vendor/sigs.k8s.io/yaml/.travis.yml deleted file mode 100644 index 54ed8f9cb9..0000000000 --- a/vendor/sigs.k8s.io/yaml/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go -arch: arm64 -dist: focal -go: 1.15.x -script: - - diff -u <(echo -n) <(gofmt -d *.go) - - diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON) - - GO111MODULE=on go vet . - - GO111MODULE=on go test -v -race ./... - - git diff --exit-code -install: - - GO111MODULE=off go get golang.org/x/lint/golint diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS b/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS deleted file mode 100644 index 73be0a3a9b..0000000000 --- a/vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS +++ /dev/null @@ -1,24 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: -- dims -- jpbetz -- smarterclayton -- deads2k -- sttts -- liggitt -- natasha41575 -- knverey -reviewers: -- dims -- thockin -- jpbetz -- smarterclayton -- deads2k -- derekwaynecarr -- mikedanese -- liggitt -- sttts -- tallclair -labels: -- sig/api-machinery diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/README.md b/vendor/sigs.k8s.io/yaml/goyaml.v2/README.md index 53f4139dc3..9a8f1e6782 100644 --- a/vendor/sigs.k8s.io/yaml/goyaml.v2/README.md +++ b/vendor/sigs.k8s.io/yaml/goyaml.v2/README.md @@ -1,143 +1,71 @@ -# go-yaml fork +# goyaml.v2 -This package is a fork of the go-yaml library and is intended solely for consumption -by kubernetes projects. In this fork, we plan to support only critical changes required for -kubernetes, such as small bug fixes and regressions. Larger, general-purpose feature requests -should be made in the upstream go-yaml library, and we will reject such changes in this fork -unless we are pulling them from upstream. +This package provides type and function aliases for the `go.yaml.in/yaml/v2` package (which is compatible with `gopkg.in/yaml.v2`). -This fork is based on v2.4.0: https://github.com/go-yaml/yaml/releases/tag/v2.4.0 +## Purpose -# YAML support for the Go language - -Introduction ------------- - -The yaml package enables Go programs to comfortably encode and decode YAML -values. It was developed within [Canonical](https://www.canonical.com) as -part of the [juju](https://juju.ubuntu.com) project, and is based on a -pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) -C library to parse and generate YAML data quickly and reliably. - -Compatibility -------------- - -The yaml package supports most of YAML 1.1 and 1.2, including support for -anchors, tags, map merging, etc. Multi-document unmarshalling is not yet -implemented, and base-60 floats from YAML 1.1 are purposefully not -supported since they're a poor design and are gone in YAML 1.2. - -Installation and usage ----------------------- - -The import path for the package is *gopkg.in/yaml.v2*. - -To install it, run: - - go get gopkg.in/yaml.v2 - -API documentation ------------------ - -If opened in a browser, the import path itself leads to the API documentation: - - * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) - -API stability -------------- - -The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). - - -License -------- - -The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. - - -Example -------- - -```Go -package main - -import ( - "fmt" - "log" - - "gopkg.in/yaml.v2" -) - -var data = ` -a: Easy! -b: - c: 2 - d: [3, 4] -` - -// Note: struct fields must be public in order for unmarshal to -// correctly populate the data. -type T struct { - A string - B struct { - RenamedC int `yaml:"c"` - D []int `yaml:",flow"` - } -} - -func main() { - t := T{} - - err := yaml.Unmarshal([]byte(data), &t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t:\n%v\n\n", t) - - d, err := yaml.Marshal(&t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t dump:\n%s\n\n", string(d)) - - m := make(map[interface{}]interface{}) - - err = yaml.Unmarshal([]byte(data), &m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m:\n%v\n\n", m) - - d, err = yaml.Marshal(&m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m dump:\n%s\n\n", string(d)) -} -``` +The purpose of this package is to: -This example will generate the following output: +1. Provide a transition path for users migrating from the sigs.k8s.io/yaml package to direct usage of go.yaml.in/yaml/v2 +2. Maintain compatibility with existing code while encouraging migration to the upstream package +3. Reduce maintenance overhead by delegating to the upstream implementation +## Usage + +Instead of importing this package directly, you should migrate to using `go.yaml.in/yaml/v2` directly: + +```go +// Old way +import "sigs.k8s.io/yaml/goyaml.v2" + +// Recommended way +import "go.yaml.in/yaml/v2" ``` ---- t: -{Easy! {2 [3 4]}} - ---- t dump: -a: Easy! -b: - c: 2 - d: [3, 4] - - ---- m: -map[a:Easy! b:map[c:2 d:[3 4]]] - ---- m dump: -a: Easy! -b: - c: 2 - d: - - 3 - - 4 -``` +## Available Types and Functions + +All public types and functions from `go.yaml.in/yaml/v2` are available through this package: + +### Types + +- `MapSlice` - Encodes and decodes as a YAML map with preserved key order +- `MapItem` - An item in a MapSlice +- `Unmarshaler` - Interface for custom unmarshaling behavior +- `Marshaler` - Interface for custom marshaling behavior +- `IsZeroer` - Interface to check if an object is zero +- `Decoder` - Reads and decodes YAML values from an input stream +- `Encoder` - Writes YAML values to an output stream +- `TypeError` - Error returned by Unmarshal for decoding issues + +### Functions + +- `Unmarshal` - Decodes YAML data into a Go value +- `UnmarshalStrict` - Like Unmarshal but errors on unknown fields +- `Marshal` - Serializes a Go value into YAML +- `NewDecoder` - Creates a new Decoder +- `NewEncoder` - Creates a new Encoder +- `FutureLineWrap` - Controls line wrapping behavior + +## Migration Guide + +To migrate from this package to `go.yaml.in/yaml/v2`: + +1. Update your import statements: + ```go + // From + import "sigs.k8s.io/yaml/goyaml.v2" + + // To + import "go.yaml.in/yaml/v2" + ``` + +2. No code changes should be necessary as the API is identical + +3. Update your go.mod file to include the dependency: + ``` + require go.yaml.in/yaml/v2 v2.4.2 + ``` + +## Deprecation Notice + +All types and functions in this package are marked as deprecated. You should migrate to using `go.yaml.in/yaml/v2` directly. diff --git a/vendor/sigs.k8s.io/yaml/goyaml.v2/yaml_aliases.go b/vendor/sigs.k8s.io/yaml/goyaml.v2/yaml_aliases.go new file mode 100644 index 0000000000..8c82bc2cb9 --- /dev/null +++ b/vendor/sigs.k8s.io/yaml/goyaml.v2/yaml_aliases.go @@ -0,0 +1,85 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package yaml + +import ( + gopkg_yaml "go.yaml.in/yaml/v2" +) + +// Type aliases for public types from go.yaml.in/yaml/v2 +type ( + // MapSlice encodes and decodes as a YAML map. + // The order of keys is preserved when encoding and decoding. + // Deprecated: Use go.yaml.in/yaml/v2.MapSlice directly. + MapSlice = gopkg_yaml.MapSlice + + // MapItem is an item in a MapSlice. + // Deprecated: Use go.yaml.in/yaml/v2.MapItem directly. + MapItem = gopkg_yaml.MapItem + + // Unmarshaler is implemented by types to customize their behavior when being unmarshaled from a YAML document. + // Deprecated: Use go.yaml.in/yaml/v2.Unmarshaler directly. + Unmarshaler = gopkg_yaml.Unmarshaler + + // Marshaler is implemented by types to customize their behavior when being marshaled into a YAML document. + // Deprecated: Use go.yaml.in/yaml/v2.Marshaler directly. + Marshaler = gopkg_yaml.Marshaler + + // IsZeroer is used to check whether an object is zero to determine whether it should be omitted when + // marshaling with the omitempty flag. One notable implementation is time.Time. + // Deprecated: Use go.yaml.in/yaml/v2.IsZeroer directly. + IsZeroer = gopkg_yaml.IsZeroer + + // Decoder reads and decodes YAML values from an input stream. + // Deprecated: Use go.yaml.in/yaml/v2.Decoder directly. + Decoder = gopkg_yaml.Decoder + + // Encoder writes YAML values to an output stream. + // Deprecated: Use go.yaml.in/yaml/v2.Encoder directly. + Encoder = gopkg_yaml.Encoder + + // TypeError is returned by Unmarshal when one or more fields in the YAML document cannot be properly decoded. + // Deprecated: Use go.yaml.in/yaml/v2.TypeError directly. + TypeError = gopkg_yaml.TypeError +) + +// Function aliases for public functions from go.yaml.in/yaml/v2 +var ( + // Unmarshal decodes the first document found within the in byte slice and assigns decoded values into the out value. + // Deprecated: Use go.yaml.in/yaml/v2.Unmarshal directly. + Unmarshal = gopkg_yaml.Unmarshal + + // UnmarshalStrict is like Unmarshal except that any fields that are found in the data that do not have corresponding struct members will result in an error. + // Deprecated: Use go.yaml.in/yaml/v2.UnmarshalStrict directly. + UnmarshalStrict = gopkg_yaml.UnmarshalStrict + + // Marshal serializes the value provided into a YAML document. + // Deprecated: Use go.yaml.in/yaml/v2.Marshal directly. + Marshal = gopkg_yaml.Marshal + + // NewDecoder returns a new decoder that reads from r. + // Deprecated: Use go.yaml.in/yaml/v2.NewDecoder directly. + NewDecoder = gopkg_yaml.NewDecoder + + // NewEncoder returns a new encoder that writes to w. + // Deprecated: Use go.yaml.in/yaml/v2.NewEncoder directly. + NewEncoder = gopkg_yaml.NewEncoder + + // FutureLineWrap globally disables line wrapping when encoding long strings. + // Deprecated: Use go.yaml.in/yaml/v2.FutureLineWrap directly. + FutureLineWrap = gopkg_yaml.FutureLineWrap +) diff --git a/vendor/sigs.k8s.io/yaml/yaml.go b/vendor/sigs.k8s.io/yaml/yaml.go index fc10246bdb..aa01acd45d 100644 --- a/vendor/sigs.k8s.io/yaml/yaml.go +++ b/vendor/sigs.k8s.io/yaml/yaml.go @@ -24,7 +24,7 @@ import ( "reflect" "strconv" - "sigs.k8s.io/yaml/goyaml.v2" + "go.yaml.in/yaml/v2" ) // Marshal marshals obj into JSON using stdlib json.Marshal, and then converts JSON to YAML using JSONToYAML (see that method for more reference) @@ -92,7 +92,7 @@ func jsonUnmarshal(reader io.Reader, obj interface{}, opts ...JSONOpt) error { d = opt(d) } if err := d.Decode(&obj); err != nil { - return fmt.Errorf("while decoding JSON: %v", err) + return fmt.Errorf("while decoding JSON: %w", err) } return nil } @@ -417,3 +417,10 @@ func jsonToYAMLValue(j interface{}) interface{} { } return j } + +// DisallowUnknownFields configures the JSON decoder to error out if unknown +// fields come along, instead of dropping them by default. +func DisallowUnknownFields(d *json.Decoder) *json.Decoder { + d.DisallowUnknownFields() + return d +} diff --git a/vendor/sigs.k8s.io/yaml/yaml_go110.go b/vendor/sigs.k8s.io/yaml/yaml_go110.go deleted file mode 100644 index 94abc1719d..0000000000 --- a/vendor/sigs.k8s.io/yaml/yaml_go110.go +++ /dev/null @@ -1,31 +0,0 @@ -// This file contains changes that are only compatible with go 1.10 and onwards. - -//go:build go1.10 -// +build go1.10 - -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package yaml - -import "encoding/json" - -// DisallowUnknownFields configures the JSON decoder to error out if unknown -// fields come along, instead of dropping them by default. -func DisallowUnknownFields(d *json.Decoder) *json.Decoder { - d.DisallowUnknownFields() - return d -}